[Tex/LaTex] Please tutor the usage of patchcmd and xpatch

macrospatchingtutorialsxpatch

I understand that the patchcmd package provides a command \patchcommand that can be used
to add material at the beginning and/or end of the replacement text of an
existing macro. It works for macros with any number of normal arguments but has limitations for macros with optional arguments.

xpatch was introduced to take care of the above limitations as well as
provide some additional functionality.

Now, when I try to comprehend the usage of the above packages by reading the user documentations (patchcmd, xpatch), I get the feeling that they move
to implementation details a little too quickly compared to other package
documentations. There are not enough explanations or examples.

I also tried to grasp the concepts by reading the relevant portion of TeX FAQ and more or less understood whatever is presented there. However, that is not enough.

So, do you think we can ask for a complete tutorial on the usage of patchcmd and xpatch? Explaining the usage of the relevant commands like \patchcmd, \pretocmd and \apptocmd as well as, \xpatchcmd, \xpretocmd and \xapptocmd with sufficient examples should suffice.

Best Answer

First of all, let's note that \patchcommand is a command defined in the package patchcmd that's completely different in nature from the commands provided by etoolbox and generalized by xpatch.

I would consider patchcmd and \patchcommand as obsolete: with etoolbox the complete functionality of \patchcommand can be obtained with \pretocmd and \apptocmd and much more is possible with \patchcmd.

etoolbox

I'll describe \pretocmd, \apptocmd and \patchcmd, after a bit of history. When biblatex was being developed, Philipp Lehmann found himself needing to redefine several commands from the LaTeX kernel, classes or packages in order to make them compatible with the new citation commands. Just to give a flavor, here is some code from biblatex1.sty:

\patchcmd\@footnotetext
   {\@makefntext}
   {\toggletrue{blx@footnote}\@makefntext}
   {\togglefalse{blx@tempa}}
   {}

The command \@footnotetext is called when typesetting a footnote: it does some bookkeeping and then it calls \@mkfntext and biblatex wants to set a toggle to true when doing this job. However, the definition of \@footnotetext is different when footmisc is loaded, so a redefinition would require checking for the loading of this package, leading to code duplication. Since also footmisc uses \@makefntext, with \patchcmd it's possible to use only one code. However, if the patch is unsuccessful (which it can be if scrbook is the document class), another toggle is set so biblatex can take the appropriate action. (Read the package file for more information, this is only an approximate description.)

The main commands are \pretocmd, \apptocmd and \patchcmd; there are also \preto, \gpreto, \appto and \gappto, but they work only for parameterless macros, so they're not really relevant here.

The syntax is simple:

\pretocmd{<command>}{<code>}{<success>}{<failure>}
\apptocmd{<command>}{<code>}{<success>}{<failure>}
\patchcmd{<command>}{<code to replace>}{<code>}{<success>}{<failure>}

For \pretocmd and \apptocmd the <code> is prepended or appended to the macro replacement text. So

\newcommand{\foo}[2]{-#1-#2-}
\apptocmd{\foo}{(#2)}{}{}

would be equivalent to

\newcommand{\foo}[2]{-#1-#2-(#2)}

Nobody would use two commands instead of one, but typically \foo would have been defined by some package and we want to add functionality to it. It's not mandatory to use one of the arguments in <code>, as the example of \@footnotetext shows: this <code> can be anything, so long as it doesn't use parameters not available for the macro: if a macro is defined to have two arguments, it's impossible to make it having three of them with etoolbox's facilities.

For \patchcmd we have an argument more, containing <code to replace>, that represents code to search for in the replacement text of the macro: in the above example, the code to search for is \@makefntext (more precisely the first appearance of it in the macro's replacement text). Such a bit of code will be completely replaced by <code>. So

\newcommand{\foo}[2]{-#1-#2-(#2)}
\patchcmd{\foo}{-#2-}{X}{}{}

would be equivalent to

\newcommand{\foo}[2]{-#1X(#2)}

The <success> and <failure> arguments are mandatory, but they're not that useful unless one is writing packages. Much more useful, during testing, is issuing, before the first patch,

\tracingpatches

that will give informative messages in the log file and on the terminal such as

[debug] tracing \patchcmd on input line 203
[debug] analyzing '\foo'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] ++ macro can be retokenized cleanly
[debug] ++ search pattern found in replacement text
[debug] ++ patching possible
[debug] == retokenizing macro now

or

[debug] tracing \patchcmd on input line 203
[debug] analyzing '\foo'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] ++ macro can be retokenized cleanly
[debug] -- search pattern not found in replacement text

or even

[debug] tracing \patchcmd on input line 203
[debug] analyzing '\foo'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] -- macro cannot be retokenized cleanly
[debug] -> the macro may have been defined under a category
[debug]    code regime different from the current one
[debug] -> the replacement text may contain special control
[debug]    sequence tokens formed with \csname...\endcsname;
[debug] -> the replacement text may contain carriage return,
[debug]    newline, or similar characters

A simple and useful example. The book class adds some vertical space in the lists of tables and figures in order to separate items belonging to different chapters. This is done by the macro \@chapter, for which we find, in book.cls,

\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
  [...initial code irrelevant for the problem...]
  \addtocontents{lof}{\protect\addvspace{10\p@}}%
  \addtocontents{lot}{\protect\addvspace{10\p@}}%
  [...final code irrelevant for the problem...]
}

If we want to remove that space we can use \patchcmd:

\makeatletter % the macro name contains @
\patchcmd{\@chapter}
  {\addtocontents{lof}{\protect\addvspace{10\p@}}%
   \addtocontents{lot}{\protect\addvspace{10\p@}}}
  {}% remove those tokens
  {}{}% <success> and <failure> code not needed
\makeatother

If we want to add a page break before each section, another simple patch is possible:

\pretocmd{\section}{\clearpage}{}{}

(in this case also \preto could be used).

xpatch

The package xpatch is an extension to the patching commands provided by etoolbox. It provides the commands \xpretocmd, \xapptocmd and \xpatchcmd that can be used as drop-in replacements for the corresponding commands without x; what's the difference, then?

With the commands provided by etoolbox it's difficult to patch commands with optional arguments or declared robust (that is, defined with \DeclareRobustCommand). So if one wants to patch \cite (just to make a silly example), the trick with \patchcmd would be

\expandafter\patchcmd\csname cite \endcsname
  {<code to replace>}
  {<code>}
  {<success>}{<failure>}

Patching a command defined by \newcommand{\foo}[2][baz]{...} (with a first optional argument) would require

 \expandafter\patchcmd\csname\string\foo\endcsname
  {<code to replace>}
  {<code>}
  {<success>}{<failure>}

and similarly for \pretocmd and \apptocmd. With xpatch it's way simpler and no knowledge of the command's internal implementation is needed:

\xpatchcmd{\cite}
  {<code to replace>}
  {<code>}
  {<success>}{<failure>}

 \xpatchcmd{\foo}
  {<code to replace>}
  {<code>}
  {<success>}{<failure>}

will work, as the command \xpatchcmd (or \xpretocmd and \xapptocmd) will take care of what macro to patch.

Moreover xpatch defines a bunch of similar commands for managing biblatex internal functions that are “macro like”, but are used in a different way, for instance with \usebibmacro{name}. For these one can use

\xpretobibmacro \xapptobibmacro \xpatchbibmacro
\xpretobibdriver \xapptobibdriver \xpatchbibdriver
\xpretofieldformat \xapptofieldformat \xpatchfieldformat
\x.....nameformat
\x.....listformat
\x.....indexfieldformat
\x.....indexnameformat
\x.....indexlistformat

There are also

\xshowcmd \xshowbibmacro \xshownameformat \xshowlistformat
\xshowindexfieldformat \xshowindexnameformat \xshowindexlistformat

for seeing on the terminal (and in the log file) the internal implementation, which should always be done when starting a patch, in order to see what the commands do.

Note that xpatch uses \pretocmd, \apptocmd and \patchcmd internally.

regexpatch

The experimental package regexpatch reimplements the \x... commands of xpatch independently of etoolbox and adds also a

\regex...

variant for each one of the commands listed above, together with some more utilities.

Showing commands

The same problems outlined above hold for \show; if you want to know the definition of \cite (to use a command already mentioned), you should do

\expandafter\show\csname cite \endcsname

but with xpatch you have \xshowcmd and \xshowcmd\cite would choose the right command to look at and produce

> \cite =\long macro:
->\@ifnextchar [{\@tempswatrue \@citex }{\@tempswafalse \@citex []}.

whereas \show\cite would only output

> \cite=macro:
->\protect \cite  .

With regexpatch there is also a *-form and \xshowcmd*\cite prints more diagnostics:

*************************************************
* xpatch message
* `\cite' is a control word defined with \DeclareRobustCommand
*************************************************
> \cite =\long macro:
->\@ifnextchar [{\@tempswatrue \@citex }{\@tempswafalse \@citex []}.
Related Question