% Package robustindex.sty, Wilberd van der Kallen 2005, 2017.
%
% 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 until 
% labels are stable.
% As usual a makeindex run has to be preceded and also followed by its
% LaTeX or pdflatex run.
%
%
% If you use hyperref, you must choose the option hyperindex=false.  
% 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}
%
% Automatic page ranges are not supported.
% 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}.
%
%
% 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.
%
% Remark.
% The package imakeidx also synchronises the index with the manuscript,
% but it has a different method and different requirements.
%
% https://www.staff.science.uu.nl/~kalle101/stind
%
% Copyright 2017 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}
  [2017/08/31
  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
}%

\newif\ifinside@range% output must be supressed inside page range.
\inside@rangefalse

\newcommand{\indpageref}[1]{%
\ifinside@range \findEndPageRange\else
   \ifnum\c@maxindctr<#1\relax\setcounter{maxindctr}{#1}\fi
   \pageref{\indstring#1}%
   \fi
}%

\newcommand{\indexpreamble}{\relax}% compare the preamble of makeindex

\newcommand{\indexincontents}{%
  \def\indexpreamble{%
     \refstepcounter{subsection}%
   % This creates a hyperlink destination.
   % Compare phantomsection in hyperref.
   % An index is not to be followed immediately by a subsection.
     \addcontentsline{toc}%
        {\ifx\c@chapter\undefined section\else chapter\fi}{\indexname}%
  }%
}%

\newcommand{\old@theindex}{}%

\let\old@theindex\theindex

\newcommand{\cndhyprndxwrng}{%
    \ifHy@hyperindex
       \PackageWarning{robustindex}{%
          Use option hyperindex=false in hyperref. Hyperlinks in the index
	  will be made through \string\pageref. Detected%
       }%
    \fi
}%

\def\theindex{%
   \old@theindex
   \indexpreamble
   \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{robustindex}{%
	    Package needs \string\make index in preamble,
	    and if you use hyperref, you must
	    use option hyperindex=false. Detected%
	 }%
      \else
         \PackageWarning{robustindex}{%
            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 suppress one page number.
      \protect\gobbleindpageref
}%


% Now it gets ugly, 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]{%
     \findleft@brack#1(\relax{#2}%
}%

\newcommand{\findleft@brack}{}%

\def\findleft@brack#1(#2\relax#3{%
   \ifx|#1| \dropleft@brack#2{#3}% bracket ( found.
   \else \findright@brack#1)\relax{#3}%
   \fi
}%

\newcommand{\dropleft@brack}{}%

\def\dropleft@brack#1(#2{%
   \ifx|#1|\indpageref{#2}\inside@rangetrue%
   \else
      \csname #1\endcsname{\indpageref{#2}}\inside@rangetrue%
   \fi
   % output for this key must be suppressed until end of range.
   \findEndPageRange%
}%


\newcommand{\findEndPageRange}{}% Name is helpful in error message if end not found.

\def\findEndPageRange#1,{% It actually removes a comma.
   \ignorespaces #1%
}%

\newcommand{\findright@brack}{}%

\def\findright@brack#1)#2\relax#3{%
   \ifx|#1|\unskip \dropright@brack#2{#3}% bracket ) found.
   \else
      \ifinside@range
        \findEndPageRange
      \else
        \csname#1\endcsname{\indpageref{#3}}%
      \fi
   \fi
}%

\newcommand{\dropright@brack}{}%

\def\dropright@brack#1)#2{%
   \inside@rangefalse% output no longer suppressed.
   \ifx|#1|\unskip \mbox{--}\nobreak\indpageref{#2}%
   \else
      \unskip \mbox{--}\nobreak\csname #1\endcsname{\indpageref{#2}}%
   \fi
   \ignorespaces
}%

\relax
