biblatex:连续参考编号,无重复

biblatex:连续参考编号,无重复

我正在使用refsegment功能biblatex在同一文档中汇编多个参考书目。我希望在refsegments 中有连续的参考编号(即,如果为 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。所有labelnumbers 最初都设置为 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}

仅有新条目的参考书目:1,2//3,4//5


这是一个同样适用于 的解决方案\nocite。该钩子\AtEveryEntrykey是在biblatex3.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}

相关内容