6

For example, I would like to know what is the difference between :

  • \setunit*{\space} (with * but without add)

and

  • \setunit{\addspace} (without *, but with add).

I sometimes see the expression \setunit*{\addspace} (with both * and add) in the biblatex .bbx files. Is it not a bit redundant, since I believe that * and the add prefix have the same function, which is avoiding double punctuation ?

I am asking this question because I just redefined the @book driver in order to reverse the order of edition and byeditor+other macros. Then, in order to remove the comma, I replaced \newunit\newblock with \setunit{\addspace}. Which gave :

\printfield{edition}%
\setunit{\addspace}%
\usebibmacro{byeditor+others}%

At this moment, I started to ask myself whether I should or not add a *, as I sometimes see in those .bbx files.

7

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 \setunits 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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.