In my efforts to familiarise myself with BIBTeX
and natbib
, I've been playing with the xampl.bib
database which is shipped with the TeXLive 2011 distribution. I created a document (using the plainnat.bst
style) which cited every entry in the database. Compiling the document produced console output as follows (after running PDFLaTeX for the third time):
(./xampl-citations.tex
! Missing = inserted for \ifnum.
<to be read again>
\def
l.15 {\citeref{book-full}
}
?
\citeref
is a command I define so that I can change the citation style easily. It appears as follows in the document preamble:
\newcommand{\refcolor}{\color{Black}}
\newcommand{\citeref}{\refcolor \citep}
After a process of elimination (ie by changing entries in the xampl.bib
database using JabRef
), I've pinned the problem down to entries in the 'year' field of the following form:
{\noopsort{1973c}}1981
As far as I can tell \noopsort
is correctly defined in the preamble of the xampl.bib
file:
@PREAMBLE{ "\newcommand{\noopsort}[1]{} "
# "\newcommand{\printfirst}[2]{#1} "
# "\newcommand{\singleletter}[1]{#1} "
# "\newcommand{\switchargs}[2]{#2#1} " }
As you might imagine, I've done a fair amount of searching around to see if anyone else has reported a similar problem, and I've found a question on this resource which suggests that the problem might be an excess of curly brackets in the .bib
file:
natbib-error-when-citing-paper-with-similar-authors-and-same-year
Indeed, an example section from my xampl.bib
file does suggest that the entries contain a superfluous pair of curly brackets:
@BOOK{book-full,
title = {Seminumerical Algorithms},
publisher = {Addison-Wesley},
year = {{\noopsort{1973c}}1981},
author = {Donald E. Knuth},
volume = {2},
series = {The Art of Computer Programming},
address = {Reading, Massachusetts},
edition = {Second},
month = {10~} # jan,
note = {This is a full BOOK entry},
fileno = {91}
}
The problem is – what do I do about it? The way my set-up works is that I hold my master database in EndNote and then export entries (required fields only) into JabRef
where I perform the necessary tweaks for LaTeX
. This system works well for me, so I don't particularly want to change it. However, if surplus curly brackets is the cause of the problem, then how do I prevent them appearing in the .bib
file?
This is not a hypothetical question, because I will need occasionally to adjust the sort order of entries in my thesis bibliography – so I need to find a way to do it. If the \noopsort
method cannot be made to work, are there any other options?
Best Answer
The problem is the supplementary pair of braces, which is however necessary for correct sorting. You should try
biblatex
, really, because it provides different fields for sorting dates.A possible patch is to write, after loading
natbib
,This will swallow the offending part, while keeping the correct sorting order.
The problem is in what's presented to LaTeX and
natbib
to interpret. If you look at the.bbl
file, you'll see that the entry starts withNow
natbib
uses this to produce the results from\citep{book-full}
(or\citet
), by applying various commands. The relevant one (that I found with somegrep
search) is\NAT@bare
that requires its arguments in the formThe relevant part is
#1(#2)
, which is derived from the argument to\bibitem
in brackets;natbib
wants to perform a numeric check, assuming that what's in parentheses is the year. But it finds{\noopsort{1973c}}1981
and this breaks off. So I make an alias to the original\NAT@bare
command, calling it\NAT@bare@aux
and doSo, when
natbib
wants to execute\NAT@bare
(it's so instructed by other macros), it will take the argumentKnuth({\noopsort{1973c}1981}) and perform an
\edef; thus
\x` will be defined as the result of completely expandingThe job of
\@firstofone
is just to strip the braces, and the expansion of\noopsort{1973c}
is just empty. So at the end LaTeX will seewhich is in the right format. The
\endgroup
balances the\begingroup
and vanishes together with the definition of\x
which has already done its job.If the entry is normal, say
\bibitem[Author(2012)]
(by the way, Happy New Year),\x
will be defined as the full expansion ofand
\@firstofone 2
will simply return2
, so in the end LaTeX will seeas it should.