% \iffalse %<*internal> \begingroup \input docstrip.tex \keepsilent \usedir{tex/latex/imakeidx} \preamble ______________________________________________________ The imakeidx package for LaTeX Copyright (C) 2010 Claudio Beccari and Enrico Gregorio All rights reserved License information appended \endpreamble \postamble Copyright 2010 Claudio Beccari Copyright 2010 Enrico Gregorio Distributable under the LaTeX Project Public License, version 1.3c or higher (your choice). The latest version of this license is at: http://www.latex-project.org/lppl.txt This work is "author-maintained" This work consists of this file imakeidx.dtx, a README file and the derived files imakeidx.sty and imakeidx.pdf. \endpostamble \askforoverwritefalse \generate{\file{imakeidx.sty}{\from{imakeidx.dtx}{package}}} \def\tmpa{plain} \ifx\tmpa\fmtname\endgroup\expandafter\bye\fi \endgroup % % %<*driver> \ProvidesFile{imakeidx.dtx}% % %\NeedsTeXFormat{LaTeX2e}[2005/12/01] %\ProvidesPackage{imakeidx}% %<*package> [2010/07/12 v.1.0a Package for typesetting indices in a synchronous mode] % %<*driver> \documentclass{ltxdoc} \def\prog#1{\textsf{\slshape#1}} \def\progpdflatex{\textsf{(\textsl{pdf})\textsl{latex}}} \def\eTeX{\mbox{$\varepsilon$-\TeX}} \def\Kvalue#1{\textsf{\textsl{#1}}} \def\pack#1{\textsf{#1}} \usepackage{multicol} \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} \usepackage[english]{babel} \usepackage{textcomp,lmodern,metalogo,booktabs} \begin{document} \makeatletter \GetFileInfo{imakeidx.dtx}% dtx extension required \title{Package \pack{imakeidx}\thanks{Version number \fileversion; last revision \filedate.}} \author{Claudio Beccari\thanks{\texttt{claudio dot beccari at gmail dot it}} \and Enrico Gregorio\thanks{\texttt{Enrico dot Gregorio at univr dot it}}} \date{} \maketitle \begin{multicols}{2} \tableofcontents \end{multicols} \smallskip \DocInput{imakeidx.dtx} \end{document} % % \fi % \CheckSum{737} % % \begin{abstract} % This package exploits the |\write18| facility of modern \TeX\ system % distributions that allows to run system commands while typesetting a % document written with the \LaTeX{} mark up. By so doing, the index % or indices, that are usually typeset at the very end of the % document, are possibly split and sorted so as to include them in the % document itself. This process has some minor limitations: it's % impossible to start an index before all other pages have been % ejected and to have the automatic run of the index sorting program. % \end{abstract} % % \section{Introduction} % It's been some years now that the typesetting engine of the \TeX\ % system is just \prog{pdftex}; the original Knuthian \prog{tex} is % still corrected by D.\,E.~Knuth himself, but is frozen, according to % his will; it is still distributed by every \TeX\ distribution, but % in practice only \prog{pdftex} is used as the interpreter of every % macro package and the true typesetter engine. The latter is updated % with the original \prog{tex} corrections, but it is the only one % that the \LaTeX3 Team maintains and upgrades. % % This program \prog{pdftex} was originally born with the facility of % producing either a pdf output file, as its name suggests, or a dvi % file. Since then it has been enriched with many upgrades, also with % regard to the evolution of the PDF language itself. It also % incorporates the extensions of \eTeX\ and has the ability to open a % shell so as to call system commands with their arguments. % % This facility, since the \TeX~Live 2010 distribution, is official, % but is sort of restricted, in the sense that the \TeX\ system % configuration file contains a list of ``safe'' system commands that % can be run by \prog{pdftex}; presently the only program relevant for % this package is \prog{makeindex}. This precaution is necessary in % order to avoid running malicious code. Other programs can be run, % though, but it's necessary to expressly tell \prog{pdftex} that it % can do so; this authorisation is given by means of a suitable % program option, as explained below. % % This package will exploit this facility in order to run a perl % script that is capable of splitting a raw index file into different % chunks and to run the \prog{makeindex} \TeX\ system program so as to % sort and format the index entries according to a specified index % style file. Once the shell is terminated, the \prog{pdftex} program % resumes its work and possibly prints the various formatted indices % produced in previous step. In this way the document indices are % always synchronous with their document and no further \prog{pdftex} % runs are necessary. % % In order to reach this goal, it necessary to enable the % \prog{pdftex} engine to run the so-called |\write18| facility; % depending on the distribution and the shell editor that is being % used to work on a specific document, it is necessary to add % \texttt{-shell-escape} (or \texttt{-\/-enable-write18} for MiK\TeX) % to the command with which \prog{pdftex} is launched, possibly by the % shell editor. If Lua\LaTeX{} is used, it's necessary to specify the % \texttt{-shell-escape} command line option. % %\section{Package usage} % This package is invoked as usual by means of a \cs{usepackage} command: % \begin{flushleft} % \cs{usepackage}\oarg{options}\texttt{\{imakeidx\}} % \end{flushleft} % % The available \meta{options} consist in a comma separated list of % the following options: % \begin{description}\def\Item[#1]{\item[\normalfont\ttfamily#1]} % \Item[makeindex] in order to use the \prog{makeindex} sorting an % formatting engine; this option is the default and is mutually % exclusive with the next option. % \Item[xindy] in order to use the \prog{xindy} sorting and formatting % engine; \texttt{texindy} is an alias for \texttt{xindy} and actually % it's the script \prog{texindy} which is called by this package. % \Item[noautomatic] disables the automatic splitting and running of % the system programs; this option might be used to save time when one % knows for sure that the index files are already OK and do not need % to be refreshed. Actually the time spent in splitting, sorting and % formatting is so short that this option might be useful only when % very lengthy indices are being processed. % \Item[nonewpage] inhibits the new page command to be issued when % using an article type document class and multiple indices are being % typeset. We don't see why someone would use multiple indices in an % article (except possibly for package documentations, which usually % provide a macro index and a list of changes). % \Item[quiet] suppresses all messages about manual index % processing. % \Item[original] uses the class provided \texttt{theindex} % environment for typesetting the indices; it is implicitly set if the % document class option \texttt{twocolumn} has been specified. % \Item[splitindex] calls the \prog{splitindex} script by Markus Kohm, % which is included in every \TeX~Live distribution since 2009. With % this option all index entries, which are written in one raw file, % are successively split into all the requested index files; in this % way there is virtually no limit on the number of indices that is % possible to create for a particular document. % \end{description} % % The last described option deserves an explanation. \LaTeX{} can % write on a limited number of files during a run, and some of these % \emph{output streams} are already reserved (among these: aux file, % table of contents, list of figures, list of tables). When more than % one index is produced, there's the risk to run off the number of % writable files, because normally \pack{imakeidx} reserves an output % stream for each index. So the \texttt{splitindex} option comes to % rescue: with it only \emph{one} index file is written. At the % first \cs{printindex} command, the program \prog{splitindex} is % called; it splits the large index file into as many parts as the % number of requested indices; after this, \prog{makeindex} (or % \prog{xindy}) can do its job. In this way only one output stream is % needed during the \LaTeX{} run. % % When should you apply this option, then? With one index it's % useless, you should begin to consider it for two or more indices and % definitely use it if you get the error % \begin{verbatim} % ! No room for a new \write % \end{verbatim} % Apart from this case, with or without it the results are the % same. See section~\ref{sec:wrong} to see what files are written % during the \LaTeX{} run with or without the option. % % \section{Specific package commands} % \addtocontents{toc}{\protect\columnbreak\protect\vspace*{.4ex}} % As it is customary when just one index is produced, the standard % \LaTeX\ facilities, i.e.\ the commands \cs{makeindex}, \cs{index}, % and \cs{printindex} must be used. This package redefines them so as % to produce multiple indices and defines some others. The first three % of the following commands may be used only in the preamble. % \begin{description}\def\Item[#1]{\item[\normalfont\ttfamily\cs{#1}]} % \Item[makeindex] with the syntax:\\[1ex] % \cs{makeindex}\oarg{key-values}\\[1ex] % where \meta{key-values} is a comma separated list of key-value % assignments of the form: \texttt{key=value}; the available % keys are the following: % \begin{description}\def\Item[#1]{\item[\normalfont\sffamily\textsl{#1}]} % \Item[name] is the symbolic name for an index; if this key is not % specified, it defaults to the value of the \cs{jobname} control % sequence, in other words the name of the current main \texttt{.tex} % program file, i.e., the file that |\input|s and/or |\include|s all % the files of the complete document. This symbolic name is necessary % only when doing multiple indices and is used with the \cs{index} % command to point to the right index.\\* % Example: \texttt{name=nameidx} % \Item[title] is the title that is typeset at the beginning of the % specific index; if not specified, the \cs{indexname} value is % used.\\* Example: \texttt{title=Index of names} % \Item[program] is the name of the system program that is used to % sort and format an index; valid choices are \prog{makeindex}, % \prog{xindy}, or \prog{texindy}. If not specified the program % specified among the package options is used. If no option is % specified, \prog{makeindex} is used. In order to use \prog{xindy}, % it's necessary to call \progpdflatex{} with the shell escape % command line option.\\* Example: \texttt{program=xindy} % \Item[options] is the list of options to be passed to the sorting % and formatting program; this list is a balanced text of program % options, separated with the syntax required by the sorting and % formatting program. For example, in order to use a different % \prog{makeindex} sorting and formatting style \pack{mystyle.ist} and % avoiding any message in the screen output write \texttt{options=-s % mystyle} % \Item[noautomatic] is a boolean key that defaults to \texttt{false}; % you can set it to \texttt{true} by simply listing its key in the % key-value list, without necessarily specifying the \texttt{=true} % part. If specified the index sorting program won't be called during % the \prog{pdftex} run for this particular index. % \Item[intoc] is a boolean variable that defaults to \texttt{false}; % if you want to set it \texttt{true} you must simply list this key in % the key-value list, with no need of specifying the \texttt{=true} % part. By setting this key to \texttt{true} an entry for this % particular index is put in the table of contents. % \Item[columns] accepts an integer representing the number of columns % in the index; this is silently ignored if the \texttt{original} or % the \texttt{twocolumn} options are set; the number can even % be~$1$.\\* Example: \texttt{columns=3} % \Item[columnsep] accepts a dimension representing the separation % between index columns; the default is $35$\,pt as in the standard % classes.\\* Example: \texttt{columnsep=15pt} % \Item[columnseprule] is boolean; if it is set, a rule will appear % between the index columns. % \end{description} % \Item[indexsetup] with the syntax:\\[1ex] % \cs{indexsetup}\oarg{key-values}\\[1ex] % where again \meta{key-values} is a comma separated list of key-value % assignments; the available keys are: % \begin{description}\def\Item[#1]{\item[\normalfont\sffamily\textsl{#1}]} % \Item[level] which takes as value a sectioning command such as % \cs{chapter} or \cs{chapter*}. Actually any command with an argument % will do and will receive the index title as its argument. The % default is \cs{chapter*} or, if the class doesn't provide chapters, % \cs{section*}. % \Item[toclevel] which takes as value a sectioning command % \emph{name} such as \texttt{section} to indicate the level at which % we want the indices appear in the table of contents. % \Item[noclearpage] is a boolean option; when set, no \cs{clearpage} % will be issued between indices. You might want to set it in order to % have a `chapter of indices'; in this case you are responsible for % setting the right value of the above keys. For example %\begin{verbatim} % \indexsetup{level=\section*,toclevel=section,noclearpage} % ... % \chapter*{Indices} % \printindex % \printindex[names] % \printindex[objects] %\end{verbatim} % \Item[firstpagestyle] which takes as value a page style, default % \texttt{plain}. You might want to set it to \texttt{empty} or some % other page style defined by the class or by yourselves. % \Item[headers] which takes as value the left and right marks. You % might want to use this for disabling automatic uppercasing, by % saying |headers={\indexname}{\indexname}|; notice that this value % should always be a pair of braced texts. % \Item[othercode] which takes as value arbitrary \TeX{} code that % will be executed at the beginning of index entries typesetting. For % example you might want to change here the setting of \cs{parskip}. % \end{description} % \Item[splitindexoptions] must have as its argument the command line % option to \prog{splitindex}; this might be necessary on some % systems. The default is |-m ""|, because we want it only for % splitting the large index file into its components which are later % processed by this package. % \Item[index] with the syntax:\\[1ex] % \cs{index}\oarg{name}\marg{entry}\\[1ex] % inserts \meta{entry} into the raw index file; upon splitting it in % different files, this particular entry is listed in the specific % index file with name \meta{name}; if no name is specified, this % \meta{entry} is added to the default index with name % \cs{jobname}. The \meta{entry} should be written according to the % particular syntax of the sorting and formatting program. % \Item[indexprologue] with the syntax:\\*[1ex] % \cs{indexprologue}\oarg{spacing}\marg{text}\\[1ex] % is used to define some text to go between the index header and the % entries; the \meta{spacing} should be a vertical space command such % as |\vspace{36pt}| (default is \cs{bigskip}), controlling the % spacing between the prologue and the index proper. The command % affects only the next index produced by \cs{printindex}. % \Item[printindex] with the syntax:\\*[1ex] % \cs{printindex}\oarg{name}\\[1ex] % is used to typeset the particular index named \meta{name}; if no % optional argument is specified, the default index with name % \cs{jobname.ind} is typeset. Actually this command activates all % the mechanism of closing the output to the raw index file, shelling % out, possibly calling the \prog{splitindex} script in order to % divide the single raw file generated by \progpdflatex{} into % distinct raw files according to the default or specified % \meta{name}s for each index, calling the sorting and % formatting program on each of these split raw files (unless % inhibited by a \Kvalue{noautomatic} option; in which case a warning % is issued in order to remember the typesetter that this particular % index has not been processed), producing the sorted and formatted % \texttt{.ind} files, and eventually inputs and typesets these % formatted files. \ Deep breath. % \end{description} % % Let's see an example. The sequence of commands %\begin{verbatim} % ... % \usepackage{imakeidx} % ... % \makeindex[title=Concept index] % \makeindex[name=persons,title=Index of names,columns=3] % ... % \begin{document} % ... % And this is the end of the story. % % \printindex % % \indexprologue{\small In this index you'll find only % famous people's names} % \printindex[persons] % \end{document} %\end{verbatim} % will produce two indices. Entries for the first one must be typed as % |\index{gnu}|, while entries for the second are of the form % |\index[persons]{Lamport, Leslie}|. The prologue will be printed % (full line) only in the ``Index of names'', which will be typeset in % three columns. % % When the \texttt{original} option is set, maybe implicitly because % of \texttt{twocolumn}, \cs{indexsetup} and the keys % \Kvalue{columns}, \Kvalue{columnsep} and \Kvalue{columnseprule} for % \cs{makeindex} have no effect. % % \section{If something goes wrong}\label{sec:wrong} % Since \pack{imakeidx} relies on good cooperation between package % options and command line options for the \LaTeX{} run, in some cases % it may happen that the indices are not correctly built or built at % all. % % If you use only \prog{makeindex} and \TeX~Live 2010 or later, then % you shouldn't need anything special, since \prog{makeindex} is among % the safe programs allowed to be called during a \LaTeX{} run, be it % \prog{latex}, \prog{pdflatex} or \prog{xelatex} (or even % \prog{lualatex}, at present with some glitches). When the options % \texttt{splitindex}, \texttt{xindy} or \texttt{texindy} are % specified (globally or locally), the \LaTeX{} run should be called % with \texttt{-shell-escape} (which is \texttt{--enable-write18} for % MiK\TeX) or the \texttt{noautomatic} option should be specified when % loading \pack{imakeidx}. % % Let's look at a couple of examples. In both we suppose that the % document \texttt{mybook.tex} defines two indices through %\begin{verbatim} % \makeindex[...] % \makeindex[name=secondary,...] %\end{verbatim} % where |...| denotes possible options excluding \texttt{name}. % % First of all we examine the case when \pack{imakeidx} is called % \emph{without} \texttt{splitindex}. Two files called % \texttt{mybook.idx} and \texttt{secondary.idx} will be written % during the \LaTeX{} run. At the corresponding \cs{printindex} % command, \prog{makeindex} will act on each of them producing the files % \texttt{mybook.ind}, \texttt{mybook.ilg}, \texttt{secondary.ind} and % \texttt{secondary.ilg}. The \texttt{.ind} files contain the relevant % \texttt{theindex} environment with alphabetized entries, while in % the \texttt{.ilg} files \prog{makeindex} will write its log. You can % check in \texttt{mybook.log} whether the \prog{makeindex} run has % been executed by searching for a line %\begin{verbatim} % runsystem(makeindex <...>)...executed %\end{verbatim} % where |<...>| stands for the rest of the command line in the % particular case. If this line is not present, then \prog{makeindex} % has not been called; this happens when you didn't specify the shell % escape command line option for the \LaTeX{} run or if you set the % \texttt{noautomatic} option for the index. % % When using \prog{splitindex}, the situation is different. During the % \LaTeX{} run, only a large index file called \texttt{mybook.idx} file % gets written; the first \cs{printindex} command will call % \prog{splitindex} (shell escape \emph{must} be active), which will % produce the two partial index files \texttt{mybook-mybook.idx} and % \texttt{mybook-secondary.idx}. These two files will be processed by % \prog{makeindex} producing the four files % \texttt{mybook-mybook.ind}, \texttt{mybook-mybook.ilg}, % \texttt{mybook-secondary.ind} and \texttt{mybook-secondary.ilg}. % The line %\begin{verbatim} % runsystem(splitindex <...>)...executed %\end{verbatim} % in \texttt{mybook.log} will tell that the splitting has been done % (see later on if this doesn't seem true). In table~\ref{tab:files} you % can see what files are produced when the first two lines are in the % preamble. % \begin{table}[tp] % \centering\begingroup\ttfamily % \begin{tabular}{rll} % \toprule % \multicolumn{3}{c}{\ttfamily\cs{makeindex}\hphantom{[name=secondary]}}\\ % \multicolumn{3}{c}{\ttfamily\cs{makeindex}[name=secondary]}\\ % \midrule % \addlinespace % &\normalfont without \texttt{splitindex} & % \normalfont with \texttt{splitindex} \\ % \cmidrule(lr){2-2} \cmidrule(lr){3-3} % \addlinespace % \normalfont(at \cs{begin}\texttt{\{document\}})\\ % \addlinespace % &mybook.idx & mybook.idx \\ % &secondary.idx \\ % \addlinespace % \normalfont(at \cs{printindex})\\ % \addlinespace % &mybook.ind & mybook-mybook.idx \\ % &mybook.ilg & mybook-secondary.idx\\ % &secondary.ind & mybook-mybook.ind\\ % &secondary.ilg & mybook-mybook.ilg\\ % & & mybook-secondary.ind \\ % & & mybook-secondary.ilg \\ % \bottomrule % \end{tabular}\endgroup % \caption{Files written during a \LaTeX{} run}\label{tab:files} % \end{table} % % Everything is the same when using \prog{texindy} for alphabetizing, % except that, by default, it doesn't write \texttt{.ilg} files. If % you want them, add |options=-t|\meta{name}|.ilg| to the relevant % \cs{makeindex} command, in our example it should be %\begin{verbatim} % \makeindex[...,options=-t mybook.ilg] % \makeindex[name=secondary,...,options=-t secondary.ilg] %\end{verbatim} % The name of the \texttt{.ilg} file \emph{must} be specified. % Remember, though, that \prog{xindy} \texttt{.ilg} files may turn out % to be very large. % % When something different from expected appears to take place, check % also the time stamps of the produced files; if they are older than % \texttt{mybook.log}, it means that they have not been written in the % last run. The most common case is that you forgot to activate the shell % escape feature (which is not necessary with \TeX~Live 2010 or later, % provided you use only \prog{makeindex}). % % Another cause of malfunction might be a wrong option passed to % \prog{makeindex}, \prog{texindy} or \prog{splitindex}. For example, % if you specify a style option for \prog{makeindex} such as % |options=-s mystyle.ist| and the style file is missing or its name % is mistyped, the run of \prog{makeindex} will result in % \texttt{mybook.log}, but it will be aborted and the \TeX{} program % has no control over this process. In this case the \texttt{.ilg} and % \texttt{.ind} files will not be produced and you can spot the % problem by checking the time stamps. On some systems a message such as %\begin{verbatim} % Index file mystyle.ist not found % Usage: makeindex [-ilqrcgLT] [-s sty] [-o ind] [-t log] [-p num] %\end{verbatim} % may appear on the screen, but often this window gets closed before % you realize you have a problem. The time stamp is the best clue to % detect such problems. % % Shell hackers may be able to redirect the \texttt{stderr} stream to % a file, but this requires skills that can't be explained here, % because they require tens of different tricks, depending on what % method is used to start a \LaTeX{} run. From the command line, % assuming \prog{bash}, it would be something like %\begin{verbatim} % pdflatex -shell-escape mybook.tex 2>latex-errors %\end{verbatim} % If shell hackers know a way to access the exit status of the called % program, we'd be glad to implement a supplementary check. % % \section{Hints} % Actually this package reaches two goals: (\textit{a})~it typesets % the indices of a specific document in just one run, and % (\textit{b})~it lets the author\slash typesetter produce % documents with multiple indices. % % If you redefine yourself the \texttt{theindex} environment, please % remember not to number the chapter or section that introduces the % index if you ask for the \Kvalue{intoc} option; either use the % commands \cs{chapter*} or the \cs{section*} respectively and the % \Kvalue{intoc} option or don't use this option and redefine your % \texttt{theindex} environment with numbered chapter or section % commands, that will put the index titles directly into the table of % contents. You may use the \pack{idxlayout} package by Thomas Titz, % which offers many functions for index typesetting customization and % is compatible with our package; remember to load \pack{idxlayout} % after \pack{imakeidx}. This package has a similar function to our % \cs{indexprologue}, called \cs{setindexprenote}; however % \pack{idxlayout} doesn't reset the index prologue, which must be % declared anew or disabled with \cs{noindexprenote} before the next % \cs{printindex} command. % % If by chance you get double entries into the table of contents, % eliminate the \Kvalue{intoc} option from your calls; your class and % packages are already taking care of it. The package \pack{tocbibind} % should be loaded with the \texttt{noindex} option, otherwise it % would interfere with our redefinition of \texttt{theindex}. % % If you redefine your \texttt{theindex} environment by means of other % packages, pay attention that these redefine a real \texttt{theindex} % environment with this very name; if they create an environment with % a different name, \pack{imakeidx} can't take care of the indices % production (in particular the \TeX\ system program \prog{makeindex} % creates a sorted and formatted \texttt{.ind} file that refers % explicitly to the \texttt{theindex} environment), and it can't take % care of the table of contents entry and of the position of the hyper % link anchor needed to navigate your document by means of hyper % links. % % Use freely the options and the key values in order to reach the % desired results, but you are advised to prepare in advance the % styles for composing the various indices in a proper way; for % example, if you use a titled style for the index, where the index % sections are distinguished with a bold face title or alphabetic % letter, you have to set up a \texttt{.ist} file, such as % \texttt{myindexstyle.ist}, made up like this: %\begin{verbatim} % headings_flag 1 % heading_prefix "\\par\\penalty-50\\textbf{" % heading_suffix "}\\\\\*\~\\\\\*" % symhead_positive "Symbols" % symhead_negative "symbols" % numhead_positive "Numbers" % numhead_negative "numbers" % delim_0 ",\~" %\end{verbatim} % where the numeric and non alphabetic entries have different % titles. But, say, you are making also an index where the entries are % file names, and for some names only the extension is entered; the % extensions start with a dot, so the sorting program will sort these % names at the beginning of the sorted index file, but you won't like % to have % a title such as ``Symbols''; you probably prefer to have a title % such as ``Extensions''; therefore you have to prepare a different % index style file, such as this one: %\begin{verbatim} % headings_flag 1 % heading_prefix "\\par\\penalty-50\\textbf{" % heading_suffix "}\\\\\*\~\\\\\*" % symhead_positive "Extensions" % symhead_negative "extensions" % numhead_positive "Numbers" % numhead_negative "numbers" % delim_0 ",\~" %\end{verbatim} % % This done, besides requiring the use of this package, you have to % declare the \cs{makeindex} command with the necessary options; pay a % particular attention to the options that involve the index symbolic % name, the index title, the index style, the fact that the index % titles shall appear in the table of contents, and if you are % preparing an e-book, you probably would like to hyper link both the % page numbers and the index titles to the proper locations. % \prog{pdflatex} will do everything for you but be careful not to % confuse it with illogical index entries. % % Especially with multiple indices it is important that you are % consistent in putting the right information in the right index and % with a consistent mark-up. Define yourself appropriate macros so % that, for example, personal names are consistently typeset, say, in % caps and small caps and are entered into a specific index; you may % even create one command to typeset the name in the document and % replicate the same name in the index. % % Of course there is no program that can decide at your place what and % where to index each piece of information; this is a task for % humans. Soooooo\dots % \begin{center} HAPPY \TeX{}ING!\end{center} % % \StopEventually{} % \section{Implementation} % The heading to the file is in common with the documentation file, % and has already been taken care of. But we require the % \pack{xkeyval} package, in order to handle the key-value lists. % % Notice that in order to create e specific name space such as to % avoid possible conflicts with other packages, all the commands % defined in this package are prefixed with the string \texttt{imki@}. % \begin{macrocode} \RequirePackage{xkeyval} % \end{macrocode} % % We define the various options and their defaults. After % \cs{ProcessOptions}, we set anyway the \texttt{original} option if % the document class has been given the \texttt{twocolumn} option, % which is incompatible with \pack{multicol}. We define also an % internal alias for |\immediate\write18|, a rudimentary check for the % typesetting engine and a macro for modifying the command line call % to \prog{splitindex}. Lua\TeX{} is recognized later by the % value~$255$ to the internal parameter \cs{imki@shellescape}. % \begin{macrocode} \DeclareOption{xindy}{\def\imki@progdefault{texindy}} \DeclareOption{texindy}{\def\imki@progdefault{texindy}} \DeclareOption{makeindex}{\def\imki@progdefault{makeindex}} \newif\ifimki@disableautomatic \DeclareOption{noautomatic}{\imki@disableautomatictrue} \newif\ifimki@nonewpage \DeclareOption{nonewpage}{% \imki@nonewpagetrue\imki@disableautomatictrue } \newif\ifimki@splitindex \DeclareOption{splitindex}{\imki@splitindextrue} \newif\ifimki@original \DeclareOption{original}{\imki@originaltrue} \DeclareOption{quiet}{\AtEndOfPackage{% \let\imki@finalmessage\@gobble \let\imki@splitindexmessage\relax}} \ExecuteOptions{makeindex} \ProcessOptions\relax \if@twocolumn\imki@originaltrue\fi \def\imki@exec{\immediate\write18} \def\imki@engine{(pdf)latex} \ifdefined\XeTeXversion\def\imki@engine{xelatex}\fi \ifdefined\directlua % luatex doesn't have \(pdf)shellescape \def\imki@engine{lualatex}\chardef\imki@shellescape\@cclv \fi \edef\imki@splitindexoptions{-m \string"\string"} \def\splitindexoptions#1{\g@addto@macro\imki@splitindexoptions{ #1}} \@onlypreamble\splitindexoptions % \end{macrocode} % % ^^A A - incompatibilities and emulation % % While experimenting we found out that some classes or packages are % either incompatible with this one, or must be faked in order to % pretend they have been loaded. % % Unfortunately there is a serious incompatibility with the % \pack{memoir} class. In facts \pack{memoir} puts all index entries % in the main \texttt{.aux} file and extracts them to the various raw % index files at |\end{document}| time. This means that no raw index % file output stream has been defined, and therefore this package % can't close it; moreover it can't typeset the indices before % |\end{document}| because they are not yet available. Therefore if % this one is the active class chosen for typesetting the whole % document, this package outputs an error message and exits. % \begin{macrocode} \@ifclassloaded{memoir}{% \PackageError{imakeidx}{Incompatible package won't be loaded} {This package is incompatible with memoir, sorry}\endinput}{} % \end{macrocode} % On the opposite we pretend that package \pack{makeidx} or package % \pack{multind} have been loaded, so that \pack{hyperref} can play % with their commands, that are substantially the same as those used % here. By so doing those packages are inhibited from being loaded % after this one. % \begin{macrocode} \@namedef{ver@makeidx.sty}{3000/12/31} \@ifpackageloaded{multind} {\PackageError{imakeidx}{Incompatible package `multind' loaded} {This package is incompatible with multind, don't load both.% \MessageBreak\@ehc}} {\@namedef{ver@multind.sty}{3000/12/31}} % \end{macrocode} % At the same time we redefine some commands defined by \pack{makeidx} % and we define the default English names for the \cs{see} and % \cs{seealso} commands. We use \cs{providecommand} so that, if % \pack{makeidx} has already been loaded, we do not redefine things % that have already been defined. % \begin{macrocode} \providecommand*\see[2]{\emph{\seename} #1} \providecommand*\seealso[2]{\emph{\alsoname} #1} \providecommand*\seename{see} \providecommand*\alsoname{see also} % \end{macrocode} % % ^^A C - \makeindex % % From here on, some commands are duplicated; this depends on the % fact that the behavior must be different when using \prog{splitindex} or % not. The memory occupied by the useless commands will be cleared at the % end of package. % \begin{macrocode} \providecommand*\makeindex{} % to use \renewcommand safely \renewcommand{\makeindex}[1][]{\imki@makeindex{#1}} % \@onlypreamble\makeindex % Already in latex.ltx % \end{macrocode} % This package implementation of \cs{makeindex} sets default values % for the keys, then evaluates its argument (which is the optional % argument to \cs{makeindex}) and calls two other macros. After that % we have to reset the defaults. % \begin{macrocode} \def\imki@makeindex#1{% \def\imki@name{\jobname}% \def\imki@title{\indexname}% \edef\imki@program{\imki@progdefault}% \let\imki@options\space \KV@imki@noautomaticfalse\KV@imki@intocfalse \setkeys{imki}{#1}% \ifimki@splitindex\KV@imki@noautomaticfalse\fi \imki@build\imki@name \imki@startidx\imki@name \imki@resetdefaults } % \end{macrocode} % % Here are the keys. As usual, the \texttt{imki} prefix is used to % distinguish anything that is being defined in this package, even the % keys. % \begin{macrocode} \define@key{imki}{name}{\def\imki@name{#1}} \define@key{imki}{title}{\def\imki@title{#1}} \define@choicekey{imki}{program}[\imki@val\imki@nr] {makeindex,xindy,texindy}{% \ifcase\imki@nr\relax \def\imki@program{makeindex}% \or \def\imki@program{texindy}% \or \def\imki@program{texindy}% \fi} \define@key{imki}{options}{\def\imki@options{ #1 }} \define@boolkey{imki}{noautomatic}[true]{} \define@boolkey{imki}{intoc}[true]{} \define@key{imki}{columns}{\def\imki@columns{#1}} \define@key{imki}{columnsep}{\def\imki@columnsep{#1}} \define@boolkey{imki}{columnseprule}[true]{} \def\imki@resetdefaults{% \def\imki@options{ }% \def\imki@columns{2}\def\imki@columnsep{35\p@}% \KV@imki@columnseprulefalse \KV@imki@intocfalse\KV@imki@noautomaticfalse} \imki@resetdefaults % \end{macrocode} % % The control sequence \cs{imki@build} defines a control sequence to % hold the setup for an index to be used when the index is sorted and % printed % \begin{macrocode} \def\imki@build#1{% \toks@{}% \imki@dokey\imki@title \imki@dokey\imki@program \imki@dokey\imki@options \imki@dokey\imki@columns \imki@dokey\imki@columnsep \ifKV@imki@noautomatic \addto@hook\toks@{\KV@imki@noautomatictrue}% \else \addto@hook\toks@{\KV@imki@noautomaticfalse}% \fi \ifKV@imki@intoc \addto@hook\toks@{\KV@imki@intoctrue}% \else \addto@hook\toks@{\KV@imki@intocfalse}% \fi \ifKV@imki@columnseprule \addto@hook\toks@{\KV@imki@columnsepruletrue}% \else \addto@hook\toks@{\KV@imki@columnseprulefalse}% \fi \expandafter\edef\csname imki@set@#1\endcsname{\the\toks@}% } % \end{macrocode} % Comand \cs{imki@dokey} receives as argument the text of the values % assigned to certain keys, and adds them to the options token list. % \begin{macrocode} \def\imki@dokey#1{% \expandafter\addto@hook\expandafter\toks@\expandafter{% \expandafter\def\expandafter#1\expandafter{#1}}} % \end{macrocode} % % Command \cs{imki@startidx} defines the output stream(s); the macro % with suffix \texttt{split} is used when \Kvalue{splitindex} is not % enabled, the one with suffix \texttt{unique} is used otherwise. In % the case of many indices, the symbolic name for an index named % `pippo' is \cs{pippo@idxfile} corresponding to the file % \texttt{pippo.idx}. When \Kvalue{splitindex} is enabled, the only % output stream is called \cs{@indexfile} as in standard \LaTeX, % corresponding to \cs{jobname.idx}. % \begin{macrocode} \def\imki@startidxsplit#1{% \if@filesw \def\index{\@bsphack \@ifnextchar [{\@index}{\@index[\jobname]}} \expandafter\newwrite\csname #1@idxfile\endcsname \immediate\openout \csname #1@idxfile\endcsname #1.idx\relax \typeout{Writing index file #1.idx}% \fi} % \end{macrocode} % We define a switch which is set to true when a \cs{makeindex} command is given: % with \Kvalue{splitindex} we open only one stream. % \begin{macrocode} \newif\ifimki@startedidx \def\imki@startidxunique#1{% \if@filesw \ifimki@startedidx\else \newwrite\@indexfile \immediate\openout\@indexfile\jobname.idx% \global\imki@startedidxtrue \fi \def\index{\@bsphack \@ifnextchar [{\@index}{\@index[\jobname]}} \expandafter\let\csname #1@idxfile\endcsname\@empty \typeout{Started index file #1}% \fi} % \end{macrocode} % % ^^A D - \index % % Provide a default definition for \cs{index}; when a \cs{makeindex} % command is given and \LaTeX\ is writing on auxiliary files, % \cs{index} will be redefined, as seen before. When index files are % written, \cs{index} always calls \cs{@index}. Some code is borrowed % from \pack{memoir.cls}, but heavily modified. We want \cs{@wrindex} % to be defined with two arguments, so that \pack{hyperref} can hook % into it just like it does with the similar commands defined by the % old packages \pack{multind} and \pack{index}. % \begin{macrocode} \renewcommand{\index}[2][]{\@bsphack\@esphack} \def\@index[#1]{% \@ifundefined{#1@idxfile}% {\PackageWarning{imakeidx}{Undefined index file `#1'}% \begingroup \@sanitize \imki@nowrindex}% {\edef\@idxfile{#1}% \begingroup \@sanitize \@wrindex\@idxfile}} \def\imki@nowrindex#1{\endgroup\@esphack} % \end{macrocode} % % Command \cs{@wrindex} must be duplicated; we have to call it the % same as usual in order to support \pack{hyperref}. But the real name % will be given at the end. % \begin{macrocode} \def\imki@wrindexsplit#1#2{% \expandafter\protected@write\csname#1@idxfile\endcsname{}% {\string\indexentry{#2}{\thepage}}% \endgroup \@esphack} \def\imki@wrindexunique#1#2{% \protected@write\@indexfile{}% {\string\indexentry[#1]{#2}{\thepage}}% \endgroup \@esphack} % \end{macrocode} % % ^^A E - \printindex % % Compilation of the indices is disabled if \texttt{-shell-escape} has % not been given or the restricted mode is not active; in this case we % emit a warning. \XeTeX{} has \cs{shellescape} instead of % \cs{pdfshellescape}, so we take care of this (hoping that users or % packages don't define a \cs{shellescape} command). In any case we % define an internal version of this command. In the case of % \prog{luatex} we can't emit the proper messages and hope that Heiko % Oberdiek will update \pack{pdftexcmds}; for the moment we set % \cs{imki@shellescape} to~$1$. The conditional % \cs{ifKV@imki@noautomatic} is defined by \cs{define@boolkey} above. % % \begin{macrocode} \def\imki@shellwarn{} \ifdefined\imki@shellescape % luatex >= 0.60 \chardef\imki@shellescape=\@ne % \RequirePackage{pdftexcmds}% % \chardef\imki@shellescape=\pdf@shellescape \else \@ifundefined{shellescape} {\let\imki@shellescape\pdfshellescape} {\let\imki@shellescape\shellescape} \fi \ifnum\imki@shellescape=\z@ \let\KV@imki@noautomaticfalse\KV@imki@noautomatictrue \KV@imki@noautomatictrue \def\imki@shellwarn{\MessageBreak or call \imki@engine\space with -shell-escape} \fi % \end{macrocode} % Do the same if \Kvalue{noautomatic} has been given as an option. % \begin{macrocode} \ifimki@disableautomatic \let\KV@imki@noautomaticfalse\KV@imki@noautomatictrue \KV@imki@noautomatictrue \fi % \end{macrocode} % % Now we set up the \texttt{theindex} environment. If the % \texttt{original} option is set, we simply patch the class % definition in order to call the macro that does the work related to % the table of contents. Otherwise we define a new \texttt{theindex} % environment, based on the standard, but using, if the number of % columns is greater than one, the \texttt{multicols} environment. % Users needing a different setup can use the \cs{indexsetup} command. % \begin{macrocode} \ifimki@original \expandafter\def\expandafter\theindex\expandafter{\expandafter \imki@maybeaddtotoc\theindex} \else \global\let\imki@idxprologue\relax \RequirePackage{multicol} \renewenvironment{theindex} {\imki@maybeaddtotoc \imki@indexlevel{\indexname}\imki@indexheaders \thispagestyle{\imki@firstpagestyle}% \ifnum\imki@columns>\@ne \columnsep \imki@columnsep \ifx\imki@idxprologue\relax \begin{multicols}{\imki@columns} \else \begin{multicols}{\imki@columns}[\imki@idxprologue] \fi \else \imki@idxprologue \fi \global\let\imki@idxprologue\relax \parindent\z@ \parskip\z@ \@plus .3\p@\relax \columnseprule \ifKV@imki@columnseprule.4\p@\else\z@\fi \raggedright \let\item\@idxitem \imki@othercode} {\ifnum\imki@columns>\@ne\end{multicols}\fi % \clearpage } \fi % \end{macrocode} % % The command \cs{indexsetup} may be used to customize some aspects of % index formatting. % \begin{macrocode} \def\imki@indexlevel{% \@ifundefined{chapter}{\section}{\chapter}*} \define@key{imkiindex}{level}{\def\imki@indexlevel{#1}} \def\imki@toclevel{% \@ifundefined{chapter}{section}{chapter}} \define@key{imkiindex}{toclevel}{\def\imki@toclevel{#1}} \define@boolkey{imkiindex}{noclearpage}[true]{\let\imki@clearpage\relax} \def\imki@indexheaders{% \@mkboth{\MakeUppercase\indexname}{\MakeUppercase\indexname}} \define@key{imkiindex}{headers}{\def\imki@indexheaders{\markboth#1}} \def\imki@firstpagestyle{plain} \define@key{imkiindex}{firstpagestyle}{\def\imki@firstpagestyle{#1}} \let\imki@othercode\relax \define@key{imkiindex}{othercode}{\def\imki@othercode{#1}} \newcommand{\indexsetup}[1]{% \ifimki@original\else\setkeys{imkiindex}{#1}\fi} \@onlypreamble\indexsetup % \end{macrocode} % % The command \cs{indexprologue} sets the internal version which is % always \cs{let} to \cs{relax} during |\begin{theindex}|. % \begin{macrocode} \newcommand{\indexprologue}[2][\bigskip]{% \long\gdef\imki@idxprologue{{#2\par}#1}} % \end{macrocode} % % Now we provide the relevant \cs{printindex} macros by transferring % the real job to a secondary macro \cs{imki@putindex} after due % checks and messages. % \begin{macrocode} \providecommand*{\printindex}{} \renewcommand*{\printindex}[1][\jobname]{% \@ifundefined{#1@idxfile}{\imki@error{#1}}{\imki@putindex{#1}}} \def\imki@error#1{% \def\@tempa{#1}\def\@tempb{\jobname}% \ifx\@tempa\@tempb \let\imki@optarg\@empty \else \def\imki@optarg{[#1]}% \fi \PackageError{imakeidx} {Misplaced \protect\printindex\imki@optarg} {You are not making this index, as no appropriate \protect\makeindex\MessageBreak command has been issued in the preamble.}} % \end{macrocode} % % We define a command to do a \cs{cleardoublepage} if the option % \Kvalue{openright} holds (in classes where \Kvalue{twoside} is % meaningful). In case \cs{chapter} is defined but not % \cs{if@openright}, we assume that the class wants ``open right''. % \begin{macrocode} \def\imki@clearpage{% \@ifundefined{chapter} {\clearpage} % article and similar classes {\@ifundefined{if@openright} {\cleardoublepage} {\if@openright \cleardoublepage \else \clearpage \fi} }} % \end{macrocode} % % We need a helper macro to do a check in order to avoid a loop and % the hook where to insert the table of contents related stuff. % \begin{macrocode} \def\imki@check@indexname{\indexname} \providecommand*\imki@maybeaddtotoc{} % \end{macrocode} % Two helper macros for preparing the final messages to the user. % \begin{macrocode} \def\imki@finalmessage#1{% \expandafter\edef\csname imki@message#1\endcsname {\imki@program\imki@options#1.idx} \AtEndDocument{\PackageWarning{imakeidx}{% Remember to run \imki@engine\space again after calling\MessageBreak `\@nameuse{imki@message#1}'\imki@shellwarn\@gobble}}} \def\imki@splitindexmessage{% \AtEndDocument{\PackageWarningNoLine{imakeidx}{% Remember to run \imki@engine\space again after calling\MessageBreak `splitindex' and processing the indices\imki@shellwarn}}} % \end{macrocode} % % Here is a helper macro for deciding whether to call the external % utility or to issue a final message. In \cs{imki@makeindexname} we % put the name of the only program allowed by default % (\prog{makeindex}). If the list is updated, we can supplement the % list here, maybe defining a list macro; for now this is % sufficient. The temporary switch \cs{if@tempswa} is set to true if % automatic processing is possible, so that the main macro can take % the appropriate action. % \begin{macrocode} \def\imki@makeindexname{makeindex} \def\imki@decide{% \@tempswafalse \ifimki@splitindex % splitindex is not "safe" \ifnum\imki@shellescape=\@ne\@tempswatrue\fi \else \ifx\imki@program\imki@makeindexname % nor is texindy \ifnum\imki@shellescape=\tw@\@tempswatrue\fi \fi \ifnum\imki@shellescape=\@ne\@tempswatrue\fi \fi \ifKV@imki@noautomatic \@tempswafalse \fi} % \end{macrocode} % We now define the main macro that puts the specified index file into % the document and possibly orders to add the index title to the % table of contents. It is duplicated as usual. The argument |#1| is % the specific symbolic name of the index. In particular if the % \Kvalue{intoc} option has been specified, the hook % \cs{imki@maybeaddtotoc} is defined in such a way that the relevant % information is added to the \texttt{toc} file. The % \cs{phantomsection} command is necessary when using \pack{hyperref}; % here it is hidden as argument to \cs{@nameuse}, so it is equivalent % to \cs{relax} and does nothing if \pack{hyperref} has not been % loaded. % \begin{macrocode} \def\imki@putindexsplit#1{% \ifimki@nonewpage\else \imki@clearpage \fi \immediate\closeout\csname #1@idxfile\endcsname \let\imki@indexname\indexname % keep \indexname \@nameuse{imki@set@#1}\imki@decide \if@tempswa % we can call the external program \imki@exec{\imki@program\imki@options#1.idx}% \else \imki@finalmessage{#1}% \fi \ifKV@imki@intoc \def\imki@maybeaddtotoc{\@nameuse{phantomsection}% \addcontentsline{toc}{\imki@toclevel}{\imki@title}}% \else \def\imki@maybeaddtotoc{}% \fi \ifx\imki@title\imki@check@indexname\else \def\indexname{\imki@title}% \fi \@input@{#1.ind} \let\indexname\imki@indexname % restore \indexname } \newif\ifimki@splitdone \def\imki@putindexunique#1{% \ifimki@nonewpage\else \imki@clearpage \fi \let\imki@indexname\indexname % keep \indexname \@nameuse{imki@set@#1}\imki@decide \if@tempswa % we can call the external program \ifimki@splitdone\else \immediate\closeout\@indexfile \imki@exec{splitindex \imki@splitindexoptions\space\jobname.idx}% \global\imki@splitdonetrue \fi \else \ifimki@splitdone\else \imki@splitindexmessage\global\imki@splitdonetrue \fi \fi \if@tempswa % we can call the external program \imki@exec{\imki@program\imki@options\jobname-#1.idx}% \fi \ifKV@imki@intoc \def\imki@maybeaddtotoc{\@nameuse{phantomsection}% \addcontentsline{toc}{\imki@toclevel}{\imki@title}}% \else \def\imki@maybeaddtotoc{}% \fi \ifx\imki@title\imki@check@indexname\else \def\indexname{\imki@title}% \fi \@input@{\jobname-#1.ind} \let\indexname\imki@indexname % restore \indexname } % \end{macrocode} % % ^^A F - Final decisions % % At this point, we choose the meaning of the relevant commands, % reclaiming the space occupied by the discarded ones % \begin{macrocode} \ifimki@splitindex \let\imki@startidx\imki@startidxunique \let\@wrindex\imki@wrindexunique \let\imki@putindex\imki@putindexunique \let\imki@startidxsplit\@undefined \let\imki@wrindexsplit\@undefined \let\imki@putindexsplit\@undefined \else \let\imki@startidx\imki@startidxsplit \let\@wrindex\imki@wrindexsplit \let\imki@putindex\imki@putindexsplit \let\imki@startidxunique\@undefined \let\imki@wrindexunique\@undefined \let\imki@putindexunique\@undefined \fi % \end{macrocode} % The end. % \Finale