6

I'm listing all my publications using biblatex (for my resume), using a separate bib file (lastname.bib). I'm using biblatex with biber backend.

I would add a section to list all my co-authors. Is there any way of doing this automatically?

9

Using the latest biblatex 3.3 and biber 2.4 development versions from Sourceforge. New mapping functionality allows loops and creating new entries and so it is possible to split up name fields into dedicated entrytypes for correct printing:

\documentclass{article}
\usepackage{filecontents}
% Declare the coauthor name field
\begin{filecontents}{\jobname.dbx}
\DeclareDatamodelFields[type=list, datatype=name, label=true]{coauthor}
\DeclareDatamodelEntrytypes{coauthor}
\DeclareDatamodelEntryfields[coauthor]{coauthor}
\end{filecontents}
\begin{filecontents}{\jobname.bib}
@ARTICLE{test1,
 AUTHOR = {Arthur Smith and James Jones and Bill Smiley and Jake Wrath},
 JOURNALTITLE = {A Journal},
 YEAR   = {2010}
}

@ARTICLE{test2,
 AUTHOR = {Philippa Smyth and Arthur Smith and Bill Likely},
 JOURNALTITLE = {Another Journal},
 YEAR   = {2011}
}

@ARTICLE{test3,
 AUTHOR = {Arthur Smith},
 JOURNALTITLE = {The Best Journal},
 YEAR   = {2013}
}

@ARTICLE{test4,
 AUTHOR = {Philippa Smyth and Arthur Smith and James Jones},
 JOURNALTITLE = {Again Another Journal},
 YEAR   = {2014}
}
\end{filecontents}
\usepackage[style=authoryear,datamodel=\jobname]{biblatex}
\addbibresource{\jobname.bib}

% 1. First, check if the author list contain me, here, "Arthur Smith"
% 2. Copy the author field to a temporary field "coauthortext". We don't need
%    datamodel declarations for this as this will be deleted after use and
%    will never get anywhere near code that queries the data model.
% 3. Remove me (Arthur Smith) from this temporary copy of the author list
% 4. Turn the resulting field into a comma-separated list
% 5. Loop over this comma-separated list, creating new entries of type
%    "coauthor" each with a "coauthor" name list field containing the data
%    from the loop variable
% 6. Remove the temporary author field copy "coauthortext"
%
% The special $MAPLOOP variable holds each value of the csv field name by
% the "foreach" option on the \map macro.
% The special $MAPUNIQ variable is a random string generated automatically
% at the beginning of each \map section. This can be when you need a unique
% string as here because entrykeys should be new unique.
\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map[overwrite]{
       \step[fieldsource=author,
             match=\regexp{Arthur\s+Smith}, final]
       \step[fieldsource=author,
             notmatch=\regexp{^Arthur\s+Smith$}, final]
       \step[fieldsource=author, fieldset=coauthortext, origfieldval]
       \step[fieldsource=coauthortext,
             match=\regexp{Arthur\s+Smith\s+and\s+},
             replace={}]
       \step[fieldsource=coauthortext,
             match=\regexp{\s+and\s+Arthur\s+Smith},
             replace={}]
       \step[fieldsource=coauthortext,
             match=\regexp{\s+and\s+},
             replace={,}]
    }
    \map[overwrite, foreach=coauthortext]{
      \step[fieldsource=coauthortext, match=\regexp{.}, final]
      \step[entrynew=\regexp{$MAPUNIQ}, entrynewtype=coauthor]
      \step[entrytarget=\regexp{$MAPUNIQVAL}, fieldset=coauthor, fieldvalue=\regexp{$MAPLOOP}]
      \step[entrytarget=\regexp{$MAPUNIQVAL}, fieldset=options, fieldvalue=skipbib]
    }
    \map[overwrite]{
       \step[fieldsource=coauthortext, null]
    }
  }
}

% Sort the biblist by coauthor name
\DeclareSortingScheme{coauthor}{
  \sort{
        \field{coauthor}
  }
}

% Driver to print the biblist items
\DeclareBibliographyDriver{coauthor}{%
  \printnames{coauthor}}

% bibcheck to strip duplicates
\defbibcheck{coauthor}{%
  \ifcsdef{\strname{coauthor}}
    {\skipentry}
    {\savenamecs{coauthor}{\strname{coauthor}}}}

% Simple bibenvironment to print the biblist
\defbibenvironment{coauthor}
{\list{}
  {\setlength{\leftmargin}{\bibhang}%
   \setlength{\itemindent}{-\leftmargin}%
   \setlength{\itemsep}{\bibitemsep}%
   \setlength{\parsep}{\bibparsep}}}
{\endlist}
{\item}

\begin{document}
\nocite{*}
\printbibliography
% This will automatically use the "coauthor" sorting scheme/biblist/driver etc.
\printbiblist[title=CoAuthors]{coauthor}
\end{document}

enter image description here

  • Thanks! This is indeed a start (I had to update my latex package to get the example running, but now it works). I would like to get a single list of all co-authors alphabetically. I'm going to scan the docs if I can find something. – tmensink Jan 21 '16 at 19:51
  • Hmm, I doubt that this is possible with the current functionality. I'll have to think about it. – PLK Jan 21 '16 at 22:24
  • See edits - this is now easier due to new mapping functionality. – PLK Jan 24 '16 at 21:11
  • Thanks again! I'll have a look tomorrow. I was trying my self now a solution with author indexing (and then removing the index). Seems to be a reasonable alternative, I'll post tomorrow. – tmensink Jan 27 '16 at 6:10
  • Your example is nicer than my answer below (since that one depends on making an index), but with your example, I run into problems when adding a single author paper, or the same co-author on different paper, see test3 and test4 reference in my example. – tmensink Jan 28 '16 at 0:49
2

I think I found an answer, using an author index. I've tried to include a MWE below, but I might have added a few lines which are unnecessary.

\documentclass{article}
\usepackage[indexing=true,maxnames=99,style=authoryear,datamodel=\jobname]{biblatex}
\usepackage{filecontents}
\usepackage{imakeidx}

\makeindex[program=makeindex,options=-s mystyle.ist,title=List of Co-Authors]
\usepackage{letltxmacro}

% Declare the coauthor name field
\begin{filecontents}{\jobname.dbx}
\DeclareDatamodelFields[type=list, datatype=name]{coauthor}
\DeclareDatamodelEntryfields{coauthor}
\end{filecontents}

% Required to remove the page number after the author in the index
\makeatletter
\let\mygobble\@gobble
\LetLtxMacro\OldIndex\index
\renewcommand{\index}[1]{\OldIndex{#1|mygobble}} 
\makeatother

\begin{filecontents*}{mystyle.ist}
quote '+'
delim_0 " "
delim_1 " "
delim_2 " "
delim_n " "
\end{filecontents*}

% I use a slightly more general bib, with a single author publication, and co-authors over several papers.
\begin{filecontents}{\jobname.bib}
@ARTICLE{test1,
 AUTHOR = {Arthur Smith and James Jones and Bill Smiley and Jake Wrath},
 JOURNALTITLE = {A Journal},
 YEAR   = {2010}
}

@ARTICLE{test2,
 AUTHOR = {Philippa Smyth and Arthur Smith and Bill Likely},
 JOURNALTITLE = {Another Journal},
 YEAR   = {2011}
}

@ARTICLE{test3,
 AUTHOR = {Arthur Smith},
 JOURNALTITLE = {The Best Journal},
 YEAR   = {2013}
}

@ARTICLE{test4,
 AUTHOR = {Philippa Smyth and Arthur Smith and James Jones},
 JOURNALTITLE = {Again Another Journal},
 YEAR   = {2014}
}
\end{filecontents}

\addbibresource{\jobname.bib}

% Create a "coauthor" name list which is a copy of the "author" name
% list, minus oneself (assuming you are "Arthur Smith" and this is how
% your name always appears in the .bib - you can always make more
% sophisticated regexps if there is name variation)
\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map[overwrite]{
       \step[fieldsource=author,
             match=\regexp{Arthur\s+Smith}, final]
       \step[fieldsource=author, fieldset=coauthor, origfieldval]
       \step[fieldsource=coauthor,
             match=\regexp{Arthur\s+Smith\s+and\s+},
             replace={}]
       \step[fieldsource=coauthor,
             match=\regexp{\s+and\s+Arthur\s+Smith},
             replace={}]
       \step[fieldsource=coauthor,
             match=\regexp{Arthur\s+Smith},
             replace={}]             
    }
  }
}

% Sort the biblist by coauthor name
\DeclareSortingScheme{coauthor}{\sort{\field{coauthor}}}

\DeclareIndexNameFormat{default}{\usebibmacro{index:name}{\index}{#1}{#3}{#5}{#7}}

\renewbibmacro*{bibindex}{\ifbibindex{\indexnames{coauthor}}{}}


% Driver to print the biblist items
\DeclareBibliographyDriver{coauthor}{\printnames{coauthor}}

% Simple bibenvironment to print the biblist
\defbibenvironment{coauthor}{\list{}{}}{\endlist}{\item}

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

Example output

  • Thanks for sharing your answer. Since you're using Biblatex, you could make everything a bit easier by using string to store, at least, the name of the author (Arthur Smith in your example), cf. this documentation. – Clément Jan 28 '16 at 3:07

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.