The differences between \setunit
and \setunit*
and between \addspace
and \space
are completely orthogonal.
Before we get into the details of biblatex
's punctuation buffer, it is a good idea to understand the basics. There are very good examples in §4.11.7 Using the Punctuation Tracker of the biblatex
documentation and I have written about it in various answers on this site, e.g. What do \setunit and \newunit do?, biblatex: \DeclareCiteCommand adds semicolon between \printfield and \printnames, but only sometimes, Proper use of in:, \intitlepunct for @inbook entries in biblatex. The main idea is that biblatex
does not print punctuation marks directly when they are encountered in a \setunit
command. Instead the punctuation is saved and then printed by the next \printtex
, \printfield
, \printlist
, \printnames
, \printdate
command that prints anything. Later \setunit
s override the punctuation from earlier \setunit
calls. The punctuation buffer means that biblatex
avoids double punctuation. It also means that you can usually avoid excessive \iffieldundef{...}
calls when it comes to making sure punctuation looks right.
\setunit
vs \setunit*
When biblatex
sees a \setunit
it saves its argument in the punctuation buffer (overwriting its previous contents). The buffer is printed the next time biblatex
encounters a \print(text|field|list|names|date)
command that prints something.
\DeclareBibliographyDriver{book}{%
\printnames{author}%
\setunit{ \textbf{A} }%
\printfield{title}%
\setunit{ \textbf{B} }%
\printfield{edition}%
\setunit{ \textbf{C} }%
\printdate}
When biblatex
sees the \setunit{ \textbf{B} }
it adds \textbf{B}
to the buffer. Then it sees \printfield{edition}
. If the edition field is not empty, biblatex
will print the contents of the buffer and then the contents of the edition field. If the field is empty, nothing happens. Then biblatex
sees the \setunit{ \textbf{C} }
and adds \textbf{C}
to the buffer. Then \printdate
prints the buffer and the date if the date is not empty and does nothing otherwise.
In particular we will see
Appleby, Humphrey A On the Importance of the Civil Service B 4th ed. C 1980
if author
, title
, edition
and date
are present, but we get
Bppleby, Humphrey A On the Importance of the Civil Service C 1981
if there is no edition
field, because \setunit
overwrites the buffer (so 'the last \setunit
wins').
\setunit*
works slightly differently: It will only add its argument to the punctuation buffer if the previous \print(text|field|list|names|date)
command printed something.
With
\DeclareBibliographyDriver{book}{%
\printnames{author}%
\setunit{ \textbf{A} }%
\printfield{title}%
\setunit{ \textbf{B} }%
\printfield{edition}%
\setunit*{ \textbf{C} }%
\printdate}
the same example entries from above will produce
Appleby, Humphrey A On the Importance of the Civil Service B 4th ed. C 1980
Bppleby, Humphrey A On the Importance of the Civil Service B 1981
That is to say in the Bppleby entry without edition
we get a B and not a C like in the \setunit
case.
That is because here \setunit*{ \textbf{B} }
checks if \printfield{edition}
printed something and only adds \texbf{B}
to the buffer if that is the case. The second entry has no edition
field, so the \setunit*
after \printfield{edition}
does nothing.
One common use for \setunit*
is between fields that usually appear together, but where in exceptional circumstances the first field may be missing (if the second field is missing it doesn't really matter whether we use \setunit
or \setunit*
because a following \setunit
will overwrite it anyway).
standard.bbx
for example has
\newbibmacro*{series+number}{%
\printfield{series}%
\setunit*{\addspace}%
\printfield{number}%
\newunit}
That means that if both series
and number
are present, there is only a space between them. But if series
is missing, there will not be a space before number
but instead the previous content of the punctuation tracker.
Another example of the difference between \setunit
and \setunit*
is at Fixing formatting of journals with only issue numbers when using period to separate journal volume and issue number in biblatex-chicago.
\addspace
vs \space
\addspace
is defined in biblatex.sty
as
\newrobustcmd*{\addspace}{%
\unspace\blx@postpunct
\space\blx@imc@resetpunctfont}
Essentially that means that \addspace
is \space
which does some additional housekeeping.
In particular the \unspace
means that \addspace
tries to suppress any previous space before it inserts its own \space
. This should help prevent spurious spaces. Compare (the bad example)
\printnames{author}
\setunit{\space}%
\printfield{title}%
and
\printnames{author}
\setunit{\addspace}%
\printfield{title}%
here the first line should read
\printnames{author}%
instead of \printnames{author}
. But \addspace
can still prevent the undesirable double space that \space
would produce.
\blx@postpunct
is an internal command that helps get American quotation marks right. In American quotation style the quotation mark may slip past a following punctuation even if it does not strictly speaking belong to the quotation itself. (See https://en.wikipedia.org/wiki/Quotation_marks_in_English#U.S._practice.)
\blx@imc@resetpunctfont
is a part of biblatex
's code for the punctfont
feature, which typesets punctuation in the same style as the previous text.
A similar thing holds for the other \add...
punctuation commands biblatex
defines. \addcomma
produces a comma, tries to avoid spurious spaces, unwanted double punctuation and does some housekeeping.
Basically you always want to use \addspace
instead of \space
(\addcomma
instead of ,
, \addperiod
instead of .
, etc. etc.), but it is not always easy to spot the difference (in particular if you use %
to avoid spurious spaces, don't use the American quotation mark convention and don't activate punctfont
).
There is just one situation in biblatex
where \space
is usually preferred over \addspace
, namely when the space directly follows a different punctuation command in the same macro that already uses \add...
. The usual idiom is
\setunit{\addcomma\space}%
instead of \setunit{\addcomma\addspace}%
because the \addcomma
already does all the necessary housekeeping so that there is nothing left to do for the space. Of course the same holds for \addcolon\space
, \addperiod\space
etc.
Concluding remarks
I could not find a single instance of \setunit*{\space}
in the biblatex
standard styles, but I could find several \setunit*{\addspace}
s. Even if you can't see a difference between \setunit*{\space}
and \setunit*{\addspace}
I would argue that \addspace
is what you should use in almost all cases.
Whether you should use \setunit
or \setunit*
in the code quoted in the question depends on the behaviour you expect if the edition
is missing.
MWE for testing
\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}