# Is there a workaround for this limitation of \patchcmd?

The \patchcmd command of the well-known etoolbox package has a minor limitation: Patching seems to fail whenever \patchcmd is used in the argument of another command and the search/replacement texts themselves include references to arguments. For example:

\documentclass{article}

\usepackage{etoolbox}

\def\test#1{#1test}

\ifdefparam{\test}{%
\patchcmd{\test}{#1}{#1-}{\typeout{juhu!}}{\typeout{oje!}}%
}{%
}

\show\test

\begin{document}

\end{document}


Here, the problem can easily be solved using the following trick:

\documentclass{article}

\usepackage{etoolbox}

\def\test#1{#1test}

\ifdefparam{\test}\iftrue\iffalse
\patchcmd{\test}{#1}{#1-}{\typeout{juhu!}}{\typeout{oje!}}
\fi

\show\test

\begin{document}

\end{document}


But the question remains: Is there a generally applicable workaround for this limitation of \patchcmd?

-
–  Werner Jun 7 '12 at 19:55
The trick works because you're not really in the argument to a command. –  egreg Jun 7 '12 at 20:23
@egreg: And, most probably, the trick won’t work with every test macro. But till today, I haven’t known a better solution. –  mhp Jun 7 '12 at 21:32

Use the \xpatchcmd command provided by the (experimental) regexpatch package. Minimal example:

\documentclass{article}

\usepackage{regexpatch}

\def\test#1{#1test}

\ifdefparam{\test}{%
\xpatchcmd{\test}{#1}{#1-}{\typeout{juhu!}}{\typeout{oje!}}%
}{%
}

\show\test

\begin{document}

\end{document}


According to its documentation, the regexpatch package is an advanced sibling of the xpatch package and is intended to replace the latter as soon as the underlying LaTeX3 packages from the l3experimental bundle have become stable.

Note that \xpatchcmd as implemented by the xpatch package shows the same limitation as \patchcmd. This might be explained by the following sentence from the regexpatch package documentation:

The package is now completely independent of etoolbox.

-
This just shows the usage of \xpatchcmd provided by xpatch. Perhaps you could elaborate on the difference between the functionality supported by xpatch and that of regexpatch. –  Werner Jun 7 '12 at 19:54
You can also do \regexpatchcmd{\test}{(\cP.1)}{\1-}{}{} that won't give any problem even in the definition of another command: the regular expression \cP.1 denotes any category 6 character (#) followed by 1; it will replaced by itself (\1) followed by a hyphen. –  egreg Jun 7 '12 at 20:33
@Werner With xpatch the result would be exactly the same as with etoolbox, because the package eventually uses \patchcmd. This is not the case with regexpatch that uses a completely different system. –  egreg Jun 7 '12 at 20:36
The fixed version of regexpatch is on its way to CTAN. –  egreg Jun 7 '12 at 21:34
This code does not compile. –  Jubobs Apr 30 '14 at 18:03