命令在 biblatex authoryear 中仅引用第一作者

命令在 biblatex authoryear 中仅引用第一作者

我想定义一个\shorttextcite仅打印第一作者和“et.al.”的命令。

标准行为\textcite应该authoryear不是被改变。

示例和 MWE:

% !TeX program=lualatex
\documentclass{scrartcl}

\usepackage{fontspec}

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

\usepackage[main=ngerman,english]{babel}

\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
    @Article{john1980,
        author  = {M. John},
        title   = {A new view on the wheel},
        journal = {Proceedings in Transportation},
        year    = {1980},
    }
    @Article{john1981,
        author  = {M. John and J. Mary},
        title   = {A new view on the wheel II},
        journal = {Proceedings in Transportation},
        year    = {1981},
    }
\end{filecontents}

\addbibresource{\jobname.bib}

\begin{document}
    \textcite{john1980,john1981}
    \printbibliography

\end{document}

得出:

enter image description here 应该\shorttextcite输出“John et. al. (1980,1981)”,但\textcite仍然应该与现在相同。

答案1

这基本上是一个副本,但\textcite使用了一点小技巧,只比较名字而不是整个名字列表,以检查我们是否压缩引用。

通常情况下,我们只需使用字段namehash来比较名称列表(实际上这\textcite通常是这样做的),但namehash要遵守截断设置并考虑引文中显示的所有名称。我们只关注第一作者,因此我们需要一种方法来访问他们的hash。这hash只有在处理名称时才可用,因此我们使用来自的技巧biblatex:动态过滤参考文献中特定作者的出版物并使用索引命令。索引命令允许我们处理姓名列表而不打印任何内容。

对于每部作品的第一作者,我们都会提取他的哈希值以及他是单独工作还是“等人”的信息。此信息被保存并与上一次引用进行比较。如果上一次引用的状态相同,则压缩它们。

\documentclass{scrartcl}
\usepackage[style=authoryear-comp,backend=biber]{biblatex}

\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
    @Article{john1980,
        author  = {M. John and B. Fairy},
        title   = {A new view on the wheel},
        journal = {Proceedings in Transportation},
        year    = {1980},
    }
    @Article{john1981,
        author  = {M. John and J. Mary},
        title   = {A new view on the wheel II},
        journal = {Proceedings in Transportation},
        year    = {1981},
    }
    @Article{john1982,
        author  = {M. John},
        title   = {A new view on the wheel III},
        journal = {Proceedings in Transportation},
        year    = {1983},
    }
\end{filecontents}

\addbibresource{\jobname.bib}
\addbibresource{biblatex-examples.bib}

\makeatletter
\DeclareIndexNameFormat{cbx@chr@getfirstauthorhash}{%
  \ifnumequal{\value{listcount}}{1}
    {\savefield{hash}{\cbx@thishash}%
     \ifmorenames
       {\gappto{\cbx@thishash}{@alone}}
       {\gappto{\cbx@thishash}{@etal}}}
    {}}

\newbibmacro*{shorttextcite}{%
  \indexnames[cbx@chr@getfirstauthorhash][1-1]{labelname}%
  \ifdefequal{\cbx@thishash}{\cbx@lasthash}
    {\iffieldundef{shorthand}
       {\ifthenelse{\iffieldequals{labelyear}{\cbx@lastyear}\AND
                    \(\value{multicitecount}=0\OR\iffieldundef{postnote}\)}
          {\setunit{\addcomma}%
           \usebibmacro{cite:extradate}}
          {\setunit{\compcitedelim}%
           \usebibmacro{cite:labeldate+extradate}%
           \savefield{labelyear}{\cbx@lastyear}}}
       {\setunit{\compcitedelim}%
        \usebibmacro{cite:shorthand}%
        \global\undef\cbx@lastyear}}
    {\ifnameundef{labelname}
       {\iffieldundef{shorthand}
          {\usebibmacro{cite:label}%
           \setunit{%
             \global\booltrue{cbx:parens}%
             \printdelim{nonameyeardelim}\bibopenparen}%
           \ifnumequal{\value{citecount}}{1}
             {\usebibmacro{prenote}}
             {}%
           \usebibmacro{cite:labeldate+extradate}}
          {\usebibmacro{cite:shorthand}}}
       {\printnames[labelname][1-1]{labelname}%
        \setunit{%
          \global\booltrue{cbx:parens}%
          \printdelim{nameyeardelim}\bibopenparen}%
        \ifnumequal{\value{citecount}}{1}
          {\usebibmacro{prenote}}
          {}%
        \iffieldundef{shorthand}
          {\iffieldundef{labelyear}
             {\usebibmacro{cite:label}}
             {\usebibmacro{cite:labeldate+extradate}}%
           \savefield{labelyear}{\cbx@lastyear}}
          {\usebibmacro{cite:shorthand}%
           \global\undef\cbx@lastyear}}%
     \stepcounter{textcitecount}%
     \global\let\cbx@lasthash\cbx@thishash}%
  \setunit{%
    \ifbool{cbx:parens}
      {\bibcloseparen\global\boolfalse{cbx:parens}}
      {}%
    \textcitedelim}}


\DeclareCiteCommand{\cbx@shorttextcite}
  {\usebibmacro{cite:init}%
   \global\undef\cbx@thishash}
  {\usebibmacro{citeindex}%
   \usebibmacro{shorttextcite}}
  {}
  {\usebibmacro{textcite:postnote}}

\DeclareCiteCommand{\shorttextcite}[\cbx@textcite@init\cbx@shorttextcite]
  {\gdef\cbx@savedkeys{}%
   \citetrackerfalse%
   \pagetrackerfalse%
   \DeferNextCitekeyHook%
   \usebibmacro{cite:init}%
   \global\undef\cbx@thishash}
  {\ifthenelse{\iffirstcitekey\AND\value{multicitetotal}>0}
     {\protected@xappto\cbx@savedcites{()(\thefield{multipostnote})}%
      \global\clearfield{multipostnote}}
     {}%
   \xappto\cbx@savedkeys{\thefield{entrykey},}%
   \indexnames[cbx@chr@getfirstauthorhash][1-1]{labelname}%
   \ifdefequal{\cbx@thishash}{\cbx@lasthash}
     {}
     {\stepcounter{textcitetotal}%
      \global\let\cbx@lasthash\cbx@thishash}}
  {}
  {\protected@xappto\cbx@savedcites{%
     [\thefield{prenote}][\thefield{postnote}]{\cbx@savedkeys}}}
\makeatother


\begin{document}
  \shorttextcite{john1980,john1981}

  \shorttextcite{knuth:ct:a,knuth:ct:b}

  \shorttextcite{john1982,john1981}

  \shorttextcite{john1982,john1981,john1980}

  \printbibliography
\end{document}

enter image description here

相关内容