2

In the bibliography of authoryear-type bibliography styles, BibLaTeX can replace repeated author lists (with all authors the same) with a dash or similar. Is is possible to change this behaviour so that the replacement is made on a per-author basis? This is found in such journals as Palaeontology.

As an example, the following references:

AUTHOR, A. 2000. First reference. Journal A, 2, 21–22.
AUTHOR, A. & BAUTHOR, B. 2001. Second reference. Journal B, 4, 34–46.
AUTHOR, A., BAUTHOR, B. & CAUTHOR, C. 2002. Third reference. Journal C, 6, 89–99.

Would be published as:

AUTHOR, A. 2000. First reference. Journal A, 2, 21–22.
——— & BAUTHOR, B. 2001. Second reference. Journal B, 4, 34–46.
——— ——— & CAUTHOR, C. 2002. Third reference. Journal C, 6, 89–99.

With three em dashes replacing each repeated author.

A reply to With biblatex, is it possible to replace one author of an author list by a bibnamedash or idem string? describes commands to replace a repeated first author only with Idem/Eadem/Eidem/Eaedem, but can this be applied to several authors in the author list?

Addendum: This image is from Porro, L.B., et al., "Computed Tomography, ...", Palaeontology, 2015, p.16.

bibliography example with multiple 3-em dashes

3
  • 2
    welcome to tex.sx. i've read the "palaeontology" instructions to authors, and find the instructions for "repeated" authors not as clear as it might be for cases of multiple authors. can you show an actual example where two papers by the same two authors have the second listed with two 3-em dashes? (in math, only a single 3-em dash would be used, indicating repetition of the exact same author "list"; if the first author is the same, but the second author different on two successive papers, the first author's name would be repeated, not "ditto"ed.) Oct 30, 2015 at 17:43
  • Certainly: I've uploaded a pdf to app.box.com/s/k0bn4eqel45orz12sllqxsbc0lxgmsro The format I described above is shown in the references under the authors Markey and Porro.
    – BenM
    Oct 31, 2015 at 19:12
  • 2
    thanks. i've taken the liberty of clipping out the relevant example and editing it into your question. (another example, just a few lines down from that one, has three 3-em dashes!) i've never seen this before! i'm afraid i can't help you with code (i don't use either biber or biblatex), but i hope that someone with more relevant experience can. (by the way, there's a typo in the last reference item; the third author should be Marshall, C.R., the same as in the first two.) Oct 31, 2015 at 20:31

1 Answer 1

3

The general idea is inspired by Audrey's answer to With biblatex, is it possible to replace one author of an author list by a bibnamedash or idem string?, but takes a very different approach in the end.

You can control the inserted dash with \bibnamedash, the separator between two of those dashes is \multidashdelim, the last is separated by \finaldashdelim.

\makeatletter
\renewcommand*{\bibnamedash}{\textemdash\textemdash\textemdash}
\newcommand*{\multidashdelim}{\addspace}
\newcommand*{\finaldashdelim}{\finalnamedelim}

\newtoggle{bbx:goahead}
\InitializeBibliographyStyle{\global\csundef{bbx@lastname@1}}

\newbibmacro*{bbx:printlist}[1]{%
  \toggletrue{bbx:goahead}%
  \printnames[dashed:given-family]{#1}}

\newbibmacro*{dash:delim}{%
  \ifnumgreater{\value{listcount}}{\value{liststart}}
    {\ifboolexpr{
       test {\ifnumless{\value{listcount}}{\value{liststop}}}
       or
       test \ifmorenames
     }
       {\multidashdelim}
       {\finaldashdelim}}
    {}}

\DeclareNameFormat{dashed:given-family}{%
   \ifboolexpr{togl {bbx:goahead} 
               and test {\iffieldequalcs{hash}{bbx@lastname@\the\value{listcount}}}}
     {\usebibmacro{dash:delim}\bibnamedash}
     {\global\togglefalse{bbx:goahead}%
      \ifgiveninits
        {\usebibmacro{name:family-given}
           {\namepartfamily}%
           {\namepartgiveni}%
           {\namepartprefix}%
           {\namepartsuffix}}
        {\usebibmacro{name:family-given}
          {\namepartfamily}%
          {\namepartgiven}%
          {\namepartprefix}%
          {\namepartsuffix}}}%
  \csxdef{bbx@lastname@\the\value{listcount}}{\thefield{hash}}}

\renewbibmacro*{author}{%
  \ifboolexpr{ test {\ifuseauthor}
               and not test {\ifnameundef{author}} }
    {\usebibmacro{bbx:printlist}{author}%
     \setunit{\addcomma\space}%
     \usebibmacro{authorstrg}}
    {\global\csundef{bbx@lastname@1}}}

\renewbibmacro*{bbx:editor}[1]{%
  \ifboolexpr{ test {\ifuseeditor}
               and not test {\ifnameundef{editor}} }
    {\usebibmacro{bbx:printlist}{editor}%
     \setunit{\addcomma\space}%
     \usebibmacro{#1}%
     \clearname{editor}}
    {\global\csundef{bbx@lastname@1}}}

\renewbibmacro*{bbx:translator}[1]{%
  \ifboolexpr{ test {\ifusetranslator}
               and not test {\ifnameundef{translator}} }
    {\usebibmacro{bbx:printlist}{translator}%
     \setunit{\addcomma\space}%
     \usebibmacro{#1}%
     \clearname{translator}}
    {\global\csundef{bbx@lastname@1}}}
\makeatother

If you want the dash to be able to jump over names, you can just change the line

\ifboolexpr{togl {bbx:goahead} 
            and test {\iffieldequalcs{hash}{bbx@lastname@\the\value{listcount}}}}

to

\iffieldequalcs{hash}{bbx@lastname@\the\value{listcount}}

you can then also remove all mentions of bbx:goahead.

MWE

\documentclass{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[american]{babel}
\usepackage{csquotes}
\usepackage[style=authortitle,
            maxbibnames=999,
            backend=biber,
            sorting=nyt,
            abbreviate=false]{biblatex}

\makeatletter
\renewcommand*{\bibnamedash}{\textemdash\textemdash\textemdash}
\newcommand*{\multidashdelim}{\addspace}
\newcommand*{\finaldashdelim}{\finalnamedelim}

\newtoggle{bbx:goahead}
\InitializeBibliographyStyle{\global\csundef{bbx@lastname@1}}

\newbibmacro*{bbx:printlist}[1]{%
  \toggletrue{bbx:goahead}%
  \printnames[dashed:given-family]{#1}}

\newbibmacro*{dash:delim}{%
  \ifnumgreater{\value{listcount}}{\value{liststart}}
    {\ifboolexpr{
       test {\ifnumless{\value{listcount}}{\value{liststop}}}
       or
       test \ifmorenames
     }
       {\multidashdelim}
       {\finaldashdelim}}
    {}}

\DeclareNameFormat{dashed:given-family}{%
   \ifboolexpr{togl {bbx:goahead} 
               and test {\iffieldequalcs{hash}{bbx@lastname@\the\value{listcount}}}}
     {\usebibmacro{dash:delim}\bibnamedash}
     {\global\togglefalse{bbx:goahead}%
      \ifgiveninits
        {\usebibmacro{name:family-given}
           {\namepartfamily}%
           {\namepartgiveni}%
           {\namepartprefix}%
           {\namepartsuffix}}
        {\usebibmacro{name:family-given}
          {\namepartfamily}%
          {\namepartgiven}%
          {\namepartprefix}%
          {\namepartsuffix}}}%
  \csxdef{bbx@lastname@\the\value{listcount}}{\thefield{hash}}}

\renewbibmacro*{author}{%
  \ifboolexpr{ test {\ifuseauthor}
               and not test {\ifnameundef{author}} }
    {\usebibmacro{bbx:printlist}{author}%
     \setunit{\addcomma\space}%
     \usebibmacro{authorstrg}}
    {\global\csundef{bbx@lastname@1}}}

\renewbibmacro*{bbx:editor}[1]{%
  \ifboolexpr{ test {\ifuseeditor}
               and not test {\ifnameundef{editor}} }
    {\usebibmacro{bbx:printlist}{editor}%
     \setunit{\addcomma\space}%
     \usebibmacro{#1}%
     \clearname{editor}}
    {\global\csundef{bbx@lastname@1}}}

\renewbibmacro*{bbx:translator}[1]{%
  \ifboolexpr{ test {\ifusetranslator}
               and not test {\ifnameundef{translator}} }
    {\usebibmacro{bbx:printlist}{translator}%
     \setunit{\addcomma\space}%
     \usebibmacro{#1}%
     \clearname{translator}}
    {\global\csundef{bbx@lastname@1}}}
\makeatother

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@BOOK{bookABC,
  author = {Anne Uthor and Enid Blyton and William Riter},
  title = {UBR},
  date = {1990},}
@BOOK{bookADC,
  author = {Anne Uthor and James Joyce and William Riter},
  title = {UJR},
  date = {1991},}
@BOOK{book1,
  author = {Buchautor, Emma-Louise},
  gender = {sf},
  title = {First Title},
  date = {2001}}
@BOOK{book2,
  author = {Buchautor, Emma-Louise},
  title = {Same female author},
  date = {2002}}
@BOOK{book3,
  author = {Buchautor, Emma-Louise and van Helsing, Sarah},
  gender = {pf},
  title = {Same first author whose gender is unspecified},
  date = {2003}}
@BOOK{book4,
  author = {Buchautor, Emma-Louise and van Helsing, Sarah and Knuth, Donald E.},
  gender = {pp},
  title = {Same first and second female authors},
  date = {2004}}
@BOOK{book5,
  editor = {Buchautor, Emma-Louise and van Helsing, Sarah and Knuth, Donald E. and Cicero, Marcus Tullius},
  gender = {pp},
  title = {Same leading names of mixed genders},
  date = {2005}}
@BOOK{book6,
  editor = {van Helsing, Abraham},
  title = {Different name},
  date = {2006}}
@BOOK{book7,
  author = {van Helsing, Abraham},
  gender = {sm},
  translator = {van Helsing, Abraham},
  title = {Same male name},
  date = {2007}}
@BOOK{book8,
  editor = {van Helsing, Abraham and Jackson, Tom},
  gender = {pm},
  translator = {Cicero, Marcus Tullius},
  title = {Same first male author},
  date = {2008}}
@BOOK{book9,
  author = {van Helsing, Abraham and Jackson, Tom},
  title = {Same male names},
  date = {2009}}
@BOOK{book10,
  author = {van Helsing, Abraham and Jackson, Tom},
  gender = {pm},
  title = {Same authors of unspecified gender},
  date = {2010}}
@article {JMOR:JMOR10504,
  author = {Markey, Molly J. and Marshall, Charles R.},
  title = {Linking form and function of the fibrous joints in the skull: A new quantification scheme for cranial sutures using the extant fish Polypterus endlicherii},
  journal = {Journal of Morphology},
  volume = {268},
  number = {1},
  doi = {10.1002/jmor.10504},
  pages = {89--102},
  date = {2007-01},
}
@article {markey:pnas,
  author = {Markey, Molly J. and Marshall, Charles R.},
  title = {Terrestrial-style feeding in a very early aquatic tetrapod is supported by evidence from experimental analysis of suture morphology},
  journal = {Proceedings of the National Academy of Sciences},
  volume = {104},
  number = {17},
  doi = {10.1073/pnas.0701706104},
  pages = {7134-7138},
  date = {2007-04},
}
@article {Markey2085,
  author = {Markey, Molly J. and Main, Russell P. and Marshall, Charles R.},
  title = {\emph{In vivo} cranial suture function and suture morphology in the extant fish \emph{Polypterus}: implications for inferring skull function in living and fossil fish},
  volume = {209},
  number = {11},
  pages = {2085--2102},
  year = {2006},
  doi = {10.1242/jeb.02266},
  journal = {Journal of Experimental Biology},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

example output


We can make this a bit more safe if we use

\newcounter{bbx:currnames}
\newcounter{bbx:lastnames}

\newbibmacro*{bbx:printlist}[1]{%
  \setcounter{bbx:currnames}{0}%
  \toggletrue{bbx:goahead}%
  \printnames[dashed:given-family]{#1}%
  \setcounter{bbx:lastnames}{\value{bbx:currnames}}}

a new macro dash:cleanup that can be implemented as

\newbibmacro{dash:cleanup}{\setcounter{bbx:lastnames}{0}}

and is used as

\InitializeBibliographyStyle{\usebibmacro{dash:cleanup}}

\renewbibmacro*{author}{%
  \ifboolexpr{ test {\ifuseauthor}
               and not test {\ifnameundef{author}} }
    {\usebibmacro{bbx:printlist}{author}%
     \setunit{\addcomma\space}%
     \usebibmacro{authorstrg}}
    {\usebibmacro{dash:cleanup}}}

\renewbibmacro*{bbx:editor}[1]{%
  \ifboolexpr{ test {\ifuseeditor}
               and not test {\ifnameundef{editor}} }
    {\usebibmacro{bbx:printlist}{editor}%
     \setunit{\addcomma\space}%
     \usebibmacro{#1}%
     \clearname{editor}}
    {\usebibmacro{dash:cleanup}}}

\renewbibmacro*{bbx:translator}[1]{%
  \ifboolexpr{ test {\ifusetranslator}
               and not test {\ifnameundef{translator}} }
    {\usebibmacro{bbx:printlist}{translator}%
     \setunit{\addcomma\space}%
     \usebibmacro{#1}%
     \clearname{translator}}
    {\usebibmacro{dash:cleanup}}}

You will then have to change the

\ifboolexpr{togl {bbx:goahead} 
            and test {\iffieldequalcs{hash}{bbx@lastname@\the\value{listcount}}}}

in dashed:given-family to the slightly longer

\ifboolexpr{togl {bbx:goahead} 
            and not test {\ifnumgreater{\value{listcount}}{\value{bbx:lastnames}}}
            and test {\iffieldequalcs{hash}{bbx@lastname@\the\value{listcount}}}}

Another clean-up solution is

\makeatletter
\newtoggle{bbx:goahead}
\newcounter{bbx:currnames}
\newcounter{bbx:lastnames}

\renewcommand*{\bibnamedash}{\textemdash\textemdash\textemdash}
\newcommand*{\multidashdelim}{\addspace}
\newcommand*{\finaldashdelim}{\finalnamedelim}

\InitializeBibliographyStyle{\usebibmacro{dash:cleanup}{0}}

\newbibmacro*{bbx:printlist}[1]{%
  \setcounter{bbx:currnames}{0}%
  \toggletrue{bbx:goahead}%
  \printnames[dashed:given-family]{#1}%
  \usebibmacro{dash:cleanup}{\value{bbx:currnames}+1}%
  \setcounter{bbx:lastnames}{\value{bbx:currnames}}}

\newbibmacro*{dash:delim}{%
  \ifnumgreater{\value{listcount}}{\value{liststart}}
    {\ifboolexpr{
       test {\ifnumless{\value{listcount}}{\value{liststop}}}
       or
       test \ifmorenames
     }
       {\multidashdelim}
       {\finaldashdelim}}
    {}}

\DeclareNameFormat{dashed:given-family}{%
   \addtocounter{bbx:currnames}{1}%
   \ifboolexpr{togl {bbx:goahead} and not test \iffirstonpage
               and test {\iffieldequalcs{hash}{bbx@lastname@\the\value{listcount}}}}
     {\usebibmacro{dash:delim}\bibnamedash}
     {\global\togglefalse{bbx:goahead}%
      \ifgiveninits
        {\usebibmacro{name:family-given}
           {\namepartfamily}%
           {\namepartgiveni}%
           {\namepartprefix}%
           {\namepartsuffix}}
        {\usebibmacro{name:family-given}
          {\namepartfamily}%
          {\namepartgiven}%
          {\namepartprefix}%
          {\namepartsuffix}}}%
  \csxdef{bbx@lastname@\the\value{listcount}}{\thefield{hash}}}

\newbibmacro{dash:cleanup}[1]{%
  \ifnumgreater{\value{bbx:lastnames}}{#1}
    {\global\csundef{bbx@lastname@\the\value{bbx:lastnames}}%
     \addtocounter{bbx:lastnames}{-1}%
     \usebibmacro{dash:cleanup}{#1}}
    {}}

\renewbibmacro*{author}{%
  \ifboolexpr{ test {\ifuseauthor}
               and not test {\ifnameundef{author}} }
    {\usebibmacro{bbx:printlist}{author}%
     \setunit{\addcomma\space}%
     \usebibmacro{authorstrg}}
    {\usebibmacro{dash:cleanup}{0}}}

\renewbibmacro*{bbx:editor}[1]{%
  \ifboolexpr{ test {\ifuseeditor}
               and not test {\ifnameundef{editor}} }
    {\usebibmacro{bbx:printlist}{editor}%
     \setunit{\addcomma\space}%
     \usebibmacro{#1}%
     \clearname{editor}}
    {\usebibmacro{dash:cleanup}{0}}}

\renewbibmacro*{bbx:translator}[1]{%
  \ifboolexpr{ test {\ifusetranslator}
               and not test {\ifnameundef{translator}} }
    {\usebibmacro{bbx:printlist}{translator}%
     \setunit{\addcomma\space}%
     \usebibmacro{#1}%
     \clearname{translator}}
    {\usebibmacro{dash:cleanup}{0}}}
\makeatother

In any case you could want to add a and not test \iffirstonpage to the \ifboolexpr in dashed:given-family.

3
  • Unfortunately, because hash is not unique across author lists, this can go wrong if authors from subsequent entries have the same initials (the author from the second entry gets dashed).
    – oulenz
    Jan 21, 2023 at 22:29
  • 1
    @oulenz Hmmm, the hash should be unique, that's its whole point. Do you have an example document that you could share with me that shows the issue. (I do notice you mention initials. Proper hashing only works with Biber. With BibTeX it is approximated with name initials, but obviously that might not be enough. So if this only occurs with BibTeX, switch to Biber.)
    – moewe
    Jan 22, 2023 at 5:14
  • Sorry, I missed that this was biber-specific! You're right, I was using the bibtex backend. I've switched to biber and now it works. (I managed a sort-of workaround by assigning \restorefield{hash}{\namepartgiven} at the top of \DeclareNameFormat{dashed:family-given}, but that only worked because I didn't have successive authors with matching given names. And there doesn't seem to be any reason not to use biber.)
    – oulenz
    Jan 22, 2023 at 8:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .