Suppose I'd like to patch a very complicated macro, say \autocite
. For this, xpatch
package is my friend. If the patch consists in applying a modal command which doesn't take arguments, such as \bfseries
, \xpretocmd
is also my friend:
\documentclass{article}
\usepackage{xpatch}
\usepackage[backend=biber]{biblatex}%
%
\addbibresource{biblatex-examples.bib}
%
% \autocite's patch
\xpretocmd{\autocite}%
{\bfseries}%
{\message{^^Jxpretocmd OK^^J^^J}}%
{\message{^^Jxpretocmd not OK^^J^^J}}
%
\begin{document}
\autocite{cicero}
\printbibliography
\end{document}
Now, suppose the patch consists in applying a macro which does take an argument, such as \textbf
: I want \autocite...
to become \textf{\autocite...}
, whatever are the star/optional/mandatory arguments in ...
. For this, I can't use \textf{
and }
as ⟨prepend⟩
and ⟨append⟩
in:
\xpretocmd{⟨command⟩}{⟨prepend⟩}{⟨success⟩}{⟨failure⟩}
\xapptocmd{⟨command⟩}{⟨append⟩}{⟨success⟩}{⟨failure⟩}
because of unbalanced braces. If {
and }
are replaced by \bgroup
and \egroup
:
\documentclass{article}
\usepackage{xpatch}
\usepackage[backend=biber]{biblatex}%
%
\addbibresource{biblatex-examples.bib}
%
% \autocite's patch
\xpretocmd{\autocite}%
{\textbf\bgroup}%
{\message{^^Jxpretocmd OK^^J^^J}}%
{\message{^^Jxpretocmd not OK^^J^^J}}
\xapptocmd{\autocite}
{\egroup}%
{\message{^^Jxapptocmd OK^^J^^J}}%
{\message{^^Jxapptocmd not OK^^J^^J}}
%
\begin{document}
\autocite{cicero}
\printbibliography
\end{document}
it doesn't work neither as \egroup
is considered as the \autocite
's argument.
Hence my question: how to patch with \xpretocmd
and \xapptocmd
a command by applying to it a macro with argument?
Edit. I placed a great deal of hope in the following trick, relying on \BODY
command from environ
package, but it fails as well…
\documentclass{article}
\usepackage{xpatch}
\usepackage{environ}
\usepackage[backend=biber]{biblatex}%
%
\addbibresource{biblatex-examples.bib}
%
\NewEnviron{boldify}{%
\textbf{\BODY}%
}
% \autocite's patch
\xpretocmd{\autocite}%
{\boldify}%
{\message{^^Jxpretocmd OK^^J^^J}}%
{\message{^^Jxpretocmd not OK^^J^^J}}
\xapptocmd{\autocite}
{\endboldify}%
{\message{^^Jxapptocmd OK^^J^^J}}%
{\message{^^Jxapptocmd not OK^^J^^J}}
%
\begin{document}
\autocite{cicero}
\printbibliography
\end{document}
Best Answer
Let's look at the definition of
\autocite
:This means that the macro looks for
*
and then passes control to another macro. It's simply not possible to make what you want by just patching\autocite
.Sorry.
You may instead redefine
\autocite
usingxparse
so that you pass the full set of arguments and *-variants, adding\textbf
around the whole thing.The user level syntax of
\autocite
isso a reimplementation with
xparse
could beYou should do similarly for
\Autocite
.Of course, something like this would be impossible for
\autocites
, where the number of arguments is variable.More likely, you should add
\begingroup\bfseries
and a matching\endgroup
where the actual typesetting takes place. This of course requires going deep in analyzing the working ofbiblatex
.