6

Using biblatex for my bibliography. When defining a \defbibentryset and using the \citeauthor command, it only cites the authors of the first key in the set, instead of all. Moreover, it ignores my \AtEveryBibitem directives (i.e., it doesn't suppress fields such as ISSN or DOI). Any ideas on how to address those?

Here is my MWE:

\begin{filecontents*}{\jobname.bib}
@ARTICLE{Iftimie.etal-largetimebehavior2003,
  author = {Iftimie, Drago\c{s} and Lopes Filho, Milton C. and Nussenzveig Lopes,
    Helena J.},
  title = {On the large-time behavior of two-dimensional vortex dynamics},
  journal = {Physica D -- Nonlinear Phenomena},
  year = {2003},
  volume = {179},
  doi = {10.1016/S0167-2789(03)00028-9},
  pages = {153--160}
}

@ARTICLE{Iftimie-LargeTimeBehavior2003,
  author = {Iftimie, Drago\c{s} and Lopes Filho, Milton C. and Nussenzveig Lopes,
    Helena J.},
  title = {Large Time Behavior for Vortex Evolution in the Half-Plane},
  journal = {Communications in Mathematical Physics},
  year = {2003},
  volume = {237},
  pages = {441--469},
  number = {3},
  doi = {10.1007/s00220-003-0843-3},
  issn = {0010-3616}
}

@ARTICLE{Iftimie.Kelliher-RemarksVanishingObstacle2009,
  author = {Iftimie, Drago\c{s} and Kelliher, James~P.},
  title = {Remarks on the Vanishing Obstacle Limit for a 3D Viscous Incompressible
    Fluid},
  journal = {Proceedings of the American Mathematical Society},
  year = {2009},
  volume = {137},
  pages = {685--694},
  number = {2}
}

\end{filecontents*}

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{csquotes}
\usepackage[style=numeric-comp,%
            sorting=nyt,sortcase=false,refsegment=section,%
            citereset=none,subentry,%
            backend=biber]{biblatex}


% Biblatex
\addbibresource{\jobname.bib}
\defbibentryset{Iftimie}{Iftimie-LargeTimeBehavior2003,Iftimie.etal-largetimebehavior2003,Iftimie.Kelliher-RemarksVanishingObstacle2009}

\AtEveryBibitem{\clearfield{url}}
\AtEveryBibitem{\clearfield{doi}}
\AtEveryBibitem{\clearfield{issn}}


\begin{document}

\section{Intro}


\par \citeauthor{Iftimie} wrote some papers \autocite{Iftimie-LargeTimeBehavior2003,Iftimie.etal-largetimebehavior2003}. Then another \autocite{Iftimie.Kelliher-RemarksVanishingObstacle2009}.

\printbibliography[heading=subbibliography,title={References},segment=1]

\end{document}

enter image description here

7

An entry of the @set type has the special field entryset defined and inherits data from the first entry in the set, but otherwise it is treated like any other individual entry. So \AtEveryBibitem and \citeauthor act only on the @set entry, not on the set members. The command \entryset{<precode>}{<postcode>} roughly executes the following for each member of the current set:

<precode>
\usedriver{}{<member entrytype>}
<postcode>

To act on the set members you'll need to access a few internals:

\makeatletter
\def\UseBibitemHook{\csuse{blx@hook@bibitem}}
\def\nodriver{\let\blx@driver\@gobble}
\makeatother

The \entryset command is used in the set bibliography driver defined by numeric.bbx. The \AtEveryBibitem hook can be added to <precode>:

\DeclareBibliographyDriver{set}{%
  \entryset
    {\UseBibitemHook%
     \ifbool{bbx:subentry}
       {\printfield[bibentrysetcount]{entrysetcount}%
        \setunit*{\addnbspace}}
       {}}
    {}%
  \newunit\newblock
  \usebibmacro{setpageref}%
  \finentry}

However you might be better off just loading biblatex with the option settings:

doi=false,isbn=false,url=false

The \citeauthor command from biblatex.def can be redefined to act on the set members, instead of the @set entry itself:

\DeclareCiteCommand{\citeauthor}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\ifentrytype{set}
     {\nodriver%
      \def\namelist{}%
      \setcounter{setcount}{0}%
      \setcounter{settotal}{0}%
      \entryset{\indexnames[count:labelname]{labelname}}{\unspace}%
      \def\namelist{}%
      \entryset{%
        \ifciteindex{\indexnames{labelname}}{}%
        \printnames[set:labelname]{labelname}}{\unspace}}
     {\ifciteindex{\indexnames{labelname}}{}%
      \printnames{labelname}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\newcounter{setcount}
\newcounter{settotal}

\DeclareIndexNameFormat{count:labelname}{%
  \ifinnamelist{#1#3#5#7}{}{%
    \namelistadd{#1#3#5#7}%
    \stepcounter{settotal}}}

\DeclareNameFormat{set:labelname}{%
  \ifinnamelist{#1#3#5#7}{}{%
    \namelistadd{#1#3#5#7}%
    \stepcounter{setcount}%
    \renewbibmacro*{name:delim}[1]{\usebibmacro{set:name:delim}{#1}}%
    \ifcase\value{uniquename}%
      \usebibmacro{name:last}{#1}{#3}{#5}{#7}%
    \or
      \ifuseprefix
        {\usebibmacro{name:first-last}{#1}{#4}{#5}{#8}}
        {\usebibmacro{name:first-last}{#1}{#4}{#6}{#8}}%
    \or
      \usebibmacro{name:first-last}{#1}{#3}{#5}{#7}%
    \fi}}

\newbibmacro*{set:name:delim}[1]{%
  \ifnumgreater{\value{setcount}}{1}
    {\ifnumless{\value{setcount}}{\value{settotal}}
       {\multinamedelim}
       {\finalnamedelim}}
    {}}

\newrobustcmd*{\namelistadd}[1]{\listxadd{\namelist}{\detokenize{#1}}}
\newrobustcmd*{\ifinnamelist}[1]{\xifinlist{\detokenize{#1}}{\namelist}}
  • The \nodriver is a very neat solution. Though, the solution does not combine all the authors in a group in a single list (not sure whether this is what the OP wants). – Guido Mar 24 '13 at 5:45
  • @Guido The approach could be adapted to combine the author lists via multiple calls to \entryset. Consistent name list disambiguation probably won't be possible under any approach with out some modifications to the bib file. – Audrey Mar 24 '13 at 17:14
  • @Audrey: I really like your answer concerning the first question: no need for extra packages, and it will automatically take into account other \AtEveryBibitem directives I may add (I also suppress month fields f.ex. for which there is no package option like there is for doi/url/isbn), but Guido's answer addresses the second one better, IMHO. Should I split my question into two? And let Guido move his answer to the second question? – Christoph B. Mar 25 '13 at 13:35
  • @ChristophB. Up to you. In any case I'll find some time this week to revise this answer to demonstrate the solution described in my earlier comment. – Audrey Mar 25 '13 at 21:06
  • 1
    @ChristophB. There are two extraneous spaces - before and after the \citeauthor. The first is due to a missing %, the second generated by \entryset. I'll fix them in a bit. – Audrey Apr 2 '13 at 13:23
5

To address the issue of removing doi,issn, and url one can load the xpatch packages (i.e., \usepackage{xpatch}) and then use

\xpatchbibdriver{set}
  {\printfield}
  {\clearfield{doi}\clearfield{issn}\clearfield{url}\printfield}
  {}
  {}

Here is a solution to cite all authors in an entryset. The field labelname is created when parsing the bib files to create the bbl file. In bbl contains the information only about the authors of the first entry in a set. However, the bbl files contains \set{key1,key2,...} where each keyN is the key for an entry in the entryset.

The idea is then to use the keyN and to use them to create a list of all (author) names in the entryset.

We start by creating such a list, and at the same time we create two counters to hold the total number of authors and the counter for the current author.

\newcommand{\AuthorList}{}
\newcounter{AuthorSetCount}
\newcounter{CurrentAuthorSet}

These the counters are use to parse the elements of the author list and to insert the proper delimiter between authors. They are used as follows:

\newcommand{\mycount}[1]{\addtocounter{AuthorSetCount}{1}}
\newcommand{\myitem}[1]{#1
  \addtocounter{CurrentAuthorSet}{1}
  \ifnumequal{\value{CurrentAuthorSet}}{\value{AuthorSetCount}}
    {\addspace}
    {\ifnumequal{\value{CurrentAuthorSet}}{\value{AuthorSetCount}-1}
      {\addcomma\finalnamedelim}
      {\addcomma\addspace}%
    }%
}

     To populate the list, we parse a name list. This is done by providing a formatting directive 

\DeclareNameFormat{myentryset}{%
  \ifinlist{#1}{\AuthorList}
    {}
    {\listgadd{\AuthorList}{#1}}%
}

The information in \set{...} is used by the biblatex command \entryset{}{} where the two arguments are for pre-code and postcode. Unfortunately, for each entry in the set \entryset processes the driver for the entry. Thus we have to disable this and instead we populesate the list of author in the entryset. We introduce a conditional in the definitions of the commands used by \entryset to guard the operation when called in a citation or called in the bibliography. In a citation we execute the formatting instruction to populate the author list, otherwise the driver for the current entry is used.

\makeatletter
\def\blx@entryset#1{%
  \blx@ifdata{#1}
    {\begingroup
     \blx@imc@clearlist{pageref}%
     \blx@getdata{#1}%
     \blx@setoptions@type\abx@field@entrytype
     \def\abx@field@entrysetcount{1}%
     \blx@entryset@precode
     \ifcitation{\printnames[myentryset]{author}}%  Modified lines
       {\blx@driver{\blx@imc@thefield{entrytype}}}% Modified lines
     \blx@entryset@postcode%
     \endgroup}
    {}%
  \let\do\blx@entryset@i}

\def\blx@entryset@i#1{%
  \blx@imc@entrydata{#1}{%
    \blx@entryset@precode
    \ifcitation{\printnames[myentryset]{author}}%   Modified lines
       {\blx@driver{\blx@imc@thefield{entrytype}}}% Modified lines
    \blx@entryset@postcode}}
\makeatother

The final step is to create a specialised cite command 

\DeclareCiteCommand{\CiteAllAuthorsInSet}{}{%
  \ifentrytype{set}
    {\entryset{}{}
    \setcounter{AuthorSetCount}{0}
    \forlistloop{\mycount}{\AuthorList}%
    \forlistloop{\myitem}{\AuthorList}%
    \setcounter{CurrentAuthorSet}{0}
    \renewcommand{\AuthorList}{}}
    {\printfield{labelname}}%
}{}{}

Use

\begin{document}

\par \CiteAllAuthorsInSet{Iftimie} wrote some papers \dots

\par \citeauthor{Iftimie} wrote some papers \autocite{Iftimie-LargeTimeBehavior2003,Iftimie.etal-largetimebehavior2003}. Then another \autocite{Iftimie.Kelliher-RemarksVanishingObstacle2009}.

\printbibliography[heading=subbibliography,title={References},segment=1]

\end{document}

to see the difference between \citeauthor and \CiteAllAuthorsInSet.

enter image description here

Here is the full code

\xpatchbibdriver{set}{\printfield}{\clearfield{doi}\clearfield{issn}\clearfield{url}\printfield}{}{}

\makeatletter
\def\blx@entryset#1{%
  \blx@ifdata{#1}
    {\begingroup
     \blx@imc@clearlist{pageref}%
     \blx@getdata{#1}%
     \blx@setoptions@type\abx@field@entrytype
     \def\abx@field@entrysetcount{1}%
     \blx@entryset@precode
     \ifcitation{\printnames[myentryset]{author}}
       {\blx@driver{\blx@imc@thefield{entrytype}}}%
     \blx@entryset@postcode%
     \endgroup}
    {}%
  \let\do\blx@entryset@i}

\def\blx@entryset@i#1{%
  \blx@imc@entrydata{#1}{%
    \blx@entryset@precode
    \ifcitation{\printnames[myentryset]{author}}
       {\blx@driver{\blx@imc@thefield{entrytype}}}%
    \blx@entryset@postcode}}
\makeatother

\newcommand{\AuthorList}{}

\DeclareNameFormat{myentryset}{%
  \ifinlist{#1}{\AuthorList}
    {}
    {\listgadd{\AuthorList}{#1}}%
}

\newcounter{AuthorSetCount}
\newcounter{CurrentAuthorSet}
\newcommand{\mycount}[1]{\addtocounter{AuthorSetCount}{1}}
\newcommand{\myitem}[1]{#1
  \addtocounter{CurrentAuthorSet}{1}
  \ifnumequal{\value{CurrentAuthorSet}}{\value{AuthorSetCount}}
    {\addspace}
    {\ifnumequal{\value{CurrentAuthorSet}}{\value{AuthorSetCount}-1}
      {\addcomma\finalnamedelim}
      {\addcomma\addspace}%
    }%
}

\DeclareCiteCommand{\CiteAllAuthorsInSet}{}{%
  \ifentrytype{set}
    {\entryset{}{}
      \setcounter{AuthorSetCount}{0}
      \forlistloop{\mycount}{\AuthorList}%
      \forlistloop{\myitem}{\AuthorList}%
      \setcounter{CurrentAuthorSet}{0}%
      \renewcommand{\AuthorList}{}%
    }
    {\printnames{labelname}}%
}{}{}
  • Great stuff, thanks Guido. See my question to Audrey regarding how I should handle this question. – Christoph B. Mar 26 '13 at 15:24

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.