URLs can be long and ugly as fuck, littered with special LaTeX-reserved characters like “#
”, “_
”, “”, “
&
”, “”, “
~
”, …etc.
The hyperref package apparently does some sophisticated gymnastics to handle the special chars. The \url{}
and \href{}{}
macros work for most (if not all) chars. But it becomes a shit-show when the same URL is used in multiple places in multiple representations. E.g. I often need to have a hyperlink as a readable string that visits an URL when clicked. \href
from the hyperref
pkg does that. But of course the URL is lost when the doc is printed. So the URL needs to become a footnote, which means the shitty-looking ungodly long URL must be entered twice. For example, a first attempt might look like this:
The \href{https://lemmy.sdf.org/c/tex_typesetting}{TeX community}\footnote{\scriptsize\verb|https://lemmy.sdf.org/c/tex_typesetting|} is where we discuss `\LaTeX`.
There is an underscore, which probably has to be escaped in the \verb
but not the \href
(not sure ATM- it’s hard to keep track of all the exceptions). Of course it’s quite annoying that the URL appears twice. So the temptation to thwart redundancy leads to this:
\newcommand{\hardlink}[2]{\href{#1}{#2}\footnote{\scriptsize#1}}
Disaster, because some chars need to be escaped for the footnote but if you escape those same chars for the \href
, the backslashes appear literally in the hyperlink which is broken as a result. Another problem is when using minipages to get two columns, the footnote width is cut in half thus forcing long URLs to wrap at the horizontal midpoint of the page instead of continuing and using the wasted footer space under the right column. \mbox
fixes that. So after much fiddling with blind hacks like \urlescape
, \noexpandarg
, \normalexpandarg
, and \expandafter
, I arrived at this:
\newcommand{\hardlink}[2]{\href{#1}{#2}\footnote{\scriptsize\mbox{\detokenize{#1}}}}
The \detokenize
works for some special chars but not others. So still a fuckin’ mess. A LaTeX wizard of sorts went off to work on this problem for me, and came up with this:
\makeatletter
% NOTE: The following is an ugly hack that temporary redefines an internal
% command of hyperref to process the verbatim URL. There is no warranty
% and no support for this code or documents using this code!
\newcommand*{\footnotelink}{%
\global\let\original@hyper@@link\hyper@@link
\let\hyper@@link\onetime@special@hyper@@link% ugly hack
\href
}
\newcommand*{\onetime@special@hyper@@link}[3]{%
\global\let\hyper@@link\original@hyper@@link% ugly hack
\hyper@@link{#1}{#2}{#3}%
\IfArgIsEmpty{#2}{\footnote{\tiny\nolinkurl{#1}}}{\footnote{\tiny\nolinkurl{#1\##2}}}%
}
\makeatother
That monstrosity is the nuclear option that works in most cases. But IIRC it still fucks up in some situations, so I must use a combination of \hardlink
and \footnotelink
.
But what about QR codes? Fuck me. Another dimension of the same problem. Producing a doc with QR codes but not the URL strips the reader of some dignity. But a footnote is a bad way to expand a barcode. The URL should appear close to the QR code so the reader need not hunt for it. But URL size and circumstances ensure we cannot simply make a macro that hard codes it. Every layout situation is different.
Having a bibliography section helps force a standard presentation, but that still requires the URL to be repeated and we don’t necessarily want to be forced to have a bibliography anyway.
What we really need is an URL database, which maps tokens to URLs in the preamble. Consider how the datetime2
pkg works. You can store a list of dates like this:
\DTMsavedate{event1}{2021-12-10}
\DTMsavedate{event2}{2022-02-21}
\DTMsavedate{event3}{2022-03-10}
…
\begin{document}
yada yada \DTMusedate{event1} yada yada \DTMsetstyle{ddmmyyyy}\DTMusedate{event3}…
lorem ipsum \DTMsetstyle{mmddyyyy}\DTMusedate{event2} lorem ipsum \DTMsetdatestyle{default}\DTMsetup{datesep=/}\DTMusedate{event1} …etc.
We need that for URLs. Simply making a \newcommand
for each URL would not work because \qrcode
, \href
, \texttt
, \verb
and family of verbatim envs all treat the special chars differently and some do not even expand commands. It needs to be a macro that can probe its own user to know which chars to escape.
One of the markdown languages supports URL references. E.g. you can declare ergonomic names for the URLs:
[diseasePlusCure]: https://krebsonsecurity.com/2016/10/spreading-the-ddos-disease-and-selling-the-cure
[diseasePlusCure-ia]: http://web.archive.org/web/20230713212522/krebsonsecurity.com/2016/10/spreading-the-ddos-disease-and-selling-the-cure
[mislabelling-ia]: <http://web.archive.org/web/20211006120915/people.torproject.org/~lunar/20160331-CloudFlare_Fact_Sheet.pdf#page=3>
[fediThreat]: https://write.pixie.town/thufie/dont-trust-cloudflare
[fediThreat-ia]: http://web.archive.org/web/20230827161847/write.pixie.town/thufie/dont-trust-cloudflare
[testamony]: https://dragonscave.space/@BlindMoon38/111954315299607397
[personalisedPricing]: https://web.archive.org/web/20240601161454/http://robindev.substack.com/p/cloudflare-took-down-our-website
Then in the doc write: “Cloudflare exploits [personalised pricing][personalisedPricing]” so the shitty URL does not obnoxiously pollute the text.
A LaTeX approach could be:
\savelink{CloudflareLies}{http://web.archive.org/web/20211006120915/https://people.torproject.org/~lunar/20160331-CloudFlare_Fact_Sheet.pdf#page=3}
…
\begin{document}
Yada yada.. This QR: \uselink[form=qr, width=20mm]{CloudflareLies} leads to \uselink[form=fixedwidthfont,wrapping=false]{CloudflareLies}.
We have something that partially works and is not well documented. There is an url
package and there is a hyperref
package. The hyperref
package is said to supercede the url
pkg. In fact, hyperref
uses the url
pkg. So you would generally ignore the url
pkg and just use hyperref
. But the docs for hyperref
conceal the existence of the \urldef
command from the url pkg. The docs for url
show that you can do this:
\urldef{\nastyurl}\url{http://www.musical-starstreams.tld/~william@orbit/very_long_using_underscores/and%20spaces/file+with^caret.pdf?arg1=x&arg2=y#page=5}
Then you can use \nastyurl
throughout your doc, including inside footnotes. But it screws up when used inside \href
(no wonder hyperref
docs neglect to mention it). It also falls over when used inside \qrcode
.