% \iffalse % ==================================================================== % @LaTeX-style-file{ % author = "David M. Jones", % version = "3.02", % date = "15 September 1993", % time = "15:11:39 EDT", % filename = "index.doc", % address = "MIT Laboratory for Computer Science % Room NE43-316 % 545 Technology Square % Cambridge, MA 02139 % USA", % telephone = "(617) 253-5936", % FAX = "(617) 253-3480", % checksum = "61047 1367 6478 49767", % email = "dmjones@theory.lcs.mit.edu", % codetable = "ISO/ASCII", % keywords = "LaTeX, index", % supported = "yes", % docstring = "This is a reimplementation of LaTeX's % indexing macros to provide better support % for indexing in LaTeX. For example, it % supports multiple indexes in a single % document and provides a more robust \index % command. % % The checksum field above contains a CRC-16 % checksum as the first value, followed by % the equivalent of the standard UNIX wc % (word count) utility output of lines, % words, and characters. This is produced % by Robert Solovay's checksum utility.", % % } % ==================================================================== % \fi % % \iffalse % % HOW TO INSTALL THIS FILE: % % If you have the latest versions of DocStrip and doc.sty installed on % your system, type "tex index.doc" to unpack the files index.sty and % sample.tex. Then install index.sty wherever style files belong on % your system and read the comments at the beginning of sample.tex to % see how to run the test. Finally, format the documentation by % executing the following three commands: % % latex index.doc % makeindex -s gind.ist index % latex index.doc % % If you don't already have DocStrip and doc.sty installed on your % system, you should get them from one of the following sources: % % ftp.uni-stuttgart.de:soft/tex/macros/latex/distribs/doc % pip.shsu.edu:tex-archive/macros/latex/distribs/doc % ftp.tex.ac.uk:tex-archive//macros/latex/distribs/doc % % If for some reason you really can't install the doc package on your % system, then you can name this file index.sty and use it as a style % file. However, you will likely notice some slowness in loading this % file, due to the large number of comments that have to be skipped % over. % % CAUTION: Use only as directed. Do not take internally. May cause % rash if applied directly to skin. Federal law prohibits % distributing without a proscription. % % __ __ % / \ / \ % / \ / \ % / \ \ / \ \ % / ) \ / ) \ % \ ( / \ ( / % \ \ / \ \ / % \ / \ / % \__/ \__/ % || || % || || % ------ ------ % % Now the real fun starts. This file is designed to serve 4 (or 5, if % you prefer) distinct functions: % % (1) In the absence of DocStrip, it can be named index.sty and used % as a LaTeX style file. % % (2) It is a DocStrip batch file that can be used to unpack index.sty % and sample.tex. This function is triggered when the file is used as % an input file for plain TeX, i.e., when the command "tex index.doc" % is executed. % % (3) It is the driver file for the documentation of index.sty. This % function is triggered when the file is used as an input file for % LaTeX, i.e., when the command "latex index.doc" is executed. % % (4) It is the source file for steps 2 and 3. % % To make this work, we have to be able to determine which of these % cases we are in and take appropriate action. % % The next few lines of code accomplish this. First, note that if % this file is used as input to the doc.sty \DocInput command, then % the \iffalse ... \fi will cause this code to be ignored. Similarly, % the guard prevents this code from being copied into any % output files by DocStrip. % % Next comes the more interesting code. We need two auxiliary % commands to make sure that the correct commands get executed at the % correct time. In order to avoid impinging on the user's namespace, % I use two macro names from index.sty. % % \proofmodetrue: This is a no-op, unless we are producing % documentation (i.e., the user has typed "latex index.doc"), in % which case it expands to the appropriate initialization code, % namely a \documentstyle command, plus \MakePercentIgnore to set % things up for doc.sty, and a call to \csname iffalse\endcsname % to match the fi that follows. (The earlier iffalse was ignored % because when that line was read, % was still a comment character % and not an ignored character.) % % \renewindex: This eats its argument unless this file is being used % as a DocStrip batchfile (i.e., the user has typed "tex % index.doc"), in which case it simply regurgitates its argument. % The commands inside the \renewindex commands are just normal % DocStrip batchfile commands. % % Before doing anything else, we check to make sure that \newindex is % not already defined. If it is, that means this file has already % been loaded once as a style file (or else someone else has already % defined a \newindex command), which means we should not load the % file a second time. (This is the same test that will be used later % to determine whether or not index.sty has already been loaded. So, % if you are using index.doc as index.sty, this test will actually be % made twice, but that should be ok.) % % Finally, we determine whether we are inside plain TeX or LaTeX by % checking to see if \documentstyle is defined. If we are inside % LaTeX, we check to see if we are being used as a style file or a % documentation file by checking to see if the \catcode of @ is 11 % (letter) or not. % % The braces around the first two blocks of code below are necessary % because DocStrip will open this file and start reading it % line-by-line. The braces ensure that the entire \ifx ... \fi % structures are picked up at once. % % No doubt strange and terrible things will happen if you feed this % file to any dialect of TeX other than plain TeX or LaTeX. % % The blame for much of the following code goes to David Wald % , who forced me to adopt this approach % after I had already come up with a safer alternative that was almost % as easy to unpack. If anything goes wrong, it's his fault. % % \fi % % \iffalse %<*install> {\expandafter\ifx\csname newindex\endcsname\relax\else\endinput\fi} { \global\let\proofmodetrue\relax \expandafter\ifx\csname documentstyle\endcsname\relax \gdef\renewindex#1{#1} \else \gdef\renewindex#1{} \ifcat a\noexpand @\else \gdef\proofmodetrue{% \documentstyle[doc]{article}\MakePercentIgnore \csname iffalse\endcsname } \fi \fi } \renewindex{\def\batchfile{index.doc}} \renewindex{\input docstrip.tex } \renewindex{\generateFile{index.sty}{t}{\from{index.doc}{style}}} \renewindex{\generateFile{sample.tex}{t}{\from{index.doc}{test}}} \renewindex{\endinput} \proofmodetrue % % \fi \def\fileversion{v3.02} \def\filedate{15 September 1993} \def\docdate {15 September 1993} %% \CheckSum{692} %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} %% % % \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,\else,\em} % \DoNotIndex{\EnableCrossrefs,\end,\endcsname,\endgroup,\endinput} % \DoNotIndex{\everypar,\expandafter,\fi,\filedate,\fileversion} % \DoNotIndex{\footnotesize,\gdef,\global,\glossary,\hangindent} % \DoNotIndex{\if@filesw,\if@nobreak,\if@twocolumn,\if@twoside} % \DoNotIndex{\hsize,\hskip,\ifhmode,\ifmmode,\ifodd,\ifvmode,\ifx} % \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,\typeout,\uppercase,\vbox,\vrule,\vskip,\vss} % \DoNotIndex{\write,\z@,\z@skip} % % \MakeShortVerb{\=} % % \setcounter{StandardModuleDepth}{1} % % \CodelineIndex % % \title{A new implementation of \LaTeX's indexing % commands\thanks{This file has version number \fileversion, % last revised \filedate, documentation dated \docdate. The % definitive version of this file is % {\tt theory.lcs.mit.edu:pub/tex/index.doc}.}} % % \author{David M. Jones} % % \date{\filedate} % % \begin{document} % % \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: % \begin{enumerate} % % \item % Support for multiple indexes. % % \item % A $*$-variant of the =\index= command that, in addition to putting % it's argument in the index, also typesets it in the running text. % % \item % A =\shortindexingon= command that makes =^= and =_= shorthand for % =\index= and =\index*=, respectively (but only outside of math mode, % of course). This can be turned of with the =\shortindexingoff= % command. % % \item % The {\tt showidx} style option has been merged into this file. The % command =\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 =\indexproofstyle= command. % % \item % A two-stage process for creating the raw index files, similar to % that used to create tables of contents. This means that if you have % a large document consisting of several =\include='d files, you no % longer lose the index if you format only part of the document with % =\includeonly=. % % \item % The =\index= command has been rewritten to be more robust. In % particular, it no longer depends on =\catcode= changes to work % properly, so the new =\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 three stages to creating an index with % \LaTeX. First, the raw index information has to be written out to a % file. Then, the raw information needs to be processed and turned % into a finished index. Finally, the finished index has to be read % back in by \LaTeX\ and formated. % % In \LaTeX, this is accomplished with the commands =\makeindex=, % =\index=, =\printindex=, and (most often) with the auxiliary program % {\tt makeindex}. Assuming that your main file is called {\tt % foo.tex}, =\makeindex= opens the file {\tt foo.idx} and initializes % it for holding the raw index entries and =\index= is used to put raw % index entries into {\tt foo.idx}. Then the raw index file is % processed by {\tt makeindex}, which puts the finished index in {\tt % foo.ind}. Finally, the =\printindex= command is used in your % \LaTeX\ document to indicate where the file {\tt foo.idx} should be % read back in, i.e., where the index should appear in your document. % % This style modifies the =\makeindex=, =\index=, and =\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 will % be put by {\tt makeindex} to be read in later by \LaTeX. % % \item % The title of the index. % % \end{enumerate} % % % \DescribeMacro{\newindex} % Correspondingly, the =\newindex= command takes four arguments. For % example, if you wanted to declare an author index, you might use the % following: % \begin{verbatim} % \newindex{aut}{adx}{and}{Name Index} % \end{verbatim} % Here, =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 % =root.tex=, then \LaTeX\ will write the raw index entries to the % file =root.adx=, and you will execute the following {\tt makeindex} % command to process the author index: % \begin{verbatim} % makeindex -o root.and root.adx % \end{verbatim} % % % \DescribeMacro{\renewindex} % The =\renewindex= command takes the same four arguments as the % =\newindex= command and can be used to redefine indexes that have % been previously declared. % % % \DescribeMacro{\makeindex} % For backwards compatibility, the =\makeindex= command is redefined % to use =\newindex=. It is essentially equivalent to % \begin{verbatim} % \newindex{default}{idx}{ind}{Index} % \end{verbatim} % The index labeled =default= is special: it is the one that will be % used by =\index= and =\printindex= unless another index is % specified (see below). % % % \DescribeMacro{\printindex} % The =\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 =\index= command is modified in two ways. First, there is a % $*$-variant of the command that, in addition to putting its % argument in an index, also typesets it on the page. Second, % =\index= now takes an optional argument that should be the tag of % the index where its argument should be put. If no such tag is % supplied, the =default= index (such as that opened by =\makeindex= % above) is used. % % % \DescribeMacro{\shortindexingon} % \DescribeMacro{\shortindexingoff} % Perhaps the most dubious feature of =index.sty= is that it allows % you to define the characters =^= and =_= to be abbreviations for % =\index*= and =\index= outside of math mode. These abbreviations % are enables by the =\shortindexingon= command and disabled by the % =\shortindexingoff= command. Both of these commands make their % changes locally rather than globally, so they can be used to enable % or disable the abbreviations within a 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, % \DescribeMacro{shortindexingon}=shortindexingon= can be used as an % environment if that seems appropriate. % % % \DescribeMacro{\proofmodetrue} % \DescribeMacro{\proofmodefalse} % \DescribeMacro{\indexproofstyle} % As mentioned above, the =showidx= document-style option has been % merged into =index.sty=. It can be turned on with =\proofmodetrue= % and turned off with =\proofmodefalse=. When it is turned on, % all\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.} index entries will be put in the % margin of the page where they appear. By default, they appear in % the typewriter font at =\footnotesize=, but the user can override % this with the =\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 raw index file. The =\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 =\disableindex= command might be useful is % if you have 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 =\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 =.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 =.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 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, =\@starttoc=, =\raggedbottom=, =\flushbottom=, % =\addcontentsline=, =\markboth=, and =\markright=. Naturally, this % could cause incompatibilities between {\tt 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. % % It's also been necessary to modify the =\theindex= environment, but % I've tried to do so very conservatively. If your style file uses % =\indexname= and your definition of =\theindex= doesn't take any % arguments, you should be ok. Otherwise, you'll have to redefine the % =\theindex= environment yourself if you don't want the \LaTeX\ {\tt % book.sty} default. % % In the current implementation, {\tt 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 =\disableindex= % for a fuller discussion of this problem and one way around it. % % % \section{To do's} % % It might be nice if the =\index*= command parsed its argument so % that, for example, instead of writing `=\index{sin@$\sin$}$\sin$=', % one could write `=\index*{sin@$\sin$}='. However, this fraught with % numerous dangers, and I'm both too lazy and too cowardly to % undertake it now. % % Maybe the user should be given the option of deciding which % characters are used for the shortindexing abbreviations % % The documentation should be carefully read, edited, and finished. % (In particular, I should add some scathing comments about some of % the problems that made it necessary to redefine so many of \LaTeX's % commands.) % % Maybe it would be nice if this package were compatible with plain % \TeX. % % \StopEventually{} % % \section{The code} % \label{sec:thecode} % % As is customary, we first make sure the file is loaded only once. % Then we print an identifying message to the terminal. % loaded % \begin{macrocode} %<*style> \@ifundefined{newindex}{}{\endinput} \typeout{Style-Option: `index' \fileversion\space <\filedate> (dmj)} % \end{macrocode} % % \begin{macro}{\@ifundefined} % We begin by redefining the \LaTeX\ command =\@ifundefined= to % prevent it from expanding its arguments prematurely. This also % requires us to redefine =\@leftmark= and =\@rightmark= to make them % =\long=. The following three definitions are borrowed from {\tt % amsart.sty}, v1.1b $\langle$31 Jul 1991$\rangle$. I rely heavily % upon this more robust definition of =\@ifundefined=. % \begin{macrocode} \def\@ifundefined#1{% \expandafter\ifx\csname#1\endcsname\relax \expandafter\@leftmark \else \expandafter\@rightmark \fi } \long\def\@leftmark#1#2{#1} \long\def\@rightmark#1#2{#2} % \end{macrocode} % \end{macro} % % \begin{macro}{\disableindex} % The =\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}{}{% \typeout{index.sty> Warning! It's too late to disable the `\@tempa' index; the output}% \typeout{index.sty> file \jobname.\@tempa\space has already been opened for output. You should}% \typeout{index.sty> put the \string\disableindex\space command before the declaration of the}% \typeout{index.sty> `\@tempa' index.}% }% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\if@newindex} % \begin{macro}{\newindex} % \begin{macro}{\renewindex} % The =\newindex= and =\renewindex= commands are defined on analogy % with the =\[re]newcommand= macros. Each index is identified by a % unique tag, which is specified in the first argument of =\newindex=. % Most of the information about the index labeled \meta{tag} is kept % in the macro =\idx@=\meta{tag}, so we can check to see if a % particular index has already been defined by checking whether % =\idx@=\meta{tag} is defined. =\newindex= and =\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 % =\@newindex=. % % The =\if@newindex= flag will be used to keep =\renewindex= from % re-allocating =\write= and =\toks= registers later. % \begin{macrocode} \newif\if@newindex \def\newindex#1{% \@ifundefined{idx@#1}% {\@newindextrue\@newindex{#1}}% {% \@latexerr{Index type `\string#1' already defined}\@ehc \expandafter\@gobble\@gobbletwo }% } \def\renewindex#1{% \@ifundefined{idx@#1}% {% \@newindextrue \@latexerr{Index type `\string#1' not defined}\@ehc }% {\@newindexfalse}% \@newindex{#1}% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\@preamblecmds} % Neither =\newindex=, =\renewindex=, nor =\disableindex= should be % used anywhere except inside style files or in the preamble of a % document, so we add them to the =\@preamblecmds= list. % \begin{macrocode} \begingroup \def\do{\noexpand\do\noexpand}% \xdef\@preamblecmds{% \@preamblecmds \do\newindex \do\renewindex \do\disableindex } \endgroup % \end{macrocode} % \end{macro} % % \begin{macro}{\@newindex} % =\@newindex= does most of the work. First, it picks up the first % three arguments of the =\[re]newindex= command and stores the second % two in an appropriate =\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, =\@newindex= also opens an appropriate output files if we are % writing auxiliary files (i.e., unless =\nofiles= has been called). % % \begin{macro}{\my@newtoks} % Since we need to declare new token registers on the fly, we need a % non-=\outer= version of =\newtoks=. % \begin{macrocode} \def\my@newtoks{\csname newtoks\endcsname} \def\@newindex#1#2#3{% \@namedef{idx@#1}{#2:#3}% \if@filesw \@ifundefined{disable@#1}{% \if@newindex \expandafter\newwrite\csname tf@#1\endcsname \expandafter\my@newtoks\csname idxtitle@#1\endcsname \else \immediate\closeout\@nameuse{tf@#1}% \fi \immediate\openout\@nameuse{tf@#1}=\jobname.#2 % \typeout{index.sty> Writing index file \jobname.#2 }% } {\typeout{index.sty> Index `#2' disabled -- not opening \jobname.#2 }}% \fi \expandafter\csname idxtitle@#1\endcsname } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\@second} % This is a useful macro for retreiving the second field of an index % specification. % \begin{macrocode} \def\@second#1:#2\@nil{#2} % \end{macrocode} % \end{macro} % % \begin{macro}{\@nearverbatim} % \begin{macro}{\@meaning} % =\@nearverbatim\foo= is much like =\meaning\foo=, except that it % suppresses the ``=macro ->='' string produced when =\meaning= % expands a macro. It is used by =\@wrindex= and =\@vwritefile= to % produce an ``almost verbatim'' copy of their arguments. This method % replaces the use of =\@sanitize= from latex.tex and allows indexing % macros to be used in places (such as inside macro arguments) where % the original =\index= command could not. Thanks to Donald Arseneau % $\langle${\tt asnd@erich.triumf.ca}$\rangle$ 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}{\@nearverbatim} \def\@nearverbatim{\expandafter\@meaning\meaning} \def\@meaning#1>{} % \end{macrocode} % \end{macro} % \end{macro} % % Now we define the =\index= macro itself. The following definitions % are adapted from {\tt latex.tex} v2.09 $\langle$25 March % 1992$\rangle$. % % \begin{macro}{\makeindex} % First we redefine =\makeindex= to define the default index using % =\newindex=. We use =\edef= to make sure that =\indexname= gets % expanded here. Otherwise we'll get into an infinite loop later on % when we try to redefine =\indexname= inside the =\theindex= % environment. % \begin{macrocode} \edef\makeindex{% \noexpand\newindex{default}{idx}{ind}{% \expandafter\ifx\csname indexname\endcsname\relax Index% \else \indexname \fi }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\if@silentindex} % \begin{macro}{\if@addtoindex} % \begin{macro}{\if@proofmode} % We need three new flags. The first, =\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 =\index*= % command. The second, =\if@addtoindex=, indicates whether entries % should be written to the index; this is used to disable the =\index= % command inside of page headings and tables of contents. The third, % =\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} % =\index= will be made self-protecting (a la =\em=, etc.) so it can % be used inside, for example, sectioning commands. Unfortunately, to % really make =\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} \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 =\index= is equal to =\@gobble=. % This is so I don't have to redefine =\@outputpage=, which % temporarily disables =\label=, =\index=, and =\glossary= by % =\let='ing them equal to =\@gobble=. (For this reason, we have to % be very careful to make sure that =\index= has expanded to % =\p@index= before it gets to =\@outputpage=.) Second, note that if % =\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 % =\index[AUT]{...}= instead of =\index[aut]{...}=. % \begin{macrocode} \def\@index[#1]{% \ifx\index\@gobble \@addtoindexfalse \fi \def\@tempf{\@@index{#1}}% \if@addtoindex \@ifundefined{idx@#1}% {% \def\@tempf{% \@latexerr{Index type `\string#1' undefined}% \@ehc \@silentindextrue \@gobble }% }% {}% \fi \@tempf } \def\@@index#1#2{% \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 \let\thepage\relax \def\@tempa{#2}% \edef\@tempa{% \write\@auxout{% \string\@vwritefile{#1}{% \string\indexentry{\@nearverbatim\@tempa}{\thepage}% }% }% }% \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 {\tt makeidx.sty}, v2.09 $\langle$21 % Oct 91$\rangle$. % \begin{macrocode} \@ifundefined{seename}{\def\seename{see}}{} \def\see#1#2{{\em \seename\/} #1} \def\printindex{\@ifnextchar [{\@printindex}{\@printindex[default]}} \def\@printindex[#1]{% \def\@indextype{#1}% \@ifundefined{idx@#1}% {\@latexerr{Index type `\string#1' undefined}\@ehc}% {% \edef\@tempa{\@nameuse{idx@#1}}% \@input{\jobname.\expandafter\@second\@tempa\@nil}% }% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\@indexstar@} % Now we set things up for =\shortindexing=. First, we define a % one-token shorthand for =\index*=. This will be needed in the % definition of =\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 =\shortindexingon= and =\shortindexinoff= commands % to turn shortindexing on and off (surprise!). =\shortindexingon= % saves the old definitions and =\catcode='s of =^= and =_= so they % can later be restored by =\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, {\tt 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 =\shortindexingon= in the preamble of one's document, and never % want to turn it off. =\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 redefine =\theindex=. We try to make the minimal possible % change, but if the user's style doesn't know about =\indexname=, we % have no alternative but to redefine the entire environment and issue % a warning. % % Thanks to Alan Jeffrey $\langle${\tt % alanje@cogs.sussex.ac.uk}$\rangle$ for pointing out how the package % should behave when =\indexname= is already defined and for the code % to implement that case. % \begin{macrocode} \expandafter\ifx\csname indexname\endcsname\relax \typeout{index.sty> Uh oh! It looks like your document style doesn't use \string\indexname.} \typeout{index.sty> I'll have to redefine the \string\theindex\space environment, using} \typeout{index.sty> the `book' style default.} \def\indexname{Index} % \end{macrocode} % The following is adapted from {\tt book.sty} v2.09 $\langle$14 Jan % 92$\rangle$. % \begin{macrocode} \def\theindex{% \@restonecoltrue \if@twocolumn\@restonecolfalse\fi \columnseprule\z@ \columnsep 35\p@ \edef\@indexname{% \expandafter\the\@nameuse{idxtitle@\@indextype}% }% \twocolumn[\@makeschapterhead{\@indexname}]% \@mkboth{\uppercase{\@indexname}}{\uppercase{\@indexname}}% \thispagestyle{plain}% \parindent\z@ \parskip\z@ plus .3\p@\relax\let\item\@idxitem } \else \@temptokena={% \edef\indexname{\the\@nameuse{idxtitle@\@indextype}}% } \toks0=\expandafter{\theindex} \edef\theindex{\the\@temptokena\the\toks0} \fi % \end{macrocode} % % \begin{macro}{\@vwritefile} % \begin{macro}{\x@vwritefile} % \begin{macro}{\y@vwritefile} % Now we define the =\@vwritefile= macro, which copies information % from the =aux= file to one of the other auxiliary files. % =\@vwritefile= performs essentially the same function as % =\@writefile=, except that it does not expand it second argument % (i.e., it writes it out verbatim (well, almost verbatim)). % % NOTE: There doesn't seem to be any reason why =\@writefile= *should* % expand its second argument and in fact, we later redefine % =\addcontentsline= to use =\@vwritefile= instead of =\@writefile=. % A slight extension of this idea could be used to solve the problem % of fragility in sectioning commands. % % =\@vwritefile=, like =\@writefile=, should be disabled when the % =aux= file is being read by =\begin{document}=. To avoid having to % redefine =\document=, we make the behaviour of =\@vwritefile= % conditional on the current meaning of =\@writefile=. % \begin{macrocode} \def\@vwritefile{% \ifx\@writefile\@gobbletwo \expandafter\@gobbletwo \else \expandafter\x@vwritefile \fi } \def\x@vwritefile#1{% \@ifundefined{tf@#1}{\@gobbletwo}{\y@vwritefile}{#1}% } \long\def\y@vwritefile#1#2{% \def\@tempa{#2}% \immediate\write\csname tf@#1\endcsname{\@nearverbatim\@tempa}% } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % Now we take some code from {\tt showidx.sty} and merge it into our % new system. There are four reasons for redefining the commands here % rather than just inputting {\tt showidx.sty} (or requiring the user % to do so). First, {\tt showidx.sty} ends with a call to % =\flushbottom=, which I want to avoid. Second, the instructions for % successfully using {\tt showidx.sty} along with {\tt index.sty} % would be somewhat tricky. This way, I can just tell users not to % use {\tt showidx.sty} at all. Third, I need to make some % alterations to =\@showidx= anyway. In particular, (a) I need to add % the =\@sanitizeat= command so this works correctly with AMS-\LaTeX\ % and (b) I want to add the =\indexproofstyle= command so the user can % customize the size and font used for the index proofs. Finally, % {\tt 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 {\tt showidx.sty}, v2.09 $\langle$16 Jun % 1991$\rangle$. % \begin{macrocode} \newinsert\@indexbox \dimen\@indexbox=\maxdimen % \end{macrocode} % \end{macro} % % \begin{macro}{\@sanitizeat} % The definition of =\@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} % Note the cautious way of calling =\reset@font=, which is necessary % for this to work correctly under both the Old and New Font Selection % Schemes. % \begin{macrocode} \newtoks\indexproofstyle \indexproofstyle{\footnotesize\csname reset@font\endcsname\tt} \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 =\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. (Incidentally, it should be possible to % use the =\@nearverbatim= trick to make arguments of sectioning % commands robust. I'll have to explore this.) % % These are based on {\tt latex.tex} 2.09 $\langle$25 March % 1992$\rangle$. % % \begin{macro}{\addcontentsline} % We need to redefine =\addcontentsline= to keep it from expanding % =\index= commands too far. In particular, we have removed =\index= % from the list of macros that are set equal to =\@gobble= and we % substitute =\@vwritefile= for =\@writefile=. This latter change % also means that we can simplify the definition of =\protect= % somewhat. % \begin{macrocode} \def\addcontentsline#1#2#3{% \if@filesw \begingroup \let\label\@gobble \let\glossary\@gobble \def\protect##1{\string##1\space}% \@temptokena{\thepage}% \edef\@tempa{% \write\@auxout{% \string\@vwritefile{#1}{\string\contentsline{#2}{#3}% {\the\@temptokena}}% }% }% \@tempa \endgroup \if@nobreak\ifvmode\nobreak\fi\fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\@starttoc} % We need to redefine =\@starttoc= to =\@addtoindexfalse= so that items % don't get written to the index from within tables of contents. The % only change here is the addition of =\@addtoindexfalse=. % \begin{macrocode} \def\@starttoc#1{% \begingroup \@addtoindexfalse \makeatletter \@input{\jobname.#1}% \if@filesw \expandafter\newwrite\csname tf@#1\endcsname \immediate\openout \csname tf@#1\endcsname \jobname.#1\relax \fi \global\@nobreakfalse \endgroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\markboth} % \begin{macro}{\markright} % Finally, we have to redefine =\markboth= and =\markright= to keep % them from disabling the expansion of =\index= while putting section % heads into the =\mark=. Otherwise, we'd end up with ``=\index='' in % the mark, which would cause problems when =\@outputpage= redefines % =\index= to be equal to =\@gobble=. Instead, we want =\index= to % expand to =\p@index= in the =\mark=, so we retain control over what % happens in \@outputpage. % % This time, the only change is to remove =\index= from the list of % macros that are =\let= equal to =\relax=. % \begin{macrocode} \def\markboth#1#2{% \gdef\@themark{{#1}{#2}}% \begingroup \let\protect\noexpand \let\label\relax \let\glossary\relax \mark{\@themark}% \endgroup \if@nobreak\ifvmode\nobreak\fi\fi } \def\markright#1{% \begingroup \let\protect\noexpand \let\label\relax \let\glossary\relax \expandafter\@markright\@themark{#1}% \mark{\@themark}% \endgroup \if@nobreak\ifvmode\nobreak\fi\fi } % % \end{macrocode} % \end{macro} % \end{macro} % % \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 =\renewindex= command and checking to make sure index is (or % is not) defined in =\newindex=, =\index= and =\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 =\index*=, proofmode, =\shortindexingon= and % =\shortindexingoff=. % % \item[v2.01 (24 Jun 1993)] % Fixed 3 bugs. (1) If proofmode was turned on, then something like % ``=\index{WORD}WORD='' would suppress the hyphenation of WORD. This % was fixed by adding ``=\penalty\@M\hskip\z@skip='' to the end of % =\@showidx=. (This is just the definition of =\allowhyphens= % borrowed from german.sty, v2 $\langle$4 Nov 1988$\rangle$). (2) The % =\hbox= in =\@mkidx= was being set at its natural width, which had a % tendency to interfere with the width of the page. The =\hbox= is % now replaced by =\rlap=. (3) If the title of an index (i.e., the % fourth argument of =\newindex=) contained a particularly fragile % command like~=\d=, havoc would ensue when =\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 $\langle$D.Wujastyk@ucl.ac.uk$\rangle$ on 24 June % 1993. Note that bugs (1) and (2) are actually bugs in showidx.sty, % v2.09 $\langle$16 Jun 1991$\rangle$. % % \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 % =\shortindexingon= and =\shortindxingoff= commands to save and % restore the =\catcode='s and meanings of =^= and =_= in the safest % possible (I hope) order. Also added the =\if@shortindexing= flag to % keep =\shortindexingoff= from doing anything if it is called outside % of the scope of a =\shortindexingon= command. (Question: Should % =\shortindexingon= check that flag before doing anything?) % % \item[v2.04 (beta) (14 Jul 1993)] % Added =\disableindex= command. Added =\newindex= and =\renewindex= % to =\@preamblecmds=. Add =\if@newindex= flag to =\@newindex= to % prevent =\renewindex= from re-allocating new =\write= and =\toks= % registers. Rewrote using {\tt doc.sty} and {\tt 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 {\tt DocStrip} CheckSum. % % \item[v3.02 (15 Sep 1993)] % Corrected spelling of =\@shortindexingfalse= in definition of % =\shortindexingoff=. Thanks to Hendrik G. Seliger $\langle % hank@Blimp.automat.uni-essen.de\rangle$ for this bug report. Also % added redefinitions of =\@leftmark= and =\@rightmark= to fix a bug % reported by Dominik Wujastyk $\langle$D.Wujastyk@ucl.ac.uk$\rangle$. % % \end{description} % % \DisableCrossrefs % % \section{The sample file} % % \begin{macrocode} %%% This is a sample file for index.sty. To run the sample, %%% execute the following commands: %%% %%% latex sample.tex %%% makeindex sample %%% makeindex -o sample.and sample.adx %%% makeindex -o sample.nnd sample.ndx %%% latex sample.tex % %\documentstyle[index]{book} % %\makeindex %\newindex{aut}{adx}{and}{Name Index} %\newindex{not}{ndx}{nnd}{List of Notation} % %\shortindexingon % %\proofmodetrue % %\def\aindex{\index*[aut]} % %\begin{document} % %\tableofcontents % %\newpage % %\chapter{Here is a ^[aut]{chapter} title} % %\section{Section header\index[aut]{section}} % %Here is some text.\index{subject} % %Here is \index[not]{notation}some more \index[not]{sin@$\sin$} %text. % %Here is some ^{more} _[not]{notation} text. % %Here is yet more \aindex{text}. % %\section{Another Section header _[aut]{section2}} % %And here is some math: $x^1_b$. % %Here is an ^[aut]{index} entry \fbox{inside an %\index[not]{min@$\min$}fbox} % %\fbox{Here is an ^[aut]{entry} in a box.} % %\printindex[not] % %\printindex[aut] % %\printindex % %\end{document} % \end{macrocode} % % \PrintIndex % \PrintChanges % % \Finale % % \end{document} \endinput