10

I am trying to work out a modification of the index in a complex document. The point is, I have a table of contents and so on. But we also want to add an index for specific terms like in:

" .... a so-called analysis of variance \index{analysis of variance}: ......".

Now, with hyperref the command index usually produces an entry to the index which is associated with the page number, then in the index you click on the page number and you get to the correct page. Very good, but we want to make the hyperlink to the SECTION instead of the page. I have found that I can change the way the .idx file is written by makeindex under hyperref, but to get to the end of it I need to insert into the command the label of the section instead of the page number. Now the present version does the page with the "\thepage" command, so I am looking to find something similar for the section by referencing to the section label which would allow things to work fine (I have tried to insert the label manually in the .idx file and it is OK, but I want makeindex to do that.... ;) ). Or, of course, if someone knows of an easier way to solve my original problem, I would be even happier....

8
  • Welcome to TeX.SX! No variable contains the string of the last label. Maybe it's better to explain your real problem; do you mean the value the label is assigned to?
    – egreg
    Commented Nov 19, 2014 at 17:00
  • Well the opriginal problem is that I am trying to make an index with hyperlinks to the sections instead of to the pages, which is what the hyperref package does. To do so, I have found that I can chage the way the .idx file is written by makeindex under hyperref, but to get to the end of it I need to insert into the command the label of the section instead of the page number. Now the present version does the page with the "\thepage" command, I was looking for something similar about the section.... I hope I have been more clear this time! Thank you! Commented Nov 19, 2014 at 17:02
  • For that use don't you want the section title (or section number) rather than the internal identifier used by label? label values are not intended to ever be printed. Commented Nov 19, 2014 at 17:03
  • @PierGiorgio I think we are going to need a fuller example to see what you mean here: sections are not normally indexed (perhaps you mean a table of contents?). It looks a bit like an 'X-Y' problem (you want to solve X but you've asked Y).
    – Joseph Wright
    Commented Nov 19, 2014 at 17:06
  • Of course I will want the section number to be printed, but the hyperreference wouldn't work if I didn't provide it with a label. And yes, I know my labels are very long, this is due to the fact that this is a cooperative writing and it is the best way we could find not to make a mess with labels written by different persons........ Commented Nov 19, 2014 at 17:07

1 Answer 1

8

Assumptions:

  • Document class with numbered sections, subsections, and subsubsections.
  • No index entries in unnumbered (sub)(sub)sections.
  • In the index should appear the (sub)(sub)section number instead of the page number.
  • hyperref is loaded.
  • Unspecified is the link target for the section numbers. Should the link go to the start of the section (maybe some pages earlier) or to the indexed page? The example provides both, see the two lines with \hyperlink.
  • Standard anchor generation of hyperref (hypertexnames, naturalnames=false, pageanchor).
  • Arabic (sub)(sub)section numbers.

With these assumptions, the following example patches the index writing to add the (sub)(sub)section values to the page number, constructing a composite page number (Makeindex supports up to ten parts). This also should automatically disable implicit page ranges (don't make too much sense with section numbers).

A project specific style file \jobname.mst redefines some keys to insert a macro in front of the page numbers. Because of the fixed format of the page number curly braces around the argument are not needed.

Then the anchor names can be calculated using the counter values stored in the composite artificial page number of the index entry.

Full example:

% Project specific makeindex style file "\jobname.mst"
% CAUTION: The file "\jobname.mst" will be overwritten
%          without asking, if package "filecontents" is loaded.
\RequirePackage{filecontents}
\begin{filecontents*}{\jobname.mst}
delim_0 ", \\MyIndexPage "
delim_1 ", \\MyIndexPage "
delim_2 ", \\MyIndexPage "
delim_3 ", \\MyIndexPage "
delim_n ", \\MyIndexPage "
delim_r "--\\MyIndexPage "
encap_prefix "\\MyEncap\\"
encap_infix "{\\MyIndexPage "
encap_suffix "}"
\end{filecontents*}

\documentclass{article}

\usepackage{makeidx}
\makeindex

\usepackage{etoolbox}
\makeatletter
\patchcmd{\@wrindex}{\thepage}{%
  \thepage
  -% page compositor
  \the\value{section}%
  -% page compositor
  \the\value{subsection}%
  -% page compositor
  \the\value{subsubsection}%
  -42% end tag
}{}{%
  \errmessage{Could not patch \string\@wrindex}%
}

\@addtoreset{subsubsection}{section}% before hyperref

\newcommand*{\MyEncap}{\@gobble{MyEncap}}
\newcommand*{\MyIndexPage}{%
  \@ifnextchar{\MyEncap}{}{\@MyIndexPage}%
}
\def\@MyIndexPage #1-#2-#3-#4-42{%
  % #1: \thepage
  % #2: \value{section}
  % #3: \value{subsection}
  % #4: \value{subsubsection}
  \edef\SectionNumber{%
    \number#2%
    \ifnum#3>0 %
      .\number#3%
      \ifnum#4>0 %
        .\number#4%
      \fi
    \fi
  }%
  \edef\SectionAnchor{%
    \ifnum#4>0 %
      subsubsection.\number#2.\number#3.\number#4%
    \else
      \ifnum#3>0 %
        subsection.\number#2.\number#3%
      \else
        section.\number#2%
      \fi
    \fi  
  }%
  % \hyperlink{page.#1}{\SectionNumber}% link to page
  \hyperlink{\SectionAnchor}{\SectionNumber}% link to start of section
}


\usepackage[
  hyperindex=false,
  colorlinks,
]{hyperref}
\usepackage{bookmark}
\bookmarksetup{
  open,
  numbered,
}

\begin{document}

\section{First section}
\index{First}
\index{Section}
\index{Section!First}
\index{Foo|see{bar}}

\section{Second section}
\index{Second}
\index{Section}
\index{Section!Second}

\subsection{First subsection}
\index{First}
\index{Subsection}
\index{Subsection!First|textbf}

\subsubsection{First subsubsection}
\index{First}
\index{Subsubsection}
\index{Subsubsection!First|textit}

\subsection{Second subsection}
\index{Second}
\index{Subsection}
\index{Subsection!Second}

\subsection{Third subsection}
\index{Third}
\index{Subsection}
\index{Subsection!Third}

\subsubsection{Second subsubsection}
\index{Second}
\index{Subsubsection}
\index{Subsubsection!Second}

\addtocounter{subsection}{6}
\subsection{Last subsection}
\index{Last|fbox}
\index{Subsection}
\index{Subsection!Last}

\printindex
\end{document}

The raw index file \jobname.idx:

\indexentry{First}{1-1-0-0-42}
\indexentry{Section}{1-1-0-0-42}
\indexentry{Section!First}{1-1-0-0-42}
\indexentry{Foo|see{bar}}{1-1-0-0-42}
\indexentry{Second}{1-2-0-0-42}
\indexentry{Section}{1-2-0-0-42}
\indexentry{Section!Second}{1-2-0-0-42}
\indexentry{First}{1-2-1-0-42}
\indexentry{Subsection}{1-2-1-0-42}
\indexentry{Subsection!First|textbf}{1-2-1-0-42}
\indexentry{First}{1-2-1-1-42}
\indexentry{Subsubsection}{1-2-1-1-42}
\indexentry{Subsubsection!First|textit}{1-2-1-1-42}
\indexentry{Second}{1-2-2-0-42}
\indexentry{Subsection}{1-2-2-0-42}
\indexentry{Subsection!Second}{1-2-2-0-42}
\indexentry{Third}{1-2-3-0-42}
\indexentry{Subsection}{1-2-3-0-42}
\indexentry{Subsection!Third}{1-2-3-0-42}
\indexentry{Second}{1-2-3-1-42}
\indexentry{Subsubsection}{1-2-3-1-42}
\indexentry{Subsubsection!Second}{1-2-3-1-42}
\indexentry{Last|fbox}{1-2-10-0-42}
\indexentry{Subsection}{1-2-10-0-42}
\indexentry{Subsection!Last}{1-2-10-0-42}

The index file \jobname.ind, generated by Makeindex:

\begin{theindex}

  \item First, \MyIndexPage 1-1-0-0-42, \MyIndexPage 1-2-1-0-42, \MyIndexPage 
        1-2-1-1-42
  \item Foo, \MyIndexPage \MyEncap\see{bar}{\MyIndexPage 1-1-0-0-42}

  \indexspace

  \item Last, \MyIndexPage \MyEncap\fbox{\MyIndexPage 1-2-10-0-42}

  \indexspace

  \item Second, \MyIndexPage 1-2-0-0-42, \MyIndexPage 1-2-2-0-42, \MyIndexPage 
        1-2-3-1-42
  \item Section, \MyIndexPage 1-1-0-0-42, \MyIndexPage 1-2-0-0-42
    \subitem First, \MyIndexPage 1-1-0-0-42
    \subitem Second, \MyIndexPage 1-2-0-0-42
  \item Subsection, \MyIndexPage 1-2-1-0-42, \MyIndexPage 1-2-2-0-42, \MyIndexPage 
        1-2-3-0-42, \MyIndexPage 1-2-10-0-42
    \subitem First, \MyIndexPage 
        \MyEncap\textbf{\MyIndexPage 1-2-1-0-42}
    \subitem Last, \MyIndexPage 1-2-10-0-42
    \subitem Second, \MyIndexPage 1-2-2-0-42
    \subitem Third, \MyIndexPage 1-2-3-0-42
  \item Subsubsection, \MyIndexPage 1-2-1-1-42, \MyIndexPage 1-2-3-1-42
    \subitem First, \MyIndexPage 
        \MyEncap\textit{\MyIndexPage 1-2-1-1-42}
    \subitem Second, \MyIndexPage 1-2-3-1-42

  \indexspace

  \item Third, \MyIndexPage 1-2-3-0-42

\end{theindex}

And finally the index on the page:

Result

Update for \see

The first token after \MyIndexPage is the "encap" command (e.g.,\see). Therefore the updated example adds macro \MyEncap before the "encap" command and puts an additional \MyIndexPage before the page number in the argument of the "encap" command via the style file for makeindex:

encap_prefix "\\MyEncap\\"
encap_infix "{\\MyIndexPage "
encap_suffix "}"

Then \MyIndexPage is redefined in such a way, that it ignores itself, if an "encap" command follows, detected by the macro \MyEncap:

\newcommand*{\MyEncap}{\@gobble{MyEncap}}
\newcommand*{\MyIndexPage}{%
  \@ifnextchar{\MyEncap}{}{\@MyIndexPage}%
}
\def\@MyIndexPage #1-#2-#3-#4-42{%
  ...
}
6
  • There's no need for \RequirePackage{filecontents}.
    – egreg
    Commented Nov 19, 2014 at 18:41
  • If the contents of the file changes, then I want that it is automatically overwritten. Alternatively the part before \documentclass can be omitted and the file \jobname.mst can be created by an editor directly. Commented Nov 19, 2014 at 18:55
  • There's a question on the site about a case where a badly named filecontents environment caused deletion of the main file. You certainly know how to use the package and the environment, my concern is about the newbies.
    – egreg
    Commented Nov 19, 2014 at 20:32
  • @egreg I have added a warning hint in the source code. Commented Nov 20, 2014 at 5:40
  • @Heiko, your solution works very well, with some modifications I could do almost all I needed to do, but now I am stuck again, what happens is that I now need to add a \see command for some of the index entries, now having the \myindex before the \see does not allow it to work properly (for the \see, I do not want any hyperlink, just writing the argument of the \see); I tried to delete manually the \myindex from the .ind file, and it works fine, now I am trying to skip it automatically, any idea how I could do? Commented Nov 26, 2014 at 16:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .