使用 \noopsort 使用 natbib 对“年份”进行排序时出现问题

使用 \noopsort 使用 natbib 对“年份”进行排序时出现问题

为了熟悉BIBTeXnatbib,我一直在使用xampl.bibTeXLive 2011 发行版附带的数据库。我创建了一个文档(使用样式plainnat.bst),其中引用了数据库中的每个条目。编译文档产生的控制台输出如下(第三次运行 PDFLaTeX 后):

(./xampl-citations.tex
! Missing = inserted for \ifnum.
<to be read again>
                   \def
l.15 {\citeref{book-full}
                         }
?

\citeref是我定义的命令,以便我可以轻松更改引用样式。它在文档序言中显示如下:

\newcommand{\refcolor}{\color{Black}}
\newcommand{\citeref}{\refcolor \citep}

经过排除过程(即通过xampl.bib使用更改数据库中的条目JabRef),我将问题归结为以下形式的“年份”字段中的条目:

{\noopsort{1973c}}1981

据我所知,\noopsort该文件的序言中正确定义了xampl.bib

@PREAMBLE{ "\newcommand{\noopsort}[1]{} "
# "\newcommand{\printfirst}[2]{#1} "
# "\newcommand{\singleletter}[1]{#1} "
# "\newcommand{\switchargs}[2]{#2#1} " }

正如您可能想象的那样,我已经进行了大量的搜索,以查看是否有其他人报告过类似的问题,并且我在此资源上发现了一个问题,该问题表明问题可能是文件中的花括号过多.bib

引用相似作者和同一年份的论文时出现 natbib 错误

事实上,我的文件中的一个示例部分xampl.bib确实表明条目包含一对多余的花括号:

@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}
}

问题是——我该怎么做?我的设置方式是,我将主数据库保存在 EndNote 中,然后将条目(仅限必填字段)导出到JabRef执行必要调整的位置LaTeX。这个系统对我来说很管用,所以我并不特别想改变它。但是,如果多余的花括号是问题的原因,那么我该如何防止它们出现在文件中.bib

这不是一个假设性的问题,因为我偶尔需要调整论文参考书目中的条目排序顺序——所以我需要找到一种方法来做到这一点。如果这种\noopsort方法行不通,还有其他选择吗?

答案1

问题在于补充括号,但这对于正确排序是必需的。您biblatex确实应该尝试一下,因为它提供了用于对日期进行排序的不同字段。

一个可能的补丁是在加载后写入natbib

\makeatletter
\let\NAT@bare@aux\NAT@bare
\def\NAT@bare#1(#2){%
 \begingroup\edef\x{\endgroup
   \unexpanded{\NAT@bare@aux#1}(\@firstofone#2)}\x}
\makeatother

这将吞掉有问题的部分,同时保持正确的排序顺序。

问题在于呈现给 LaTeX 并natbib进行解释的内容。如果你查看该.bbl文件,你会看到条目以

\bibitem[Knuth({\noopsort{1973c}}1981)]{book-full}

现在使用它通过应用各种命令来产生来自(或)natbib的结果。相关的命令(我通过搜索找到的)是需要其参数的形式\citep{book-full}\citetgrep\NAT@bare

\def\NAT@bare#1(#2)#3(@)#4\@nil#5{%

相关部分是#1(#2),它来自括号\bibitem中的参数;natbib想要执行数字检查,假设括号中的内容是年份。但它找到了{\noopsort{1973c}}1981,这中断了。所以我为原始\NAT@bare命令创建了一个别名,调用它\NAT@bare@aux并执行

\def\NAT@bare#1(#2){%
  \begingroup\edef\x{\endgroup
  \unexpanded{\NAT@bare@aux#1}(\@firstofone#2)}\x}

因此,当natbib要执行时\NAT@bare(其他宏如此指示),它将接受参数Knuth({\noopsort{1973c}1981})并执行\edef;因此\x将被定义为完全扩展的结果

\endgroup\unexpanded{\NAT@bare@aux Knuth}(\@firstofone{\noopsort{1973c}}1981)

的作用\@firstofone只是去掉括号,而 的展开\noopsort{1973c}只是空的。所以最后 LaTeX 会看到

\NAT@bare@aux Knuth(1981)

格式正确。\endgroup平衡了,并且与已经完成其任务\begingroup的定义一起消失了。\x

如果条目是正常的,比如说\bibitem[Author(2012)](顺便说一下,新年快乐),\x将被定义为

\endgroup\unexpanded{\NAT@bare@aux Author}(\@firstofone 2012)

\@firstofone 2会返回2,所以最后 LaTeX 会看到

\NAT@bare@aux Author(2012)

正如它应该。

答案2

我注意到你的\refcite命令调用了 natbib 的\citep命令,但它这样做时没有明确指出\citep需要参数。一个可能的解决方案——我说可能的因为我还没有真正尝试过——应该在序言中使用以下命令:

\usepackage[svgnames]{xcolor}  % or: \usepackage{color}
...
\providecommand{\noopsort}[1]{}
\newcommand{\refcolor}{Black}
\newcommand{\citeref}[1]{\textcolor{\refcolor}{\citep{#1}}}

相关内容