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 []}.
xpatch
an enhancement of the according patch macros frometoolbox
, not frompatchcommand
. See therefore in subsection 3.4 “Patching” (belonging to section 3 “Author Commands”) of etoolbox. But: Of course you can ask, we are on a question & answer site here.