@Section
   @Title { Indexes }
   @Tag { indexes }
@Begin
@PP
Although Lout is not clever enough to guess what entries should go in
indexes. @Index { indexes }
your index, it will do almost everything else for you:  sort the
entries and attach the correct page numbers automatically.  As for
tables of contents, the default setting is to have an index in
books but not in other types of documents.  This and a few aspects of
the appearance of the index can be changed by changing the setup file,
as explained at the end of this section.
@PP
Now, suppose you are discussing Galileo and you want his name in your
index.  Let's be ambitious and say that you want the index to contain
something like this:
@ID @OneRow lines @Break {
Galileo Galilei
    life of, 201
    telescope, his use of, 201--203
    trial of, 205--211, @I 242, 395
}
These lines show off Lout's five tricks:  the first is a @I { raw entry }
(no page number attached); the second is a @I sub-entry (indented); the
third has a @I { page number range } instead of a single page number; and
the fourth has a @I { merged entry } (several page numbers or ranges within
one entry) and a @I { special element } (the page number in italics).
@PP
We'll get to them in a moment, but first, let's see how to get a basic
entry, like this one:
@ID { Galileo Galilei, 201 }
To get this into your index, type
@ID @Code "galileo @Index { Galileo Galilei }"
at the point where you mention Galileo.  Nothing will be printed there,
but the object following the @Code "@Index" symbol will be placed in
index.sym @Index { @Code "@Index" symbol }
the index, plus a comma and the correct page number.
@PP
The object preceding the @Code "@Index" symbol is a compulsory key
which is used for sorting the index entries,
@FootNote {
The collating sequence used to decide what comes after what is either
the collating sequence used by the @Code "memcmp()" library routine (just
the underlying binary character codes), or else the one used by the
@Code "strcoll()" collating sequence, which understands accented
characters and whose effect depends on your locale.  To find out
whether @Code "strcoll()" is in use or not, type @Code "lout -V" which
prints out several lines of this and similar information, including
information about command line flags to switch between the two kinds of
collation.
@PP
If the sorting you get turns out to be not what you expected, the
first thing to try is the replacement of all accented letters in index
keys by unaccented ones.  Sorting is quite an intractable problem:  even
collation.order @Index { collation order }
sorting.order @Index { sorting order }
if @Code "strcoll()" gets the sorting right for one language, there still
remains the problem of sorting multilingual indexes.
}
but which is not itself printed.  It is best to construct these
keys from lower-case letters and the . character only, beginning
with a letter, although multi-word keys are allowed.  These sorting keys
do not have to be distinct from the tags used in cross referencing;
however, they do have to be distinct from each other, unless you want
merged entries (see below).
@PP
Our first trick, raw entries (no page number attached), is very
easy:  just use @Code "@RawIndex" instead of {@Code "@Index"}.  So the
rawindex.sym @Index { @Code "@RawIndex" symbol }
first line of our ambitious example is obtained by
@ID @Code "galileo @RawIndex { Galileo Galilei }"
This could go anywhere, since no page numbers are involved.
@PP
Our second trick, sub-entries, is also easy, since a sub-entry
is just an ordinary entry with an indent.  The symbol is
{@Code "@SubIndex"}, so the second line of our ambitious example is
subindex.sym @Index { @Code "@SubIndex" symbol }
produced by
@ID @Code "galileo.life @SubIndex { life of }"
You should always give sub-entries the same sorting key as their
corresponding main entries, plus a . and another word, because then
you can be certain that the sorting will place sub-entries directly
after their main entries.  There is a @Code "@SubSubIndex" symbol that
produces a double indent, and there are @Code "@RawSubIndex" and
@Code "@RawSubSubIndex" symbols.
@PP
For our third trick, page number ranges, we use the @Code "to" option
of the {@Code "@Index"}, {@Code "@SubIndex"}, and {@Code "@SubSubIndex"}
symbols.  For example, to produce the sub-entry
@ID { telescope, his use of, 201--203 }
put
@ID @Code {
  "galileo.telescope @SubIndex to { gt.end } { telescope, his use of }"
}
at the beginning of the range, and
@ID @Code "@PageMark { gt.end }"
at the end.  You can use any tag you like inside the @Code "to" option,
as long as it differs from every other tag (notice that sorting keys
do not have to differ from tags, but @Code "to" options do:  this
is because @Code "to" options go into @Code "@PageMark" like other
tags do, and if two tags are the same we would have an ambiguous
result of {@Code "@PageOf"}).  If both ends of the range fall on the
same page, the @Code "to" option is ignored:  you will never get
201--201.
@PP
Our fourth trick is the merged entry:
@ID { trial of, 205--211, 242, 395 }
This merged entry was originally three separate entries (sub-entries
in this case):
@ID @OneRow lines @Break {
trial of, 205--211
trial of, 242
trial of, 395
}
We know how to produce these, using three @Code "@SubIndex" symbols,
one with a @Code "to" option.  Lout is able to merge several entries
into one entry.  This raises two questions:  how does Lout know which
entries to merge? and given those entries, what does the merging produce?
@PP
The answer to the first question is that Lout merges entries whose
sorting keys are equal.  The merged entry above is produced by these
three entries, placed in the appropriate places:
@ID @OneRow @Code {
"galileo.trial @SubIndex to { gtrial.end } { trial of }"
"galileo.trial @SubIndex { trial of }"
"galileo.trial @SubIndex { trial of }"
}
The entries are merged because they have the same sorting key
({@Code "galileo.trial"}), not because they happen to have the
same content ({@Code "trial of"}).
@PP
Now, having decided that the three entries
@ID @OneRow lines @Break {
trial of, 205--211
trial of, 242
trial of, 395
}
must be merged, what does Lout do?  Without being too formal, it
finds the shortest larger entry that contains everything in the
given entries, more or less, preserving the order in which
the entries' points of origin appear in the final printed document.
@PP
If the entries are not different at all, then the result will be
the same as each of them.  With this in mind, let us return to
our initial, ambitious example:
@ID @OneRow lines @Break {
Galileo Galilei
    life of, 201
    telescope, his use of, 201--203
    trial of, 205--211, 242, 395
}
We now know how to produce all four of these entries, but one problem
of some practical importance remains.  Suppose we delete the section on
the life of Galileo.  If we had put the entry that produces `Galileo
Galilei' in that section, we might inadvertently delete it, and the
other two sub-entries will lose their main entry.  Before deleting
anything, we must hunt through it for index entries and ponder their
significance, an error-prone and time-wasting thing to do.
@PP
The solution is as follows.  When an index entry has sub-entries, make
it raw, and repeat it just before each of its sub-entries:
@ID @OneRow @Code {
"galileo @RawIndex { Galileo Galilei }"
"galileo.life @SubIndex { life of }"
}
at the first place,
@ID @OneRow @Code {
"galileo @RawIndex { Galileo Galilei }"
"galileo.telescope @SubIndex { telescope, his use of }"
}
at the second, and so on.  Now it is easy to verify that every
sub-entry has a main entry; and when deleting a sub-entry we can and
should delete the adjacent main entry.  After sorting, our index
entries will be
@ID @Tab
    @Fmta { @Col @Code A ! @Col B }
{
@Rowa
    A { galileo }
    B { Galileo Galilei }
@Rowa
    A { galileo }
    B { Galileo Galilei }
@Rowa
    A { galileo }
    B { Galileo Galilei }
@Rowa
    A { galileo }
    B { Galileo Galilei }
@Rowa
    A { galileo }
    B { Galileo Galilei }
@Rowa
    A { galileo.life }
    B { {}    life of, 201 }
@Rowa
    A { galileo.telescope }
    B { {}    telescope, his use of, 201--203 }
@Rowa
    A { galileo.trial }
    B { {}    trial of, 205--211 }
@Rowa
    A { galileo.trial }
    B { {}    trial of, 242 }
@Rowa
    A { galileo.trial }
    B { {}    trial of, 395 }
}
The first five entries have the same sorting key, and will be merged
as required.
@PP
Each index entry symbol has a @Code { pnformat } option, which affects the
way the page number of the entry is printed in the index.  For example,
@ID @Code "galileo.trial @SubIndex pnformat { Main } { trial of }"
indicates that this is an entry of format {@Code Main}.  By default the
format is {@Code Ordinary}; it may be {@Code Main}, producing a
bold page number in the index, or {@Code Special}, producing an
italic page number.
@PP
As the name suggests, the @Code pnformat option is actually a format
option, within which the @Code "@PageNum" symbol stands for the index
page number, so you could even write
@ID @Code "galileo.trial @SubIndex pnformat { @Underline @PageNum } { trial of }"
to get an underlined page number.  However, it is rarely a good
idea to use the @Code { pnformat } option in this way.  Better to
decide once and for all what variants on the basic format you are
going to have, call one variant {@Code Main} and the other {@Code Special},
use the setup file options described later in this section to redefine
the appearance of page numbers for these two index entry formats, and
explain in the @Code "@IndexText" what the formats mean.
@PP
When index entries with different formats are merged, naturally each page
number preserves its own format.  If there are two merged entries with
the same page number but different formats, the result is plausible but
indeterminate.  A page number range is formatted according to the format
of the index entry which is its starting point.  To change the format
of the @I stem of the index entry, just do the usual thing.  For example,
@ID @Code "galileo @Index @I { Galileo Galilei }"
will cause the stem of the entry to appear in an italic font.
@PP
The language of the index entry will be the initial language of the
document as a whole, which is not necessarily the language at the point
where the index entry occurs.  To get the correct language you will need a
@Code "@Language" symbol following the @Code "@Index" symbol:
@ID @Code "galileo. @Index Italian @Language { Galileo Galilei }"
or whatever.  If you don't do this your index entry might be hyphenated
incorrectly.
@PP
Although the page numbers in index entries will be kept up to date
automatically as the document changes, as all cross references are, 
it is best to refrain from inserting index entries until the document
is complete and an overall plan of the structure of the index can
be made.  Place index entries for floating figures and tables within
their captions.
@PP
Large indexes may benefit from {@I spacers}:  empty spaces or
spacers. @Index { spacers in indexes }
headings between the parts for each letter of the alphabet.  One
way to get blank line spacers is with {@Code "@RawIndex"}, like this:
@ID @OneRow @Code {
"b @RawIndex {}"
"c @RawIndex {}"
"d @RawIndex {}"
"..."
"z @RawIndex {}"
}
These phantom entries will insert blank lines before the region of each
English letter except `a'.  In fact there is a symbol called
@Code "@IndexBlanks" that makes
indexblanks. @Index @Code "@IndexBlanks"
exactly these 25 entries.  Unfortunately, these blanks will occasionally
appear at the top of a column, and if there are no tags beginning with
x, for example, there will be two blank lines between the w and y
entries.  You can start off with @Code "@IndexBlanks" and replace it
later by the appropriate subset, if necessary.
@FootNote {
For Lout to solve this problem automatically, it would need to be told
which letter each index entry belongs under, perhaps by symbols
{@Code "@AIndex"}, {@Code "@BIndex"}, etc.  The author felt that this
would have been too tedious.
}
@PP
More elaborate spacers can be inserted with
indexspacer. @Index @Code "@IndexSpacer"
the @Code "@IndexSpacer" symbol, like this:
@ID @Code "a @IndexSpacer A"
This is similar to @Code "a @RawIndex A" in that it puts the entry
@Code A at sort position {@Code a}; but it also places extra space
above and below it, and it includes a font change, so that the
@Code A stands out like a heading (you can see the effect in the
index of this document).  @Code "@IndexSpacer" also includes a
conditional new page, so that the spacer never appears alone at
the bottom of a column.
@PP
The first spacer needs to be slightly different, since no
space is wanted above it:
initialindexspacer. @Index @Code "@InitialIndexSpacer"
@ID @Code "a @InitialIndexSpacer A"
There is an @Code "@IndexLetters" symbol which places the 26 spacers
indexletters. @Index @Code "@IndexLetters"
@ID @OneRow @Code @Verbatim {
a @InitialIndexSpacer A
b @IndexSpacer B
...
z @IndexSpacer Z
}
into your document for you in one go.  Users of other alphabets are
recommended to define a similar symbol of their own.
@PP
The remainder of this section describes how to change the appearance of
the index by setting options in the setup file.  For setup files and
their options in general, consult Section {@NumberOf setup}.
@PP
There are several setup file options for the index.  Here they are with
their default values:
@ID @OneRow @Code @Verbatim {
@MakeIndex { No }
@IndexText { @Null }
@IndexFont { }
@IndexBreak { oragged 1.2fx }
@IndexFormat { @Body }
@SubIndexFormat { {1f @Wide}@Body }
@SubSubIndexFormat { {2f @Wide}@Body }
@IndexTypeOrdinary { @PageNum }
@IndexTypeMain { @B @PageNum }
@IndexTypeSpecial { @I @PageNum }
@IndexRangeFormat { @From--@To }
@IndexColumnNumber { 2 }
@IndexColumnGap { 1.00c }
@IndexCtd { Yes }
@IndexCtdWord { continued }
@IndexCtdFormat { @Body @I (@CtdWord) }
@IndexSpacerAbove { 2v }
@IndexSpacerBelow { 1v }
@IndexSpacerFont { +3p }
@IndexSpacerFormat { @Body }
}
The @Code "@MakeIndex" option, which may be @Code Yes or {@Code No},
makeindex. @Index @Code "@MakeIndex"
determines whether to produce an index or not.  Although the default
value is {@Code No}, any type of document may be given an index just
by changing it to {@Code Yes}.  This has already been done in the
@Code book setup file, but not in the others.
@PP
@Code "@IndexText" is some text to put at the start of the index,
after the heading but before any index entries.  It will appear
full width on the page.  This option is also available as an option
of the {@Code "@Document"}, {@Code "@Report"}, and {@Code "@Book"}
symbols.
@PP
@Code "@IndexFont" determines the font and font size of index entries
indexfont. @Index @Code "@IndexFont"
(e.g. {@Code "Times Base 12p"}).  Leaving it empty as above produces
the same font as the rest of the document.  @Code "@IndexBreak" is the
indexbreak. @Index @Code "@IndexBreak"
paragraph breaking style applied to index entries; @Code oragged is the
traditional and best way.
@PP
@Code "@IndexFormat" allows a more radical control of the appearance
indexformat. @Index @Code "@IndexFormat"
of the index entry than just its font and break style.  Within it,
the @Code "@Body" symbol stands for the entry, not including any page
numbers.  The default value just leaves the index entry as is, but the
corresponding options for formatting subindexes ({@Code "@SubIndexFormat"}
and {@Code "@SubSubIndexFormat"}) are more interesting:
@ID @Code "@SubIndexFormat { {1f @Wide}@Body }"
causes subindexes to begin with an indent of width {@Code 1f},
immediately followed by the entry.  For more information about
lengths like {@Code 1f}, see Section {@NumberOf objects}.  Another
possible format is
@ID @Code "@SubIndexFormat { --  @Body }"
which causes the subindex to begin with an en-dash and two spaces
instead of an indent.
@PP
{@Code "@IndexTypeOrdinary"}, {@Code "@IndexTypeMain"}, and
{@Code "@IndexTypeSpecial"} give the page number format to use
when the index entry type is {@Code Ordinary}, {@Code Main}, and
{@Code Special} respectively.  Within them the @Code "@PageNum"
symbol stands for the page number or page number range being
printed.  The value of these options can be an arbitrary object. 
If the value of a @Code pnformat option is not {@Code Ordinary},
{@Code Main}, or {@Code Special}, then the @Code pnformat option
itself is printed; it too may contain a @Code "@PageNum" symbol,
as explained earlier.
@PP
{@Code "@IndexRangeFormat"} gives the format to use when a page
number range, such as 5--8, is to be included in an index entry.
Within it the symbols @Code "@From" and @Code "To" stand for
the first and last page numbers respectively.  These will always
be different when {@Code "@IndexRangeFormat"} is used; Lout knows
never to insert a range when the two end points are equal.  The
default value just separates the two numbers by an en-dash with
no space.
@PP
@Code "@IndexColumnNumber" and @Code "@IndexColumnGap" determine the
indexcolumnnumber. @Index @Code "@IndexColumnNumber"
indexcolumngap. @Index @Code "@IndexColumnGap"
number of index columns per page, and the gap between them, and are
exactly analogous to the @Code "@ColumnNumber" and @Code "@ColumnGap"
options described in Section {@NumberOf columns}.
@PP
The next three options control the appearance of running headers
@FootNote {
Owing to problems behind the scenes, in the highly unlikely case
where more than three copies of the same running header appear on
the same page, their horizontal positions will become confused,
probably resulting in the apparent disappearance of all but the
last three.
}
in the index:
indexctd. @Index { @Code "@IndexCtd" }
indexctdword. @Index { @Code "@IndexCtdWord" }
indexctdformat. @Index { @Code "@IndexCtdFormat" }
@ID @OneRow @Code @Verbatim {
@IndexCtd { Yes }
@IndexCtdWord { continued }
@IndexCtdFormat { @Body @I (@CtdWord) }
}
If an @Code "@Index" entry has @Code "@SubIndex" entries
that run over to the next column, Lout will print an unobtrusive running
header at the top of that column, something like this in English:
@ID { procrastination @I (ctd.) }
It will print two running headers if a @Code "@SubIndex" entry has
@Code "@SubSubIndex" entries that run over, one for the main entry and an
indented one for the sub-entry.  You can turn off these running headers by
setting @Code "@IndexCtd" to {@Code No}.  A particular word is associated
with index running headers; by default it is @Code "ctd." in English and
its equivalent in other languages.  This is what the default value,
{@Code "continued"}, of the @Code "@IndexCtdWord" option gives you; if you
want some other word, change that option to the word you want.  Finally,
you can control the format of the running headers using
{@Code "@IndexCtdFormat"}.  Within this option, the symbol @Code "@Body"
stands for the value of the index entry that is running over (as formatted
by {@Code "@IndexFormat"}, {@Code "@SubIndexFormat"}, or
{@Code "@SubSubIndexFormat"} but without any page numbers), and
@Code "@CtdWord" stands for the word produced by the @Code "@IndexCtdWord"
option.  The default value of {@Code "@IndexCtdFormat"}, shown above,
yields the index entry followed by @Code "@IndexCtdWord" in
italics and parentheses.
@PP
Finally, we have four options to control the appearance of index
spacers:
indexspacerabove. @Index { @Code "@IndexSpacerAbove" }
indexspacerbelow. @Index { @Code "@IndexSpacerBelow" }
indexspacerfont. @Index { @Code "@IndexSpacerFont" }
indexspacerformat. @Index { @Code "@IndexSpacerFormat" }
@ID @OneRow @Code @Verbatim {
@IndexSpacerAbove { 2v }
@IndexSpacerBelow { 1v }
@IndexSpacerFont { +3p }
@IndexSpacerFormat { @Body }
}
@Code "@IndexSpacerAbove" and @Code "@IndexSpacerBelow" determine the
amount of extra space to insert above and below index spacers (except
that {@Code "@InitialIndexSpacer"} uses @Code {0v} for its above space).  Any
lengths from Section {@NumberOf objects} are acceptable here; the default
lengths shown are two times and one times the current inter-line
spacing.  @Code "@IndexSpacerFont" may contain any font change acceptable
to the {@Code "@Font"} symbol; the default increases the size by 3
points.  For more radical changes to the spacer format,
@Code "@IndexSpacerFormat" allows any symbols to be applied to the
spacer object, which is represented by the symbol @Code "@Body" within
this option.  For example,
@ID @Code "@IndexSpacerFormat { @Underline @Body }"
will cause the spacer to be underlined.
@PP
The @Code "@IndexSpacer" symbol has {@Code above}, {@Code below},
{@Code font}, and {@Code format} options which override the four
setup file options.  For example, @Code "@InitialIndexSpacer" is
equivalent to
@ID @Code "@IndexSpacer above { 0v }"
Whether you will ever need to vary the appearance of index spacers
individually in this way is very doubtful, but the capacity is there.
@PP
Lout offers three independent indexes (useful for author indexes,
etc.).  The other two are called index A and index B, and they
precede the main index in the output.  Just replace @Code Index
by @Code IndexA to refer to index A, and by @Code IndexB to refer
to index B.  For example,
@ID @Code "smith.j @IndexA { Smith, John }"
will insert an index entry to index A, and @Code "@IndexBBlanks"
will insert the usual 25 blank entries into index B.  There are
setup file options to change the titles of indexes.
@PP
In large projects it might help to rename the @Code "@IndexA" symbol
to something else, such as {@Code "@AuthorIndex"}.  This can
be done by placing
@ID @Code {
"import @DocumentSetup"
"macro @AuthorIndex { @IndexA }"
}
in the @Code mydefs file (Section {@NumberOf definitions}).  The
word @Code macro is needed here instead of @Code "def" because we
are introducing a new name for an existing symbol, not defining
a new symbol.
@End @Section
