# Automatically indexing references by author and year

I'm writing a literature review, and would like to add indices for both authors and publication year (i.e., two separate indices). Now, I could manually enter the appropriate \index{} commands, but it seems like this is something that could be automatically handled by biblatex. It would certainly make maintenance a lot easier, an important consideration since I intend to keep the review up-to-date over the next couple of years as I progress through my research.

I have been playing with the indexing option that is built into biblatex but cannot see how to make it work with multiple indices (or even index by year alone for that matter). Similarly, I have been looking at questions such as this one on writing custom \cite commands, but am struggling to see how they work as well.

A manually indexed minimal working example (using biblatex and multind) which shows the sort of final result I'm after:

\documentclass{report}

\usepackage{filecontents}
\begin{filecontents*}{testing.bib}
@article{Author2010,
author="Author, A and Writer, B",
journal="Slackers Monthly",
title="An overly long treatise on procrastination",
year=2010,
month=jun,
}
@article{Writer2011,
author="Writer, B and Scribe, C",
journal="Fake Online Journal",
title="Waste of time or time of waste: procrastination in a modern society",
year=2011,
month=oct,
}
@book{Writer2003,
author="Writer, B",
title="Procrastination for dummies",
year=2003,
publisher="Procrastination House",
}
\end{filecontents*}

\usepackage[style=authoryear]{biblatex}

\usepackage{multind}
\makeindex{authors}
\makeindex{years}

\begin{document}

\chapter{Introductory works}

\section{An overly long treatise on procrastination}

\fullcite{Author2010}
\index{authors}{Author, A!An overly long treatise on procrastination (2010)}
\index{authors}{Writer, B!An overly long treatise on procrastination (2010)}
\index{years}{2010!An overly long treatise on procrastination}

This paper was really useful in telling me how to waste more time rather
than doing real work.

\section{Waste of time or time of waste: procrastination in a modern society}

\fullcite{Writer2011}
\index{authors}{Writer, B!Waste of time or time of waste: procrastination in a modern society (2011)}
\index{authors}{Scribe, C!Waste of time or time of waste: procrastination in a modern society (2011)}
\index{years}{2011!Waste of time or time of waste: procrastination in a modern society}

Applies post-modern philosophical theory to procrastination.

\section{Procrastination for dummies}

\fullcite{Writer2003}
\index{authors}{Writer, B!Procrastination for dummies (2003)}
\index{years}{2003!Procrastination for dummies}

A classic reference book for anybody starting a research position.

\printbibliography
\printindex{authors}{Author index}
\printindex{years}{Year index}

\end{document}


And a Makefile to compile it:

default:
xelatex mwe
bibtex mwe
xelatex mwe
xindy -M texindy -M page-ranges -L english -C utf8 authors.idx
xindy -M texindy -M page-ranges -L english -C utf8 years.idx
xelatex mwe


So is this possible to achieve with a custom cite command (or a built-in one for that matter)? Or would I be better off writing a script to parse the BibTeX/biber output to generate the input to xindy?

This answer has been updated in the light, particularly, of Audrey's perceptive comments.

Yes. There are a number of ways to do this.

The code below is a revision of my original suggestion, which (I hope) corrects various deficiencies in its general use. Specifically:

• My original code didn't deal gracefully with empty years: this does.

• My original code "hardwired" multind's syntax and your chosen index names: in this version the index names are in macros which means they can be changed.

• My original code didn't make use of the indexsorttitle and indextitle fields: this does, as it should.

• My original code could cause problems with certain macros (e.g. \TeX used in indextitles, as Audrey properly pointed out. This handles those properly, I hope.

On the example you gave, none of this changes anything -- but I've added two further example entries which the original version would have handled wrongly or stupidly, and this handles directly.

Oddly, \fullcite doesn't seem to call the indexing macros, which is why I've used \cite; I daresay there's an explanation for that, but I don't have time to dig into it.

\documentclass{report}

\usepackage{filecontents}
\begin{filecontents*}{testing.bib}
@article{Author2010,
author="Author, A and Writer, B",
journal="Slackers Monthly",
title="An overly long treatise on procrastination",
year=2010,
month=jun,
}
@article{Writer2011,
author="Writer, B and Scribe, C",
journal="Fake Online Journal",
title="Waste of time or time of waste: procrastination in a modern society",
year=2011,
month=oct,
}
@book{Writer2003,
author="Writer, B",
title="Procrastination for dummies",
year=2003,
publisher="Procrastination House",
}
@book{knuth:ct:b,
hyphenation = {american},
sortyear = {1986-1},
sorttitle = {Computers & Typesetting B},
indexsorttitle = {TeX: The Program},
author = {Knuth, Donald E.},
title = {\TeX: The Program},
shorttitle = {\TeX},
maintitle = {Computers \& Typesetting},
volume = {B},
date = {1986},
annotation = {The second volume of a five-volume book. Note the
\texttt{sorttitle} and \texttt{sortyear} fields. Also note the
\texttt{indexsorttitle} field}
}
@book{yearless,
author = {Lazy B. Ugger},
title  = {I Can't Be Bothered with Years},
publisher = {Equally Lazee},
}
\end{filecontents*}

\usepackage[style=authoryear,indexing=cite]{biblatex}
\makeatletter
% For the "years" index, we redefine the ordinary bibmacro
% which indexes titles, so that it indexes into the years
\renewbibmacro*{index:title}[2]{%
\iffieldundef{year}
{\usebibmacro{index:years}%
{\index}%
{\undated}%
{\thefield{indexsorttitle}}%
{\thefield{entrykey}}}
{\usebibmacro{index:years}%
{\index}%
{\thefield{year}}%
{\thefield{indexsorttitle}}%
{\thefield{entrykey}}}}

\newbibmacro*{index:years}[4]{%
\begingroup
\protected@edef\theindexentry{%
\unexpanded{#1}\yearsindex{#2!#3\actualoperator\unexpanded{\citefield}{#4}{indextitle}}}%
\theindexentry
\endgroup}

% For authors we just redefine the field format (so that it
% includes title and year information
\DeclareIndexNameFormat{default}{%
\iffieldundef{year}
{\usebibmacro{index:name}%
{\index}%
{#1}%
{#3}%
{#5}%
{#7}%
{\thefield{indexsorttitle}}%
{\thefield{entrykey}}%
{}}
{\usebibmacro{index:name}%
{\index}%
{#1}%
{#3}%
{#5}%
{#7}%
{\thefield{indexsorttitle}}%
{\thefield{entrykey}}%
{ (\thefield{year})}}}
% ... and modify the relevant bibmacro to add the extra information
\renewbibmacro*{index:name}[8]{%
\begingroup
\ifuseprefix
{\protected@edef\theindexentry{%
\unexpanded{#1}\authorsindex{%
\ifblank{#4}{}{#4 }%
\@firstofone #2% remove spurious braces
\ifblank{#5}{}{ #5}%
\ifblank{#3}{}{, #3}%
\actualoperator
\ifblank{#4}{}{\MakeCapital{#4} }%
#2%
\ifblank{#5}{}{ #5}%
\ifblank{#3}{}{, #3}!#6
\actualoperator\unexpanded{\citefield}{indextitle}#8}}}%
{\protected@edef\theindexentry{%
\unexpanded{#1}\authorsindex{%
\@firstofone #2% remove spurious braces
\ifblank{#5}{}{ #5}%
\ifblank{#3#4}{}{,}%
\ifblank{#3}{}{ #3}%
\ifblank{#4}{}{ #4}!#6\actualoperator
\unexpanded{\citefield}{#7}{indextitle}#8}}}%
\theindexentry
\endgroup}
\makeatother
% redefine this if the index for years is differently named, or if using
% index or imakeidx
\newcommand{\yearsindex}{{years}}

% redefine this if the index for authors is differently named, or if
% using index or imakeidx
\newcommand{\authorsindex}{{authors}}

% undated entries
\newcommand{\undated}{n.d.}

\usepackage{multind}
\makeindex{authors}
\makeindex{years}

\begin{document}

\chapter{Introductory works}

\section{An overly long treatise on procrastination}

\fullcite{Author2010}

This paper was really useful in telling me how to waste more time rather
than doing real work.

\section{Waste of time or time of waste: procrastination in a modern society}

\cite{Writer2011}

Applies post-modern philosophical theory to procrastination.

\section{Procrastination for dummies}

\cite{Writer2003}

A classic reference book for anybody starting a research position.

\cite{knuth:ct:b}

An author who uses a title that indexing programs find hard to cope
with, but certainly no procrastinator.

\cite{yearless}

An author so lazy that he cannot be bothered to put a year of publication.

\printbibliography
\printindex{authors}{Author index}
\printindex{years}{Year index}

\end{document}


(If you need to, you can coax biblatex to do very complex indexing: I've just completed the first version of a style which can produce many, many, indexes (more than 33!), and which indexes based not just on title fields, but uses postnotes to set sub-items. It's not thrilling to set up, but it's absolutely do-able as biblatex stands.)

• Awesome, that works beautifully thanks. After a bit of exploration I think I see how all that fits together. If at some point I manage to confuse myself I'll come back and ask another question. – Blair Aug 23 '12 at 5:27
• This will get tripped up on titles containing some control sequences - The \TeX book is one example. You can fix this by preventing titles from being fully expanded. Further details can be found at the github issue Maieul submitted. Please feel free to join the discussion. – Audrey Aug 23 '12 at 17:11
• Yes. It could get tripped up in various ways -- including many I haven't thought of I'm sure. It would certainly (as a first step) be better to replace \thefield{title} with \thefield{indextitle}. – Paul Stanley Aug 23 '12 at 17:25
• @PaulStanley Users can reasonably put control sequences in indextitle, just not indexsorttitle. But, yes, you should use these fields instead of title to correctly sort titles that contain control sequences, start with "The" or "A", etc. – Audrey Aug 23 '12 at 17:38
• Doh! Yes, of course. I'll have a look at this later when I'm thinking straight and put that right. The basic principle is sound, but as you point out the devil is in the details. – Paul Stanley Aug 23 '12 at 18:01

Thanks to a feature request from Maieul and feedback from Paul, a number of auxiliary commands and macros were introduced in biblatex 2.3 to aid indexing, particularly indexing with the subentry operator !. Example 22 from the documentation (22-indexing-subentry.tex) demonstrates multiple indices with subentries using the imakeidx package. Here is a similar example using multind.

\documentclass{article}
\usepackage[american]{babel}
\usepackage{csquotes}
\usepackage[indexing=cite,style=authoryear,backend=bibtex]{biblatex}

% Define indices
\usepackage{multind}
\makeindex{authors}
\makeindex{years}

% Name indexing directive for names with title subentries
\DeclareIndexNameFormat{name:title}{%
\iffieldundef{title}
{\usebibmacro{index:name}{\index{authors}}{#1}{#3}{#5}{#7}}
{\usebibmacro{index:name:title:year}{\index{authors}}{#1}{#3}{#5}{#7}}}

% Based on index:name:title macro defined in biblatex.def, takes the arguments:
%   {<index command>}{<last name>}{<first name>}{<first initials>}{<last name prefix>}
% The index:name:subentry macro (also defined in biblatex.def) takes two more:
%   {<plain entry>}{<formatted entry>}
% and forms the subentry: !<plain entry>@<formatted entry>
\newbibmacro*{index:name:title:year}[5]{%
\iffieldundef{year}
{\usebibmacro{index:name:title}{#1}{#2}{#3}{#4}{#5}}
{\usebibmacro{index:name:subentry}{#1}{#2}{#3}{#4}{#5}
{\thefield{indexsorttitle}}
{\emph{\csfield{indextitle}}~(\thefield{labelyear})}}}

% Title indexing directive for years with title subentries
\DeclareIndexFieldFormat{year:title}{%
\iffieldundef{year}
{\usebibmacro{index:entry}{\index{years}}{%
\mkbibindexentry{0}{Not dated}%
\subentryoperator%
\mkbibindexfield{\thefield{indexsorttitle}}{\emph{#1}}}}
{\usebibmacro{index:entry}{\index{years}}{%
\thefield{year}\subentryoperator%
\mkbibindexfield{\thefield{indexsorttitle}}{\emph{#1}}}}}

\renewbibmacro*{citeindex}{%
\ifciteindex
{\indexnames[name:title]{author}%
\indexfield[year:title]{indextitle}}
{}}

% Index entries accessed via \fullcite
\DeclareCiteCommand{\fullcite}
{\usebibmacro{prenote}}
{\usebibmacro{citeindex}%
\usedriver
{\DeclareNameAlias{sortname}{default}}
{\thefield{entrytype}}}
{\multicitedelim}
{\usebibmacro{postnote}}

\begin{document}
\fullcite{knuth:ct,knuth:ct:a,knuth:ct:c,knuth:ct:d}
\cite{aristotle:anima,aristotle:poetics,aristotle:physics,aristotle:rhetoric}
\printbibliography
\raggedright
\printindex{authors}{Author and Title Index}
\printindex{years}{Year and Title Index}
\end{document}


I use a script python for a similar problem http://geekographie.maieul.net/Un-index-des-sources-primaires-3.

I just open a ticket to ask the possibilty to index more than one field. https://github.com/plk/biblatex/issues/31

• I think you'll find this is already possible. You need to look at the citeindex and bibindex macros (in biblatex.def); there's no reason in principle they could not be adapted to index any field you want. The technique for doing so is apparent from the existing indexing facilities (or the code above). – Paul Stanley Aug 22 '12 at 17:42
• no, I try. Citeindex can't index only one field (as the author said in the ticket) – Maïeul Aug 22 '12 at 17:59
• It certainly means some rewriting: but it can be done. Indeed, if you look at the code in my answer above, you'll see that it is being done there: we are producing index entries in the form {[author]![title]}. Indeed, even the standard macros index two fields, because they produce entries in the form {indexsortitle@indextitle} IIRC. Have a look at how {index:field} does it and work from there. – Paul Stanley Aug 22 '12 at 18:13
• a yes, I did'nt see your answer. I will look like. But my system is working too. – Maïeul Aug 22 '12 at 18:46
• I think the best solution will be this function be in standard of biblatex? – Maïeul Aug 22 '12 at 18:47