我用贾布夫使用 Biblatex 根据 ISO 4 标准自动缩写我的参考文献列表中的期刊标题。
我希望会议论文集的标题(即条目字段title
和@proceedings
条目booktitle
领域@inproceedings
)也能同样缩写,因为它们往往非常冗长和公式化(例如,“第 53 届计算语言学协会年会和第 7 届国际自然语言处理联合会议论文集”可以压缩为“第 53 届计算语言学协会年会和第 7 届国际自然语言处理联合会议论文集”。)。
考虑以下最小示例:
\documentclass{article}
\begin{filecontents}{\jobname.bib}
@inproceedings{foo,
author = {John Smith},
title = {International Linguistics is Fun},
booktitle = {Proceedings of the 53rd {Annual} {Meeting} of the {Association} for {Computational} {Linguistics} and the 7th {International} {Joint} {Conference} on {Natural} {Language} {Processing}},
year = 2015,
}
@inbook{bar,
author = {Mary Taylor},
title = {Some Chapter I Wrote},
booktitle = {European Analytical Chemistry},
year = 2022,
}
\end{filecontents}
\usepackage[backend=biber]{biblatex}
\addbibresource{\jobname.bib}
\usepackage{jabbrv}
% Variant 1
% \DeclareFieldInputHandler{booktitle}{\def\NewValue{\JournalTitle{#1}}}
% Variant 2
% \DeclareFieldFormat[inproceedings]{booktitle}{\JournalTitle{#1}}
\begin{document}
\nocite{*}\printbibliography
\end{document}
如果我取消注释变体 1(这是jabbrv
包本身应用于journaltitle
字段的方式),则@inproceedings
条目的booktitle
缩写将正确。但是,@inbook
条目的缩写booktitle
也会被缩写(为“Eur. Anal. Chem.”),这是我不想要的。
软件包jabbrv
源代码包含一条注释,内容如下
%% This package provides the "\JournalTitle{<title>}" command, where
%% "<title>" is a journal title that you wish to have automatically
%% abbreviated. For example,
%% \JournalTitle{Journal of the Optical Society of America}
%% will be replaced to read
%% J. Opt. Soc. Am.
这让我相信,我的最小示例的变体 2 可能会将缩写限制为条目booktitle
中的那些字段@inproceedings
。但是,如果我使用此变体而不是变体 1,则文档完全无法编译:
ERROR: Missing \endcsname inserted.
--- TeX said ---
<to be read again>
\let
l.31 \end
{document}
--- HELP ---
From the .log file...
The control sequence marked <to be read again> should
not appear between \csname and \endcsname.
有任何想法吗?
答案1
也许令人惊讶的是,该\DeclareFieldFormat
解决方案不起作用,因为\JournalTitle
这是一个相当复杂的宏,基本上只能处理原始文本。字段格式booktitle
虽然在标准样式中,原始文本不会调用字段格式,但它的使用方式如下(biblatex.def
,v3.18 中的 ll. 2849-3861)
\newbibmacro*{booktitle}{%
\ifboolexpr{
test {\iffieldundef{booktitle}}
and
test {\iffieldundef{booksubtitle}}
}
{}
{\printtext[booktitle]{%
\printfield[titlecase]{booktitle}%
\setunit{\subtitlepunct}%
\printfield[titlecase]{booksubtitle}}%
\newunit}%
\printfield{booktitleaddon}}
这意味着booktitle
字段格式全部通过
\printfield[titlecase]{booktitle}%
\setunit{\subtitlepunct}%
\printfield[titlecase]{booksubtitle}%
可以理解的是,这\JournalTitle
让人窒息。
\DeclareFieldInputHandler
我们可以使用 来模拟特定类型\iffieldequalstr
。虽然通常不能保证在\DeclareFieldInputHandler
处理时其他字段的值可用,但.bbl
文件的结构确保可以检查条目类型(对于除entrykey
和entrytype
本身之外的所有字段)。
\documentclass{article}
\usepackage[backend=biber]{biblatex}
\usepackage{jabbrv}
\makeatletter
\DeclareFieldInputHandler{booktitle}{%
\iffieldequalstr{entrytype}{inproceedings}
{\def\NewValue{\JournalTitle{#1}}}
{\def\NewValue{#1}}}
\makeatother
\begin{filecontents}{\jobname.bib}
@inproceedings{foo,
author = {John Smith},
title = {International Linguistics is Fun},
booktitle = {Proceedings of the 53rd Annual Meeting
of the Association for Computational Linguistics
and the 7th International Joint Conference
on Natural Language Processing},
year = 2015,
}
@inbook{bar,
author = {Mary Taylor},
title = {Some Chapter I Wrote},
booktitle = {European Analytical Chemistry},
year = 2022,
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}\printbibliography
\end{document}
\JournalTitle
另一种选择是当 Biber 读取数据时使用源映射直接注入宏。
\documentclass{article}
\usepackage[backend=biber]{biblatex}
\usepackage{jabbrv}
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map{
\pertype{inproceedings}
\step[fieldsource=booktitle,
match=\regexp{\A(.*)\Z},
replace=\regexp{\\JournalTitle{$1}}]
}
}
}
\begin{filecontents}{\jobname.bib}
@inproceedings{foo,
author = {John Smith},
title = {International Linguistics is Fun},
booktitle = {Proceedings of the 53rd Annual Meeting
of the Association for Computational Linguistics
and the 7th International Joint Conference
on Natural Language Processing},
year = 2015,
}
@inbook{bar,
author = {Mary Taylor},
title = {Some Chapter I Wrote},
booktitle = {European Analytical Chemistry},
year = 2022,
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}\printbibliography
\end{document}
答案2
尝试了一段时间后,仍然不明白为什么我的问题中的变体 2 不能按预期工作,下面是我想出的一个解决方案。我不确定这是否是最优雅的,因此欢迎另一个答案来解释原始问题的原因,并(如有必要)提供一个不太复杂的解决方案。
% Variant 3
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map{
\step[fieldsource=booktitle]
\step[fieldset=usera, origfieldval]
}
}
}
\DeclareFieldInputHandler{usera}{\def\NewValue{\JournalTitle{#1}}}
\DeclareFieldFormat[inproceedings]{booktitle}{\mkbibemph{\printfield{usera}}}
此变体使用源映射将booktitle
字段复制到usera
所有条目的字段,然后定义一个字段输入处理程序将usera
其包装在jabbrv
命令中\JournalTitle
,最后定义booktitle
条目字段的格式@proceedings
以打印usera
字段而不是字段booktitle
。
答案3
Biblatex 的人们可能有更好的解决方案,但你可以用以下方法替换驱动程序inproceedings
(用 % 强调键替换):
\DeclareFieldFormat{abbrv}{\JournalTitle{#1}}
\DeclareBibliographyDriver{inproceedings}{%
\usebibmacro{bibindex}%
\usebibmacro{begentry}%
\usebibmacro{author/translator+others}%
\setunit{\printdelim{nametitledelim}}\newblock
\usebibmacro{title}%
\newunit
\printlist{language}%
\newunit\newblock
\usebibmacro{byauthor}%
\newunit\newblock
\usebibmacro{in:}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\usebibmacro{maintitle+booktitle}%
{\em\printfield[abbrv]{booktitle}}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newunit\newblock
\usebibmacro{event+venue+date}%
\newunit\newblock
\usebibmacro{byeditor+others}%
\newunit\newblock
\iffieldundef{maintitle}
{\printfield{volume}%
\printfield{part}}
{}%
\newunit
\printfield{volumes}%
\newunit\newblock
\usebibmacro{series+number}%
\newunit\newblock
\printfield{note}%
\newunit\newblock
\printlist{organization}%
\newunit
\usebibmacro{publisher+location+date}%
\newunit\newblock
\usebibmacro{chapter+pages}%
\newunit\newblock
\iftoggle{bbx:isbn}
{\printfield{isbn}}
{}%
\newunit\newblock
\usebibmacro{doi+eprint+url}%
\newunit\newblock
\usebibmacro{addendum+pubstate}%
\setunit{\bibpagerefpunct}\newblock
\usebibmacro{pageref}%
\newunit\newblock
\iftoggle{bbx:related}
{\usebibmacro{related:init}%
\usebibmacro{related}}
{}%
\usebibmacro{finentry}}