4

I use biblatex to compile an author index.

Some authors publish under several different names, so there are bibfile entries with different author/editor names that I would like to consolidate for the author index. (Basically, "Doe, John Jack" and "Doe, John" should be merged to "Doe, John Jack".)

There's an indextitle field for an alternative title to be used for the index. Any ideas how I could get a similar thing to work for author/editor names? Thanks, guys!

Edit: Needs to use backend=bibtex. (Sorry for not making this clearer before.)

Super-minimal example (for now):

\documentclass{scrartcl}

\usepackage{filecontents}
\begin{filecontents*}{bb.bib}
@article{doe1979,
    Author = {Doe, John},
    Indexauthor = {Doe, John Jack},
    Journal = {Journal of Everything},
    Pages = {163--176},
    Title = {Great Stuff},
    Volume = {7},
    Year = {1979}}

@article{doe1981,
    Author = {Doe, John Jack},
    Indexauthor = {Doe, John Jack},
    Journal = {Journal of Nothing},
    Pages = {164--178},
    Title = {More Great Stuff},
    Volume = {4},
    Year = {1981}}
\end{filecontents*}

\usepackage{fontspec}
\setmainfont[Mapping=tex-text]{Arial Unicode MS}

\usepackage[style=authoryear,indexing=cite,backend=bibtex]{biblatex}
\addbibresource{bb.bib}

\usepackage{makeidx}
\makeindex

\begin{document}


\cite{doe1979,doe1981}

\printbibliography

\printindex

\end{document}
  • Please also add maxnames=999 to biblatex. Otherwise, you will miss plenty of authors (in case there are more than 3 per article - the default of maxnames is 3). – koppor Jan 9 '17 at 22:09
2

The following solution uses the Biber back-end because we need to create a new field (indexname).

Analogue to shortname and sortname our new field is called indexname.

First we need to make the new field known to Biber and biblatex. Create a .dbx file with the following contents

\DeclareDatamodelFields[type=list, datatype=name]{indexname}
\DeclareDatamodelEntrytypes{indexname}
\DeclareDatamodelEntryfields{indexname}

and put it somewhere LaTeX can find it (in the MWE below this is done via filecontents). If you now load biblatex, load it with the datamodel option and give the file name of the .dbx (without extension), in the MWE that would be

\usepackage[style=authoryear,indexing=cite,backend=biber,datamodel=\jobname]{biblatex}

(note that we use Biber and not BibTeX as can be seen by backend=biber).

We then just make the indexing macros use indexname

\renewbibmacro*{citeindex}{%
  \ifciteindex
    {\ifnameundef{indexname}
       {\indexnames{labelname}}
       {\indexnames{indexname}}%
     \indexfield{indextitle}}
    {}}

\renewbibmacro*{bibindex}{%
  \ifbibindex
    {\ifnameundef{indexname}
       {\indexnames{labelname}}
       {\indexnames{indexname}}%
     \indexfield{indextitle}}
    {}}

and are good to go. The index falls back to the standard labelnames if no indexname is supplied.

As PLK suggests, it might be a nice idea to let Biber fill indexname itself

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \step[fieldsource=author, match=\regexp{Doe,\s+John(\s+Jack)?|John(\s+Jack)?\+*Doe}, final]
      \step[fieldset=indexname, fieldvalue={Doe, John Jack}]
    }
  }
}

MWE

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@article{doe1979,
    Author = {Doe, John},
    indexname = {Doe, John Jack},
    Journal = {Journal of Everything},
    Pages = {163--176},
    Title = {Great Stuff},
    Volume = {7},
    Year = {1979}}

@article{doe1981,
    Author = {Doe, John Jack},
    indexname = {Doe, John Jack},
    Journal = {Journal of Nothing},
    Pages = {164--178},
    Title = {More Great Stuff},
    Volume = {4},
    Year = {1981}}
\end{filecontents*}

\begin{filecontents}{\jobname.dbx}
\DeclareDatamodelFields[type=list, datatype=name]{indexname}
\DeclareDatamodelEntrytypes{indexname}
\DeclareDatamodelEntryfields{indexname}
\end{filecontents}

\usepackage[style=authoryear,indexing=cite,backend=biber,datamodel=\jobname]{biblatex}
\addbibresource{\jobname.bib}
\addbibresource{biblatex-examples.bib}

\usepackage{makeidx}
\makeindex

\renewbibmacro*{citeindex}{%
  \ifciteindex
    {\ifnameundef{indexname}
       {\indexnames{labelname}}
       {\indexnames{indexname}}%
     \indexfield{indextitle}}
    {}}

\renewbibmacro*{bibindex}{%
  \ifbibindex
    {\ifnameundef{indexname}
       {\indexnames{labelname}}
       {\indexnames{indexname}}%
     \indexfield{indextitle}}
    {}}

\begin{document}
\cite{doe1979,doe1981,sigfridsson}

\printbibliography
\printindex
\end{document}

index section of the MWE


If you use BibTeX you cannot use the fancy datamodel features. It is then probably easiest to use the custom namea field instead of indexname, there is no need for a datamodel (.dbx) file. But then you cannot use the sourcemapping features from above.

MWE for BibTeX

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@article{doe1979,
    Author = {Doe, John},
    namea = {Doe, John Jack},
    Journal = {Journal of Everything},
    Pages = {163--176},
    Title = {Great Stuff},
    Volume = {7},
    Year = {1979}}

@article{doe1981,
    Author = {Doe, John Jack},
    namea = {Doe, John Jack},
    Journal = {Journal of Nothing},
    Pages = {164--178},
    Title = {More Great Stuff},
    Volume = {4},
    Year = {1981}}
\end{filecontents*}


\usepackage[style=authoryear,indexing=cite,backend=bibtex]{biblatex}
\addbibresource{\jobname.bib}
\addbibresource{biblatex-examples.bib}

\usepackage{makeidx}
\makeindex

\renewbibmacro*{citeindex}{%
  \ifciteindex
    {\ifnameundef{namea}
       {\indexnames{labelname}}
       {\indexnames{namea}}%
     \indexfield{indextitle}}
    {}}

\renewbibmacro*{bibindex}{%
  \ifbibindex
    {\ifnameundef{namea}
       {\indexnames{labelname}}
       {\indexnames{namea}}%
     \indexfield{indextitle}}
    {}}

\begin{document}
\cite{doe1979,doe1981,sigfridsson}

\printbibliography
\printindex
\end{document}
  • 2
    In addition to this, you can also use a sourcemap (\DeclareSourcemap) to simply copy the author field into indexname and then use a regular expression map to normalise the name variants. That way you don't even need to put indexname in your .bib, it will be automatically created and normalised by biber as it reads the .bib. – PLK Jan 26 '16 at 17:36
  • @PLK Very good point, thanks. I will amend the answer later, have to go now. – moewe Jan 26 '16 at 17:39
  • Wow, thanks so much. This is great! But ... I cannot use biber for my current project (external constraints). Is there any way to do this with backend=bibtex? (Your answer is still very useful and instructive to me as I'm sure I'll be wanting to do this with biber one day too. Just at the moment I'm forced to use BibTeX.) – kelpie Jan 28 '16 at 12:48
  • 1
    @kelpie You could use the field namea instead of indexname and drop the datamodel file (.dbx), then this should be doable with BibTeX only. – moewe Jan 28 '16 at 17:06
  • @moewe This is wonderful. Thanks so much. (I have accepted your answer. I hope this is everything I need to do to close this question.) – kelpie Feb 7 '16 at 14:08

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.