5

I'm trying to patch biblatex's bibmacro cite using xpatch's \xpretobibmacro and \xapptobibmacro in a way that would require (I think...) to give unbalanced braces to the patch commands. Namely, I'd like to patch the cite bibmacro in the form "if the entry is of a certain entrytype, do as I say, otherwise do what you would normally do".

So, I thought of using xpatch for this, which would enable me to do this patch irrespective of the current citestyle, which is pretty much what I'd like to. But, to do this, I'd need to prepend the conditional with a hanging open brace, and append a single close brace. Which, of course, makes latex complain.

Is there a way to do this?

Here a MWE:

\documentclass{article}

\usepackage[style=authoryear]{biblatex}
\usepackage{xpatch}

\addbibresource{biblatex-examples.bib}

% This is the desired end result, which works
\renewbibmacro*{cite}{%
    \ifentrytype{article}
        {This is an article.}
      {\iffieldundef{shorthand}
          {\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
             {\usebibmacro{cite:label}%
              \setunit{\printdelim{nonameyeardelim}}}
             {\printnames{labelname}%
              \setunit{\printdelim{nameyeardelim}}}%
           \usebibmacro{cite:labeldate+extradate}}
          {\usebibmacro{cite:shorthand}}}%
    }

% This is what I'd like to do, which doesn't work
%\xpretobibmacro{cite}{%
%   \ifentrytype{archive}
%       {This is an article.}
%       {%
%   }
%{}{}% <success> and <failure>
%
%\xapptobibmacro{cite}{}}
%{}{}% <success> and <failure>

\xshowbibmacro{cite}

\begin{document}

An article: \cite{bertram}.

A book: \cite{gerhardt}.

\end{document}
5

You can use regexpatch:

\documentclass{article}

\usepackage[style=authoryear]{biblatex}
\usepackage{regexpatch}

\addbibresource{biblatex-examples.bib}

\regexpatchbibmacro{cite}
  { \A (.*) \Z } % match everything, remember as \1
  {
   \c{ifentrytype}\cB\{\cL(article)\cE\}
     \cB\{\cL(This)\ \cL(is)\ \cL(an)\ \cL(article).\cE\}
     \cB\{\1\cE\}
  }
  {}{}

%\xshowbibmacro{cite}

\begin{document}

An article: \cite{bertram}.

A book: \cite{gerhardt}.

\end{document}

enter image description here

Some notes: \A (.*) \Z matches the entire input; the parentheses make a capturing group, available in the substitution string as \1. In the substitution string, \c{ifentrytype} stands for the macro \ifentrytype: basically the string is

\ifentrytype{article}{This is an article.}{\1}

but we have to tell LaTeX precisely about the nature of the various tokens: \cB\{ and \cE\} stand for braces (in TeX's special meaning), \cL(...) makes the text inside to consist of letters (category code 11).

  • That's brilliant! I'll have to dig into the syntax, but that should more than do. Thank you very much! – gusbrs Jan 14 '18 at 17:42
  • egreg, I'm looking for the documentation of l3regex for details, but I couldn't find it either with texdoc or on the package page on CTAN. Am I missing somewhere obvious where I should be looking? – gusbrs Jan 14 '18 at 18:19
  • Found it! For the record, on the l3kernel CTAN page, "The LaTeX3 in­ter­faces" document. – gusbrs Jan 14 '18 at 18:25
  • 1
    @gusbrs I'll add some details later. – egreg Jan 14 '18 at 19:08
  • egreg, thank you once again for the further details! – gusbrs Jan 14 '18 at 20:23
3

This is inspired (or pillaged?) from Audrey's approach at hyperlink name with biblatex authoryear (biblatex 1.4b) which fits very well this particular problem, so I thought it was worth to place it here too.

The approach is to use biblatex's \savebibmacro and \restorebibmacro to save cite and then restore it's original value while redefining it.

\documentclass{article}

\usepackage[style=authoryear]{biblatex}

\addbibresource{biblatex-examples.bib}

\savebibmacro{cite}

\renewbibmacro*{cite}{%
  \ifentrytype{article}
    {This is an article.}
    {\restorebibmacro{cite}%
      \usebibmacro{cite}}}

\begin{document}

An article: \cite{bertram}.

A book: \cite{gerhardt}.

\end{document}

"Tricky"? Perhaps. I find it quite ingenious. And it does seem to get the job done.

  • Apparently, the restoration happens in a group, so it doesn't stay after \cite has been used. – egreg May 10 '18 at 21:14
  • 1
    @egreg Yes, as far as I understand, that's what happens. Both savebibmacro and restorebibmacro have local scope, but we use the first ungrouped and the second grouped. Probably, if we ask to showbibmacro we will find not a proper patched macro, but it will do as it is supposed to every time it is called. Quite ingenious. Well, that as far as I get it. Do you see how this might eventually fail? – gusbrs May 10 '18 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.