% \def\filename{index.dtx}
% \def\fileversion{4.04}
% \def\filedate{2025/02/06}

% \iffalse meta-comment
%
% David M. Jones
% dmjones@alum.mit.edu
%
% Copyright 2024, 2025 David M. Jones
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   https://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008 or later.
%
%    CAUTION: Use only as directed.  Do not take internally.  May cause
%    rash if applied directly to skin.  Federal law prohibits distributing
%    without a proscription.
%
% This work has the LPPL maintenance status `maintained'.
% 
% The Current Maintainer of this work is David M. Jones.
%
% \fi
%
% \iffalse
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\documentclass{ltxdoc}

\DoNotIndex{\!,\/,\?,\@,\^,\_}
\DoNotIndex{\@@par,\@M,\@auxout,\@bsphack,\@esphack,\@depth,\@ehc}
\DoNotIndex{\@for,\@flushglue,\@gobble,\@gobbletwo,\@height,\@idxitem}
\DoNotIndex{\@ifnextchar,\@ifstar,\@ifundefined,\@input,\@latexerr}
\DoNotIndex{\@makeschapterhead,\@namedef,\@nameuse,\@nil}
\DoNotIndex{\@nobreakfalse,\@restonecolfalse,\@restonecoltrue}
\DoNotIndex{\@tempa,\@tempf,\@temptokena,\@themark,\@width}
\DoNotIndex{\active,\aindex,\baselineskip,\begin,\begingroup,\box}
\DoNotIndex{\c@page,\catcode,\chapter,\char,\chardef,\closeout}
\DoNotIndex{\CodelineIndex,\sp,\sb,\label,\leavevmode,\mark}
\DoNotIndex{\mark,\newinsert,\newwrite,\newtoks,\xdef}
\DoNotIndex{\columnsep,\columnseprule,\columnwidth,\csname,\def}
\DoNotIndex{\dimen,\do,\DocInput,\documentstyle,\edef,\em}
\DoNotIndex{\EnableCrossrefs,\end,\endcsname,\endgroup,\endinput}
\DoNotIndex{\everypar,\expandafter,\filedate,\fileversion}
\DoNotIndex{\footnotesize,\gdef,\global,\glossary,\hangindent}
\DoNotIndex{\if@filesw,\else,\fi}
\DoNotIndex{\if@nobreak,\if@twocolumn,\if@twoside,\fi,\fi,\fi}
\DoNotIndex{\hsize,\hskip}
\DoNotIndex{\ifhmode,\ifmmode,\ifodd,\ifvmode,\ifx,\fi,\fi,\fi,\fi,\fi}
\DoNotIndex{\immediate,\insert,\item,\jobname,\long}
\DoNotIndex{\let,\lineskip,\marginparsep,\marginparwidth,\maxdimen}
\DoNotIndex{\makeatletter,\noexpand,\openout,\protect,\rlap}
\DoNotIndex{\min,\newpage,\nobreak,\normalbaselineskip}
\DoNotIndex{\normallineskip,\p@,\par,\parfillskip,\parindent,\parskip}
\DoNotIndex{\penalty,\relax,\section,\sin,\sloppy,\space,\string}
\DoNotIndex{\tableofcontents,\the,\thepage,\thispagestyle,\toks,\tt}
\DoNotIndex{\twocolumn,\uppercase,\vbox,\vrule,\vskip,\vss}
\DoNotIndex{\write,\z@,\z@skip}

\setcounter{StandardModuleDepth}{1}

\newcommand*{\email}[1]{$\langle$\texttt{#1}$\rangle$}
\newcommand*{\vdate}[1]{$\langle$#1$\rangle$}
\newcommand*{\bundle}[1]{\texttt{#1}}
\newcommand*{\program}[1]{\textsf{#1}}
\newcommand*{\Ltag}[1]{\texttt{\bslash#1}}
\newcommand*{\Lopt}[1]{\textsf {#1}}
\newcommand*{\Lenv}[1]{\texttt {#1}}
\newcommand*{\cls}[1]{\texttt {#1}}
\newcommand*{\pck}[1]{\texttt {#1}}
\newcommand*{\file}[1]{\texttt {#1}}
\CodelineIndex

\title{A new implementation of \LaTeX's indexing commands}

\author{David M. Jones}

\date{\filedate}

\begin{document}

\DocInput{index.dtx}

\PrintIndex

% ^^A\PrintChanges

\end{document}
%</driver>
% \fi
%
%    \maketitle
%
%    \section{Introduction}
%
%    This style file reimplements \LaTeX's indexing macros to provide
%    better and more robust support for indexes.  In particular, it
%    provides the following features:\footnote{Earlier versions of
%    this package provided a ``shortindexing'' feature (see below for
%    description).  This feature is now deprecated and will be removed
%    in a future release of this package.}
%    \begin{enumerate}
%
%    \item
%    Support for multiple indexes.
%
%    \item
%    Indexing of items by counters other than the page number.
%
%    \item
%    A $*$-variant of the \cs{index} command that, in addition to
%    putting it's argument in the index, also typesets it in the
%    running text.
%
%    \item
%    The \bundle{showidx} style option has been merged into this file.
%    The command \cs{proofmodetrue} can be used to enable the printing
%    of index entries in the margin of pages.  The size and style of
%    font can be controlled with the \cs{indexproofstyle} command.
%
%    \item
%    A two-stage process, similar to that used to create tables of
%    contents, for creating the raw index files.  This means that when
%    processing a portion of a document using the \cs{includeonly}
%    command, the index entries from the rest of the document are not
%    lost.
%
%    \item
%    A more robust \cs{index} command.  In particular, it no longer
%    depends on \cs{catcode} changes to work properly, so the new
%    \cs{index} command can be used in places that the original
%    couldn't, such as inside the arguments of other macros.
%
%    \end{enumerate}
%
%
%    \section{Creating an index with \LaTeX}
%
%    Conceptually, there are four stages to creating an index.  First,
%    \LaTeX\ must be informed of your intention to include an index in
%    your document.  Second, you must add appropriate markup commands
%    to your document to tell \LaTeX\ what to put in the index.
%    Third, after \LaTeX\ has been run on your document, the raw index
%    information must be processed and turned into a form that \LaTeX\
%    can process to typeset the index.  Finally, the finished index
%    must be inserted at the appropriate point in your document.
%
%    In \LaTeX, these steps are accomplished with the commands
%    \cs{makeindex}, \cs{index}, \cs{printindex}, and (typically) with
%    the auxiliary program \program{MakeIndex}.  For example, assuming
%    that your main file is called \file{foo.tex}, \cs{makeindex}
%    opens the file \file{foo.idx} and initializes it for holding the
%    raw index entries, and \cs{index} is used to add raw index
%    entries into \file{foo.idx}.  Then the raw index file is
%    processed by \program{MakeIndex}, which puts the finished index
%    in \file{foo.ind}.  Finally, the \cs{printindex} command is used
%    in your \LaTeX\ document to indicate where the file
%    \file{foo.idx} should be inserted, i.e., where the index should
%    appear in your document.
%
%    The \bundle{index} package modifies the \cs{makeindex},
%    \cs{index}, and \cs{printindex} commands, as described below.
%
%
%    \section{The user interface}
%
%    There are four pieces of information associated with each index:
%    \begin{enumerate}
%
%    \item
%    A short, unique tag that identifies the index.
%
%    \item
%    The extension of the output file where the raw index information
%    will be put by \LaTeX.
%
%    \item
%    The extension of the input file where the processed information
%    created by \program{MakeIndex} will be stored to be read in later
%    by \LaTeX.
%
%    \item
%    The title of the index.
%
%    \end{enumerate}
%
%    \DescribeMacro{\newindex}
%    Correspondingly, the \cs{newindex} command has four required
%    arguments.  For example, to declare an author index, you might
%    use the following:
%    \begin{verbatim}
%    \newindex{aut}{adx}{and}{Name Index}\end{verbatim}
%    Here, \texttt{aut} is the tag used to identify the author index,
%    and ``Name Index'' is the title of the index.  If the name of
%    your main file is \file{root.tex}, then \LaTeX\ will write the
%    raw index entries to the file \file{root.adx}, and you will
%    execute the following \program{MakeIndex} command to process the
%    author index:
%    \begin{verbatim}
%    makeindex -o root.and root.adx\end{verbatim}
%
%    By default, the \cs{index} tags its argument with the page number
%    (i.e., the value of \cs{thepage}), but occasionaly you may want
%    to index items according to a different counter.  For example,
%    you may want an index that contains figure numbers instead of
%    page numbers.  To accomodate, this, the \cs{newindex} command
%    takes an optional argument, which is the name of the command that
%    generates the number that should be included in the index.  For
%    instance, to include the number of a figure, you might say
%    \begin{verbatim}
%    \newindex[thefigure]{fig}{fdx}{fnd}{Figures}\end{verbatim}
%
%    However, this introduces a new technicality: When creating an
%    index with page numbers, the choice of which page number is to be
%    written to the \texttt{aux} file should be deferred until the
%    page containing the entry is shipped out to the \texttt{dvi}
%    file, otherwise the wrong number will sometimes be chosen.
%    However, when using counters other than the page counter, one
%    normally wants the opposite behaviour: the number written to the
%    \texttt{aux} file should be chosen immediately, otherwise every
%    item on a given page will be tagged with the number of the last
%    item on that page.  So, when a counter is specified using the
%    optional argument of \cs{newindex}, it is assumed that the
%    counter should be evaluated immediately.  If for some reason you
%    need the choice to be deferred until the page is written to the
%    \texttt{dvi} file, you can force this behaviour by putting a $*$
%    {\em after\/} the optional argument:
%    \begin{verbatim}
%    \newindex[thefigure]*{fig}{fdx}{fnd}{Figures}\end{verbatim}
%    (One consequence of this scheme is that if, for some reason, you
%    need the choice of page number to be made immediately instead of
%    being deferred until a page is shipped out to the \texttt{dvi}
%    file, you can acomplish this by beginning your index declaration
%    with
%    \begin{verbatim}
%    \newindex[thepage]*\end{verbatim}
%
%
%    \DescribeMacro{\renewindex}
%    The \cs{renewindex} command takes the same arguments as the
%    \cs{newindex} command and can be used to redefine indexes that
%    have been previously declared.
%
%
%    \DescribeMacro{\makeindex}
%    For backwards compatibility, the \cs{makeindex} command is
%    redefined to use \cs{newindex}.  It is essentially equivalent to
%    \begin{verbatim}
%    \newindex{default}{idx}{ind}{Index}\end{verbatim}
%    The index labeled \texttt{default} is special: it is the one that
%    will be used by \cs{index} and \cs{printindex} unless another
%    index is specified (see below).
%
%
%    \DescribeMacro{\printindex}
%    The \cs{printindex} command is modified by the addition of an
%    optional argument, which is the tag of the index that should be
%    printed.
%
%
%    \DescribeMacro{\index}
%    The \cs{index} command is modified in two ways.  First, there is
%    a $*$-variant of the command that, in addition to putting its
%    argument into an index, also typesets it on the page.  Second,
%    \cs{index} now takes an optional argument to indicate which index
%    the new entry should be added to.  If given, the optional
%    argument should be the identifying tag of a previously-defined
%    index.  If no such tag is supplied, the \texttt{default} index
%    (such as that opened by \cs{makeindex} above) is used.
%
%
%    \DescribeMacro{\shortindexingon}
%    \DescribeMacro{\shortindexingoff}
%    Perhaps the most dubious feature of \bundle{index.sty} is that it
%    allows you to define the characters |^| and |_| to be
%    abbreviations for \cs{index*} and \cs{index} outside of math
%    mode.  These abbreviations are enabled by the
%    \cs{shortindexingon} command and disabled by the
%    \cs{shortindexingoff} command.  The scope of both of these latter
%    commands is local to the current group.  (This might be useful,
%    for example, if you wanted the abbreviations turned on throughout
%    most of the documentation, but turned off in one particular
%    environment.)  In addition,
%    \DescribeEnv{shortindexingon}\Lenv{shortindexingon} can be used
%    as an environment if that seems appropriate.  \textbf{Warning:
%    This feature is deprecated and will disappear in a future release
%    of this package.}
%
%
%    \DescribeMacro{\proofmodetrue}
%    \DescribeMacro{\proofmodefalse}
%    \DescribeMacro{\indexproofstyle}
%    As mentioned above, the \bundle{showidx} document-style option
%    has been merged into \bundle{index.sty}.  It can be turned on
%    with \cs{proofmodetrue} and turned off with \cs{proofmodefalse}.
%    When it is turned on, all index entries\footnote{Well, most, at
%    least.  There are some circumstances under which the index
%    entries won't show up in the proofs, although they will show up
%    in the index.} will be put in the margin of the page where they
%    appear.  By default, they appear in the typewriter font at
%    \cs{footnotesize}, but the user can override this with the
%    \cs{indexproofstyle} command; for example,
%    \begin{verbatim}
%    \indexproofstyle{\footnotesize\it}\end{verbatim}
%    will cause them to be put in italics instead.
%
%
%    \DescribeMacro{\disableindex}
%    There are some circumstances where it might be helpful to
%    suppress the writing of a particular index.  The
%    \cs{disableindex} command is provided for this purpose.  It takes
%    one argument, a comma-separated list of tags of the indexes that
%    should be disabled.  This command should come {\em before\/} the
%    declarations for the indexes that are being
%    disabled\footnote{This limits its usefulness somewhat, but since
%    the output file for an index is opened when the index is
%    declared, the damage has already been done.  We could close the
%    file, but we can't prevent a new output stream from being
%    allocated and we can't keep the old file from being truncated.}.
%    One situation where the \cs{disableindex} command might be useful
%    is if there are so many indexes that you are exhausting \TeX's
%    supply of output streams\footnote{\TeX\ only has 16 output
%    streams, which are allocated with the {\tt\string\newwrite}
%    command.  The standard \LaTeX\ styles use from 3 to 7 of these,
%    which should leave room for up to 9 indexes.  Of course, if you
%    have extra output files, then there will be fewer output streams
%    left for indexes.}.  For example, suppose you have 10 indexes,
%    but only 5 output streams available for indexes.  Then you could
%    add a \cs{disableindex} command to the top of your file to
%    suppress the writing of all but 5 of the indexes.  (Note that the
%    index entries would still get written to the \texttt{aux} file;
%    they just wouldn't get copied to the individual raw index files
%    at the end of the run.)  At the end of the run, you could then
%    re-run your main file a couple of times with different indexes
%    disabled until you had created all of the raw index files.  This
%    is somewhat clumsy, but safer than any alternative I've come up
%    with\footnote{A less clumsy (for the user, at least) solution
%    would be to read the \texttt{aux} file multiple times at the end
%    of the run, each time writing just one of the raw index files.
%    The main disadvantage of this scheme at present is that it would
%    require a modification of {\tt\string\enddocument}.}.
%
%
%    \section{Caveats}
%
%    In order to implement this style file, it's been necessary to
%    modify a number of \LaTeX\ commands seemingly unrelated to
%    indexing, namely, \cs{@starttoc}, \cs{raggedbottom},
%    \cs{flushbottom}, and \cs{addcontents}.  Naturally, this could
%    cause incompatibilities
%    between \bundle{index.sty} and any style files that either
%    redefine these same commands or make specific assumptions about
%    how they operate.  See Section~\ref{sec:thecode} for explanations
%    of why these various commands needed modification.
%
%    The redefinition of \cs{@starttoc} is particularly bad, since it
%    introduces an incompatibility with the AMS document classes.
%    This will be addressed soon.
%
%    Unfortunately, it's also been necessary to modify the
%    \Lenv{theindex} environment, so if you don't like the default
%    \LaTeX\ definition, you'll need copy the definition of
%    \Lenv{theindex} from this file and modify it appropriately.
%
%    In the current implementation, \bundle{index.sty} uses one output
%    stream for each index.  Since there are a limited number of
%    output indexes, this means that there is a limit on the number of
%    indexes you can have in a document.  See the description of
%    \cs{disableindex} for a fuller discussion of this problem and one
%    way around it.
%
%
%    \section{To do's}
%
%    It might be nice if the \cs{index*} command parsed its argument
%    so that, for example, instead of writing
%    `|\index{sin@$\sin$}$\sin$|', one could write
%    `|index*{sin@$\sin$}|'.  However, this is fraught with numerous
%    dangers, and I'm both too lazy and too cowardly to undertake it
%    now.
%
%    It would be reasonable to add support for \cs{makeglossary} and
%    similar things, if they were well-defined enough to decide what
%    the general syntax for defining them should be.
%
%    The documentation should be carefully read, edited, and finished,
%    especially since it's still based on the 2.09 version, even
%    though a few substantial changes have been made for the \LaTeXe\
%    version.
%
%    For some truly outlandish ideas, see the file \file{TODO} in the
%    distribution.
%
%    \StopEventually{}
%
%    \section{The code}
%    \label{sec:thecode}
%
%    As is customary, identify this as a \LaTeXe\ package.
%    \begin{macrocode}
%<*style>
\NeedsTeXFormat{LaTeX2e}[2024/11/01]

\ProvidesPackage{index}[2025/02/06 v4.04 Improved index support (dmj)]
%    \end{macrocode}
%
%    \begin{macro}{\disableindex}
%    The \cs{disableindex} should come before the declarations of the
%    indexes it refers to.  (Question: If an index has been disabled,
%    should it show up in index proofs?  Maybe there should be a
%    separate command to disable index proofs on and index-by-index
%    basis.)
%    \begin{macrocode}
\def\disableindex#1{%
    \@for\@tempa:=#1\do{%
        \@namedef{disable@\@tempa}{}%
        \@ifundefined{tf@\@tempa}{}{%
            \PackageWarningNoLine{index}{It's too late to disable
                the `\@tempa' index;\MessageBreak
                \jobname.\@tempa\space has already
                been opened for output. You \MessageBreak
                should put the \string\disableindex\space command
                before\MessageBreak
                the declaration of the `\@tempa' index}%
        }%
    }%
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\if@newindex}
%    \begin{macro}{\newindex}
%    \begin{macro}{\renewindex}
%    The \cs{newindex} and \cs{renewindex} commands are defined on
%    analogy with the \cs{[re]newcommand} macros.  Each index is
%    identified by a unique tag, which is specified in the first
%    required argument of \cs{newindex}.  Much of the information
%    about the index labeled \meta{tag} is kept in the macro
%    \cs{idx@}\meta{tag}, so we can check to see if a particular index
%    has already been defined by checking whether \cs{idx@}\meta{tag}
%    is defined.  \cs{newindex} and \cs{renewindex} both check to see
%    if their first argument is already associated with an index and
%    then either issue an appropriate error message or call
%    \cs{def@index}.
%
%    The \cs{if@newindex} flag will be used to keep \cs{renewindex}
%    from re-allocating \cs{write} and \cs{toks} registers later.  The
%    \cs{if@tempswa} switch will be used to determine whether the
%    \cs{write}s for this index should be done \cs{immediate}ly or
%    not.
%    \begin{macrocode}
\newif\if@newindex

\def\newindex{%
    \@tempswafalse
    \@ifnextchar[{\@tempswatrue\x@newindex}{\x@newindex[thepage]}%
}

\def\x@newindex[#1]{%
    \@ifstar {\@tempswafalse\y@newindex{#1}}
             {\y@newindex{#1}}%
}

\def\y@newindex#1#2{%
    \@ifundefined{idx@#2}%
        {\@newindextrue\def@index{#1}{#2}}%
        {%
            \@latexerr{Index type `\string#2' already defined}\@ehc
            \expandafter\@gobble\@gobbletwo
        }%
}

\def\renewindex{%
    \@tempswafalse
    \@ifnextchar[{\@tempswatrue\x@renewindex}{\x@renewindex[thepage]}%
}

\def\x@renewindex[#1]{%
    \@ifstar {\@tempswafalse\y@renewindex{#1}}
             {\y@renewindex{#1}}%
}

\def\y@renewindex#1#2{%
    \@ifundefined{idx@#2}%
        {%
            \@newindextrue
            \@latexerr{Index type `\string#2' not defined}\@ehc
        }%
        {\@newindexfalse}%
    \def@index{#1}{#2}%
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    \begin{macro}{\@preamblecmds}
%    Neither \cs{newindex}, \cs{renewindex}, nor \cs{disableindex}
%    should be used anywhere except inside style files or in the
%    preamble of a document, so we add them to the \cs{@preamblecmds}
%    list.
%    \begin{macrocode}
\@onlypreamble\newindex
\@onlypreamble\renewindex
\@onlypreamble\disableindex
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\def@index}
%    \cs{def@index} does most of the work.  First, it picks up the
%    first three arguments of the \cs{[re]newindex} command and stores
%    the second two in an appropriate \cs{idx@} macro.  The title of
%    the index is treated differently, however, since it is
%    potentially fragile in a particularly odd way.  To prevent
%    mishaps, it is stored in a token register.  In addition to
%    stashing away the information about the index, \cs{def@index}
%    also opens an appropriate output file if we are writing auxiliary
%    files (i.e., unless \cs{nofiles} is in effect).
%
%    \begin{macrocode}
\def\def@index#1#2#3#4{%
    \@namedef{idx@#2}{#3:#4:#1}%
    \expandafter\let\csname if@immediate@#2\endcsname\if@tempswa
    \if@filesw
        \if@newindex
            \expandafter\newtoks\csname idxtitle@#2\endcsname
        \fi
        \@ifundefined{disable@#2}{%
            \if@newindex
                \expandafter\newwrite\csname tf@#2\endcsname
            \else
                \immediate\closeout\@nameuse{tf@#2}%
            \fi
            \immediate\openout\@nameuse{tf@#2}\jobname.#3 %
            \PackageInfo{index}{Writing index file \jobname.#3}%
        }
        {\PackageInfo{index}{Index `#2' disabled -- not opening
                      \jobname.#3}}%
    \fi
    \expandafter\csname idxtitle@#2\endcsname
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\@first}
%    \begin{macro}{\@second}
%    \begin{macro}{\@third}
%    These are useful macros for retrieving individual components
%    of an index specification.
%    \begin{macrocode}
\def\@first#1:#2:#3\@nil{#1}

\def\@second#1:#2:#3\@nil{#2}

\def\@third#1:#2:#3\@nil{#3}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    \begin{macro}{\@nearverbatim}
%    |\@nearverbatim\foo| is much like |\meaning\foo|,
%    except that it suppresses the ``\texttt{macro ->}'' string
%    produced when \cs{meaning} expands a macro.  It is used by
%    \cs{@wrindex} to produce an ``almost verbatim'' copy of their
%    arguments.  This method replaces the use of \cs{@sanitize} from
%    latex.tex and allows indexing macros to be used in places (such
%    as inside macro arguments) where the original \cs{index} command
%    could not.  Thanks to Donald Arseneau
%    \email{asnd@erich.triumf.ca} for pointing out this trick to me.
%    (For more information on this trick, see Dirty Trick \#3 of the
%    \TeX book, page 382).
%
%    As defined, \@nearverbatim only works on macros.  It would be
%    nice if it could work with other tokens, but it's more important
%    that it work only by expansion, which means we can't put in tests
%    to see what the next token is.
%    \begin{macrocode}
\def\@nearverbatim{\expandafter\strip@prefix\meaning}
%    \end{macrocode}
%    \end{macro}
%
%    Now we define the \cs{index} macro itself.  The following
%    definitions are adapted from \bundle{latex.tex} v2.09 \vdate{25
%    March 1992}.
%
%    \begin{macro}{\makeindex}
%    First we redefine \cs{makeindex} to define the default index
%    using \cs{newindex}.  We use \cs{edef} to make sure that
%    \cs{indexname} gets expanded here.  Otherwise we'll get into an
%    infinite loop later on when we try to redefine \cs{indexname}
%    inside the \cs{theindex} environment.
%
%    Unfortunately, this means that if the user changes \cs{indexname}
%    in the preamble, the index will come out with the wrong heading.
%    \begin{macrocode}
\edef\makeindex{%
    \noexpand\newindex{default}{idx}{ind}{\indexname}%
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\if@silentindex}
%    \begin{macro}{\if@addtoindex}
%    \begin{macro}{\if@proofmode}
%    We need three new flags.  The first, \cs{if@silentindex},
%    indicates whether the entry should be typeset in running text, as
%    well as written out to the index; this is used to implement the
%    \cs{index*} command.  The second, \cs{if@addtoindex}, indicates
%    whether entries should be written to the index; this is used to
%    disable the \cs{index} command inside of page headings and tables
%    of contents.  The third, \cs{ifproofmode}, indicates whether
%    index entries should be put in the margin of the page for
%    proofing purposes.
%    \begin{macrocode}
\newif\if@silentindex\@silentindextrue

\newif\if@addtoindex\@addtoindextrue

\newif\ifproofmode\proofmodefalse
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    \begin{macro}{\index}
%    \begin{macro}{\p@index}
%    \begin{macro}{\x@index}
%    \cs{index} will be made self-protecting (a la \cs{em}, etc.) so
%    it can be used inside, for example, sectioning commands.
%    Unfortunately, to really make \cs{index} robust, we have to
%    redefine some of \LaTeX's commands for dealing with tables of
%    contents and page headings.  (See below.) $*$sigh$*$
%    \begin{macrocode}
\protected\def\index{\protect\p@index}

\def\p@index{%
    \if@silentindex\@bsphack\fi
    \@ifstar{\@silentindexfalse\@xindex}{\@silentindextrue\@xindex}%
}

\def\@xindex{\@ifnextchar[{\@index}{\@index[default]}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    \begin{macro}{\@index}
%    \begin{macro}{\@@index}
%    \begin{macro}{\@wrindex}
%    The following is much more complicated than it should have to be.
%    First, note the check to see if \cs{index} is equal to
%    \cs{@gobble}.  This is so I don't have to redefine
%    \cs{@outputpage}, which temporarily disables \cs{label},
%    \cs{index}, and \cs{glossary} by \cs{let}'ing them equal to
%    \cs{@gobble}.  (For this reason, we have to be very careful to
%    make sure that \cs{index} has expanded to \cs{p@index} before it
%    gets to \cs{@outputpage}.)  Second, note that if
%    \cs{if@addtoindex} is false, we don't complain about undefined
%    index types.  This is because if your page headings, for example,
%    are being typeset in all uppercase, you might end up with
%    something like \cs{index[AUT]{...}} instead of
%    \cs{index[aut]{...}}.
%    \begin{macrocode}
\def\@index[#1]{%
    \ifx\index\@gobble
        \@addtoindexfalse
    \fi
    \def\@tempf{%
        \begingroup
            \@sanitize
            \@@index{#1}%
    }%
    \if@addtoindex
        \@ifundefined{idx@#1}%
            {%
              \def\@tempf{%
                  \@latexerr{Index type `\string#1' undefined}%
                  \@ehc
                  \@silentindextrue
                  \@gobble
              }%
            }%
            {}%
    \fi
    \@tempf
}

\def\@@index#1#2{%
    \endgroup
    \if@addtoindex
        \if@filesw\@wrindex{#1}{#2}\fi
        \ifproofmode\@showidx{#2}\fi
    \fi
    \if@silentindex
        \expandafter\@esphack
    \else
        \@silentindextrue#2%
    \fi
}

\def\@wrindex#1#2{%
    \begingroup
        \def\@tempa{#2}%
        \edef\@tempb{\@nameuse{idx@#1}}%
        \edef\@tempb{\expandafter\@third\@tempb\@nil}%
        \csname if@immediate@#1\endcsname \else
            \expandafter\let\csname\@tempb\endcsname\relax
        \fi
        \edef\@tempa{%
           \write\@auxout{%
              \string\@writefile{#1}{%
                  \string\indexentry{\@nearverbatim\@tempa}%
                                    {\@nameuse{\@tempb}}%
              }%
           }%
        }%
    \expandafter\endgroup\@tempa
    \if@nobreak\ifvmode\nobreak\fi\fi
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    \begin{macro}{\seename}
%    \begin{macro}{\see}
%    \begin{macro}{\printindex}
%    \begin{macro}{\@printindex}
%    The following are adapted from \bundle{makeidx.sty}, v2.09
%    \vdate{21 Oct 91}.  \cs{index@prologue} adapted from
%    \bundle{doc.dtx}.  \Lenv{theindex} based on version from
%    \bundle{classes.dtx}, v1.3g, 26 June 1995.
%    \begin{macrocode}
\providecommand{\seename}{see}

\providecommand*{\see}[2]{\emph{\seename} #1}

\@ifclassloaded{article}{%

    \renewenvironment{theindex}{%
        \edef\indexname{\the\@nameuse{idxtitle@\@indextype}}%
        \if@twocolumn
            \@restonecolfalse
        \else
            \@restonecoltrue
        \fi
        \columnseprule \z@
        \columnsep 35\p@
        \twocolumn[%
            \section*{\indexname}%
            \ifx\index@prologue\@empty\else
                \index@prologue
                \bigskip
            \fi
        ]%
        \@mkboth{\MakeUppercase\indexname}%
                {\MakeUppercase\indexname}%
        \thispagestyle{plain}%
        \parindent\z@
        \parskip\z@ \@plus .3\p@\relax
        \let\item\@idxitem
    }{%
        \if@restonecol
            \onecolumn
        \else
            \clearpage
        \fi
    }
}{%
    \renewenvironment{theindex}{%
        \edef\indexname{\the\@nameuse{idxtitle@\@indextype}}%
        \if@twocolumn
            \@restonecolfalse
        \else
            \@restonecoltrue
        \fi
        \columnseprule \z@
        \columnsep 35\p@
        \twocolumn[%
            \@makeschapterhead{\indexname}%
            \ifx\index@prologue\@empty\else
                \index@prologue
                \bigskip
            \fi
        ]%
        \@mkboth{\MakeUppercase\indexname}%
                {\MakeUppercase\indexname}%
        \thispagestyle{plain}%
        \parindent\z@
        \parskip\z@ \@plus .3\p@\relax
        \let\item\@idxitem
    }{%
        \if@restonecol
            \onecolumn
        \else
            \clearpage
        \fi
    }
}

\def\printindex{\@ifnextchar[{\@printindex}{\@printindex[default]}}

\def\@printindex[#1]{%
    \@ifnextchar[{\@print@index[#1]}{\@print@index[#1][]}%
}

\long\def\@print@index[#1][#2]{%
    \def\@indextype{#1}%
    \long\def\index@prologue{#2}%
    \@ifundefined{idx@#1}%
        {\@latexerr{Index type `\string#1' undefined}\@ehc}%
        {%
            \edef\@tempa{\@nameuse{idx@#1}}%
            \edef\@tempb{%
                \jobname.\expandafter\@second\@tempa\@nil
            }%
            \edef\@tempc{%
                \jobname.\expandafter\@first\@tempa\@nil
            }%
            \InputIfFileExists{\@tempb}{}{%
                \typeout{No file \@tempb: Run makeindex -o
                    \@tempb \space \@tempc}%
            }%
        }%
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    \begin{macro}{\@indexstar@}
%    Now we set things up for
%    \cs{shortindexing}.\footnote{\textbf{Warning:} This feature is
%    deprecated and will be removed entirely in a future release of
%    this package.} First, we define a one-token shorthand for
%    \cs{index*}.  This will be needed in the definition of
%    \cs{idx@activehat}.
%    \begin{macrocode}
\def\@indexstar@{\index*}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\idx@activehat}
%    \begin{macro}{\idx@activebar}
%    Next, we define the values that |^| and |_| will have when
%    shortindexing is turned on.
%    \begin{macrocode}
\def\idx@activehat{%
    \relax
    \ifmmode\expandafter\sp\else\expandafter\@indexstar@\fi
}

\def\idx@activebar{%
    \relax
    \ifmmode\expandafter\sb\else\expandafter\index\fi
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%
%    \begin{macro}{\shortindexingon}
%    \begin{macro}{\shortindexingoff}
%    Now we define the \cs{shortindexingon} and \cs{shortindexinoff}
%    commands to turn shortindexing on and off (surprise!).
%    \cs{shortindexingon} saves the old definitions and \cs{catcode}'s
%    of |^| and |_| so they can later be restored by
%    \cs{shortindexingoff}.  Both of these make their changes local to
%    any enclosing group, so they can be used as declarations to
%    disable or enable shortindexing temporarily.  In addition,
%    \Lenv{shortindexingon} can also be used as an environment.
%
%    This is potentially very confusing.  My basic rationale (if it
%    can be described as such) was that under normal circumstances,
%    one would put \cs{shortindexingon} in the preamble of one's
%    document, and never want to turn it off.  \cs{shortindexingoff}
%    is an attempt to make allowance for the contingency that someone
%    might want to turn shortindexing off, either permanently or
%    temporarily.
%    \begin{macrocode}
\newif\if@shortindexing

\begingroup

    \catcode`\^\active
    \catcode`\_\active

    \gdef\shortindexingon{%
        \@shortindexingtrue
        \chardef\old@idxhatcode\catcode`\^\relax
        \chardef\old@idxbarcode\catcode`\_\relax
        \catcode`\^\active
        \catcode`\_\active
        \let\old@idxhat ^%
        \let\old@idxbar _%
        \let^\idx@activehat
        \let_\idx@activebar
    }

    \gdef\shortindexingoff{%
        \if@shortindexing
            \@shortindexingfalse
            \let^\old@idxhat
            \let_\old@idxbar
            \catcode`\^\old@idxhatcode
            \catcode`\_\old@idxbarcode
        \fi
    }

\endgroup
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%
%    Now we take some code from \bundle{showidx.sty} and merge it into
%    our new system.  There are four reasons for redefining the
%    commands here rather than just inputting \bundle{showidx.sty} (or
%    requiring the user to do so).  First, \bundle{showidx.sty} ends
%    with a call to \cs{flushbottom}, which I want to avoid.  Second,
%    the instructions for successfully using \bundle{showidx.sty}
%    along with \bundle{index.sty} would be somewhat tricky.  This
%    way, I can just tell users not to use \bundle{showidx.sty} at
%    all.  Third, I need to make some alterations to \cs{@showidx}
%    anyway.  In particular, (a) I need to add the \cs{@sanitizeat}
%    command so this works correctly with AMS-\LaTeX\ and (b) I want
%    to add the \cs{indexproofstyle} command so the user can customize
%    the size and font used for the index proofs.  Finally,
%    \bundle{showidx.sty} has at least two annoying bugs in it.  See
%    the edit-history for version 2.01 for a description.
%
%    \begin{macro}{\@indexbox}
%    This code is adapted from \bundle{showidx.sty}, v2.09 \vdate{16
%    Jun 1991}.
%    \begin{macrocode}
\newinsert\@indexbox

\dimen\@indexbox\maxdimen
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\@sanitizeat}
%    The definition of \cs{@sanitizeat} is slightly tricky, since we
%    need |@| to be active when this macro is defined, but we also
%    need it to be part of the control sequence name.
%    \begin{macrocode}
\begingroup
    \catcode`\@\active
    \expandafter\gdef\csname\string @sanitizeat\endcsname
        {\def @{\char`\@}}
\endgroup
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\indexproofstyle}
%    \begin{macro}{\@showidx}
%    \begin{macro}{\@leftidx}
%    \begin{macro}{\@rightidx}
%    \begin{macro}{\@mkidx}
%    \begin{macro}{\raggedbottom}
%    \begin{macro}{\flushbottom}
%    \begin{macro}{\@texttop}
%    \begin{macrocode}
\newtoks\indexproofstyle

\indexproofstyle{\footnotesize\reset@font\ttfamily}

\def\@showidx#1{%
    \insert\@indexbox{%
        \@sanitizeat
        \the\indexproofstyle
        \hsize\marginparwidth
        \hangindent\marginparsep \parindent\z@
        \everypar{}\let\par\@@par \parfillskip\@flushglue
        \lineskip\normallineskip
        \baselineskip .8\normalbaselineskip\sloppy
        \raggedright \leavevmode
        \vrule \@height .7\normalbaselineskip \@width \z@\relax#1\relax
        \vrule \@height\z@ \@depth.3\normalbaselineskip \@width\z@\relax
    }%
    \ifhmode\penalty\@M \hskip\z@skip\fi
}

\def\@leftidx{\hskip-\marginparsep \hskip-\marginparwidth}

\def\@rightidx{\hskip\columnwidth \hskip\marginparsep}

\def\@mkidx{%
    \vbox to \z@{%
        \rlap{%
            \if@twocolumn
                \if@firstcolumn \@leftidx \else \@rightidx \fi
            \else
                \if@twoside
                    \ifodd\c@page \@rightidx \else \@leftidx \fi
                \else
                    \@rightidx
                \fi
            \fi
            \box\@indexbox
        }%
        \vss
    }%
}

\def\raggedbottom{%
    \def\@textbottom{\vskip\z@ plus.0001fil}%
    \let\@texttop\@mkidx
}

\def\flushbottom{\let\@textbottom\relax \let\@texttop\@mkidx}

\let\@texttop\@mkidx
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    Now, this next bit really gets up my nose.  The only way to make
%    sure that the \cs{index} command gets handled correctly when used
%    inside of sectioning commands is to redefine a bunch of \LaTeX's
%    table of contents and running-heads macros. $*$blech$*$ Fragility
%    rears its ugly head again.
%
%    These are based on \bundle{latex.tex} 2.09 \vdate{25 March 1992}.
%
%    \begin{macro}{\addcontentsline}
%    We need to redefine \cs{addcontentsline} to keep it from
%    expanding \cs{index} commands too far.  In particular, we have
%    removed \cs{index} from the list of macros that are set equal to
%    \cs{@gobble} and we substitute \cs{@vwritefile} for
%    \cs{@writefile}.  This latter change also means that we can
%    simplify the definition of \cs{protect} somewhat.
%    \begin{macrocode}
\CheckCommand\addtocontents[2]{%
  \protected@write\@auxout
      {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
      {\string\@writefile{#1}{#2}}%
}

\renewcommand{\addtocontents}[2]{%
    \protected@write\@auxout
      {\let\label\@gobble \let\glossary\@gobble}%
      {\string\@writefile{#1}{#2}}%
}
%    \end{macrocode}
%    \end{macro}
%
%    \begin{macro}{\@starttoc}
%    We need to redefine \cs{@starttoc} to \cs{@addtoindexfalse} so
%    that items don't get written to the index from within tables of
%    contents.  The only change here is the addition of
%    \cs{@addtoindexfalse}.
%
%    Unfortunately, this will break pretty badly with the AMS document
%    classes, since they redefine \cs{@starttoc} to take two arguments
%    rather than one.  This must be addressed.
%
%    \begin{macrocode}
\let\old@starttoc\@starttoc

\renewcommand{\@starttoc}[1]{%
    \begingroup
        \@addtoindexfalse
        \old@starttoc{#1}%
    \endgroup
}
%    \end{macrocode}
%    \end{macro}
%
%    \section{Finale}
%
%    The usual \cs{endinput} to ensure that random garbage at the end of
%    the file doesn't get copied by \texttt{docstrip}.
%    \begin{macrocode}
\endinput
%    \end{macrocode}
%
%    \section{Edit history}
%
%    \begin{description}
%
%    \item[v1.00 (4 Mar 1993)]
%    initial version, posted to comp.text.tex.
%
%    \item[v1.01 (4 Mar 1993)]
%    added \cs{renewindex} command and checking to make sure index is
%    (or is not) defined in \cs{newindex}, \cs{index} and
%    \cs{printindex}.  Also tightened up the code in various places
%    and added check to make sure file is only loaded once.
%
%    \item[v2.00 (24 Mar 1993)]
%    added support for \cs{index*}, proofmode, \cs{shortindexingon}
%    and \cs{shortindexingoff}.
%
%    \item[v2.01 (24 Jun 1993)]
%    Fixed 3 bugs.  (1) If proofmode was turned on, then something
%    like ``\cs{index{WORD}WORD}'' would suppress the hyphenation of
%    WORD.  This was fixed by adding ``|\penalty\@M\hskip\z@skip|'' to
%    the end of \cs{@showidx}.  (This is just the definition of
%    \cs{allowhyphens} borrowed from \bundle{german.sty}, v2 \vdate{4
%    Nov 1988}).  (2) The \cs{hbox} in \cs{@mkidx} was being set at
%    its natural width, which had a tendency to interfere with the
%    width of the page.  The \cs{hbox} is now replaced by \cs{rlap}.
%    (3) If the title of an index (i.e., the fourth argument of
%    \cs{newindex}) contained a particularly fragile command
%    like~\cs{d}, havoc would ensue when \cs{theindex} tried to
%    extract the title.  Titles are now kept in token registers to
%    prevent such unpleasantness.  Bugs (2) and (3) were reported by
%    Dominik Wujastyk \email{D.Wujastyk@ucl.ac.uk} on 24 June 1993.
%    Note that bugs (1) and (2) are actually bugs in showidx.sty,
%    v2.09 \vdate{16 Jun 1991}.
%
%    \item[v2.02 (25 Jun 1993)]
%    Rewrote the code that implements the short indexing commands (|^|
%    and |_|) to make index.sty compatible with other style files that
%    need to make |^| and |^| active in some contexts.  See the code
%    for more details.
%
%    \item[v2.03 (30 Jun 1993)]
%    Once again rewrote the code that implements the short indexing
%    commands.  Dumped the shortindexing environment and rewrote the
%    \cs{shortindexingon} and \cs{shortindxingoff} commands to save
%    and restore the \cs{catcode}'s and meanings of |^| and |^| in the
%    safest possible (I hope) order.  Also added the
%    \cs{if@shortindexing} flag to keep \cs{shortindexingoff} from
%    doing anything if it is called outside of the scope of a
%    \cs{shortindexingon} command.  (Question: Should
%    \cs{shortindexingon} check that flag before doing anything?)
%
%    \item[v2.04 (beta) (14 Jul 1993)]
%    Added \cs{disableindex} command.  Added \cs{newindex} and
%    \cs{renewindex} to \cs{@preamblecmds}.  Added \cs{if@newindex}
%    flag to \cs{@newindex} to prevent \cs{renewindex} from
%    re-allocating new \cs{write} and \cs{toks} registers.  Rewrote
%    using \bundle{doc.sty} and \program{DocStrip}.  Also cleaned up
%    the code somewhat.
%
%    \item[v3.00 (15 Jul 1993)]
%    Made further minor tweaks to code and internal documentation.
%    Booted version number up to 3.00 and released on the world.
%
%    \item[v3.01 (19 Jul 1993)]
%    Fixed \program{DocStrip} CheckSum.
%
%    \item[v3.02 (15 Sep 1993)]
%    Corrected spelling of \cs{@shortindexingfalse} in definition of
%    \cs{shortindexingoff}.  Thanks to Hendrik G. Seliger
%    \email{hank@Blimp.automat.uni-essen.de} for this bug report.
%    Also added redefinitions of \cs{@leftmark} and \cs{@rightmark} to
%    fix a bug reported by Dominik Wujastyk
%    \email{D.Wujastyk@ucl.ac.uk}.
%
%    \item[v3.03 (beta) (20 Feb 1994)]
%    Added \cs{long} to the definition of \cs{@ifundefined} to cover
%    the unlikely contingency that someone wanted to use, for example,
%    |\string\par| in the middle of a control sequence name.  Added an
%    optional argument to \cs{newindex} to specify which counter to
%    use in place of \cs{thepage}.  The first change was suggested by
%    Martin Schr\"oder \email{l15d@zfn.uni-bremen.de}; the second was
%    suggested independently by Schr\"oder and Stefan Heinrich
%    H\"oning \email{hoening@pool.informatik.rwth-aachen.de}.  The
%    \cs{@newindex} command was renamed \cs{def@index}.  Also fixed
%    the \cs{disableindex} command.
%
%    \item[v3.04 (7 Mar 1994)]
%    Rewrote the user documentation (Sections 1--5) and released on
%    the world.  Also deleted some extraneous spaces that had crept
%    into some macros.
%
%    \item[v4.00beta, (20 Feb 1995)]
%    Preliminary conversion to a native \LaTeXe\ package.  Fixed
%    \cs{@printindex} to work under \LaTeXe\ (bug reported by Carsten
%    Folkertsma \email{cai@butler.fee.uva.nl}).  Removed much code
%    that had been put in to work around various ancient versions of
%    \LaTeX~2.09.  Added \cs{index@prologue} support (modelled on
%    \bundle{doc.sty}) at suggestion of Nick Higham
%    \email{higham@ma.man.ac.uk}.
%
%    \item[v4.01beta (28 Sep 1995)]
%    Rewrote as a \LaTeXe\ package (finally!).  Changes too numerous
%    to list, but in general deleted some now-superfluous code,
%    replaced some tricks by tricks from the \LaTeXe\ kernel, and
%    added some bullet-proofing.  Much still remains to be done, but
%    this should be good enough for testing.
%
%    Changed definition of \cs{protect} in \cs{markright} and
%    \cs{markboth} to fix bug reported by Dominik Wujastyk.
%
%    \item[??? (5 Jan 2004)]
%
% \end{description}

\endinput
