Here is exactly what I am trying to do. I have a file with many commands of the form \href{a}{b}
for strings a
and b
. I would like to redefine \href
so that it executes the following: \footnote{\href{a}{b}}
. Thus want to change the URL's into footnotes to URL's. – Is this possible?
3 Answers
This can be done using the standard \let
technique:
\let\oldhref=\href
\renewcommand{\href}[2]{\footnote{\oldhref{#1}{#2}}}
-
9Completing Andrey's answer:
\let\oldhref\href
saves the current meaning of\href
. You can then use this old version of\href
in the new definition of\href
. jrhorn424's solution below would cause an infinite loop as Joseph says below:\href{a}{b}
would expand to\footnote{\href{a}{b}}
, and the\href
in there would expand to\footnote{\href{a}{b}}
, etc. Commented Mar 6, 2011 at 17:18 -
2This does not work if the second argument contains active characters. Try
\href{Test}{http://www.test.com/a=3&b=5}
. Commented Jul 23, 2011 at 12:36
This solution also works with URLs that include active characters such as &, % and # (requires hyperref
):
\makeatletter
\newcommand\hreffootnote@[2]{\footnote{\hyper@linkurl{\Hurl{#2}}{#1}}}
\DeclareRobustCommand{\hreffootnote}{\hyper@normalise\hreffootnote@}
\makeatother
However, as far as I understand your blog post, you actually want that \href{a}{b}
behaves like b\footnote{\url{a}}
. This can be achieved as follows:
\makeatletter
\newcommand\myhref@[2]{#2\footnote{\url@{#1}}}
\DeclareRobustCommand{\myhref}{\hyper@normalise\myhref@}
\makeatother
Also, see my answer to this question.
The first argument of \href
must be handled as verbatim which makes redefinitions tricky. Michael Ummels's answer correctly shows how to use hyperref
s internal macros for this. However, the recent update of my newverbs
package provides a way to collect an argument verbatim easily:
\documentclass{article}
\usepackage{hyperref}
\usepackage{newverbs}[2011/07/24]
\let\orighref\href
\renewcommand{\href}{\Collectverb{\hrefii}}
\newcommand\hrefii[2]{\footnote{\orighref{#1}{#2}}}
\usepackage{lipsum}% Dummy text
\begin{document}
\lipsum*[1]\href{http://test.com/%$^£$%^_@~}{Test URL}
% With other argument separators as { }:
\lipsum*[2]\href|http://test.com/%$^£$}{%^_@~|{Test URL}
% If a real \href is wanted (also used for comparison here)
\lipsum*[3]\orighref{http://test.com/%$^£$%^_@~}{Test URL}
\end{document}
-
-
4@lockstep: Done. I'm never sure about it. When I mention it's my package it sounds like advertising and if I don't, it looks like hidden advertising :-) Commented Jul 27, 2011 at 7:30