![使用 \noopsort 使用 natbib 对“年份”进行排序时出现问题](https://linux22.com/image/244228/%E4%BD%BF%E7%94%A8%20%5Cnoopsort%20%E4%BD%BF%E7%94%A8%20natbib%20%E5%AF%B9%E2%80%9C%E5%B9%B4%E4%BB%BD%E2%80%9D%E8%BF%9B%E8%A1%8C%E6%8E%92%E5%BA%8F%E6%97%B6%E5%87%BA%E7%8E%B0%E9%97%AE%E9%A2%98.png)
为了熟悉BIBTeX
和natbib
,我一直在使用xampl.bib
TeXLive 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
:
事实上,我的文件中的一个示例部分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}
\citet
grep
\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}}}