[Tex/LaTex] biblatex output like REVTeX style

biblatex

I am using biblatex 2.0 and Biber. A multiple-entry citation using \mcite gives as output:

[1] a) Author 1, Phys. Rev. Lett. 11, 1 (2012); b) Author 2,
Phys. Rev. Lett. 22, 2 (2012).

but I would like to have the output like some REVTeX styles, in which consecutive citations on the same journal appears as "ibid."

[1] a) Author 1, Phys. Rev. Lett. 11, 1 (2012); b) Author 2,
ibid. 22, 2 (2012).

Is there a simple way to get this automatically?

Best Answer

Multiple-entry citations via \mcite and friends are implemented using entry sets. Bibliography items for entry sets are generated by the set driver. This driver depends on the style, but in general it contains the code:

\entryset{<precode>}{<postcode>}

For each member of the set, \entryset executes <precode>, the entrytype-specific driver and <postcode>. The entrysetcount field keeps track of the entry currently being processed in the set.

To introduce abbreviations, you can modify the set driver to track the first author list and title. The author and journal bibliography macros can then perform abbreviations where appropriate.

\documentclass{article}
\usepackage[american]{babel}
\usepackage{csquotes}
\usepackage[backend=biber,mcite,subentry,sorting=none]{biblatex}

\providecommand*{\mkibid}[1]{#1}

\makeatletter

% Based on definition in numeric.bbx
\DeclareBibliographyDriver{set}{%
  \entryset
    {\ifbool{bbx:subentry}
       {\printfield[bibentrysetcount]{entrysetcount}%
        \setunit*{\addnbspace}}
       {}}
    {\ifnumequal{\thefield{entrysetcount}}{1}
       {\savefield{namehash}{\bbx@lasthash}%
        \savefield{journaltitle}{\bbx@lastjournal}}
       {}}%
  \global\undef\bbx@lasthash
  \global\undef\bbx@lastjournal
  \newunit\newblock
  \usebibmacro{setpageref}%
  \finentry}

% Based on definition in biblatex.def
\renewbibmacro*{author}{%
  \iffieldequals{namehash}{\bbx@lasthash}
    {\nopunct}
    {\global\undef\bbx@lasthash
     \ifboolexpr{ test \ifuseauthor and not test {\ifnameundef{author}} }
       {\printnames{author}%
        \iffieldundef{authortype}
          {}
          {\setunit{\addcomma\space}%
           \usebibmacro{authorstrg}}}
       {}}
    {}}

% Based on definition in biblatex.def
\renewbibmacro*{journal}{%
  \iffieldundef{journaltitle}
    {}
    {\iffieldequals{journaltitle}{\bbx@lastjournal}
       {\iffieldequals{namehash}{\bbx@lasthash}
          {}
          {\bibstring[\mkibid]{ibidem}}}
       {\global\undef\bbx@lastjournal
        \printtext[journaltitle]{%
          \printfield[titlecase]{journaltitle}%
          \setunit{\subtitlepunct}%
          \printfield{journalsubtitle}}}}}

\makeatother

% Some additional formatting to conform with desired output
\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \pertype{article}
       \step[fieldset=title,null]
       \step[fieldset=pages,null]
       \step[fieldset=series,null]
       \step[fieldset=issue,null]
       \step[fieldset=month,null]
    }
  }
}
\renewcommand*{\newunitpunct}{\addcomma\space}
\DeclareFieldFormat{bibentrysetcount}{\mknumalph{#1}\bibrightparen}
\DeclareFieldFormat{journaltitle}{#1}
\renewbibmacro*{in:}{%
  \ifentrytype{article}{}{\printtext{\bibstring{in}\intitlepunct}}}
\renewbibmacro*{volume+number+eid}{%
  \printfield{volume}%
  \newunit
  \printfield{number}%
  \setunit{\addcomma\space}%
  \printfield{eid}}

\begin{filecontents}{\jobname.bib}
@article{glashow:quark,
  title = {Where is the Top Quark?},
  author = {Glashow, Sheldon},
  journal = {Phys.~Rev.~Lett.},
  volume = {45},
  issue = {24},
  pages = {1914--1916},
  year = {1980},
  month = {Dec}}
@article{weinberg:muon,
  title = {Muon Absorption in Liquid Hydrogen},
  author = {Weinberg, Steven},
  journal = {Phys.~Rev.~Lett.},
  volume = {4},
  pages = {575--578},
  year = {1960}}
@article{wilson,
  title = {Obedience},
  volume = {77},
  number = {1},
  journal = {Publications of the English Goethe Society},
  author = {Wilson, Daniel},
  year = {2008},
  pages = {47--59}}
\end{filecontents}

\addbibresource{\jobname.bib}
\addbibresource{biblatex-examples.bib}
\begin{document}
Define a set with common author \mcite{set1,*glashow,*glashow:quark}.
Define a set with common journal \mcite{set2,*gillies,*wilson}.
Define a set with common author and journal \mcite{set3,*weinberg,*weinberg:muon}.
Define a set with no common author or journal \mcite{set4,*bertram,*reese}.
Define a set with common author \mcite{set5,*knuth:ct,*knuth:ct:a}.
Filler text \cite{knuth:ct:b,glashow,glashow:quark,weinberg,weinberg:muon}.
\printbibliography
\end{document}

enter image description here

Some notes:

  • Abbreviations are applied only for recurrent names and titles from the first member of an entry set. The solution can be adapted to other schemes, but these might be prone to ambiguities.
  • The namehash field uniquely identifies the truncated labelname list. To consider all names in the list, use fullhash instead.