plk / biblatex

biblatex is a sophisticated bibliography system for LaTeX users. It has considerably more features than traditional bibtex and supports UTF-8
520 stars 118 forks source link

\multicitedelim in a \setunit? #285

Open maieul opened 10 years ago

maieul commented 10 years ago

I have a problem of spurious space when using anonymous works.

See the following MWE

\documentclass{article}
\usepackage{polyglossia,csquotes,fontspec}
\setmainfont{Linux Libertine O}
\setmainlanguage{french}
\usepackage[bibstyle=verbose,citestyle=verbose-trad2]{biblatex}
\addbibresource{toto.bib}

\begin{document}
\cites[222]{Delvoye1980}{BHG225}
\end{document}

And the .bib file

@INPROCEEDINGS{Delvoye1980,
  AUTHOR        = {Charles Delvoye},
  BOOKSUBTITLE  = {État des recherches},
  BOOKTITLE     = {Salamine de Chypre Histoire et Archéologie},
  LOCATION      = {Paris},
  NUMBER        = {578},
  PAGES         = {313-327},
  PUBLISHER     = {Édition du Centre National de la Recherche Scientifique},
  SERIES        = {Colloques internationaux du Centre National de la Recherche Scientifique},
  TITLE         = {La place des grandes basiliques de Salamine de Chypre dans l'architecture paléochrétienne},
  YEAR          = {1980},
}

@BOOKINBOOK{BHG225,
  BOOKTITLE     = {Acta Apostolorum Apocrypha},
  EDITOR        = {Maximilien Bonnet},
  LOCATION      = {Darmstadt},
  ORIGDATE      = {1903},
  ORIGLOCATION  = {Leipzig},
  ORIGPUBLISHER = {Hermann Mendelssohn},
  PAGES         = {292-302},
  PUBLISHER     = {Wissenschaftliche Buchgesellschaft},
  TITLE         = {Acta Barnabae},
  VOLUME        = {2.2},
  YEAR          = {1959},
}

As there is no author or translator in BHG225, the \setunit{\labelnamepunct}\newblock of the l. 199 of standard.bbx print a unity between the postnotes field of Delvoye1980 and the title field of BHG225.

So there is a spurious spaces after the ; and before the Acta Barnabae, implicated by the \multicitedelim.

The solution is to consider the \multicitedelim as a setunit command :

\renewcommand*{\multicitedelim}{\setunit{\addsemicolon\space}}

My suggestion will be to automatically include the multiple citation delimitator in a \setunit.

plk commented 10 years ago

@audrey - looks like a standard style issue and in your area of expertise ...

aboruvka commented 10 years ago

\setunit should be invoked after printing a field that might be missing. Citation labels are never entirely missing, so \multcitedelim isn't the problem here; it is rather the use of \setunit{\labelnamepunct} instead of \setunit*{\labelnamepunct} in the bibliography driver generating the full/verbose citation label.

Thanks for pointing this out. Since all the standard drivers need to be revised and I've had some issues with \setunit* behaving consistently, this fix will take some time to incorporate and test. For now you should use your solution as a workaround.

maieul commented 10 years ago

You're right. I didn't know the starred version. I will patch the style in the biblatex-anonymous, before biblatex be corrected.

aboruvka commented 10 years ago

The starred variant likely needs fixing because it probably won't correct all instances of this problem. It should for \fullcite, but I am not certain about \cites and friends.

maieul commented 10 years ago

Indeed, see (with the same entries)

\documentclass{article}
\usepackage{polyglossia,csquotes,fontspec}
\setmainfont{Linux Libertine O}
\setmainlanguage{french}
\usepackage[bibstyle=verbose,citestyle=verbose-trad2]{biblatex}
\usepackage{biblatex-anonymous}

\addbibresource{toto.bib}

\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
  \usebibmacro{addendum+pubstate}%
  \setunit{\bibpagerefpunct}\newblock
  \usebibmacro{pageref}%
  \newunit\newblock
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}

\begin{document}

\cites[222]{Delvoye1980}{BHG225}
\end{document}
plk commented 9 years ago

@aboruvka - is this likely to be done soon? If not, I won't worry about it for the next release.

maieul commented 9 years ago

somes news about this issue?

maieul commented 8 years ago

hi @aboruvka do you think this issue could be solvable soon ?

moewew commented 8 years ago

One problem with the starred version is that there are situations where an entire bibmacro prints nothing, yet blx@lastins is not set to "false" because the bibmacro didn't actually engage in calling any \print... commands. If in @maieul's example above we were to make sure that author/translator+others actually does something with

\renewbibmacro*{translator+others}{%
  \printnames{translator}%
  \ifboolexpr{
    test \ifusetranslator
    and
    not test {\ifnameundef{translator}}
  }
    {\setunit{\addcomma\space}%
     \usebibmacro{translator+othersstrg}%
     \clearname{translator}}
    {}}

say, then the additional space disappears.

There are more macros that could actually do nothing at all in certain circumstances and as such don't toggle blx@lastins.

First one would have to think about the question whether macros that don't do anything should qualify for blx@lastins in the same way \print... commands do. (I'm not to sure if the general idea of making bibmacros behave that way causes issues.) A quick idea was

\renewrobustcmd*{\usebibmacro}{%
  \global\togglefalse{blx@lastins}%
  \@ifstar
    {\blx@usebibmacro@i}
    {\blx@usebibmacro}}

that will however destroy (at least, no idea what else it might wreck) the ability to start macros with a \setunit* (which I consider bad style, but that is still not something we should do).


See also

\documentclass{article}
\usepackage{biblatex}

\addbibresource{biblatex-examples.bib}

\newbibmacro{nooped}{\ifnameundef{editor}{}{\printnames{editor}}}
% compare with
%\newbibmacro{nooped}{\printnames{editor}}

\DeclareBibliographyDriver{article}{%
  \printnames{author}%
  \setunit*{A}%
  \usebibmacro{nooped}%
  \setunit*{B}%
  \printfield{title}%
}

\begin{document}
\cite{sigfridsson}\printbibliography
\end{document}
aboruvka commented 8 years ago

@maieul Unlikely for me as there have been many changes that I need to catch up on. I would also like to wait unil these other issues settle down.

aboruvka commented 8 years ago

@maieul The problem is that the punctuation tracker isn't initialized inside citations, even though the citation labels are generated by the bibliography driver. For now you might use \makeatletter\AtEveryCitekey{\blx@initunit}\makeatother as a temporary workaround. I will look for a proper solution soon.

maieul commented 8 years ago

Thanks @aboruvka I have added it to biblatex-anonymous.sty before it will be corrected on biblatex

maieul commented 8 years ago

The hack was problematic if using prenote. Use \AtEveryCitekey{\iffieldundef{prenote}{\blx@initunit}{}} instead.

moewew commented 4 years ago

I'm wondering if \printunit{\multicitedelim} might help here. That way no two punctuations can clash and \multicitedelim prevails.


edit \printunit should definitely help here, but there is the wider issue here that some parts of biblatex bypass the punctuation tracker and print punctuation and space directly. In those cases it can be dangerous to mix the tracker and direct punctuation.

The best solution for this issue might still be to control initialise all macros properly so that \setunit* does the right thing...

Toy example

\documentclass{article}
\usepackage[style=verbose-trad2]{biblatex}

\DeclareDelimFormat[bib]{nametitledelim}{XXXX}

\iffalse
\DeclareCiteCommand{\cite}
  {\usebibmacro{prenote}}
  {\usebibmacro{citeindex}%
   \usebibmacro{cite}}
  {\printunit{\multicitedelim}}
  {\usebibmacro{cite:postnote}}

\DeclareMultiCiteCommand{\cites}{\cite}{\printunit{\multicitedelim}}
\fi

\begin{filecontents}[force]{\jobname.bib}
@INPROCEEDINGS{Delvoye1980,
  AUTHOR        = {Charles Delvoye},
  BOOKSUBTITLE  = {État des recherches},
  BOOKTITLE     = {Salamine de Chypre Histoire et Archéologie},
  LOCATION      = {Paris},
  NUMBER        = {578},
  PAGES         = {313-327},
  PUBLISHER     = {Édition du Centre National de la Recherche Scientifique},
  SERIES        = {Colloques internationaux du Centre National de la Recherche Scientifique},
  TITLE         = {La place des grandes basiliques de Salamine de Chypre dans l'architecture paléochrétienne},
  YEAR          = {1980},
}
@BOOKINBOOK{BHG225,
  BOOKTITLE     = {Acta Apostolorum Apocrypha},
  EDITOR        = {Maximilien Bonnet},
  LOCATION      = {Darmstadt},
  ORIGDATE      = {1903},
  ORIGLOCATION  = {Leipzig},
  ORIGPUBLISHER = {Hermann Mendelssohn},
  PAGES         = {292-302},
  PUBLISHER     = {Wissenschaftliche Buchgesellschaft},
  TITLE         = {Acta Barnabae},
  VOLUME        = {2.2},
  YEAR          = {1959},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\cites[222]{Delvoye1980}{BHG225}
\end{document}

Related: https://github.com/plk/biblatex/issues/988?

I think it makes sense to use the punctuation tracker as much as possible. This would probably involve \printunit{\multicitedelim} instead of bare \multicitedelims. Since \multicitedlim should only be invoked between two citations that print something there should be no disadvantage in using \printdelim if we can assume that the citation macros are well behaved in the sense that they won't print anything outside of \printfield, \printtext etc.