Error when citing in the frontmatter (Spanish)
This is not a complete answer, for I cannot figure out how things are interacting here, or the reason why they break. But I was able to pin down the source of the problem, and it has to do with babel
's change of roman numerals, which are used in lower case for page numbering of the front matter in the standard classes, book
included. babel
spanish
changes that:
Como en castellano no se usan números romanos en minúscula,
\roman
se redefine para que los dé en versalitas. La opción de paquetees-minimal
los desactiva cones-ucroman
, yes-sloppy
cones-lcroman
.
So, you can opt out of this particular option, if you are OK with lower case roman numbering in your front matter. This can be done with the option es-lcroman
passed to babel
.
\documentclass[spanish]{book}
\usepackage[es-lcroman]{babel}
\usepackage[utf8]{inputenc}
\usepackage[style=apa,backend=biber]{biblatex}
\addbibresource{refs.bib}
\begin{document}
\frontmatter
\chapter{Introduction}
Trying to cite \cite{Wren1996}.
\end{document}
The issue is caused by a combination of the way biblatex
handles back-references (records of where a source was cited), and a redefinition by Spanish babel of the \@roman
macro, which makes it unexpandable. The result is that it is being included in an .aux
file and then (I believe) expanded prematurely as part of the creation of an internal list.
You have a number of options:
As noted by gusbrs in his answer, load Spanish babel with options that prevent it from the critical redefinition. This will, however, mean that you do not get small capital roman page-numbering.
Load
biblatex-apa
withbackref=false
. As it happens, the APA style does not require back references.biblatex-apa
only prints them if you setapabackref=true
. It's not clear to me why it always sets the packagebackref
option true, but it doesn't need to. Anyway, if you don't want back references, and you apparently don't need them to comply with APA style, that's an easy option.Disable backreferences in the front matter. To do this put
\backtrackerfalse
at the start of the frontmatter and\backtrackertrue
at the end. Once you are in\mainmatter
there is no problem anyway.Get hacky. The following document illustrates one possible hack: we save the "working" version of
\@roman
before loadingbabel
, and then redefine the critical macro in\biblatex
so that it distinguishes between\frontmatter
and\backmatter
. Actually, it has a known bug. The standard classes (as far as I can tell) don't separately track whether they are in\frontmatter
or\backmatter
, but set a single boolean switch dependent on\mainmatter
. That will mean, given my definition, that citations in\backmatter
will (wrongly) get back references with roman page numbers. To avoid that, you would have to add some additional flag to track backmatter. Also, the roman pagenumbers are not in small capitals; to get that to work would be still more work.\documentclass[spanish]{book} \usepackage{filecontents} \begin{filecontents}{\jobname.bib} @InCollection{Wren1996, author = {Anthony Wren}, title = {Scheduling, timetabling and rostering {\textemdash} A special relationship?}, booktitle = {Practice and Theory of Automated Timetabling}, year = {1996}, publisher = {Springer Berlin Heidelberg}, pages = {46--75}, doi = {10.1007/3-540-61794-9_51}, } \end{filecontents} \makeatletter % Clone an expandable form of @roman before babel is loaded \let\@oldroman\@roman % Define an expandable equivalent of \thepage which distinguishes % between front and mainmatter \def\my@safepage{% \if@mainmatter \thepage \else \@oldroman\c@page \fi} \makeatother \usepackage{babel} \usepackage[utf8]{inputenc} \usepackage[style=apa,backend=biber,apabackref=true]{biblatex} \makeatletter \def\blx@addbackref@i#1{% \ifbacktracker \blx@leavevmode \if@filesw \protected@write\@mainaux{}{\string\abx@aux@backref {\the\c@instcount}{#1}{\the\c@refsection}% {\my@safepage}{\noexpand\the\c@page}}%<-substitute \my@safepage for \thepage \fi \fi} \makeatother \addbibresource{\jobname.bib} \begin{document} \frontmatter \chapter{Introduction} Trying to cite \cite{Wren1996}. \mainmatter Trying to cite again: \cite{Wren1996} \clearpage And again \cite{Wren1996} \backmatter \printbibliography \end{document}
Unless you actually need backreferences to the frontmatter (which seems super hard to believe) I think the second or third options are much the best. My redefinition is really not what it should be to be robust. Meanwhile, either the Spanish babel maintainers need to think about their methods and/or the biblatex maintainers may want to think about how and when commands from the backreferencing commands in the aux file get expanded.
tl;dr This was a bug that is fixed in
biblatex
v3.13 (2019/08/17). An update should fix the issue.
biblatex
made some (unrealistic, as it turns out) implicit assumptions about the value of \thepage
for its backref
functionality.
While it is not outright assumed that only Arabic or Roman numerals are used, the implementation with macros like \ifinlistcs
work better when \thepage
expands to something that contains only alphanumeric characters.
In particular biblatex
would throw an error when it tried to check if \es@scroman {i}
(the value of \thepage
on the first page of the front matter) is already contained in the list of pages where a particular entry was cited. Furthermore, biblatex
would have issues adding non-expandable content like \es@scroman {i}
to the pageref
list, because it would try to expand the list items completely when they were added to the list.
Following Paul Stanley's bug report at the biblatex
bug tracker https://github.com/plk/biblatex/issues/859, the bug was fixed with commit https://github.com/plk/biblatex/commit/071809e815f692074f6af0b059fde7dae9e01ef1. The fix is included from biblatex
v3.13 onwards.
This fix is equivalent to the modified code in the following MWE
\documentclass[spanish]{book}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage[style=authoryear,backref,backend=biber]{biblatex}
\addbibresource{biblatex-examples.bib}
\makeatletter
% \ifinlist{<item>}{<list>} is not a good idea
% for printable stuff according to the etoolbox docs
% for \ifinlist (p. 31)
\newrobustcmd{\blx@ifprintableinlist}[2]{%
\begingroup
\def\blx@tempa{\endgroup
\@secondoftwo}%
\renewcommand*{\do}[1]{%
\ifstrequal{##1}{#1}
{\def\blx@tempa{\endgroup
\@firstoftwo}%
\listbreak}
{}}%
\dolistloop{#2}%
\expandafter\blx@tempa}
\newrobustcmd{\blx@ifprintableinlistcs}[2]{%
\expandafter\blx@ifprintableinlistcs@i\csname #2\endcsname{#1}}
\long\def\blx@ifprintableinlistcs@i#1#2{\blx@ifprintableinlist{#2}{#1}}
% use the more robust \blx@ifprintableinlist instead of \ifinlist
\protected\def\blx@aux@backref#1#2#3#4#5{%
\ifcsundef{blx@pref@#3@\detokenize{#2}}
{\global\cslet{blx@pref@#3@\detokenize{#2}}\@empty
\expandafter\blx@onlypreamble\csname blx@pref@#3@\detokenize{#2}\endcsname}
{}%
\blx@ifprintableinlistcs{#4}{blx@pref@#3@\detokenize{#2}}
{}
{\listcsgadd{blx@pref@#3@\detokenize{#2}}{#4}}%
\blx@addpagesum{#1}{#5}}
\let\abx@aux@backref\blx@aux@backref
% don't expand the list all the way, just expand it once
\def\blx@addpageref#1{%
\begingroup
\blx@tempcnta\z@
\let\blx@tempa\@empty
\def\do##1{%
\appto\blx@tempa{{##1}}%
\advance\blx@tempcnta\@ne}%
\dolistcsloop{blx@pref@\the\c@refsection @#1}%
\edef\blx@tempa{\endgroup\noexpand\blx@bbl@listdef
{pageref}{\the\blx@tempcnta}{\expandonce{\blx@tempa}}}%
\blx@tempa}
\makeatother
\begin{document}
\frontmatter
\chapter{Introduction}
Trying to cite \cite{sigfridsson}.
Trying to cite \cite{sigfridsson}.
\clearpage
Trying to cite \cite{sigfridsson}.
\clearpage
Trying to cite \cite{sigfridsson}.
Trying to cite \cite{sigfridsson}.
\clearpage
foo
\clearpage
Trying to cite \cite{sigfridsson}.
\mainmatter
Trying to cite \cite{sigfridsson}.
Trying to cite \cite{sigfridsson}.
\clearpage
Trying to cite \cite{sigfridsson}.
\clearpage
Trying to cite \cite{sigfridsson}.
Trying to cite \cite{sigfridsson}.
\clearpage
foo
\clearpage
Trying to cite \cite{sigfridsson}.
\printbibliography
\end{document}
As far as I can tell, things work fine. The only downside is that the Roman numerals produced in Spanish style are not compressed like Arabic and normal Roman numerals ("i-iii" for example).
Further testing would be greatly appreciated. Issuescan be reported at https://github.com/plk/biblatex/issues/.