6

I want to patch \label, involving #1, and it seems that with hyperref, you have to do so after \begin{document} or using \AtBeginDocument. (The code should work without hyperref, too.) So this is what I tried, and it fails:

\documentclass{article}
\usepackage{hyperref}
\usepackage{xpatch}

% Attempt 1 - does nothing
% \pretocmd{\label}{#1}{}{err}

% Attempt 3 - fails (err)
% \AtBeginDocument{\pretocmd{\label}{#1}{}{err}}

% Attempt 4 - fails (err)
\AtBeginDocument{\pretocmd{\label}{##1}{}{err}}

\begin{document}
    % Attempt 2 - works, inelegant
    % \pretocmd{\label}{#1}{}{err}

    Label name is \label{mylabel}.
\end{document}
bers
  • 5,404
  • I don't understand what you want to achieve with #1 in \pretocmd. What should #1 do there? -- it is not accessible there! –  Jan 30 '17 at 10:49
  • Just an explanation, no solution: When \AtBeginDocument saves its argument for later use, it tokenizes its argument. In this process # gets doubled to ##, which is what \pretocmd later adds to the \label command. – gernot Jan 30 '17 at 10:50
  • My three failing attempts may be wrong, but attempt 2 shows what I want: use (not output - use) #1. I chose to output it in the examples for reasons of simplicity, but in my application, showkeys etc would not work. – bers Jan 30 '17 at 11:16
  • @gernot: Sorry, I was on the wrong track. I tried to use \pretocmd once and accessing of #1 , but it failed, because I did not realize that the command hat moving arguments. I've forgotten about that this was the cause of the failure –  Jan 30 '17 at 11:24

1 Answers1

9

I see no real way to overcome this chicken and egg problem with etoolbox (or xpatch that's just a wrapper over its macros). You simply can't use #1 in the replace part of \patchcmd or the analogous part in \pretocmd or \apptocmd when the command is in the argument to another command, in this case \AtBeginDocument.

There is a way out with regexpatch:

\documentclass{article}

\usepackage{regexpatch}
\usepackage{hyperref}

\AtBeginDocument{%
  \makeatletter
  % \A is the start of string anchor, \cP\# is l3regex for 'parameter token'
  \regexpatchcmd{\label}{\A}{\cP\#1}{}{\err}%
  \makeatother
}

\begin{document}

Label name is \label{mylabel}.

\end{document}

On the other hand, packages such as showkeys or showlabels are much better for this purpose.

egreg
  • 1,121,712
  • Thanks! This has been very useful in making http://tex.stackexchange.com/a/351155/30810 independent of whether hyperref is loaded. – bers Jan 30 '17 at 11:55