我正在使用refsegment
功能biblatex
在同一文档中汇编多个参考书目。我希望在refsegment
s 中有连续的参考编号(即,如果为 N 的最后一个新参考refsegment
分配了编号i
,则为 N+1 的第一个新参考refsegment
分配了编号i+1
)。我还想避免在子参考书目中重复已引用的参考文献。也就是说,虽然给定的参考文献可能在多个 中被引用refsegment
,但它应该仅包含在它首次出现的 的子参考书目中refsegment
。这是一个简单的例子:
refsegment #1:
The quick brown fox [1] jumps over the lazy dog [2].
Bibliography:
[1] Fox reference.
[2] Dog reference.
refsegment #2:
The lazy dog [2] was busy doing nothing [3].
Bibliography:
[3] Reference on nothing.
请注意,参考文献 #2 虽然在第二个参考书目中被引用,但却没有包含在第二个参考书目中,refsegment
因为它已经包含在第一个参考书目中。
这个帖子提出了一种解决该问题的方法,即onlynew
书目检查,它可以抑制重复的书目项。提出的解决方案会持续记录书目项(存储在控制序列中\blx@entrycount
),并在每个书目项的开头记录下一个参考编号refsegment
(在控制序列中\blx@entrycount@\the\c@refsegment
)。然后,如果分配给给定书目项的编号(\thefield{labelnumber}
)小于(\ifnumless{}
)后一个数量,则在书目中跳过它(因为它已经被引用)。但是,在编译时(TeX Live 2019),所有引用都被分配了数字零,书目为空,并发出以下警告:
LaTeX Warning: Empty bibliography on input line <n>
以下示例重现了该问题。需要进行哪些更改才能修复 MWE 中的代码?
平均能量损失(改编自链接文章):
\documentclass{article}
\usepackage[defernumbers=true]{biblatex}
\usepackage{filecontents}
\makeatletter
% Overall entry counter
\csnumgdef{blx@entrycount}{0}
\AtEveryBibitem{%
\csnumgdef{blx@entrycount}{\csuse{blx@entrycount}+1}}
% Continued from this label number
\appto{\newrefsegment}{%
\csnumgdef{blx@entrycount@\the\c@refsegment}{\csuse{blx@entrycount}+1}}
% Skip entries with label numbers less than the continued number
\defbibcheck{onlynew}{%
\ifnumless{\thefield{labelnumber}}{\csuse{blx@entrycount@\the\c@refsegment}}
{\skipentry}
{}}
\makeatother
\begin{filecontents}{\jobname.bib}
@Book{companion,
author = {Goossens, Michel and Mittelbach, Frank and Samarin, Alexander},
title = {The LaTeX Companion},
edition = {1},
publisher = {Addison-Wesley},
location = {Reading, Mass.},
date = {1994}}
@Article{gillies,
author = {Gillies, Alexander},
title = {Herder and the Preparation of Goethe's Idea of World Literature},
journaltitle = {Publications of the English Goethe Society},
volume = {9},
date = {1933},
pages = {46--67}}
@Article{bertram,
author = {Bertram, Aaron and Wentworth, Richard},
title = {Gromov invariants for holomorphic maps on Riemann surfaces},
journaltitle = {J.~Amer. Math. Soc.},
volume = {9},
number = {2},
date = {1996},
pages = {529--571}}
@Book{poetics,
author = {Aristotle},
editor = {Lucas, D. W.},
title = {Poetics},
series = {Clarendon Aristotle},
publisher = {Clarendon Press},
location = {Oxford},
date = {1968}}
@Book{rhetoric,
author = {Aristotle},
editor = {Cope, Edward Meredith},
commentator = {Cope, Edward Meredith},
title = {The Rhetoric of Aristotle with a commentary by the late Edward Meredith Cope},
volumes = {3},
publisher = {Cambridge University Press},
date = {1877}}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\newrefsegment
refsegment \therefsegment:
\cite{companion,rhetoric}
\printbibliography[segment=\therefsegment,check=onlynew]
\newrefsegment
refsegment \therefsegment:
\cite{companion,bertram,poetics}
\printbibliography[segment=\therefsegment,check=onlynew]
\newrefsegment
refsegment \therefsegment:
\cite{companion,bertram,gillies,rhetoric}
\printbibliography[segment=\therefsegment,check=onlynew]
\end{document}
编译:pdflatex && biber && pdflatex && pdflatex
输出:
答案1
引用的答案已有八年多历史,从那时起一些内部事情已经发生了变化。我不能完全确定,但主要问题似乎是选项defernumbers
。所有labelnumber
s 最初都设置为 0,并且只有在参考书目中打印条目后才会分配非零数字。不幸的是,\ifnumless{\thefield{labelnumber}}{\csuse{blx@entrycount@\the\c@refsegment}}
如果 为 0,则测试将始终为真labelnumber
,因此每个参考书目中都会跳过所有条目,这意味着参考书目保持为空,因此blx@entrycount
永远不会增加。
我建议使用以下希望更稳定的解决方案。对于每个条目,它会记录refsegment
它被引用的第一个条目。onlynew
然后过滤器只需要检查这个条目refsegment
的数字是否小于当前的数字refsegment
。
\documentclass{article}
\usepackage[defernumbers=true]{biblatex}
\makeatletter
\AtEveryCitekey{%
\ifcsundef{blx@entry@refsegment@\the\c@refsection @\thefield{entrykey}}
{\csnumgdef{blx@entry@refsegment@\the\c@refsection @\thefield{entrykey}}{\the\c@refsegment}}
{}}
\defbibcheck{onlynew}{%
\ifnumless{0\csuse{blx@entry@refsegment@\the\c@refsection @\thefield{entrykey}}}{\the\c@refsegment}
{\skipentry}
{}}
\makeatother
\addbibresource{biblatex-examples.bib}
\begin{document}
\newrefsegment
refsegment \therefsegment:
\cite{sigfridsson,worman}
\printbibliography[segment=\therefsegment,check=onlynew]
\newrefsegment
refsegment \therefsegment:
\cite{sigfridsson,geer,nussbaum}
\printbibliography[segment=\therefsegment,check=onlynew]
\newrefsegment
refsegment \therefsegment:
\cite{sigfridsson,geer,pines,worman}
\printbibliography[segment=\therefsegment,check=onlynew]
\end{document}
这是一个同样适用于 的解决方案\nocite
。该钩子\AtEveryEntrykey
是在biblatex
3.15 中添加的(请参阅https://github.com/plk/biblatex/issues/934)。如果您使用的是旧版本的biblatex
,请参阅编辑历史以找到解决方法。
\documentclass{article}
\usepackage[defernumbers=true]{biblatex}
\makeatletter
\AtEveryEntrykey{%
\ifcsundef{blx@entry@refsegment@\the\c@refsection @#1}
{\csnumgdef{blx@entry@refsegment@\the\c@refsection @#1}{\the\c@refsegment}}
{}}
{}{}
\defbibcheck{onlynew}{%
\ifnumless{0\csuse{blx@entry@refsegment@\the\c@refsection @\thefield{entrykey}}}{\the\c@refsegment}
{\skipentry}
{}}
\makeatother
\addbibresource{biblatex-examples.bib}
\begin{document}
\newrefsegment
refsegment \therefsegment:
\cite{sigfridsson,worman}
\printbibliography[segment=\therefsegment,check=onlynew]
\newrefsegment
refsegment \therefsegment:
\cite{sigfridsson,geer,nussbaum}\nocite{knuth:ct:a}
\printbibliography[segment=\therefsegment,check=onlynew]
\newrefsegment
refsegment \therefsegment:
\cite{sigfridsson,geer,pines,worman}\nocite{knuth:ct:a,knuth:ct:b}
\printbibliography[segment=\therefsegment,check=onlynew]
\end{document}