使用 BibLaTeX 样式“numeric-comp”根据作者自定义引用

使用 BibLaTeX 样式“numeric-comp”根据作者自定义引用

我想重现结果这个帖子使用 numeric-comp citestyle。按原样使用该解决方案,我收到一条错误消息,提示“宏‘cite’未定义”,并且没有任何内容以粗体显示。

我尝试在相关行中将其更改citecite:comp(见下文),并从中获得了一些粗体,但不一致。看起来压缩范围内的最后一个数字不会变成粗体,除非它后面跟着另一个粗体数字,但我不知道为什么。任何帮助都将不胜感激。谢谢!

梅威瑟:

\documentclass{article}
\usepackage{filecontents}
\usepackage[backend=biber,style = numeric-comp, sortcites]{biblatex}
\usepackage[colorlinks=true, breaklinks, allcolors = blue]{hyperref}
\DeclareSourcemap{%
  \maps[datatype=bibtex]{%
    \map{%
      \step[fieldsource=author, match=Doe, final]%
      \step[fieldset=keywords, fieldvalue=doe]%
    }%
  }%
}
\begin{filecontents}{\jobname.bib}
@Book{p1,
  author =       "Joe Bar",
  title =        "A Scientific Article 1",
  year =         "1995"  
}
@Book{p2,
  author =       "John Doe",
  title =        "A Scientific Article 2",
  year =         "1985"  
}
@Book{p3,
  author =       "A. U. Thor and John Doe",
  title =        "A Scientific Article 3",
  year =         "1975"  
}
@Book{p4,
  author =       "A. U. Thor and John Doe",
  title =        "A Scientific Article 4",
  year =         "2010"  
}
@Book{p5,
  author =       "Jane Zaz",
  title =        "A Scientific Article 5",
  year =         "2005"  
}
@Book{p6,
  author =       "Jane Zaz",
  title =        "A Scientific Article 6",
  year =         "2015"  
}
@Book{p7,
  author =       "Jane Zaz and John Doe",
  title =        "A Scientific Article 7",
  year =         "2020"  
}
\end{filecontents}
\addbibresource{\jobname.bib}

\DeclareFieldFormat{keywordcite}{\ifkeyword{doe}{\mkbibbold{#1}}{#1}}
\csletcs{old:cite:comp}{abx@macro@cite:comp}
\renewbibmacro{cite:comp}{\printtext[keywordcite]{\csuse{old:cite:comp}}}

\nocite{*}
\begin{document}

In \cite{p2, p3, p4, p6}, 2 and 4 should be \textbf{bold}.

In \cite{p2, p3, p4, p7}, 2, 4, and 7 should be \textbf{bold}.

In \cite{p1, p3, p4, p5, p6, p7}, 3 and 7 should be \textbf{bold}.

In \cite{p1, p2, p3}, 3 should be \textbf{bold}.

In \cite{p1, p2, p3, p7}, 3 and 7 should be \textbf{bold}.

\printbibliography
\end{document}

在此处输入图片描述

更新:

我可以通过添加以下几行来让事情变得更好一些

\csletcs{old:cite:dump}{abx@macro@cite:dump}
\renewbibmacro{cite:dump}{\printtext[keywordcite]{\csuse{old:cite:dump}}}

在此处输入图片描述

但仍然不是一个完整的解决方案。

答案1

与其他引用样式相比,的代码numeric-comp非常复杂。引用输出的不同位由不同的辅助 bibmacros 生成,并且为了使压缩功能正常工作,甚至需要打印“超出范围”的某些条目的数据(即,在处理其他条目时可能会打印某个条目的引用 - 此时我们无法轻松访问该条目的其他数据)。

这使得实现您想要的目标变得非常具有挑战性。这不仅仅是将单个 bibmacro 包装在 中的问题\printtext[keywordcite],因为该 bibmacro 最终可能会打印对其他条目的引用,甚至可能根本不打印“当前”条目。首先,我们需要\printtext[keywordcite]{...}在每个 bibmacro 中注入一个,以产生当前范围内条目的引用输出。然后,我们需要“记住”打印“超出范围”的引用的关键字状态,并将此记住的状态用于打印“超出范围”数据的 bibmacros。因此,我们最终得到了以下 100 行的怪物。

以下代码是针对当前版本biblatex(2020-12-31 的 v3.16)设计和测试的。如果我没记错的话,它至少需要 v3.15a(2020-08-23),并且不适用于旧版本。

\documentclass{article}

\usepackage[backend=biber,style = numeric-comp, sortcites]{biblatex}

\usepackage[colorlinks=true, breaklinks, allcolors = blue]{hyperref}

\DeclareSourcemap{%
  \maps[datatype=bibtex]{%
    \map{%
      \step[fieldsource=author, match=Doe, final]%
      \step[fieldset=keywords, fieldvalue=doe]%
    }%
  }%
}

\makeatletter
\DeclareFieldFormat{keywordcite}{\ifkeyword{doe}{\mkbibbold{#1}}{#1}}

\newcommand*{\cbx@if@lastkeyword@doe}{}
\let\cbx@if@lastkeyword@doe\@secondoftwo

\DeclareFieldFormat{lastkeywordcite}{\cbx@if@lastkeyword@doe{\mkbibbold{#1}}{#1}}

\renewbibmacro*{cite:comp:comp}{%
  \cbx@iflabelprefixequalslast
    {\ifnumequal{\thefield{labelnumber}}{\value{cbx@tempcntb}}
       {\savefield{entrykey}{\cbx@lastkey}%
        \savefield{labelnumber}{\cbx@lastnumber}%
        \ifkeyword{doe}
          {\global\let\cbx@if@lastkeyword@doe\@firstoftwo}
          {\global\let\cbx@if@lastkeyword@doe\@secondoftwo}%
        \stepcounter{cbx@tempcnta}}
       {\ifnumequal{\thefield{labelnumber}}{\value{cbx@tempcntb}-1}
          {% current cite is *exactly* the same a previous source
           % this can only happen if the same source is cited twice
           % and sortcites is turned off
           % print nothing
          }
          {\usebibmacro{cite:comp:end}}}}
    {\usebibmacro{cite:comp:end}}%
  \setcounter{cbx@tempcntb}{\thefield{labelnumber}}%
  \savefield{labelprefix}{\cbx@lastprefix}}

\renewbibmacro*{cite:comp:inset}{%
  \stepcounter{cbx@tempcntd}%
  \ifboolexpr{    togl {cbx:subentrycomp}
              and test {\cbx@iflabelnumberandprefixequallast}}
    {\ifnumequal{\thefield{entrysetcount}}{\value{cbx@tempcntd}}
       {\savefield{entrykey}{\cbx@lastkey}%
        \savefield{entrysetcount}{\cbx@lastentrysetcount}%
        \ifkeyword{doe}
          {\global\let\cbx@if@lastkeyword@doe\@firstoftwo}
          {\global\let\cbx@if@lastkeyword@doe\@secondoftwo}%
        \stepcounter{cbx@tempcntc}}
       {\ifnumequal{\thefield{entrysetcount}}{\value{cbx@tempcntd}-1}
          {% current cite is *exactly* the same a previous source
           % this can only happen if the same source is cited twice
           % and sortcites is turned off
           % print nothing
          }
          {\usebibmacro{cite:dump:inset}%
           \ifnumgreater{\value{cbx@tempcntd}}{-1}
             {\setunit{\multicitesubentrydelim}}
             {}%
           \usebibmacro{cite:print:subentry:comp}}}}
    {\usebibmacro{cite:dump}%
     \ifnumgreater{\value{cbx@tempcntb}}{-1}
       {\multicitedelim}
       {}%
     \setcounter{cbx@tempcntd}{-1}%
     \usebibmacro{cite:print:subentry:full}%
     \savefield{labelprefix}{\cbx@lastprefix}%
     \savefield{labelnumber}{\cbx@lastnumber}}%
    \setcounter{cbx@tempcntd}{\thefield{entrysetcount}}%
    \setcounter{cbx@tempcntb}{-1}}

\renewbibmacro*{cite:print:shorthand}{%
  \printtext[bibhyperref]{%
    \printtext[keywordcite]{%
      \printfield{shorthand}}}}

\renewbibmacro*{cite:print:labelnumber}{%
  \printtext[bibhyperref]{%
    \printtext[keywordcite]{%
      \printfield{labelprefix}%
      \printfield{labelnumber}}}}

\renewbibmacro*{cite:print:subentry:comp}{%
  \printtext[bibhyperref]{%
    \printtext[keywordcite]{%
      \printfield{entrysetcount}}}}

\renewbibmacro*{cite:print:subentry:full}{%
  \printtext[bibhyperref]{%
    \printtext[keywordcite]{%
      \printfield{labelprefix}%
      \printfield{labelnumber}%
      \printfield{entrysetcount}}}}

\renewbibmacro*{cite:print:last:subentry:comp}{%
  \printtext[bibhyperref:lastkey]{%
    \printtext[lastkeywordcite]{%
      \printtext[entrysetcount]{\cbx@lastentrysetcount}}}}

\renewbibmacro*{cite:print:last:labelnumber}{%
  \printtext[bibhyperref:lastkey]{%
    \printtext[lastkeywordcite]{%
      \ifdef\cbx@lastprefix
         {\printtext[labelprefix]{\cbx@lastprefix}}
        {}%
      \printtext[labelnumber]{\cbx@lastnumber}}}}
\makeatother


\begin{filecontents}{\jobname.bib}
@Book{p1,
  author = {Joe Bar},
  title  = {A Scientific Article 1},
  year   = {1995},
}
@Book{p2,
  author = {John Doe},
  title  = {A Scientific Article 2},
  year   = {1985},
}
@Book{p3,
  author = {A. U. Thor and John Doe},
  title  = {A Scientific Article 3},
  year   = {1975},
}
@Book{p4,
  author = {A. U. Thor and John Doe},
  title  = {A Scientific Article 4},
  year   = {2010},
}
@Book{p5,
  author = {Jane Zaz},
  title  = {A Scientific Article 5},
  year   = {2005},
}
@Book{p6,
  author = {Jane Zaz},
  title  = {A Scientific Article 6},
  year   = {2015},
}
@Book{p7,
  author = {Jane Zaz and John Doe},
  title  = {A Scientific Article 7},
  year   = {2020},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
In \cite{p2, p3, p4, p6}, 2 and 4 should be \textbf{bold}.

In \cite{p2, p3, p4, p7}, 2, 4, and 7 should be \textbf{bold}.

In \cite{p1, p3, p4, p5, p6, p7}, 3 and 7 should be \textbf{bold}.

In \cite{p1, p2, p3}, 3 should be \textbf{bold}.

In \cite{p1, p2, p3, p7}, 3 and 7 should be \textbf{bold}.

\printbibliography
\end{document}

输出为“在 [2–4, 6] 中,2 和 4 应为粗体。在 [2–4, 7] 中,2、4 和 7 应为粗体。在 [1, 3–7] 中,3 和 7 应为粗体。在 [1–3] 中,3 应为粗体。在 [1–3, 7] 中,3 和 7 应为粗体。”其中预期数字以粗体显示。

相关内容