xindy, hyperref et |see

lundi 2 novembre 2015, mise à jour jeudi 21 janvier 2016, par Maïeul
Suivre la vie du site RSS 2.0 Forum

Une personne m’a demandé comment utiliser xindy avec hyperref et l’option d’indexation |see. Je tire donc un article de la solution proposée.

Fichier d’exemple

Je suppose que vous avez, au préalable, créé votre fichier .xdy contenant les instructions proposées dans l’article xindy et hyperref. Je suppose que vous avez également chargé le package hyperref avec l’option hyperindex=false :

\usepackage[hyperindex=false]{hyperref}

Je prend maintenant le fichier contenant les commandes d’indexation suivantes :

\indexentry{félin}{1}
\indexentry{chat|see{félin}}{1}

Je souhaite que la commande |see non seulement renvoie vers la bonne entrée, mais en plus intègre un lien hypertexte.

Analyse du fichier .idx et du fichier .ind

Le fichier .idx produit est le suivant

\indexentry{félin}{1}
\indexentry{chat|see{félin}}{1}

Après un passage par xindy avec mon précédent .xdy, on obtient les lignes suivantes dans le fichier .ind :

(…)
\item chat, \see{félin}{}
(…)
\item félin, \hyperpage{1}
(…)

On constate donc que si il existe bien un renvoi depuis « chat » vers « félin » et si félin pointe bien avec un lien hypertexte sur la page 1, le renvoi ne propose pas de lien hypertexte.

Modification du .xdy

Nous allons modifier notre fichier .xdy pour ajouter :

  • une commande pour indiquer que « félin » est un lieu de destination.
  • une commande pour indiquer que « chat » pointe vers félin, ou plus exactement que le \see{félin}{} point vers félin.

Ajoutons donc les deux lignes suivantes au fichier .xdy :

(markup-keyword-list :open "\targetindexentry{"           :close"}")
(markup-crossref-list :open "\seelink{" :close "}{}" :class "see")

La première ligne indique d’entourer les mots-c’est à dire les entrées d’indexation, par \targetindexentry{ à gauche et par } à droite.

La seconde ligne indique que le paramètre marqué entre les accolades qui suivant le |see, ici félin doit être entouré à gauche par \seelink{ et à droite par }{}.

Ceci nous produit donc le fichier .ind avec les lignes suivantes :

(…)
\item \targetindexentry{chat}, \seelink{félin}{}
(…)
\item \targetindexentry{félin}, \hyperpage{1}

Définition de \seelink et de \targetindexentry

Il ne reste plus qu’à définir dans notre fichier .tex les deux commandes \targetindexentry et \seelink qui utilisent des commandes du package hyperref.

\newcommand{\targetindexentry}[1]{\hypertarget{index:#1}{#1}}
\newcommand{\seelink}[1]{\hyperlink{index:#1}{\see{#1}}}

Rien de bien méchant : targetindexentry crée une ancre sur son argument. Le nom de l’ancre correspond à son argument précédé par index: ; \seelink point vers une ancre dont le nom correspond à son argument précédé de index:, le texte pointeur étant tout simple la commande \see à laquelle on passe son argument.

Correction de \hyperlink et hypertarget

Le problème est que les commandes \hyperkink et hypertarget ne fonctionne pas si le premier argument contient des accents. Il nous faut donc corriger ces commandes. Cependant une telle correction ralentissant considérablement le temps de calcul [1], il est recommandé de les faire uniquement avant l’index.

Ajoutez donc ces lignes avant le premier \printindex.

La différence principale avec les définitions de hyperref est l’emploi de \pdfstringdef qui permet de transformer les accents en caractères acceptables dans le code interner d’un pdf, donc dans les liens hypertextes.

Et maintant, non seulement |see fonctionne, mais en plus il produit des liens hypertextes. Miaou !

Notes

[1D’après l’auteur du package, Otto Oberdierk.

Vos commentaires

  • Le 15 janvier 2016 à 17:49, par LePingouin En réponse à : xindy, hyperref et |see

    Merci pour ces explications très utiles. Par contre j’ai deux remarques.
    La première est un conseil : l’utilisation de package \usepackage[shorthands=;!?]{babeltools} peut aider pour ceux qui utilisent le package \usepackage[french]{babel}. Car sinon l’utilisation de index:#1 est parasitée par babel.
    La deuxième est une question. Est-ce normal que chez moi, le numéro de page associé à l’entrée qui utilise |see, ne s’affiche pas ? comment résoudre ce problème ?

  • Le 15 janvier 2016 à 18:02, par Maïeul En réponse à : xindy, hyperref et |see

    Merci pour le conseil, même si je n’utilise pas babel (notamment à cause de ce genre de problème).

    Concernant le second point, je pense que la lecture de l’article "Indexation et renvoi" devrait résoudre le problème.

  • Le 18 janvier 2016 à 15:49, par LePingouin En réponse à : xindy, hyperref et |see

    En réalité mon problème n’est pas sur la référence après |see, mais sur le numéro de page.
    En effet, pour reprendre ton exemple si j’ai une entrée du fichier .idx qui est \indexentry{chat|see{félin}}{1}
    avec ta solution nous obtenons un résultat dans le fichier .ind \item \targetindexentry{chat}, \seelink{félin}{}.
    Mais est-il possible d’obtenir \item \targetindexentry{chat} \hyperpage{1}, \seelink{félin}{} ?

  • Le 18 janvier 2016 à 18:47, par Maïeul En réponse à : xindy, hyperref et |see

    Si je comprend bien, tu veux donc avoir à la fois un renvoi à la page du terme et un renvoi à une autre entrée.

    Dans ce cas il faut que tu fasse deux indexations : une avec |see et une sans.

  • Le 19 janvier 2016 à 16:50, par LePingouin En réponse à : xindy, hyperref et |see

    Merci, en effet tu as bien compris et bien répondu à ma question.
    Je comprend un peu mieux comment cela fonctionne à présent.

    Par contre, je me suis aperçu d’un bug que je n’arrive pas à comprendre. J’ai reproduis l’exemple fourni ici, en utilisant polyglossia et XeLaTeX et je n’arrive pas a avoir un hyperlink sur les mots accentués.
    Dans le fichier .ind la commande \item \targetindexentry{chat}, \seelink{félin}{} ou si je rajoute à la suite de mon fichier .tex la commande \hyperlink{index:félin}{félin} créent bien une un hyperlien contenant le félin, mais ce lien est vide, il ne mène lorsqu’on clique dessus. Est-ce normal ? Ou ai-je mal compris quelque chose ?

  • Le 19 janvier 2016 à 17:03, par Maïeul En réponse à : xindy, hyperref et |see

    il me faudrait un exemple complet minimal pour que je puisse comprendre le problème.

  • Le 20 janvier 2016 à 10:51, par LePingouin En réponse à : xindy, hyperref et |see

    Voici un exemple minimal complet.
    le fichier .tex

    % A compiler avec xelatex -shell-escape
    \documentclass{article}
     
    \usepackage{fontspec}
    \usepackage{polyglossia}
    \setmainlanguage{french}
    \usepackage{setspace}
    \onehalfspacing
    \usepackage[xindy]{indextools}%On précise qu'on veut utiliser xindy
    \usepackage[hyperindex=false]{hyperref}
    
    	\def\xindyopt{ -I xelatex -M style_index1 -L french }
    	\makeindex[program=truexindy, options=\xindyopt, intoc] 				
    
    	
    \begin{document}
    
    toto    \index{toto}  \newpage 
    téte\index{téte}
    toti\index{toti} \index{toti|seealso{toto}} \index{toti|see{téte}} \newpage
    ta\index{ta|see{toto}}\index{ta|seealso{toti}} \newpage
    tata\index{tata}
    
    \printindex
    
    \hyperlink{index:téte}{téte}
    
    \end{document} 

    avec le fichier style_index1.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 "\seelink{" :sep "; " :close "}{}")
    
    (define-crossref-class "seealso")
    (markup-crossref-layer-list :sep ", ")
    (markup-crossref-list :class "seealso" :open "\seealsolink{" :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
                        }
                        \newcommand{\targetindexentry}[1]{\hypertarget{index:#1}{#1}}
                        \newcommand{\seelink}[1]{\see{\hyperlink{index:#1}{#1}}}
                        \newcommand{\seealsolink}[1]{\seealso{\hyperlink{index:#1}{#1}}}
                    ~n"     
        :close "~n~n\end{theindex}~n"
        :tree)
    
    
    (markup-indexentry :open "~n \item "            :depth 0)
    (markup-indexentry :open "~n    \subitem "      :depth 1)
    (markup-indexentry :open "~n      \subsubitem " :depth 2)
    
    
    (markup-locref-list :sep ", ")
    (markup-locclass-list :open "\dotfill " :close "" )
    
    
    (markup-locref :open "\hyperpage{" :close "}")
    (markup-locref :open "\hyperpage{" :close "}" :attr "hyperpage")   
    
    
    (markup-keyword-list :open "\targetindexentry{" :close "}" )

    Après compilation, il y a bien des liens hypertextes. Mais ceux sur le mot « téte » ne fonctionnent pas, je suppose que cela est causé par le caractère « é ».
    J’espère que c’est plus claire comme ça.

  • Le 20 janvier 2016 à 11:01, par Maïeul En réponse à : xindy, hyperref et |see

    Je vais regarder cela. Peux tu par contre utiliser la balise <code> pour marquer des bouts de code.

  • Le 20 janvier 2016 à 14:41, par Maïeul En réponse à : xindy, hyperref et |see

    Bon, effectivement limite d’hyperref. Je pose la question sur http://tex.stackexchange.com/q/288553/7712

  • Le 21 janvier 2016 à 10:14, par Maïeul En réponse à : xindy, hyperref et |see

    J’ai ajouté un dernier paragraphe donnant une solution.

  • Le 29 janvier 2016 à 16:00, par LePingouin En réponse à : xindy, hyperref et |see

    Merci pour le conseil. J’ai même décider de passer sur XeLaTeX avec tes conseils.
    Avec ta solution, tout fonctionne super bien. Merci !

Qui êtes-vous ?

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Acheter XeLaTeX appliqué aux sciences humaines

À propos

Titulaire d’un doctorat en théologie et d’un doctorat en histoire, sous la direction conjointe de Frédéric Amsler et d’Élisabeth_Malamut, je commence à partir du 1er août 2017 un travail d’édition critique des Actes de Barnabé.

Dans le cadre de la rédaction de mon mémoire de master puis de ma thèse de doctorat, j’ai été emmené à utiliser LaTeX, et j’ai donc décider de partager mes techniques. En effet, au cours de mes premiers apprentissages, j’ai découvert que les ressources indiquant les outils pour l’utilisation de LaTeX en sciences humaines étaient rares. Ceci m’a conduit à maintenir ou créer plusieurs packages LaTeX et à donner plusieurs formations.

J’ai reçu en 2018 le prix DANTE e.V pour mon travail autour de LaTeX, en particulier autour de reledmac et reledpar.

Par ailleurs, je suis membre actif de la communauté SPIP, au sein de laquelle j’administre le site Spip-Contrib. Je propose sur ce site quelques notes sur SPIP, en général à destination de webmestre.

Il m’arrive également de faire un petit peu de Python, de temps en temps.

Enfin, je tiens un blog de réflexions politiques et religieuses.

Maïeul