Proper use of in:, \intitlepunct for @inbook entries in biblatex

The following code produces what are (to me) unexpected results and I would like to know where I am going wrong. Here's the code:

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@bookinbook{robber-early-years,
crossref  =   {robber-robberies},
title     =   {Robbing Trains: The Early Years},
pages     =   {33-245}}
@inbook{robber-greatest,
crossref  =   {robber-robberies},
title     =   {My Greatest Robbery Yet},
pages     =   {456--468}}
@book{robber-robberies,
author    =   {Robber, Great Train},
title     =   {A Robber's Life},
year      =   2014,
publisher =   {Fictitious Emporium Ltd.},
\end{filecontents}
\usepackage{biblatex}
\makeatletter
% http://tex.stackexchange.com/a/10686/39222
\renewbibmacro{in:}{%
\ifentrytype{article}{}{\printtext{\bibstring{in}\intitlepunct}}}
\makeatother
\bibliography{\jobname.bib}

\begin{document}

\autocites{robber-early-years}{robber-greatest}

\printbibliography

\end{document}


What I expect this to do for entry types which use the bibmacro in: and which are not of type @article is to use in or In followed by a breakable space rather than in or In followed by a colon etc. However, I get a full stop as well and I do not understand why:

I can avoid this by redefining the @inbook entry type:

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@bookinbook{robber-early-years,
crossref  =   {robber-robberies},
title     =   {Robbing Trains: The Early Years},
pages     =   {33-245}}
@inbook{robber-greatest,
crossref  =   {robber-robberies},
title     =   {My Greatest Robbery Yet},
pages     =   {456--468}}
@book{robber-robberies,
author    =   {Robber, Great Train},
title     =   {A Robber's Life},
year      =   2014,
publisher =   {Fictitious Emporium Ltd.},
\end{filecontents}
\usepackage{biblatex}
\makeatletter
% http://tex.stackexchange.com/a/10686/39222
\renewbibmacro{in:}{%
\ifentrytype{article}{}{\printtext{\bibstring{in}\intitlepunct}}}
\makeatother
\bibliography{\jobname.bib}
\makeatletter
\DeclareBibliographyDriver{inbook}{%
\usebibmacro{bibindex}%
\usebibmacro{begentry}%
\usebibmacro{author/translator+others}%
\setunit{\labelnamepunct}\newblock
\usebibmacro{title}%
\newunit
\printlist{language}%
\newunit\newblock
\usebibmacro{byauthor}%
\newunit\newblock
\usebibmacro{in:}%
%   \usebibmacro{bybookauthor}%
%   \newunit\newblock
\usebibmacro{maintitle+booktitle}%
\newunit\newblock
\usebibmacro{byeditor+others}%
\newunit\newblock
\printfield{edition}%
\newunit
\iffieldundef{maintitle}
{\printfield{volume}%
\printfield{part}}
{}%
\newunit
\printfield{volumes}%
\newunit\newblock
\usebibmacro{series+number}%
\newunit\newblock
\printfield{note}%
\newunit\newblock
\usebibmacro{publisher+location+date}%
\newunit\newblock
\usebibmacro{chapter+pages}%
\newunit\newblock
\iftoggle{bbx:isbn}
{\printfield{isbn}}
{}%
\newunit\newblock
\usebibmacro{doi+eprint+url}%
\newunit\newblock
\setunit{\bibpagerefpunct}\newblock
\usebibmacro{pageref}%
\newunit\newblock
\iftoggle{bbx:related}
{\usebibmacro{related:init}%
\usebibmacro{related}}
{}%
\usebibmacro{finentry}}
\makeatother

\begin{document}

\autocites{robber-early-years}{robber-greatest}

\printbibliography

\end{document}


But this is surely not the best way to do this. It strikes me as odd that the driver for @inbook tries to use the book author as well as the author. As I understand it, @inbook and @bookinbook are for precisely those cases in which the author of the whole is also the author of a distinct part. An example for @bookinbook mentioned in the manual is the collected works of an author. But in that case, you would not expect a distinct author and it seems silly to include the author twice when laying out the entry.

This makes me think that I'm fundamentally misunderstanding something here - either about how the commands work or about the intended purpose of these entry types.

If I stick to the standard definition of in:, I don't get spurious full stops but I do, of course, get the colon I wanted to get rid of. (This looks especially silly for non-article entries, in my view, and in is altogether unnecessary for article entries so eliminating the colon seemed a good option. The comment in the code is to the question I took the code from but I cannot get it to work 'right'.)

Can anybody explain how to do this correctly and how these are intended to be used?

-

Although I can't promise I've understood it, I think that by using \addspace you are confusing the punctuation tracker. Because the tracker sees that no relevant punctuation mark has been printed, when the next \newunit occurs (immediately after bybookauthor has printed nothing), it backs up, removes your space, and inserts \newunitpunct.

You can sort this out by defining \intitlepunct as \addspace\nopunct, which I think should be safe in this context.

-
This seems to work great - thanks! I had wondered if it had to do with this but did not know how to trace it or correct for/work around it. This seems (on brief testing) to do the job nicely. I would like to understand better the underlying issue with the tracker. Do you know if this is documented somewhere? –  cfr May 7 at 18:11
It's quite extensively documented in the manual (around 4.7) but it is highly condensed. –  Paul Stanley May 7 at 19:23
Thanks. That is helpful. I find navigating the biblatex manual a bit challenging at times ;). –  cfr May 7 at 22:00

biblatex has a punctuation tracker and a punctuation buffer, a \newunit or \setunit command inserts the respective punctuation mark into the buffer, it does not print the punctuation mark straight away, subsequent \setunits overwrite the buffer.

So the \addspace in the buffer is overwritten by the \newunit following the bybookauthor macro. Luckily for us, the biblatex developers got into trouble with this concept at some point and decided to add \printunit. \printunit inserts a punctuation mark that persist in the buffer, i.e. cannot be overwritten by other \setunits.

If we add the \printunit command to the redefinition of in:

\renewbibmacro{in:}{%
\ifentrytype{article}{}{\printtext{\bibstring{in}\printunit{\intitlepunct}}}}


the output should be as expected. (I don't know why this is not the default, after all, the "in:" is always printed and one would want it to be followed by the proper punctuation mark as defined in \intitlepunct.)

This problem seems to occur only with \intitlepunct set to \addspace or \space, any of the other \add commands work like a charm without \printunit.

You can read more about the wonderful world of punctuation with biblatex in §4.7 Punctuation and Spacing, p. 189 of the biblatex documentation.

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@bookinbook{robber-early-years,
crossref  =   {robber-robberies},
title     =   {Robbing Trains: The Early Years},
pages     =   {33-245}}
@inbook{robber-greatest,
crossref  =   {robber-robberies},
title     =   {My Greatest Robbery Yet},
pages     =   {456--468}}
@book{robber-robberies,
author    =   {Robber, Great Train},
title     =   {A Robber's Life},
year      =   2014,
publisher =   {Fictitious Emporium Ltd.},
\end{filecontents*}
\usepackage{biblatex}

\renewbibmacro{in:}{%
\ifentrytype{article}{}{\printtext{\bibstring{in}\printunit{\intitlepunct}}}}


Thanks very much for the explanation and answer. Is this solution preferable to the use of \nopunct suggested by Paul Stanley in his answer? His seems to work well in the case I was dealing with but I'd prefer to use the most robust solution or I'm bound to get caught out at some point when I fail to notice unexpected results. (As happened initially in this case, in fact.) –  cfr May 7 at 21:03
For my own part I think the solutions are equally good/bad. In fact, I originally used moewe's but preferred \nopunct because I think it more accurately expresses the intention: his effectively means "punctuate this with intitlepunct (even if it's not punctuation)", whereas mine means "use a space, and no following punctuation". In this case, however, it comes to the same thing, I think. –  Paul Stanley May 7 at 22:45
At first, I thought my solution to be the more biblatex-y (that's why I posted it in the first place after Paul Stanley had already given an answer). But seeing that some of the things I expected when playing around with the punctuation did not come true - and given Paul Stanley's reasoning above - I tend to think that his solution as actually preferable in this case: it's slightly shorted and probably more meaningful. –  moewe May 8 at 5:20
@PaulStanley On wone thing though I have to disagree. I think my solution actually tells biblatex: "Print this 'punctuation' mark (OK, in our case it is only a space: but now we use \printunit and that can be used for whitespace as well) after the 'in', no matter what anyone else tells you; make sure it is the thing that comes after the 'in'." –  moewe May 8 at 5:23
@moewe That's right ... nearly -- because technically I think \printunit doesn't actually print the unit: it sits it in the buffer but makes it persist there regardless of subsequent \newunit or \setunits. But the actual printing only happens when the buffer clears. A second \printunit will still clobber it. But that's irrelevant in this case, and not a reason to prefer my solution! –  Paul Stanley May 8 at 7:25