1

I use biblatex package. I have a problem with changing multiple citations punctuation.

I want use such commands as \cites and \parentcites follows:

\cites{AuthorYYYY,AuthorYYYY,AuthorYYYY}

I have in output:

Author1 YYYY; Author2 YYYY; Author3 YYYY.

But I want to have:

Author1 YYYY and Author2 YYYY

Author1 YYYY, Author2 YYYY, and Author3 YYYY

Author1 YYYY, p. 1-3, Author2 YYYY, and Author3 YYYY, pp. 4 and 12-14

How do I change it?

Thank you!

2

You can change the general punctuation between consecutive citations that are passed to the same cite-command by changing \multicitedelim. So, something like \renewcommand{\multicitedelim}{\addcomma\space} should change your output to

Author1 YYYY, Author2 YYYY, Author3 YYYY

for \cites{AuthorYYYY,AuthorYYYY,AuthorYYYY}.

Now you even want a different treatment with 'and' in case of two citations and comma between all citations, except the last where it should be 'and' with Oxford-comma in case of more than two citations. I think this is not easily possible, because seemingly biblatex does not distinguish between the delimiter for the last item and all other items separately, as it does for the author-name and list delimiters.

4

I'm late for the party, but I think now biblatex allows you to do that.

Consider the example:

\documentclass{article}
\usepackage{geometry}
\usepackage[citestyle=authoryear-comp]{biblatex}
\addbibresource{biblatex-examples.bib}
\begin{document}
\cites{glashow,herrmann}

\cites{glashow,herrmann,kastenholz}

\cites[1-3]{glashow}{herrmann}[\ppno~4 and~12--14]{kastenholz}
\end{document}

which prints:

enter image description here

If we redefine \multicitedelim we can make it print different delimiters, depending on the number of citations (stored in the citetotal counter) and the number of the current citation (stored in the citecount counter):

\renewcommand*{\multicitedelim}{%
  \iflastcitekey
    {%
      \ifboolexpr{
            test {\ifnumgreater{\value{citetotal}+\value{multicitetotal}-1}{2}}
         or test {\ifnumgreater{\value{lastcitetotal}+\value{citetotal}}{2}}
       }
       {\finalandcomma}
       {}%
      \addspace\bibstring{and}\space
   }
   {\addcomma\space}%
  \ifnumequal{\value{citetotal}}{\value{citecount}}
   {\setcounter{lastcitetotal}{\value{citetotal}}}
   {}%
}

The above definition checks if the current citation key is the last one in the comma separated list using \iflastcitekey. If it's not the last citation, just print \addcomma\space (i.e., ,␣). Otherwise, if it's the last key, we check if the expression \value{citetotal}+\value{multicitetotal}-1 or \value{lastcitetotal}+\value{citetotal} are greater than two, and if they are, print a \finalandcomma and then \addspace\bibstring{and}\space in all cases (,␣and␣).

The first expression is less or equal the total number of citations in the multi-cite command, so if there are multiple citations it will ensure the \finalandcomma. This expression will only fail in the case \cites{one,two}{three}, where multicitetotal is two and citetotal is 1 when three is being processed. In this case the expression evaluates to 2 and the \finalandcomma is not printed, whereas it should.

To work around that exception I added a bodge temporary counter which stores the previous citetotal. In the case of the exception, lastcitetotal will be 2 and citetotal, 1, and their sum will be larger than 2 so the \finalandcomma will be printed.

Adding that definition to our example:

\documentclass{article}
\usepackage{geometry}
\usepackage[citestyle=authoryear-comp]{biblatex}
\addbibresource{biblatex-examples.bib}
\newcounter{lastcitetotal}
\renewcommand*{\multicitedelim}{%
  \iflastcitekey
    {%
      \ifboolexpr{
            test {\ifnumgreater{\value{citetotal}+\value{multicitetotal}-1}{2}}
         or test {\ifnumgreater{\value{lastcitetotal}+\value{citetotal}}{2}}
       }
       {\finalandcomma}
       {}%
      \addspace\bibstring{and}\space
   }
   {\addcomma\space}%
  \ifnumequal{\value{citetotal}}{\value{citecount}}
   {\setcounter{lastcitetotal}{\value{citetotal}}}
   {}%
}
\begin{document}
\pagestyle{empty}
\cites{glashow,herrmann}

\cites{glashow,herrmann,kastenholz}

\cites[1-3]{glashow}{herrmann}[\ppno~4 and~12--14]{kastenholz}
\end{document}

we get:

enter image description here

  • biblatex has the test \iflastcitekey that should also take into account multicites. – moewe Apr 4 at 15:48
  • I should also note that the p.~ in [p.~1--3] is superfluous (since biblatex automatically adds the "p."/"pp." in postnotes if they contain only a page range) and that in [pp.~4 and~12--14] I would prefer [\ppno~4 and~12--14] (here the page detection will yield false because of the and, so we need to ask for the "pp." explicitly). – moewe Apr 4 at 15:51
  • 2
    Yes, "pp." instead of "p." is expected (at least for English texts). Traditionally, "p." stands for "page" while "pp." stands for the plural "pages". Since 1-3 is a page range it would be prefixed with "pp." and not "p.". (Other languages might be different, in German we use "S." for both singular and plural.) – moewe Apr 4 at 19:38
  • 1
    Finally managed to wrap my head around the lastcitetotal idea. I'm pretty much convinced that it should do the right thing here. Of course the additional counter is not pretty, but I'm not sure if it is possible to get a real 'overall citecount' ready... – moewe Apr 4 at 20:05
  • 2
    @moewe Oh, I agree, it's a very clumsy approach. I think it should be possible to have the “overall citecount” as well, mainly because when the first \multicitedelim is inserted we already know how much is multicitetotal, so it means biblatex already scanned the list of [<postnote>]{<citation>}s once, it just didn't count the citations inside that list. Of course I might be reading something wrong here. When I have some time I'll take a look to see if I manage to do something nicer than lastcitetotal, meanwhile I'll point that in my answer. Thanks for the help :) – Phelype Oleinik Apr 4 at 21:35

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.