This question led to a new package:
xpatch
This is likely a simple question, but I'm getting stuck on the small details. I have an internal command, defined by a package as
\newcommand\foo@[3][]{...stuff...}
and somewhere in there I'd like to patch the command to include a call to \label{#1}
. I'm already using etoolbox
, so I planned to use
\patchcmd{\foo@}{hook}{\label{#1}hook}{success}{failure}
Unfortunately this doesn't work, because \foo@
is defined as
> \foo@=macro:
->\@protected@testopt \foo@ \\foo@ {}.
l.359 \show\foo@
Which has no parameters and therefore the patching code fails. So I tried to figure out how to get \\foo@
(note the doubled slash and the trailing space) as a csname, and I got snarled up.
So then I tried using the old-style approach of \let\my@foo@=\foo@\renewcommand\foo@[3][]{...\my@foo@[#1]{#2}{#3}
— I know the original idiom is to use \let
and \def
, but since \foo@
was defined with \newcommand
I tried using \renewcommand
. But this doesn't work, and fails with a TeX capacity exceeded error, and the log file appears to show an endless cycle of macro expansion.
So. What is the correct name for the internal macro defined by \newcommand
when optional arguments are present, and how do I build the csname for that so I can patch it with \patchcmd
?
Best Answer
You can get
\\foo@
using\csname\string\foo@\endcsname
. The space shown behind it with\show
is not part of the macro name (but could be added using a\space
before\endcsname
). So you can use:Full example: