我正在尝试遵循作者年份引用风格,该风格要求引用形式为“blah blah(一家名称很长的公司(ACWALN)2018)……某物(ACWALN 2005)”,但前提是多次引用名称很长的公司。
也就是说,我需要为列表中的每个名称处理四种情况:
- 自然人(可通过名字检测),每次仅打印姓氏或姓氏加消歧义首字母,如默认的 biblatex authoryear.cbx
- 仅引用一次的公司,打印全名(作者字段中的名称)
- 首次引用的公司,随后再次引用,打印全名,如果有简称,则用括号括起来
- 后续引用某个公司时,如果存在则打印其简称,如果不存在则打印其全名。
据推测我需要\cbx@ifnameseen
根据其值选择适当的名称进行打印,然后将所有被引用多次的名称以合适的宏形式写入辅助文件,以便下次处理文件时可以打印正确的第一个引用。
有没有更好的方法来实现这一点?如果没有,以前有人实现过吗?
(不,我不能只使用合理的引用样式,并且官方的尾注样式文件不能正常工作,因此使用 Word 而不是乳胶不会有帮助。)
答案1
这比大卫的回答,但它适用于名称而不是入门级别。
基本策略是一样的,只是\ifciteseen
我们\cbx@ifnameseen
使用首次出现时自动完整引用作者姓名而不是citecounter
我们实现一个名称计数器来计算一个特定名称的出现次数。为了能够正确处理名称列表和唯一性,我们使用了新的扩展名称格式(参见Bibtex/Biber:如何使用埃塞俄比亚惯例引用作者?)。
\documentclass{article}
\begin{filecontents*}[force]{corp.dbx}
\DeclareDatamodelConstant[type=list]{nameparts}{prefix,family,suffix,given,long,short}
\end{filecontents*}
\usepackage[style=authoryear,citecounter,citetracker,datamodel=corp]{biblatex}
\DeclareSortingNamekeyTemplate[corp]{
\keypart{
\namepart{long}
}
}
\DeclareUniquenameTemplate[corp]{
\namepart[base]{short}
\namepart{long}
}
\makeatletter
%%% nametracker
% provides \cbx@ifnameseen to check if a name was seen already
% requires use of \cbx@nametracker{\thefield{hash}}
% in the appropriate place
\newrobustcmd*{\cbx@nametracker@global}[1]{%
\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}
{}
{\listcsxadd{cbx@bseen@names@\the\c@refsection}{#1}}}
\newrobustcmd*{\cbx@nametracker@context}[1]{%
\iftoggle{blx@footnote}
{\xifinlistcs{#1}{cbx@fseen@names@\the\c@refsection}
{}
{\listcsxadd{cbx@fseen@names@\the\c@refsection}{#1}}}
{\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}
{}
{\listcsxadd{cbx@bseen@names@\the\c@refsection}{#1}}}}
\newrobustcmd*{\cbx@ifnameseen@global}[1]{%
\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}}
\newrobustcmd*{\cbx@ifnameseen@context}[1]{%
\iftoggle{blx@footnote}%
{\xifinlistcs{#1}{cbx@fseen@names@\the\c@refsection}}%
{\xifinlistcs{#1}{cbx@bseen@names@\the\c@refsection}}}
\DeclareBibliographyOption[string]{nametracker}[true]{%
\ifcsdef{blx@opt@nametracker@#1}
{\csuse{blx@opt@nametracker@#1}}
{\blx@err@invopt{nametracker=#1}{}}}
\def\blx@opt@nametracker@global{%
\let\cbx@ifnameseen\cbx@ifnameseen@global
\let\cbx@nametracker\cbx@nametracker@global}
\let\blx@opt@nametracker@true\blx@opt@nametracker@global
\def\blx@opt@nametracker@false{%
\protected\long\def\cbx@ifnameseen##1##2##3{##3}%
\let\cbx@nametracker\relax}
\def\blx@opt@nametracker@context{%
\let\cbx@ifnameseen\cbx@ifnameseen@context
\let\cbx@nametracker\cbx@nametracker@context}
\appto\blx@secinit{%
\ifcsundef{cbx@bseen@names@\the\c@refsection}
{\global\cslet{cbx@bseen@names@\the\c@refsection}\@empty}
{}%
\ifcsundef{cbx@fseen@names@\the\c@refsection}
{\global\cslet{cbx@fseen@names@\the\c@refsection}\@empty}
{}}
\InitializeCitationStyle{%
\global\cslet{cbx@bseen@names@\the\c@refsection}\@empty
\global\cslet{cbx@fseen@names@\the\c@refsection}\@empty}
\ExecuteBibliographyOptions{nametracker=context}
%%% namecounter
% defines \namecounter{<hash>}
% requires \cbx@countname{\thefield{hash}} in the appropriate place
\def\blx@namecount@global#1{%
0\csuse{blx@namecount@\the\c@refsection @#1}%
}
\def\blx@namecount@context#1{%
0%
\iftoggle{blx@footnote}
{\csuse{blx@fnnamecount@\the\c@refsection @#1}}
{\csuse{blx@namecount@\the\c@refsection @#1}}%
}
\protected\def\blx@aux@namecount#1#2{%
\csnumgdef{blx@namecount@#1@#2}{%
\csuse{blx@namecount@#1@#2}+1}}
\protected\def\blx@aux@fnnamecount#1#2{%
\csnumgdef{blx@fnnamecount@#1@#2}{%
\csuse{blx@fnnamecount@#1@#2}+1}}
\let\abx@aux@namecount\@gobbletwo
\let\abx@aux@fnnamecount\@gobbletwo
\AtEndDocument{%
\let\abx@aux@namecount\@gobbletwo
\let\abx@aux@fnnamecount\@gobbletwo}
\def\blx@countname@global#1{%
\ifbool{@filesw}
{\ifbool{citetracker}
{\immediate\write\@mainaux{%
\string\abx@aux@namecount
{\the\c@refsection}{#1}}}
{}}
{}}
\def\blx@countname@context#1{%
\ifbool{@filesw}
{\ifbool{citetracker}
{\immediate\write\@mainaux{%
\iftoggle{blx@footnote}
{\string\abx@aux@fnnamecount}
{\string\abx@aux@namecount}%
{\the\c@refsection}{#1}}}
{}}
{}}
\DeclareBibliographyOption[boolean]{namecounter}[true]{%
\ifcsdef{blx@opt@namecounter@#1}
{\csuse{blx@opt@namecounter@#1}}
{\blx@err@invopt{namecounter=#1}{}}}
\def\blx@opt@namecounter@true{%
\let\cbx@namecount\blx@namecount@global
\let\cbx@countname\blx@countname@global
\let\abx@aux@namecount\blx@aux@namecount
\let\abx@aux@fnnamecount\blx@aux@namecount
\booltrue{citetracker}}
\def\blx@opt@namecounter@context{%
\let\cbx@namecount\blx@namecount@context
\let\cbx@countname\blx@countname@context
\let\abx@aux@namecount\blx@aux@namecount
\let\abx@aux@fnnamecount\blx@aux@fnnamecount
\booltrue{citetracker}}
\def\blx@opt@namecounter@false{%
\let\cbx@namecount\@gobbleone
\let\cbx@countname\@gobbleone
\let\abx@aux@namecount\@gobbletwo
\let\abx@aux@fnnamecount\@gobbletwo}
\ExecuteBibliographyOptions{namecounter=context}
%%% name formats
\DeclareNameFormat{given-family}{%
\ifsortingnamekeytemplatename{corp}
{\usebibmacro{name:corp}
{\namepartlong}
{\empty}}
{\ifgiveninits
{\usebibmacro{name:given-family}
{\namepartfamily}
{\namepartgiveni}
{\namepartprefix}
{\namepartsuffix}}
{\usebibmacro{name:given-family}
{\namepartfamily}
{\namepartgiven}
{\namepartprefix}
{\namepartsuffix}}}%
\usebibmacro{name:andothers}}
\DeclareNameFormat{family-given}{%
\ifsortingnamekeytemplatename{corp}
{\usebibmacro{name:corp}
{\namepartlong}
{\empty}}
{\ifgiveninits
{\usebibmacro{name:family-given}
{\namepartfamily}
{\namepartgiveni}
{\namepartprefix}
{\namepartsuffix}}
{\usebibmacro{name:family-given}
{\namepartfamily}
{\namepartgiven}
{\namepartprefix}
{\namepartsuffix}}}%
\usebibmacro{name:andothers}}
\DeclareNameAlias{sortname}{family-given}
\DeclareNameFormat{labelname}{%
\ifuniquenametemplatename{corp}
{\usebibmacro{labelname:corp}}
{\usebibmacro{labelname:normal}}%
\usebibmacro{name:andothers}%
\cbx@nametracker{\thefield{hash}}%
\cbx@countname{\thefield{hash}}}
\newbibmacro{labelname:corp}{%
\ifboolexpr{ ( test {\iffieldequalstr{uniquepart}{short}}
or test {\iffieldequalstr{uniquepart}{base}})
and test {\ifnumgreater{\cbx@namecount{\thefield{hash}}}{1}}}
{\cbx@ifnameseen{\thefield{hash}}
{\usebibmacro{name:corp}
{\empty}
{\namepartshort}}
{\usebibmacro{name:corp:both}
{\namepartlong}
{\namepartshort}}}
{\usebibmacro{name:corp}
{\namepartlong}
{\empty}}}
\newbibmacro{labelname:normal}{%
\ifcase\value{uniquename}%
\usebibmacro{name:family}
{\namepartfamily}
{\namepartgiven}
{\namepartprefix}
{\namepartsuffix}%
\or
\ifuseprefix
{\usebibmacro{name:given-family}
{\namepartfamily}
{\namepartgiveni}
{\namepartprefix}
{\namepartsuffixi}}
{\usebibmacro{name:given-family}
{\namepartfamily}
{\namepartgiveni}
{\namepartprefixi}
{\namepartsuffixi}}%
\or
\usebibmacro{name:given-family}
{\namepartfamily}
{\namepartgiven}
{\namepartprefix}
{\namepartsuffix}%
\fi}
\newbibmacro*{name:corp}[2]{%
\usebibmacro{name:delim}{#1#2}%
\usebibmacro{name:hook}{#1#2}%
\ifdefvoid{#1}{}{\mkbibnamecorplong{#1}}%
\ifdefvoid{#2}{}{\mkbibnamecorpshort{#2}}}
\newbibmacro*{name:corp:both}[2]{%
\usebibmacro{name:delim}{#1}%
\usebibmacro{name:hook}{#1}%
\mkbibnamecorplong{#1}%
\ifdefvoid{#2}{}{\space\mkbibnamecorpshortintro{#2}}}
\newcommand*\mkbibnamecorplong{\mkbibnamefamily}
\newcommand*\mkbibnamecorpshort{\mkbibnamecorplong}
\newcommand*{\mkbibnamecorpshortintro}[1]{\mkbibbrackets{\mkbibnamecorpshort{#1}}}
\makeatother
\begin{filecontents}[force]{\jobname.bib}
@book{SCA,
author = {long={Some Corporate Author}, short={SCA}, nametemplates=corp},
title = {Title},
location = {Location},
publisher = {Publisher},
date = {2018}
}
@book{SCAb,
author = {long={Some Corporate Author}, short={SCA}, nametemplates=corp},
title = {Title},
location = {Location},
publisher = {Publisher},
date = {2017}
}
@book{ACA,
author = {long={Another Corporate Author}, nametemplates=corp},
title = {Another Title},
location = {Location},
publisher = {Publisher},
date = {2017}
}
@book{YACA,
author = {long={Yet Another Corporate Author}, short={YACA}, nametemplates=corp},
title = {Yet Another Title},
location = {Location},
publisher = {Publisher},
date = {2016}
}
@book{Author,
author = {Author, Personal},
title = {Yet Another Title},
location = {Location},
publisher = {Publisher},
date = {2015}
}
@book{ElkAPA,
author = {Anne Elk and long={American Psychological Association}, short={APA}, nametemplates=corp},
title = {On the Psychology of Brontosauruses},
location = {Location},
publisher = {Publisher},
date = {1974}
}
@book{HumphreyAPA,
author = {Humphrey Appleby and long={American Psychological Association}, short={APA}, nametemplates=corp},
title = {The Civil Service},
location = {Location},
publisher = {Publisher},
date = {1981}
}
\end{filecontents}
\addbibresource{\jobname.bib}
\addbibresource{biblatex-examples.bib}
\begin{document}
\parencite{sigfridsson}
\parencite{SCA}; \parencite{SCA}
\parencite{ACA}; \parencite{ACA}
\parencite{YACA,SCAb}
\parencite{Author,ElkAPA}
\parencite{HumphreyAPA}
\printbibliography
\end{document}
答案2
citetracker
您可以使用和citecounter
选项以及字段biblatex
来实现这一点shortauthor
。
在这个解决方案中,我重新定义了 bibmacro cite
(来自authoryear.cbx
)以添加许多测试。逻辑是:
- 如果没有
shortauthor
字段或之前已经看到过输入键(使用\ifciteseen
- 然后只需执行默认操作,即打印
labelname
。
- 然后只需执行默认操作,即打印
- 别的
author
按labelname
格式打印- 然后,如果此输入键在当前参考部分出现多次,则
labelname
在括号中打印(这将包含shortauthor
)
- 最后,打印
labeldate
平均能量损失
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{SCA,
author = {{Some Corporate Author}},
shortauthor = {SCA},
title = {Title},
location = {Location},
publisher = {Publisher},
date = {2018}
}
@book{ACA,
author = {{Another Corporate Author}},
title = {Another Title},
location = {Location},
publisher = {Publisher},
date = {2017}
}
@book{YACA,
author = {{Yet Another Corporate Author}},
shortauthor = {YACA},
title = {Yet Another Title},
location = {Location},
publisher = {Publisher},
date = {2016}
}
@book{Author,
author = {Author, Personal},
title = {Yet Another Title},
location = {Location},
publisher = {Publisher},
date = {2015}
}
\end{filecontents}
\usepackage[style=authoryear,citecounter,citetracker]{biblatex}
\addbibresource{\jobname.bib}
\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{document}
\parencite{SCA}; \parencite{SCA}
\parencite{ACA}; \parencite{ACA}
\parencite{YACA}
\parencite{Author}
\printbibliography
\end{document}