Biblatex gobbles punctuation after undefined references
Fixed in version 3.8 of
biblatex
(#630)
I had a bit of time on my hands to investigate this.
In a \cite
-like command the first time the citation list is processed with \blx@citeadd
, this happens in \blx@citeloop
. That command distinguishes citations that were found in the .bib
file and those that weren't (i.e. are undefined). The citations that were found are saved in a macro for further processing, the keys of those that weren't found are written out immediately in bold. Then the defined citations are passed on to \blx@citeprint
.
The command \blx@postcode
that does the postpunct stuff - and a little bit more if required - is only called in \blx@citeprint
when the last item has been processed.
If we have only undefined citations in our cite command, we never call \blx@postcode
since the chain of macros is only executed with the list of defined citations, and not at all if this list is empty.
So we need to make \blx@citeloop
call \blx@postcode
directly in case there are no defined citations. It turns out that due to the nature of the additional code that \blx@postcode
might contain it is not safe to execute there. We need to save the postpunct in a new command and use that instead.
My solution is to split the postpunct part from \blx@postcode
into a new \blx@postpunct@saved
(sadly the name \blx@postpunct
was already taken, but suggestions for a better name are gladly accepted). This new macro can then be called in \blx@citeloop
if there are no defined citations and otherwise together with \blx@postcode
in \blx@citeprint
.
The necessary modifications are not very copious, but the nature of the changed macros does not allow for a short MWE. The necessary changes can be found in the pull request https://github.com/plk/biblatex/pull/630; it has been merged and the fix is included in biblatex
v3.8.
Now
\listfiles
\documentclass[american]{article}
\usepackage{babel}
\usepackage[style = authortitle]{biblatex}
\addbibresource{biblatex-examples.bib}
\begin{document}
\textcite{UNDEFINED}A
\textcite{fghgvjh}:
\textcite{UNDEFINED}:
\textcite{aksin}:
\textcite{UNDEFINED,aksin}:
\cite{UNDEFINED,aksin}.
\textcite{aksin,UNDEFINED,gundf}:
\textcite{UNDEFINED,FLUNDF}A
\textcite{UNDEFINED,FLUNDF}:
\textcite{aksin,sigfridsson}:
\cite[14]{UNDEFINED,aksin}:
\cite[14]{UNDEFINED,aksin}A
\end{document}
gives
What I decided on in the end is to patch \blx@citeadd
. I am not sure if this is the best macro to patch. It seems the "gobbled" punctuation is kept in \abx@field@postpunct
.
\documentclass{article}
\usepackage{xpatch}
\usepackage[style = authoryear]{biblatex}
\addbibresource{biblatex-examples.bib}
\makeatletter
\xpatchcmd{\blx@citeadd}{%
\expandafter\abx@missing\expandafter{\blx@realkey}%
}{%
\expandafter\abx@missing\expandafter{\blx@realkey}%
\ifundef{\abx@field@postpunct}{}{\abx@field@postpunct}%
}{}{}%
\makeatother
\begin{document}
\textcite{UNDEFINED}A
\textcite{UNDEFINED}:
\textcite{aksin}:
\end{document}