(Don’t) forget to run MakeIndex

2012-09-28 by . 1 comments

Post to Twitter

Many books should have an index, particularly scientific or technical ones. Since the first days, LaTeX has a companion program called MakeIndex that helps in sorting the index entries one can specify in the LaTeX document with \index.

Having to run a helper program is often a nuisance and people tend to forget it, unless some automated system is used. Another well known helper program is BibTeX (or Biber), but for bibliographic cross references LaTeX has a means to make us notice that a run of BibTeX is possibly needed. How can one avoid forgetting to run MakeIndex? Well, it’s possible to forget running it without losing anything: read on!

The old days

The traditional setting was

\documentclass{book}

\usepackage{makeidx}
\makeindex

\begin{document}

Here is the start\index{start} of my document.

...

\printindex

\end{document}

A limitation of this approach is that only one index can be generated. But more on this later; for the moment let’s assume we have only one index.

The making of the index is asynchronous: a LaTeX run on main.tex produces, if \makeindex is issued in it, the auxiliary file main.idx that must be processed with MakeIndex which sorts and compacts the entries and finally writes the file main.ind that, if present, is input by the command \printindex.

Thus a typical session involving a bibliography and an index would require

pdflatex main
bibtex main
pdflatex main
pdflatex main
makeindex main
pdflatex main

in order that the bibliographical references are resolved and the index entries show the correct page number. Of course, during the preparation of the book it’s not necessary to do all those runs (and nowadays probably biber is run instead of bibtex, but that’s another question).

Failing to run MakeIndex can lead to incorrect page numbers. But while changed references related to \ref or \cite make LaTeX issue the well known message

Label(s) may have changed. Rerun to get cross-references right.

nothing of this sort is available for index entries.

The new era

At the GuITmeeting 2009 Claudio Beccari announced TeX Live’s plan to allow some selected programs to be run from inside (La)TeX and presented a strategy for ensuring that MakeIndex was run automatically during the LaTeX compilation of a document. Unfortunately (or happily) the feature was not included in TeX Live 2009, but delayed to the 2010 release. The idea of developing a package out of the small kernel presented by Claudio popped out immediately; the name chosen for it was, without much fantasy, imakeidx (maybe “improved makeidx“). We foresaw the possibility, with TeX Live 2010 or later, to shorten the necessary steps to

pdflatex main
bibtex main
pdflatex main
pdflatex main

by only changing \usepackage{makeidx} into \usepackage{imakeidx}. The only real limitation was (and is) that no index entry may appear after the index itself. The MakeIndex run is safely called without user intervention!

Multiple indices

Some packages had already been developed for supporting multiple indices in books: multind, index and splitidx, so one of our tasks was to provide support for more than one index. We decided for a key-value interface; here are the main ones:

\makeindex[name=<name>, title=<Index header>, options=<options for makeindex>, intoc={true|false},columns=<number>]

For example

\makeindex[name=people, title=Index of names, options=-s latex.ist -c, intoc, columns=3]

will enable to say \index[people]{Archimedes} in order to insert the famous mathematician’s name in an index titled “Index of names”, processed using the MakeIndex style latex.ist, and compressing blanks (any set of MakeIndex options can be specified); the index will be listed in the main table of contents and will be typeset in three column format. The number of columns can be also one, for annotated indices; the default is, as usual, two.

In this case, printing the index will be obtained by the command

\printindex[people]

With only one index it’s not necessary to specify a name option.

Apart from the optional argument that tells LaTeX what index the entry belongs to, the syntax for the mandatory argument to \index is the same as the standard one. So, for instance,

\index[people]{Godel@Gödel, Kurt}

can be used so that “Gödel” will be sorted as if it were “Godel”.

Multiple index troubles

What about having ten different indices maybe along with glossaries, nomenclatures and acronym lists? No, imakeidx doesn’t support those kinds of lists, but they can be needed in a book and there are very good packages around for managing them. The problem is that every index uses up an output stream and TeX is able to write only in 16 different files at the same time; for a book there can be already four streams in use for writing the main .aux file, the table of contents, the list of tables and the list of figures. It’s easy to overflow the limit.

Markus Kohm’s splitidx package comes to the rescue, because it provides also a helper program, called splitindex that we decided to make available also to imakeidx users: one can pass an option to the package

\usepackage[splitindex]{imakeidx}

and all the index entries will be saved in only one file, that will be automatically split at the first call of \printindex. There is one catch, however: splitindex is not in the list of programs that can be run from inside a (La)TeX run, so in this case one has to launch pdflatex (as well as latex, xelatex or lualatex) with the --shell-escape option

pdflatex --shell-escape main.tex

We hope that splitindex can be amended so that it can be included in the restricted list.

Xindy

For some years there’s been another index processor around, much more powerful than MakeIndex. It can sort by different collation rules (useful for languages other than English) and apply many processing options. One can choose this processor globally

\usepackage[xindy,...]{imakeidx}

or on a per index basis with

\makeindex[program=xindy,...]

where ... stands for the other options discussed so far (maybe also splitindex). This option actually calls the script texindy that chooses a set of Xindy options specially tailored for LaTeX. The “naked” program can be called by the option truexindy (a recent addition to the package, in version 1.2). Since xindy and texindy are not in the restricted list, the --shell-escape switch is needed when an index has to be processed with Xindy in any of its forms.

Compatibility

The package is compatible with all main classes we know (with the notable exception of the AMS classes, for which a different system is needed, using amsmidx). It’s also compatible with memoir, with the caveat that its internal method for doing multiple indices is hijacked by ours. Recent updates to the package have removed small incompatibilities (particularly with combine).

Bell and whistles

Yes, there’s more. One can define prologues to indices, that is, text that’s printed between the index title and the entries. Other aspects of the indices can be changed and the package is compatible with idxlayout by Thomas Titz.

Final words

You can forget to run MakeIndex. But don’t forget to prepare a good index for your book: your readers will be grateful.

Filed under LaTeX Packages

One Comment

Subscribe to comments with RSS.

  • Harish Kumar says:

    @egreg Nice article Enrico! That was very informative! Thank you.

  • Leave a comment

    Log in
    with Stack Exchange
    or