例如,我想知道以下两者之间的区别:
\setunit*{\space}
(有*
但没有add
)
和
\setunit{\addspace}
(没有*
,但有add
)。
我有时会在 biblatex文件中看到这样的表达\setunit*{\addspace}
(同时包含*
和) 。这是否有点多余,因为我认为add
.bbx
*
和add
前缀具有相同的功能,即避免双重标点符号?
我之所以问这个问题,是因为我刚刚重新定义了 @book 驱动程序,以便反转edition
和byeditor+other
宏的顺序。然后,为了删除逗号,我用 替换了\newunit\newblock
。\setunit{\addspace}
这得到了 :
\printfield{edition}%
\setunit{\addspace}%
\usebibmacro{byeditor+others}%
这时,我开始问自己是否应该添加*
,因为我有时会在那些.bbx
文件中看到。
答案1
\setunit
和之间以及和\setunit*
之间的差异是完全正交的。\addspace
\space
在深入了解biblatex
标点符号缓冲区的细节之前,最好先了解一下基础知识。§4.11.7 中有非常好的例子使用标点符号追踪器的biblatex
文档我已经在本网站的各种答案中写过它,例如\setunit 和 \newunit 起什么作用?,biblatex:\DeclareCiteCommand 在 \printfield 和 \printnames 之间添加分号,但只是有时,biblatex 中 @inbook 条目的 in:, \intitlepunct 正确使用。主要思想是,biblatex
当在命令中遇到标点符号时,不会直接打印标点符号\setunit
。相反,标点符号会被保存,然后由下一个打印任何内容的\printtex
、\printfield
、\printlist
、\printnames
、\printdate
命令打印。后面的\setunit
s 会覆盖先前调用的标点符号\setunit
。标点符号缓冲区意味着可以避免重复标点符号。这还意味着,在确保标点符号正确时,biblatex
通常可以避免过多的调用。\iffieldundef{...}
\setunit
对比\setunit*
当biblatex
看到 时,\setunit
它会将其参数保存在标点缓冲区中(覆盖其先前的内容)。下次biblatex
遇到\print(text|field|list|names|date)
打印某些内容的命令时,会打印缓冲区。
\DeclareBibliographyDriver{book}{%
\printnames{author}%
\setunit{ \textbf{A} }%
\printfield{title}%
\setunit{ \textbf{B} }%
\printfield{edition}%
\setunit{ \textbf{C} }%
\printdate}
当biblatex
看到时,\setunit{ \textbf{B} }
它会将其添加\textbf{B}
到缓冲区。然后它会看到\printfield{edition}
。如果版本字段不为空,biblatex
将打印缓冲区的内容,然后打印版本字段的内容。如果字段为空,则不会发生任何事情。然后biblatex
看到\setunit{ \textbf{C} }
并将它添加 \textbf{C}
到缓冲区。然后\printdate
打印缓冲区和日期(如果日期不为空),否则不执行任何操作。
特别是我们将看到
阿普尔比,汉弗莱A 论公务员制度的重要性 乙第 4 版C1980
如果author
、title
和edition
存在date
,但我们得到
布普比,汉弗莱A 论公务员制度的重要性 C1981
如果没有edition
字段,因为\setunit
会覆盖缓冲区(因此“最后的\setunit
胜利”)。
\setunit*
工作方式略有不同:如果前一个命令打印了某些内容,它才会将其参数添加到标点符号缓冲区\print(text|field|list|names|date)
。
和
\DeclareBibliographyDriver{book}{%
\printnames{author}%
\setunit{ \textbf{A} }%
\printfield{title}%
\setunit{ \textbf{B} }%
\printfield{edition}%
\setunit*{ \textbf{C} }%
\printdate}
上面的相同示例条目将产生
阿普尔比,汉弗莱A 论公务员制度的重要性 乙第 4 版C1980
布普比,汉弗莱A 论公务员制度的重要性 乙1981
也就是说,在 Bppleby 条目中,edition
我们得到了一个乙而不是C就像这个\setunit
案例一样。
这是因为这里\setunit*{ \textbf{B} }
检查是否\printfield{edition}
打印了某些内容,并且只添加\texbf{B}
到缓冲区如果是这样的话。第二个条目没有edition
字段,因此\setunit*
后续操作\printfield{edition}
不执行任何操作。
一个常见的用途\setunit*
是在字段之间通常\setunit
同时出现,但在特殊情况下第一个字段可能会缺失(如果第二个字段缺失,那么我们是否使用或并不重要,\setunit*
因为后面的字段\setunit
无论如何都会覆盖它)。
standard.bbx
例如
\newbibmacro*{series+number}{%
\printfield{series}%
\setunit*{\addspace}%
\printfield{number}%
\newunit}
这意味着如果 和 都series
存在number
,则它们之间只有一个空格。但如果series
缺少 ,则标点符号跟踪器前面不会有空格number
,而是前面的内容。
\setunit
和之间的另一个区别的例子\setunit*
是在 biblatex-chicago 中使用句点分隔期刊卷和发行号时,修复仅包含发行号的期刊的格式。
\addspace
对比\space
\addspace
定义biblatex.sty
为
\newrobustcmd*{\addspace}{%
\unspace\blx@postpunct
\space\blx@imc@resetpunctfont}
本质上这意味着它\addspace
会\space
做一些额外的管理工作。
特别是\unspace
,\addspace
在插入自己的 之前尝试抑制任何先前的空格\space
。这应该有助于防止出现虚假空格。比较(坏例子)
\printnames{author}
\setunit{\space}%
\printfield{title}%
和
\printnames{author}
\setunit{\addspace}%
\printfield{title}%
这里第一行应该是
\printnames{author}%
而不是\printnames{author}
。但仍然可以防止产生\addspace
不必要的双倍空格。\space
\blx@postpunct
是一个内部命令,可帮助正确使用美式引号。在美式引号风格中,引号可能会越过后面的标点符号,即使严格来说它不属于引文本身。(见https://en.wikipedia.org/wiki/Quotation_marks_in_English#US_practice。
\blx@imc@resetpunctfont
biblatex
是该功能代码的一部分punctfont
,它以与以前的文本相同的样式排版标点符号。
\add...
其他标点符号命令的定义也类似biblatex
。\addcomma
产生逗号,尽量避免虚假空格和不必要的双标点,并进行一些常规处理。
基本上,您总是希望使用\addspace
而不是\space
(\addcomma
而不是,
,\addperiod
而不是.
等等),但并不总是容易发现差异(特别是如果您使用%
以避免虚假空格,不要使用美国引号约定并且不要激活punctfont
)。
只有一种情况通常优先使用biblatex
where而不是 ,即当空格直接跟在同一个宏中已经使用 的不同标点符号命令之后时。通常的习惯用法是\space
\addspace
\add...
\setunit{\addcomma\space}%
而不是,\setunit{\addcomma\addspace}%
因为\addcomma
已经完成了所有必要的整理工作,因此空间无需再做任何事。当然,\addcolon\space
等\addperiod\space
也是如此。
结束语
\setunit*{\space}
在标准样式中,我找不到 的一个实例biblatex
,但我可以找到几个\setunit*{\addspace}
。即使您看不出 和 之间的区别\setunit*{\space}
,但\setunit*{\addspace}
我认为\addspace
在几乎所有情况下您都应该使用 。
是否应该在问题中引用的代码中使用\setunit
或取决于如果缺少则您期望的行为。\setunit*
edition
用于测试的 MWE
\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}
\usepackage[style=authoryear, backend=biber]{biblatex}
\DeclareBibliographyDriver{book}{%
\printnames{author}
\setunit{\addspace}%
\printfield{title}%
\setunit{ \textbf{B} }%
\printfield{edition}%
\setunit{ \textbf{C} }%
\printdate
\setunit{\par}%
\printnames{author}
\setunit{\addspace}%
\printfield{title}%
\setunit{ \textbf{B} }%
\printfield{edition}%
\setunit*{ \textbf{C} }%
\printdate}
\begin{filecontents}{\jobname.bib}
@book{appleby,
author = {Humphrey Appleby},
title = {On the Importance of the Civil Service},
date = {1980},
edition = {4},
}
@book{bppleby,
author = {Humphrey Bppleby},
title = {On the Importance of the Civil Service},
date = {1981},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\cite{appleby,bppleby}
\printbibliography
\end{document}