1

Xindy for an index with cross references and hyperref do not play nice.

This is why I tried the approach of this question which disables hyperrefs automatic linking for indexes and then uses Xindy to add hypertargets and hyperlinks manually.

However, the approach in the linked question falls short for referencs to subindexentries like so:

\index{join!hash}
\index{hash join|see{join, hash}}

Which is why I tried to code an extension, however, the code does not work, the link targets seem broken. In a (now deleted) quesiton I checked that building the links works in a document.

Why don't the links to subentries work?

MWE:

%pdflatex
%xindy index.idx -M indexStyle -L english -C utf8
%pdflatex

\documentclass{article}
\usepackage{filecontents}

\begin{filecontents*}{indexStyle.xdy}
(define-location-class "arabic-page-numbers" ("arabic-numbers")             
:min-range-length 2)                            

(define-attributes (("definition" "usage" "default" "hyperpage")))


(define-crossref-class "see")
(markup-crossref-list :class "see" :open "\seelinkk{" :sep "; " :close "}{}")

(define-crossref-class "seealso")
(markup-crossref-layer-list :sep ", ")
(markup-crossref-list :class "seealso" :open "\seealsolinkk{" :sep "; " :close "}{}")

(define-crossref-class "hyperindexformat")
(markup-crossref-list :class "hyperindexformat" :open
"\hyperindexformat{" :sep "; " :close "}{}")


(define-location-class-order (
"arabic-page-numbers"
"see"
"seealso"))

(markup-index :open  "~n\begin{theindex}
    \providecommand*\lettergroupDefault[1]{}
    \providecommand*\lettergroup[1]{%
        \par\textbf{#1}\par
        \nopagebreak
    }
    \def\tedIDXlvlZero{}
    \def\tedIDXlvlOne{}
    \def\tedIDXlvlTwo{}

    \newcommand{\tedSetter}[1]{
        \if\tedLevel0
        \def\tedIDXlvlZero{#1}
        \else{
            \if\tedLevel1
            \def\tedIDXlvlOne{#1}
            \else
            \def\tedIDXlvlTwo{#1}
            \fi
        }\fi
    }
    \def\tedLevel{0}
    \newcommand{\buildlinktargett}[1]{%
        \if\tedLevel0%
        index:#1%
        \else{%
            \if\tedLevel1%
            index:\tedIDXlvlZero, #1%
            \else%
            %           \ifx\tedLevel\tedIDXlvlTwo %implicit%
            index:\tedIDXlvlZero, \tedIDXlvlOne, #1%
            \fi%
        }\fi%
    }
    \newcommand{\targetindexentryy}[1]{\tedSetter{#1}\hypertarget{\buildlinktargett{#1}}{#1}}
    \newcommand{\seelinkk}[1]{\see{\hyperlink{index:#1}{#1}}}
    \newcommand{\seealsolinkk}[1]{\seealso{\hyperlink{index:#1}{#1}}}
    ~n"     
    :close "~n~n\end{theindex}~n"
:tree)


(markup-indexentry :open "~n \def\tedLevel{0} \item "            :depth 0)
(markup-indexentry :open "~n \def\tedLevel{1}    \subitem "      :depth 1)
(markup-indexentry :open "~n \def\tedLevel{2}      \subsubitem " :depth 2)


(markup-locref-list :sep ", ")
(markup-locclass-list :open "\dotfill " :close "" ) ;; :sep ", "


(markup-locref :open "\hyperpage{" :close "}")
(markup-locref :open "\hyperpage{" :close "}" :attr "hyperpage")   


(markup-keyword-list :open "\targetindexentryy{" :close "}" )

;;;(require "lang/english/utf8.xdy")

(markup-letter-group :open-head "~n~n \vspace{1cm} {\hfill\bf " :close-head "\hfill}" :capitalize)
\end{filecontents*}

\usepackage[xindy, nonewpage]{imakeidx} %nonewpage needed for index entries after \printindex

\makeindex[program=truexindy, intoc, options={-M indexStyle -L english -C utf8}]

\usepackage[hyperindex=false]{hyperref}
\begin{document}
Hello some useless text.\clearpage
\index{foo}
\index{foo!bar}
\index{bar}
\index{cat}
\index{carbon}
\index{combobreaker}
\index{join}
\index{join!hash}
\index{hash join|see{join, hash}}

\printindex
\end{document}

Attempt to verify linking:

\documentclass{article}

\usepackage{hyperref}

\def\foo{1}
\def\additionalString{soso}

\newcommand{\makeLink}[1]{%
    \if\foo1%
        index:\additionalString, #1%
    \else%
        index:#1%
    \fi%
}

\newcommand{\makeLinkPart}[1]{%
    \if\foo1%
        \additionalString, #1%
    \else%
        #1%
    \fi%
}

\newcommand{\workarround}[2][]{
    \if\foo1%
        #1\additionalString, #2%
    \else%
        #1#2%
    \fi%
}

\begin{document}
    \hyperlink{index:soso, with}{Link written to macro target}

    \hyperlink{composed:soso, with}{Link written to composed target}

    \hyperlink{\makeLink{with}}{Link macro to macro target}

    \hyperlink{composed:\makeLinkPart{with}}{Link composed to composed target}

%   \hyperlink{\workarround[index:]{with}}{Link workaround to macro target}

%   \hyperlink{\workarround[composed:]{with}}{Link workaround to composed target}
    \workarround[composed:]{with}

    \clearpage

    "\makeLink{with}"

    "composed:\makeLinkPart{with}"

    \hypertarget{\makeLink{with}}{Completly from macro}

    \hypertarget{composed:\makeLinkPart{with}}{Composed}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.