9

I have managed to create an index where the page number links to the correct page. But I would like it to link to the correct part of the page, not to the top of the page. Is this possible?

Here is the code I have so far (on GitHub with Makefile) and explicitly:

\documentclass[a5paper]{book}
\usepackage{makeidx}  % for automatically generation of an index
\usepackage{hyperref} % has to be after makeidx
\usepackage[margin=2.5cm]{geometry} % layout

\makeindex

\begin{document}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, 
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea 
rebum. Stet \index{clita} clita kasd gubergren, no sea takimata sanctus 
est Lorem 
ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum 
dolor sit amet.   

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum dolore eu feugiat nulla facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.   

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, 
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea 
rebum. Stet clita kasd gubergren, no sea takimata sanctus 
est Lorem 
ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum 
dolor sit amet.   

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum \index{dolore} dolore eu feugiat nulla facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.   

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, 
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea 
rebum. Stet \index{clita} clita kasd gubergren, no sea takimata sanctus 
est Lorem 
ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita \index{kasd} kasd gubergren, no sea takimata sanctus est Lorem ipsum 
dolor sit amet.   

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum dolore eu feugiat nulla facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.   

\printindex % print the automatically created index

\end{document}
lockstep
  • 250,273
Martin Thoma
  • 18,799

1 Answers1

12

Assuming you'll only have one instance of an index for a given term per page, you can set up a hypertarget when you index the term like this:

\documentclass[a5paper]{book}
\usepackage{etoolbox}
\usepackage{makeidx}  % for automatically generation of an index
\usepackage[hyperindex=false]{hyperref} % has to be after makeidx
\usepackage[margin=2.5cm]{geometry} % layout

\newcounter{indexanchor}

\newcommand*{\xindex}[1]{%
  \stepcounter{indexanchor}% make anchor unique
  \def\theindexterm{#1}%
  \edef\doindexentry{\noexpand\index
    {\expandonce\theindexterm|indexanchor{index-\theindexanchor}}}%
  \raisebox{\baselineskip}{\hypertarget{index-\theindexanchor}%
    {\doindexentry}}%
}

\newcommand*{\indexanchor}[2]{\hyperlink{#1}{#2}}

\makeindex

\begin{document}
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, 
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea 
rebum. Stet \xindex{clita} clita kasd gubergren, no sea takimata
sanctus 
est Lorem 
ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum 
dolor sit amet.   

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum dolore eu feugiat nulla facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.   

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, 
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea 
rebum. Stet clita kasd gubergren, no sea takimata sanctus 
est Lorem 
ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum 
dolor sit amet.   

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum \xindex{dolore} dolore eu feugiat nulla
facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.   

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam 
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam 
erat, 
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea 
rebum. Stet \xindex{clita} clita kasd gubergren, no sea takimata
sanctus 
est Lorem 
ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur 
sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore 
et dolore magna aliquyam erat, sed diam voluptua. At vero eos et 
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, 
no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum 
dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod 
tempor invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. 
Stet clita \xindex{kasd} kasd gubergren, no sea takimata sanctus est
Lorem ipsum 
dolor sit amet.   

Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse 
molestie consequat, vel illum dolore eu feugiat nulla facilisis at 
vero eros et accumsan et iusto odio dignissim qui blandit praesent 
luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam 
nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat 
volutpat.   

\printindex % print the automatically created index

\end{document}
Nicola Talbot
  • 41,153
  • I tried your solution with Adobe Reader 9 and Ubuntus Document Viewer 2.30.3. It worked, but the view was one line too low. Is it possible to fix that? (I've also tried it with Google Chrome, but it didn't work at all. I guess this is an error of Chrome and can't be fixed.) – Martin Thoma Oct 17 '12 at 06:23
  • @moose I've edited my answer so that it raises the target by one line. – Nicola Talbot Oct 17 '12 at 07:34
  • Works like a charm. Thank you very much :-) – Martin Thoma Oct 17 '12 at 18:22
  • Thank you very much for this. Nevertheless, I'm having problems with the amsmath package. If you try to index a sum like this: \xindex{$\sum_{i\in I}\kappa_i$} some spurious '@' appear in the idx file, and the entry gets rejected. On the other hand, this works with \lim. Do you have any idea on how to solve this? – Pedro Sánchez Terraf Jan 08 '17 at 18:11
  • @PedroSánchezTerraf I can't reproduce the problem, but it sounds as though you have a command that's expanding to an internal command when it's being written to the .idx file. If so, try adding \protect before the command to prevent expansion. If that doesn't work, I think you'll need to post a follow-up question with a MWE that shows the problem. – Nicola Talbot Jan 09 '17 at 13:18
  • It worked! :-) Because of this, I'm not sure if it's worth another question, but the MWE is this: In your example, add \usepackage{amsmath} before the \newcounter, and add \xindex{$\sum_{i\in I}\kappa_i$} anywhere in the text. In the idx file, I obtain an entry of the shape:

    \indexentry{$\DOTSB \sum@ \slimits@ _{i\in I}\kappa _i$|indexanchor{index-1}}{1},

    which is rejected while running makeindex. Protecting \sum solves the problem, but perhaps you can come up with a uniform solution. If that's so, I'll be happy to post a new question for you.

    – Pedro Sánchez Terraf Jan 09 '17 at 14:24
  • 1
    @PedroSánchezTerraf It looks like amsmath changes the definition of \sum which is causing the expansion. I can't think of a uniform solution (there may be commands that need expansion in some contexts) but it's possible someone else might be able to suggest something. (Another possibility is to make the problem commands robust, e.g. using etoolbox's \robustify command, but you still need to know which commands are problematic.) – Nicola Talbot Jan 10 '17 at 09:19
  • Thank you very much. (It's a pity that thanking in this area is discouraged.) – Pedro Sánchez Terraf Jan 10 '17 at 18:56
  • 1
    I have used this solution for a text I'm preparing, and while proof-checking I noticed that lines containing the \xindex macro are a bit taller (it can be seen in your example code). A solution is that the hypertarget have height 0. \raisebox has an optional argument, but it can't be used inside that code. I managed to define a macro \raiseboxzero that does that by working on \raisebox's definition, but perhaps there is a more elegant solution. – Pedro Sánchez Terraf Dec 06 '18 at 00:36
  • The code is \makeatletter \long\def\raiseboxzero#1#2{\@begin@tempboxa\hbox{#2}\setlength\@tempdima{#1}\setlength\@tempdimb{0pt}\setbox\@tempboxa\hbox{\raise\@tempdima\box\@tempboxa}\ht\@tempboxa\@tempdimb\box\@tempboxa\@end@tempboxa} \makeatother and then I replace \raisebox in your definition by \raiseboxzero. (I'm having trouble to put it in a codeblock.) – Pedro Sánchez Terraf Dec 06 '18 at 00:40
  • A simpler solution is replacing \raisebox{\baselineskip}{…} by \raisebox{\baselineskip}[0pt]{…} (the optional argument is the height of the final box). – Circumscribe Jan 25 '19 at 12:08