我使用的是 ext-authoryear-ibid 样式。我试图实现如下输出(如果存在,则以“[]”简写):
- 首次引用:(美国国家航空航天局 [NASA],2022 年,第 12 页)
- 第二次引用:(同上,第 14 页)
- 另一个来源:(Doe,John,2019,第 550 页)
- 第 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}
请注意,我们没有使用citecounter
,我们使用了更简单的\ifciteseen
测试。