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 packagepatchcmd
that's completely different in nature from the commands provided byetoolbox
and generalized byxpatch
.I would consider
patchcmd
and\patchcommand
as obsolete: withetoolbox
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. Whenbiblatex
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 frombiblatex1.sty
:The command
\@footnotetext
is called when typesetting a footnote: it does some bookkeeping and then it calls\@mkfntext
andbiblatex
wants to set a toggle to true when doing this job. However, the definition of\@footnotetext
is different whenfootmisc
is loaded, so a redefinition would require checking for the loading of this package, leading to code duplication. Since alsofootmisc
uses\@makefntext
, with\patchcmd
it's possible to use only one code. However, if the patch is unsuccessful (which it can be ifscrbook
is the document class), another toggle is set sobiblatex
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:
For
\pretocmd
and\apptocmd
the<code>
is prepended or appended to the macro replacement text. Sowould be equivalent to
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 withetoolbox
'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>
. Sowould be equivalent to
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,that will give informative messages in the log file and on the terminal such as
or
or even
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, inbook.cls
,If we want to remove that space we can use
\patchcmd
:If we want to add a page break before each section, another simple patch is possible:
(in this case also
\preto
could be used).xpatch
The package
xpatch
is an extension to the patching commands provided byetoolbox
. It provides the commands\xpretocmd
,\xapptocmd
and\xpatchcmd
that can be used as drop-in replacements for the corresponding commands withoutx
; 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 bePatching a command defined by
\newcommand{\foo}[2][baz]{...}
(with a first optional argument) would requireand similarly for
\pretocmd
and\apptocmd
. Withxpatch
it's way simpler and no knowledge of the command's internal implementation is needed: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 managingbiblatex
internal functions that are “macro like”, but are used in a different way, for instance with\usebibmacro{name}
. For these one can useThere are also
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 ofxpatch
independently ofetoolbox
and adds also avariant 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 dobut with
xpatch
you have\xshowcmd
and\xshowcmd\cite
would choose the right command to look at and producewhereas
\show\cite
would only outputWith
regexpatch
there is also a *-form and\xshowcmd*\cite
prints more diagnostics: