0

In my document's preamble I have the following code related to showidx and hyperref, which also appears in many posts on this forum.

What is its purpose?

%Begin the ``quick and dirty hack'' due to Heiko Oberdiek which loads showidx
\makeatletter
\ifHy@hyperindex
  \def\HyInd@ParenLeft{(}%
% Hook in \HyInd@@wrindex
  \let\HyInd@showidx\@empty
% Hook in \HyInd@@wrindex for package showidx
  \def\HyInd@showidx#1{%
    \@showidx{#1}%
    \if@nobreak
      \ifvmode
        \nobrak
      \fi
    \fi
  }%
% Load package showidx
  \let\siOrg@makeindex\makeindex
  \let\siOrg@@index\@index
  \let\siOrg@@wrindex\@wrindex
  \let\siOrg@index\index
  \RequirePackage{showidx}
  \let\makeindex\siOrg@makeindex
  \let\@index\siOrg@@index
  \let\@wrindex\siOrg@@wrindex
  \let\index\siOrg@index
% rest of hyperref part
  \@ifpackageloaded{multind}{%
    \let\HyInd@org@wrindex\@wrindex
    \def\@wrindex#1#2{\HyInd@@wrindex{#1}#2||\\}%
    \def\HyInd@@wrindex#1#2|#3|#4\\{%
      \ifx\\#3\\%
        \HyInd@org@wrindex{#1}{#2|hyperpage}%
      \else
        \def\Hy@temp@A{#3}%
        \ifx\Hy@temp@A\HyInd@ParenLeft
          HyInd@org@wrindex{#1}{#2|#3hyperpage}%
        \else
          \HyInd@org@wrindex{#1}{#2|#3}%
        \fi
      \fi
    }%
  }{%
    \def\@wrindex#1{\@@wrindex#1||\\}
    \def\@@wrindex#1|#2|#3\\{%
      \ifx\\#2\\%
        \protected@write\@indexfile{}{%
          \string\indexentry{#1|hyperpage}{\thepage}%
        }%
      \else
        \def\Hy@temp@A{#2}%
        \ifx\Hy@temp@A\HyInd@ParenLeft
          \protected@write\@indexfile{}{%
             \string\indexentry{#1|#2hyperpage}{\thepage}%
          }%
        \else
          \protected@write\@indexfile{}{%
            \string\indexentry{#1|#2}{\thepage}%
          }%
        \fi
      \fi
      \endgroup
      \HyInd@showidx{#1}%
      \@esphack
    }%
  }%
\fi
\makeatother
%
%End the ``quick and dirty hack'' due to Heiko Oberdiek which loads showidx 

Among posts where this appears are: How to refer to indexed words, TOC, Chapter Toc, and Appendix misfunctions, How to restate a theorem keeping the same number?, How to display index entries on the same line as the text being indexed, Distinguish forward cross-references from backward cross-references.

murray
  • 7,944

1 Answers1

3

It was created as an answer to the question

hyperref appears to be trashing the index of my article document.
Without hyperref (which I really need), the index, generated
with makeidx package commands \makeindex and \printindex, looks great. 
With hyperref, which I tend to load with these options,

\usepackage[plainpages=false,hyperindex]{hyperref}

the index is collapsed from hundreds of entries with various page
numbers down to a single entry 

For more insight see https://groups.google.com/forum/#!topic/comp.text.tex/fof9f-cln-I

However tested 18 years later "the quick fix" (included in full below) is still needed to correct hyperref especially working with showidx with \documentclass{article}. Also see comment by @murry below suggesting there may be other cases for its use

"And with the memoir documentclass, where showidx is not explicitly loaded, but rather emulated by memoir ?" - murry

I am also including comments from Ulrike with reference to this from a deleted duplicate answer about its continued use.

"The hack has not been added to hyperref, and depending on the loading order either showidx or the hyperlinks from the index break. I don't think that the latter is really a problem as one doesn't need showidx for the final version of a document. I tested with Heiko's example in the google.groups you linked to after removing the hack (but leaving showidx). – Ulrike Fischer

enter image description here

Here is the source test file (in case the above link is lost)

%%% cut %%% test.tex %%% cut %%%
\documentclass{article}
\usepackage{makeidx}
\usepackage{hyperref}

\makeatletter
\ifHy@hyperindex
  \def\HyInd@ParenLeft{(}%
% Hook in \HyInd@@wrindex
  \let\HyInd@showidx\@empty
% Hook in \HyInd@@wrindex for package showidx
  \def\HyInd@showidx#1{%
    \@showidx{#1}%
    \if@nobreak
      \ifvmode
        \nobrak
      \fi
    \fi
  }%
% Load package showidx
  \let\siOrg@makeindex\makeindex
  \let\siOrg@@index\@index
  \let\siOrg@@wrindex\@wrindex
  \let\siOrg@index\index
  \RequirePackage{showidx}
  \let\makeindex\siOrg@makeindex
  \let\@index\siOrg@@index
  \let\@wrindex\siOrg@@wrindex
  \let\index\siOrg@index
% rest of hyperref part
  \@ifpackageloaded{multind}{%
    \let\HyInd@org@wrindex\@wrindex
    \def\@wrindex#1#2{\HyInd@@wrindex{#1}#2||\\}%
    \def\HyInd@@wrindex#1#2|#3|#4\\{%
      \ifx\\#3\\%
        \HyInd@org@wrindex{#1}{#2|hyperpage}%
      \else
        \def\Hy@temp@A{#3}%
        \ifx\Hy@temp@A\HyInd@ParenLeft
          HyInd@org@wrindex{#1}{#2|#3hyperpage}%
        \else
          \HyInd@org@wrindex{#1}{#2|#3}%
        \fi
      \fi
    }%
  }{%
    \def\@wrindex#1{\@@wrindex#1||\\}
    \def\@@wrindex#1|#2|#3\\{%
      \ifx\\#2\\%
        \protected@write\@indexfile{}{%
          \string\indexentry{#1|hyperpage}{\thepage}%
        }%
      \else
        \def\Hy@temp@A{#2}%
        \ifx\Hy@temp@A\HyInd@ParenLeft
          \protected@write\@indexfile{}{%
             \string\indexentry{#1|#2hyperpage}{\thepage}%
          }%
        \else
          \protected@write\@indexfile{}{%
            \string\indexentry{#1|#2}{\thepage}%
          }%
        \fi
      \fi
      \endgroup
      \HyInd@showidx{#1}%
      \@esphack
    }%
  }%
\fi
\makeatother

\makeindex
\begin{document}
\section{Hello World}
Hello\index{Hello} World\index{World}
\newpage
\index{abc}
abc def
\printindex
\end{document}
%%% cut %%% test.tex %%% cut %%%
  • And with the memoir documentclass, where showidx is not explicitly loaded, but rather emulated by memoir? – murray May 29 '19 at 22:02