Windex: An index compilation program

by Ronald L. Rivest MIT Laboratory for Computer Science

                  rivest@theory.lcs.mit.edu

December 14, 1989

Windex is a system to assist in compiling an index for a Latex document. It consists of a modification to the Latex \index command and a C program for compiling the index.

1 Using windex — basic case

To use windex in its simplest form, you need to obtain (or obtain access to) two files:

• windex.tex—a Latex macro package.

• windex—the compiled form of windex.c.

You should then do the following:

• Include the lines

      \makeindex
      \include{windex}

before the \begin{document} command in your latex file.

• Include an index command of the form \index{term} at the position you wish to index term in your document, for each such term.

• Compile your document with Latex. If your document is called paper, then Latex will create a file called paper.idx containing the raw index information.

• Issue the command windex paper. The windex program will read the file paper.idx and produce as output a file called paper.index containing the actual Latex commands necessary to produce the index.

• Include the command \input{paper.index} at the place you wish the index to appear in your paper.

• Recompile paper with latex.

• Review the index produced and modify your paper as necessary until the index produced is satisfactory.

The output index will be alphabetized, and page ranges will be automatically created when possible to conserve space. For example, the page numbers “20, 21, 22, 23” will be condensed to read “20–23”. This provides a very simple indexing capability.

Windex also has a number of sophisticated features that you can use for more complicated indices. In particular, windex supports the following capabilities:

• using multi-level entries (up to three levels),

• using \index commands in the source document to indicate where a range of relevant pages begins and where it ends,

• separately specifying the text to sort an entry by, and the text to print,

• formatting control for page numbers, such as allowing italicized page numbers, or replacing the page number with text of the form “See fruit.” for cross-references.

The following sections give details on using the \index command to use these features and obtain satisfactory results.

2 Placing index commands in your document

In general, you should place the \index immediately before the term being indexed, with no intervening spaces, so that the page reference generated is to the beginning of the term. Once in a while Latex may split a term across pages, and you want the index command to refer to the first page the term is on. As an example,

     falls in the area of \index{machine learning}machine learning,
     which. . .

gives the desired behavior, even if a page break occurs between machine and

learning.

The text of the index entry may not contain the characters: { } / < > [ ]. These characters have special meaning to windex, as noted below. The text may contain blanks, hyphens, periods, or other special characters.

Windex does not directly support non-arabic page numbers, such as you might have in a preface. If you place an \index command on a page with nonarabic page numbers, you’ll get the arabic version of the page number in the index. By using the format control for page numbers, however, you can solve this problem (see Section 7).

3 Multi-level entries

You can use the “/” character to separate levels in a multi-level index entry. For example, an entry of the form \index{fruit/apples} on page 10 will produce in the index a two-level entry of the form

fruit apples, 10

You can create an index with up to three levels. For example, an entry of the form \index{fruit/apples/Macintosh} would cause a three-level entry to be generated.

Note that you don’t need to specify the “parent” entries separately. For example, in the above example, the parent entry for “fruit” (with no page reference) was automatically generated from the occurrence of \index{fruit/apples}. You may have entries for the parent entry too, but a dummy one with no page reference is generated if you don’t give one explicitly.

4 Alphabetization

Windex uses the following rules when alphabetizing the index.

• The entries are sorted according to their top-level entry, then according to the second-level entry, and so on, in the natural manner.

• Blanks and hyphens are ignored. Thus, we might have as output:

high bettor, 10 highest elevation, 12 high-point, 15

• In the second and third levels, initial prepositions and articles are also ignored. Thus, we might have as output:

fruit banana, 15 in cakes, 20 as a decoration, 30 grapefruit, 19

• Capitalization is ignored unless two entries agree in all but capitalization, in which case the capitalized entry goes second. For example, we might have as output:

apple, 15 Apple, 20

5 Page ranges

You can place one \index command at the beginning of a range of pages for a given term, and another \index command at the end of the range of pages. The first \index command should contain the character “<”, and the second command should contain the character “>”.

   For example, the entry \index{number-theory algorithms/gcd<} on page
300 and the corresponding entry \index{number-theory algorithms/gcd>}

on page 306 generates as output

number-theory algorithms gcd, 300–306

In addition to the ranges you create explicitly in this manner, windex may create ranges of its own by combining a sequence of consecutive pages references into a page range. Windex may also combine several page ranges into one, or combine extend a range to include additional pages in the obvious manner. In general, windex attempts to describe the pages covered in the most compact form possible. For example, the list of pages and ranges

301,302,302–305,304,306–308,308,309–311,311–320,321

combines to yield

301–321

If the range includes other individual pages in their interior, they will be eliminated from the listing (e.g., page 304 in the above example.)

If the two index commands you give to specify happen to end up on the same page, then only a single reference, rather than a range, is printed.

6 Controlled printing of index keys

Windex allows you to print the text for a given entry in an arbitrary manner. For example, your index entry terms can be printed in italics or can contain mathematical symbols. The \index command allows you to specify how to print an index term separately from how to place it in the sorted order. To specify special printing for an index entry, merely include within the argument to the \index command the Latex commands for printing the entry, enclosed within braces. For example, the commands

     \index{beta-decay{$\beta$-decay}} on page 12
     \index{Lovasz, L.{Lov\'asz, L.}} on page 15
     \index{fruit/apple{\bf apple}} on page 18

might produce as output β-decay, 12 fruit

apple, 18 Lovász, L., 15

Let us call the text within braces the print value for that index entry, and call the unenclosed text the sort key for that index entry. Ordinarily, only the sort key is given, and the print value is automatically determined by windex to be the same as the sort key. (Or, in the case of a multi-level entry, the print value is automatically taken to be the same as the last component of the multi-level entry.)

Note that specifying the print value affects only how that entry is printed; the print value is not considered during the alphabetization of the entries. In particular, two entries are considered the same if and only if they have the same sort key. If two entries have the same sort key, but one of them specifies a print value and the other doesn’t, then the entries will be considered the same, and printed with the given print value. For example, the commands

     \index{fruit<} on page 101
     \index{fruit{\bf fruit}>} on page 120
     \index{fruit} on page 130

will produce as output

fruit, 101–120, 130

Only one print value can be associated with a given sort key. If two different \index commands specify different print values for the same sort key an error is reported.

7 Controlled printing of page references

Windex also allows you to control how the page references are printed, including a format for the page reference in brackets within the argument to the \index command. The digit “0”, if present within the format, will be replaced with the actual page reference. For example, the commands

     \index{vegetable} on page 10
     \index{vegetable[\bf 0]} on page 15
     \index{vegetable[\it 0]} on page 20
     \index{vegetable[0 ff.]} on page 25

will produce as output:

vegetable, 10, 15, 20, 25 ff.

Note that the brackets delimit the scope of Latex commands. (That is, there is no need to surround the format with an outer set of braces; the format is automatically surrounded by braces when included in the Latex output.)

You can also get roman numerals out in this manner for page references in prefaces, etc. For example, the command

     \index{Knuth, Donald E.[\romanpage{0}]} on page xv

where \romanpage has been defined

     \newcounter{pgno}
     \newcommand{\romanpage}[1]{\setcounter{pgno}{#1}\roman{pgno}}

will produce as output

Knuth, Donald E., xv

Note, however, that the roman format for the page reference doesn’t affect where in the list of page references xv will appear; it will be sorted after page 13 and before page 17. (If this is a problem, you have to edit your .index file by hand or modify the windex.c program.)

A special case occurs when the format does not include the digit “0” at all. In this case the format actually specifies a replacement for the page reference. For example, the commands

     \index{pomme} on page 10
     \index{pomme[{\em See also} apple]} on page 20
     \index{gcd[{\em See} greatest common divisor]} on page 30

will produce as output

gcd, See greatest common divisor

pomme, See also apple, 10

Note that replacement texts are always placed at the beginning of a list of page references, independent of which page the \index command specifying the replacement text occurred on.

If no format is given, the default format of “[0]” is used, causing just the page number to be printed. However, parent entries that are created automatically have a default format of “[]”, causing no page reference or replacement text at all to be printed. For example, the two-level command

     \index{fruit/apples}

is entirely equivalent to the pair of commands

     \index{fruit[]}
     \index{fruit/apples}

Specifying a format of “[]” can be useful when you wish to give a print value to an automatically created parent entry. For example, if we wish to put both “fruit” and “apple” in boldface in the above example, the commands

\index{fruit{\bf fruit}[]} on page 10
\index{fruit/apples{\bf apples}} on page 10

produces as output

fruit apples, 10

The specification of formats and replacement texts affects how windex combines page references into ranges. Specifically, pages are only combined into ranges if they have the same format. If they are combined, the range string “nnn-mmm” is placed at the position of the 0 in the format string. For example, the commands

\index{apple[\em 0]} on page 301
\index{apple[\em 0]} on page 302
\index{apple} on page 302
\index{apple} on page 303
\index{apple<} on page 400
\index{apple[\em 0]<} on page 401
\index{apple[\bf 0]} on page 403
\index{apple[\bf 0]} on page 404
\index{apple>} on page 405
\index{apple} on page 406
\index{apple[\em 0]>} on page 410

produce as output

apple 301–302, 302–303, 400–406, 401–410, 403–404

In such an example, the ranges are sorted into order according to the first page number in each range.

If you really want a “0” in your format or replacement string, use the Tex command “\char48”. For example, you might have on page 200

\index{zero-one programming[\char48-1 programming]}

which will produce

0-1 programming, 200

8 Macros and interfacing with Latex

If all you do to create \index commands is to place them directly in your document, then you don’t need to read this section. If, however, you wish to write Latex macros that generate \index macros automatically, then you will find this section helpful.

If you use the \index command inside a macro, and there are Latex commands inside the argument to\index, then you should precede them with \string to prevent their interpretation until the index is produced. For example, the following defines a variant of the \index command that automatically makes a boldface print value.

     \newcommand{\bfindex}[1]{\index{#1{\string\bf{#1}}}}

Because of the special way that the \index command parses its argument, writing macros that generate \index commands is rather tricky, and is best avoided. The given macro \bfindex, for example, does not work correctly if formats are given containing Latex commands.

9 Implementation notes

The “.idx” file that is produced by the \index commands consists of one line for each \index command. Each such line has the form.

     text:nn

where text is the argument to the \index command and nn is the page number on which that \index command was placed.

The C program windex.c is extensively commented, and easily modified, should you want slightly different behavior from windex.