Store URLs in a macro without replaceing # and %
You asked,
"How can I store a URL in a macro if the URL has a
#
and/or a%
in it?"
The \urldef
directive of the url
package lets you create precisely such macros. E.g.,
\urldef{\myURL}\url{https://books.google.com/books?id=4tFFDwAAQBAJ&pg=PT233&dq=history+of+trigonometry&hl=en&newbks=1&newbks_redir=0&sa=X&ved=2ahUKEwjIzcj0-tnqAhXwFjQIHZ6XDLUQ6AEwAnoECAQQAg#v=onepage&q&f=false}
Note the syntax: \urldef{<macroname>}\url{<URLstring>}
. Observe taht \url{<URLstring>}
must not be enclosed in curly braces.
\myUrl
may be used in the argument of \footnote
directives.
hyperref
's \hyper@normalise
comes in extremely handy here. It can be used to sanitise the argument of a macro and allow it to accept special characters without escaping. (I think I first learned about \hyper@normalise
from Michael Ummels' answer to Getting those %#!^& signs in the footnote!)
Just use it to define a new macro like \newcommand*{\csdefurl}[1]{\hyper@normalise{\csdef{#1}}}
. (Note that the argument that is going to be "normalised" is not explicitly part of the definition. \newcommand*{\csdefurl}[2]{\hyper@normalise{\csdef{#1}}{#2}}
would not work because then the argument is read with the unnormalised catcode setup.)
\documentclass{article}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{tikz}
\makeatletter
\newcommand*{\csdefurl}[1]{\hyper@normalise{\csdef{#1}}}
\makeatother
\csdef{url Title 1}{The Google}
\csdefurl{url Link 1}{http://www.google.com}
\csdef{url Title 2}{TeX.SE}
\csdefurl{url Link 2}{http://tex.stackexchange.com}
\csdef{url Title 3}{Algebra and Trigonometry:~History of Trigonometry}
\csdefurl{url Link 3}{https://example.com/~test/a%20and%20b.html#anchor}
\def\MaxNUmberOfURLs{5}
\newcommand{\DisplayURLs}{%
\textbf{List of URLs}
\foreach \xCount in {1,...,\MaxNUmberOfURLs} {%
\ifcsdef{url Title \xCount}{%
\par\xCount:
\href{\csuse{url Link \xCount}}{\csuse{url Title \xCount}}
}{}%
}%
}
\begin{document}
\DisplayURLs
\end{document}
Some more testing reveals that
\makeatletter
\newcommand*{\csdefurl@i}{}
\newrobustcmd*{\csdefurl}[1]{%
\def\csdefurl@i{\csdef{#1}}%
\hyper@normalise\csdefurl@i}
\makeatother
might be safer.
Compare this definition to the one above in
\documentclass{article}
\usepackage{etoolbox}
\usepackage{hyperref}
\usepackage{tikz}
\makeatletter
\newcommand*{\csdefurl@i}{}
\newrobustcmd*{\csdefurl}[1]{%
\def\csdefurl@i{\csdef{#1}}%
\hyper@normalise\csdefurl@i}
\makeatother
\csdef{ürl Title 1}{The Google}
\csdefurl{ürl Link 1}{http://www.google.com}
\csdef{ürl Title 2}{TeX.SE}
\csdefurl{ürl Link 2}{http://tex.stackexchange.com}
\csdef{ürl Title 3}{Algebra and Trigonometry:~History of Trigonometry}
\csdefurl{ürl Link 3}{https://example.com/~test/a%20and%20b.html#anchor}
\def\MaxNUmberOfURLs{5}
\newcommand{\DisplayURLs}{%
\textbf{List of URLs}
\foreach \xCount in {1,...,\MaxNUmberOfURLs} {%
\ifcsdef{ürl Title \xCount}{%
\par\xCount:
\href{\csuse{ürl Link \xCount}}{\csuse{ürl Title \xCount}}
}{}%
}%
}
\begin{document}
\DisplayURLs
\end{document}
where we have the non-ASCII ürl
instead of url
.