% Package robustindex.sty, Wilberd van der Kallen Feb 2005. % % This package addresses two issues. % % 1. The main issue. % Third parties often change the page numbers without rerunning makeindex. % One would like to make the page numbers in the index entries more robust. % We use the \pageref mechanism for that. Only after adding, deleting or % otherwise modifying an \index{entry}, or after changing the order of the % index entries, does one have to rerun makeindex. % Other changes do not matter, as long as one runs LaTeX or pdflatex twice. % As usual a makeindex run has to be preceded and also followed by its % LaTeX or pdflatex run. % % 2. A patch. % The theindex environment does not create a hyperref destination. % Therefore we introduce \indexincontents. % It does what \addcontentsline{toc}{chapter}{Index} or % \addcontentsline{toc}{section}{Index} should have done in the first place: % When one clicks on the link that displays the word Index, one actually ends % up in the index. % Our patch is much more simpleminded than the tocbibind package. % % If you use hyperref, choose the option hyperindex=false. Otherwise hyperref % may block our code. And our package already gives hyperlinks in the % index. % Alternatively, you may go against the advice of hyperref and put our % package later. % % We tested a little with % % \usepackage[plainpages=false,hyperindex=false]{hyperref} % % The implicit page range formation of makeindex is disabled. % Commands of the type \index{entry|editing command} are supported, % but much more naively than in the encapsulating mechanism of makeindex. % For instance, \index{term|(textbf} may be followed by \index{term|)textit}, % but not by \index{term|textbf}, even if there is a later % \index{term|)textbf}. % % See robustsample.tex at % http://www.math.uu.nl/people/vdkallen/stind.html % for further details. % % There you find examples like % % \index{alpha!see beta} % \index{alpha!see also gamma\gobblepageref} % % \indexincontents % always put this before the index. % % Our package performs no miracles. But in simple situations all you need is % adding the \usepackage{robustindex} to the preamble. Do not exclude any % relevant files, as in \includeonly. % % Copyright 2005 Wilberd van der Kallen % % This file may be distributed under the conditions of the LaTeX Project Public % License, either version 1.2 of this license or (at your option) any % later version. The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.2 or later is part of all distributions of LaTeX % version 1999/12/01 or later. \ProvidesPackage{robustindex} [2005/02/24 index entries with pagerefs] \newcounter{indexctr}% \newcounter{maxindctr}% Used to check if number of \index commands has changed. \newcommand{\indstring}{ind.}% \def\@wrindex#1{% \stepcounter{indexctr}% \stepcounter{indexctr}% second time, to emulate makeindex -r. \@bsphack \protected@write \@auxout {}{% \string \newlabel {\indstring\theindexctr}{{\relax }{\thepage }% \ifx\ifHy@bookmarks\undefined\else{\relax }{page.\thepage }{}\fi% }% }% \@esphack \protected@write \@indexfile {}{\string \indexentry {\findencap#1|\relax }{\theindexctr}}% \findencap will check for the \endgroup % encap symbol | in the argument. \@esphack }% \newcommand{\indpageref}[1]{% \ifnum\c@maxindctr<#1\relax\setcounter{maxindctr}{#1}\fi \pageref{\indstring#1}% }% \newcommand{\indexpreamble}{\relax}% compare the preamble of makeindex \newcommand{\indexincontents}{% \def\indexpreamble{% \addcontentsline{toc}% {\ifx\c@chapter\undefined section\else chapter\fi}{\indexname}% }% }% \newcommand{\old@theindex}{}% \let\old@theindex\theindex \newcommand{\cndhyprndxwrng}{% \ifHy@hyperindex \PackageWarning{robustind}{% Use option hyperindex=false in hyperref. Hyperlinks in the index will be made through \string\pageref. Detected% }% \fi }% \def\theindex{% \old@theindex \refstepcounter{subsection}\indexpreamble % We use that \refstepcounter{subsection} creates a destination. % An index is not to be followed immediately by a subsection. % We do not use \phantomsection, as we do not assume hyperref is used. \ifx\ifHy@hyperindex\undefined\else\cndhyprndxwrng\fi }% \ifx\ifHy@hyperindex\undefined\else\Hy@hyperindexfalse\fi % If you put our package after the hyperref package, % then you probably do not mind our disabling its hyperindex mechanism. \AtEndDocument{% \ifnum\c@indexctr=\c@maxindctr \else \ifnum\c@indexctr=0% \PackageWarning{robustind}{% Package needs \string\make index in preamble, and if you use hyperref, you must use option hyperindex=false. Detected% }% \else \PackageWarning{robustind}{% Index not up to date, run makeindex. Detected% }% \fi \fi }% \newcommand{\wrappageref}{\protect\wrapindpageref}% \newcommand{\wrapindpageref}{}% \def\wrapindpageref#1, \indpageref#2{% \ifnum\c@maxindctr<#2\relax \setcounter{maxindctr}{#2}% \fi #1{\pageref{\indstring#2}}% }% \newcommand{\gobbleindpageref}{\wrappageref\@gobble} \newcommand{\gobblepageref}{% to supress one page number. \protect\gobbleindpageref }% % Now it gets technical, because we wish to implement a poor man's encap % mechanism, distinguishing \index{entry}, \index{entry|(}, \index{entry|)}, % \index{entry|(towrap}, \index{entry|)towrap}, where towrap is a sequence % of letters and \towrap is to be wrapped around \indpageref{countervalue}. \newcommand{\findencap}{}% \def\findencap#1|#2\relax{% \ifx\relax#2\relax #1|indpageref% The easy case \else #1|\wr@pencap#2% There is a | in the argument. \fi }% \newcommand{\wr@pencap}{}% \def\wr@pencap#1|{encpageref{#1}}% \newcommand{\encpageref}[2]{% \findleftbrack#1(\relax{#2}% }% \newcommand{\findleftbrack}{}% \def\findleftbrack#1(#2\relax#3{% \ifx|#1| \dropleftbrack#2{#3}% \else \findrightbrack#1)\relax{#3}% \fi }% \newcommand{\dropleftbrack}{}% \def\dropleftbrack#1(#2{% \unskip \ifx|#1|\indpageref{#2}% \else \csname #1\endcsname{\indpageref{#2}}% \fi \gobblecomma }% \newcommand{\gobblecomma}{}% \newcommand{\oldndpgrf}{}% \let\oldndpgrf\indpageref \def\gobblecomma#1,{% \def\indpageref{\rangewarning}% \ignorespaces #1% }% \newcommand{\rangewarning}{% \PackageWarning{robustind}{% You must first close the page range. Detected% }% }% \newcommand{\findrightbrack}{}% \def\findrightbrack#1)#2\relax#3{% \ifx|#1| \droprightbrack#2{#3} \else \csname#1\endcsname{\indpageref{#3}}% \fi }% \newcommand{\droprightbrack}{}% \def\droprightbrack#1)#2{% \let\indpageref\oldndpgrf \ifx|#1|\unskip \mbox{--}\nobreak\indpageref{#2}% \else \unskip \mbox{--}\nobreak\csname #1\endcsname{\indpageref{#2}}% \fi \ignorespaces }% \relax