ext-biblatex 首次引用时使用 ext-authoryear-ibid 打印完整作者 +

ext-biblatex 首次引用时使用 ext-authoryear-ibid 打印完整作者 +

我使用的是 ext-authoryear-ibid 样式。我试图实现如下输出(如果存在,则以“[]”简写):

  1. 首次引用:(美国国家航空航天局 [NASA],2022 年,第 12 页)
  2. 第二次引用:(同上,第 14 页)
  3. 另一个来源:(Doe,John,2019,第 550 页)
  4. 第 n 次引用:(NASA,2022 年,第 102 页)

意思是,只有第一次引用时,如果存在简写,则使用 (1)。对于所有后续引用,仅使用简写,但前提是中间有引用。否则使用 ibid。

我目前有一些代码几乎可以满足我的要求。问题是,它禁用了 ibid 函数。MWE:

\documentclass[
    paper=A4,
    fontsize=12pt,
]{article}

\usepackage[
    backend=biber,
    sorting=nyt,
    style=ext-authoryear-ibid,
    citecounter,
    citetracker=true,
]{biblatex}

% Comma between title and year
\renewcommand*{\labelnamepunct}{\adddot\space}
\DeclareDelimFormat{nameyeardelim}{\addcomma\space}

% Hack for shortauthor, disables ibidem
\renewbibmacro*{cite}{%
    \iffieldundef{shorthand}
    {\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
        {\usebibmacro{cite:label}%
            \setunit{\printdelim{nonameyeardelim}}}
        {\ifboolexpr{
                test{\ifnameundef{shortauthor}}
                or
                test{\ifciteseen}
            }
            {\printnames{labelname}%
                \setunit{\printdelim{nameyeardelim}}}
            {\printnames[labelname]{author}%
                \ifnumgreater{\value{citecounter}}{1}
                {\setunit{\addspace}%
                    \printtext[parens]{\printnames{labelname}}}%
                {}%
                \setunit{\printdelim{nameyeardelim}}}}%
        \usebibmacro{cite:labeldate+extradate}}
    {\usebibmacro{cite:shorthand}}}

\begin{filecontents*}{testbib.bib}
    @online{test1,
        author = {{National Aeronautics and Space Administration}},
        shortauthor = {NASA},
        title = {Aliens},
        year = {2022}
    }
    
    @online{test2,
        author = {John Doe},
        title = {Generic Names},
        year = {2019}
    }
\end{filecontents*}

\addbibresource{testbib.bib}

\begin{document}
    \parencite[][12]{test1}\par \parencite[][14]{test1} $\rightarrow$ needs to be: (ibid., 2022, p. 14)\par \parencite[][550]{test2}\par \parencite[][102]{test1}
    \printbibliography
\end{document}

感谢您的支持。

答案1

问题中显示的 bibmacro的重新定义cite似乎是基于authoryear.cbx(v3.17 中第 10-18 行). 对于您的样式 ( ext-authoryear-ibid),重新定义应基于cite来自的 bibmacroauthoryear-ibid.cbx(第 18-29 行)

如果我们稍微改变方法,使其更加灵活,并允许(如果你想定义其他名称字段,shorteditor实际上允许所有类型的名称字段),我们最终可能会得到short...

\documentclass{article}

\usepackage[
  backend=biber,
  style=ext-authoryear-ibid,
  citetracker,
]{biblatex}

\DeclareDelimFormat[bib]{nametitledelim}{\adddot\space}
\DeclareDelimFormat{nameyeardelim}{\addcomma\space}

% some auxiliary macros to
% check if we are in the shortauthor/shorteditor case
% and to strip the "short" from those field names to get the "long" field
\makeatletter
\newcommand*{\ifstartswithshort}[1]{\ifstartswithshort@i #1short\stopscanning}
\newcommand*{\ifstartswithshort@i}{}
\def\ifstartswithshort@i#1short#2\stopscanning{\ifblank{#1}}

\newcommand*{\iffieldstartswithshort}[1]{%
  \expandafter\ifstartswithshort
  \expandafter{\expanded{\thefield{#1}}}}

\newcommand*{\stripshort}[1]{\stripshort@i #1\stopscanning}
\newcommand*{\stripshort@i}{}
\def\stripshort@i#1short#2\stopscanning{#2}

\newcommand*{\stripshortfromfield}[1]{%
  \expandafter\stripshort
  \expandafter{\expanded{\thefield{#1}}}}
\makeatother

\renewbibmacro*{cite}{%
  \global\boolfalse{cbx:loccit}%
  \iffieldundef{shorthand}
    {\ifthenelse{\ifciteibid\AND\NOT\iffirstonpage}
       {\usebibmacro{cite:ibid}}
       {\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
          {\usebibmacro{cite:label}%
           \setunit{\printdelim{nonameyeardelim}}}
          {\ifciteseen
             {\printnames{labelname}}
             {\iffieldstartswithshort{labelnamesource}
                {\printnames[labelname]{\stripshortfromfield{labelnamesource}}%
                 \setunit{\addspace}%
                 \printtext[parens]{\printnames{labelname}}}
                {\printnames{labelname}}}%
           \setunit{\printdelim{nameyeardelim}}}%
        \usebibmacro{cite:labeldate+extradate}}}
    {\usebibmacro{cite:shorthand}}}

\begin{filecontents*}{\jobname.bib}
@online{test1,
  author      = {{National Aeronautics and Space Administration}},
  shortauthor = {NASA},
  title       = {Aliens},
  year        = {2022},
}
@online{test2,
  author = {John Doe},
  title  = {Generic Names},
  year   = {2019}
}
\end{filecontents*}
\addbibresource{\jobname.bib}

\begin{document}
  \parencite[][12]{test1}

  \parencite[][14]{test1}
  
  \parencite[][550]{test2}
  
  \parencite[][102]{test1}

  \printbibliography
\end{document}

(美国国家航空航天局 [NASA],2022 年,第 12 页)(同上,第 14 页)(Doe,2019 年,第 550 页)(NASA,2022 年,第 102 页)

请注意,我们没有使用citecounter,我们使用了更简单的\ifciteseen测试。

相关内容