hyperref
hyperref copied to clipboard
Hyperref shifts location of "see" and "see also" in index
First a minimal working example is as follows.
\documentclass{report}
\usepackage{makeidx}
\makeindex
\usepackage{hyperref}
\begin{document}
foo\index{foo}\index{foo|seealso{bar}}
foo\index{foo}
bar\index{bar}
\printindex
\end{document}
Index page output without the \usepackage{hyperref}
line is as follows. The last output line correctly sees the pageno located before the see also reference.
Index bar, 1 foo, 1, see also bar
However, index page output including the \usepackage{hyperref}
line incorrectly/undesirably relocates the see also reference before the pageno.
Index bar, 1 foo, see also bar, 1
Question: How can I have my cake and eat it too, i.e., include hyperref
but locate pageno references before see and see also index entry text as in the output without hyperref
?
Could hyperref
fix the question?
Similar: Hyperref shifts location of "see" and "see also" in index. How to restore? on TeX-SX
Similar: Hyperref shifts location of "see" and "see also" in index. How to restore? on TeX-SX
While the solution in the link doesn't work as before since it produces no hyperlinks on pagenoes any more. Also I think it should be a bug of hyperref
.
While the solution in the link doesn't work as before since it produces no hyperlinks on pagenoes any more.
No hyperlinks on page numbers, really? In some examples of that answer, although package option hyperindex=false
is used, hyperlink commands like \hyperpage
are added back through .ist
files.
When two indices share the same entry are
- on different pages, then they're ordered by page numbers;
- on the same page, and only one has encap field, like
\index{foo}\index{foo|seealso{bar}}
, then the one without encap comes first (that's whysee also
comes last in your example, withouthyperref
); - on the same page, and both have encap field, then they're ordered by their encap fields/strings, see relevant lines in
makeindex
's source file.
The third case is the case when hyperref
is loaded with default setting hyperindex=true
. It converts \index{foo}
and \index{foo|seealso{bar}}
to \indexentry{foo|hyperpage}{1}
and \indexentry{foo|hyperindexformat{\seealso{bar}}}{1}
, respectively. Then since i
< p
, see also comes first.
Inn the latex step which generates .idx
, it may be impossible to keep two group of index entries having the same order:
-
\indexentry{foo}{1}
and\indexextry{foo|seealso{bar}}{1}
-
\indexentry{foo|<encap1>}{1}
and\indexentry{foo|<encap2>{\seealso{bar}}}{1}
But it's feasible to solve the problem in the makeindex step, which generates .ind
from .idx
, with a .ist
style file. hyperref
package manual, sec. 13.2 Index with makeindex contains one such .ist
example, but it seems it doesn't work for entries with encap. Here's my attempt:
\begin{filecontents}[noheader, force]{hyperpage.ist}
delim_0 ", \\hyperpageIdx{"
delim_1 ", \\hyperpageIdx{"
delim_2 ", \\hyperpageIdx{"
delim_n "}\\nil, \\hyperpageIdx{"
delim_t "}\\nil"
encap_prefix "\\"
encap_infix "}{{"
encap_suffix "}"
\end{filecontents}
\documentclass{article}
\usepackage{makeidx}
\makeindex
\usepackage{etoolbox} % for \ifstrempty
\usepackage[hyperindex=false]{hyperref}
% no encap, e.g., \hyperpageIdx{1}\relax
% with encap, e.g., \hyperpageIdx{\seealso{bar}}{{2}}\relax
\def\hyperpageIdx#1#2\nil{%
\ifstrempty{#2}
{\hyperpage{#1}}
{\ignorespaces#1{\hyperpage#2}}%
}
\def\seexalso#1#2{\emph{see xalso} #1} % "a" < "x" so "seealso" < "seexalso"
\begin{document}
text\index{bar}
\index{diff pages I}
\index{diff pages II|seealso{bar}}
\index{same page, one encaped}
\index{same page, one encaped|seealso{bar}}
\index{same page, both encaped|seealso{bar}}
\index{same page, both encaped|seexalso{bar}}
\newpage
text
\index{diff pages I|seealso{bar}}
\index{diff pages II}
\printindex
\end{document}
While the solution in the link doesn't work as before since it produces no hyperlinks on pagenoes any more.
No hyperlinks on page numbers, really? In some examples of that answer, although package option
hyperindex=false
is used, hyperlink commands like\hyperpage
are added back through.ist
files.When two indices share the same entry are
- on different pages, then they're ordered by page numbers;
- on the same page, and only one has encap field, like
\index{foo}\index{foo|seealso{bar}}
, then the one without encap comes first (that's whysee also
comes last in your example, withouthyperref
);- on the same page, and both have encap field, then they're ordered by their encap fields/strings, see relevant lines in
makeindex
's source file.The third case is the case when
hyperref
is loaded with default settinghyperindex=true
. It converts\index{foo}
and\index{foo|seealso{bar}}
to\indexentry{foo|hyperpage}{1}
and\indexentry{foo|hyperindexformat{\seealso{bar}}}{1}
, respectively. Then sincei
<p
, see also comes first.Inn the latex step which generates
.idx
, it may be impossible to keep two group of index entries having the same order:
\indexentry{foo}{1}
and\indexextry{foo|seealso{bar}}{1}
\indexentry{foo|<encap1>}{1}
and\indexentry{foo|<encap2>{\seealso{bar}}}{1}
But it's feasible to solve the problem in the makeindex step, which generates
.ind
from.idx
, with a.ist
style file.hyperref
package manual, sec. 13.2 Index with makeindex contains one such.ist
example, but it seems it doesn't work for entries with encap. Here's my attempt:\begin{filecontents}[noheader, force]{hyperpage.ist} delim_0 ", \\hyperpageIdx{" delim_1 ", \\hyperpageIdx{" delim_2 ", \\hyperpageIdx{" delim_n "}\\nil, \\hyperpageIdx{" delim_t "}\\nil" encap_prefix "\\" encap_infix "}{{" encap_suffix "}" \end{filecontents} \documentclass{article} \usepackage{makeidx} \makeindex \usepackage{etoolbox} % for \ifstrempty \usepackage[hyperindex=false]{hyperref} \makeatletter % no encap, e.g., \hyperpageIdx{1}\relax % with encap, e.g., \hyperpageIdx{\seealso{bar}}{{2}}\relax \def\hyperpageIdx#1#2\nil{% \ifstrempty{#2} {\hyperpage{#1}} {\ignorespaces#1{\hyperpage#2}}% } \makeatother \def\seexalso#1#2{\emph{see xalso} #1} % "a" < "x" so "seealso" < "seexalso" \begin{document} text\index{bar} \index{diff pages I} \index{diff pages II|seealso{bar}} \index{same page, one encaped} \index{same page, one encaped|seealso{bar}} \index{same page, both encaped|seealso{bar}} \index{same page, both encaped|seexalso{bar}} \newpage text \index{diff pages I|seealso{bar}} \index{diff pages II} \printindex \end{document}
I don't know why this doesn't work in MacTeX 2022 which is used on my Mac.
Did you specify makeindex -s hyperpage.ist <main>
?