Indexer sa thèse au format texte

2023-02-25

Ce billet s’adresse aux personnes intéressées par l’écriture scientifique au format texte (avec des outils comme Markdown, Pandoc, Zettlr) et qui se demandent comment on peut y intégrer la création d’un index. Par exemple, si vous avez lu le billet Rédiger la thèse avec Zettlr d’Aurore Turbiau et que vous voulez savoir si vous pouvez créer un index de votre thèse avec ces outils-là, alors ce qui suit est pour vous. Et si vous ne savez pas trop ce qu’est un index, ni à quoi ça peut servir, continuez aussi : j’explique tout ça au fur et à mesure.

La solution que je présente ci-dessous a été testée avec ma propre thèse. Celle-ci existe en deux versions, PDF et HTML. À la date où je rédige ce billet, je n’ai pas encore testé l’indexation appliquée à la version HTML, je ne parlerai donc que du PDF. Mais avant d’entrer dans les questions techniques, il me paraît indispensable de bien présenter le sujet.

Qu’est-ce que l’index d’une thèse ?

Un index est un outil de navigation interne au document. Il joue un rôle similaire à celui de la table des matières, mais à un niveau de granularité beaucoup plus fin. C’est une liste alphabétique qui peut contenir des termes et des noms propres, avec des renvois vers les pages dans lesquelles on peut trouver les occurrences de ces termes ou bien du contenu qui s’y rapporte.

Exemple d’index qui mélange termes et noms propres. Il s’agit du début de l’index de ma thèse ; l’index complet fait environ 14 pages. Les renvois correspondent aux numéros de page de la version PDF.

L’art de créer un index est né en France. Pourtant, notre pays semble l’avoir totalement oublié. La plupart des livres et des thèses francophones ne contiennent pas d’index, ou alors une version rudimentaire comme dans l’exemple ci-dessous, qui n’est en fait pas un index mais une concordance – une liste de termes qui apparaissent tels quels dans le texte, et dont toutes les occurrences sont comptées.

Exemple d’index qui se rapproche plutôt d’une concordance. Ce n’est pas un extrait mais l’intégralité de l’index. J’ai masqué les termes pour éviter qu’on identifie le document d’origine, l’essentiel étant de comprendre qu’il s’agit d’un cas représentatif (j’en ai au moins cinq ou six comme ça dans ma bibliothèque Zotero).

Ce type d’index n’est pas un très bon outil savant. On peut le comprendre de manière simple : si vous voulez lire les passages qui se rapportent à un concept, mais que l’entrée correspondante dans l’index indique pas moins d’une cinquantaine de renvois, comment savoir quel passage consulter ?

Un bon index est le résultat d’un travail d’analyse du texte, qui conduit à en reformuler le contenu pour donner des points d’accès au lecteur. La longueur de l’index dépend alors de la complexité et de la densité du texte à indexer. Dans le cas d’une thèse, un index peut ainsi facilement occuper plus d’une dizaine de pages. Les indexeurs professionnels parlent d’un « index n% », où le pourcentage correspond au volume de l’index rapporté au volume du texte indexé ; à titre d’exemple, j’ai fait pour ma thèse un index 5% (14 pages d’index pour environ 280 pages de texte).

Exemple de sous-entrées et de renvois : Par ailleurs, un index c’est aussi une liste structurée de manière très spécifique, dans le but d’optimiser la recherche d’information. Les entrées les plus volumineuses sont divisées en différentes sous-entrées. Quant aux renvois internes (voir, voir aussi), ils permettent de multiplier les points d’accès vers une même information, de réduire l’ambiguïté entre termes homographes et d’orienter le lecteur vers certaines expressions plutôt que d’autres.

Par conséquent, créer un index c’est du travail. On comprend alors pourquoi il existe des indexeurs professionnels, et pourquoi beaucoup de doctorantes et de doctorants baissent les bras devant l’ampleur de la tâche, se contentant de faire une petite concordance rapide via Word ou LibreOffice.

Pourtant, il y a de bonnes raisons de relever ce défi. Lorsqu’on écrit une thèse, j’en vois au moins deux. D’abord, c’est un exercice d’analyse et de synthèse très puissant, qui renforce la maîtrise qu’on a de notre sujet, et qui développe la capacité à en faire la médiation. En effet, faire un index implique de se relire et de résumer progressivement les thèmes abordés, d’une manière qui doit être utile aux futurs lecteurs. Cela aide notamment à restituer la thèse sous une forme condensée, que ce soit lors la soutenance ou après.

Et ensuite, le résultat est un outil précieux pour les lecteurs, à commencer par le jury. Un index de qualité facilitera le travail des rapporteurs, qui ne manqueront pas de le signaler. Mais n’oublions pas que nous sommes aussi notre propre lecteur : je ne compte plus les fois où j’ai ouvert mon mémoire de thèse depuis la soutenance pour vérifier ce que j’avais écrit à propos de telle personne ou telle thématique ; à chaque fois, je pars de l’index, qui s’avère beaucoup plus utile que la recherche plein texte.

C’est donc un gros boulot – j’ai mis une semaine entière à faire l’index de ma thèse, en travaillant du matin au soir – mais pour moi le jeu en vaut la chandelle.

Et maintenant, passons aux choses concrètes !

Indexer via Pandoc : deux options

J’ai rédigé ma thèse en Pandoc Markdown. On a parfois besoin de faire des choses pour lesquelles il n’y a pas de notation prévue ni dans la syntaxe Markdown de base, ni dans la variante de Pandoc ; par exemple, créer un index. On a alors deux possibilités.

Première possibilité : on se concentre sur l’un des formats d’export que l’on vise, et qui est capable de faire ce qu’on essaye de faire. Par exemple, il est possible de créer un index dans un PDF généré via LaTeX : cela passe par l’ajout de commandes \index{…} dans le texte, qui sont interprétées par le programme pour générer automatiquement l’index en fin de document. La solution consiste alors tout simplement à ajouter dans notre fichier rédigé en Markdown les instructions exprimées dans la syntaxe du format d’export visé. Concrètement ici, on parsème notre texte de commandes LaTeX. Exemple :

… cette expression fait référence au travail de Michel Foucault\index{Foucault, Michel} sur l'implication réciproque du savoir et du pouvoir.

Ces commandes ne seront interprétées par Pandoc que lorsqu’on convertit le fichier en LaTeX ou en PDF via LaTeXLaTeX est l’un des moteurs que peut utiliser Pandoc pour convertir un fichier Markdown en PDF. Je parle de « PDF via LaTeX » pour désigner ces exports. On peut aussi utiliser Pandoc pour convertir son fichier Markdown en LaTeX, puis utiliser un autre programme pour passer du fichier LaTeX au fichier PDF ; c’est d’ailleurs la solution que je détaille dans la section d’après.
. Dans les autres formats d’export, elles seront tout simplement ignorées.

Deuxième possibilité : plusieurs formats d’exports que l’on vise sont capables de faire ce qu’on veut faire, et on veut donc en profiter. Par exemple, on sait qu’on va générer un index via LaTeX pour le PDF mais aussi qu’on a un programme tiers (autre que Pandoc) capable de faire de même pour la version HTML. Dans ce cas, on peut s’appuyer sur deux capacités apportées par Pandoc : le balisage sémantique et la programmation éditoriale. Je m’explique : « balisage sémantique » signifie qu’on va d’abord marquer le texte avec une syntaxe générique, propre à Pandoc, pour rajouter une métadonnée relative à la signification du passage concerné. Exemple :

… cette expression fait référence au travail de [Michel Foucault]{index="Foucault, Michel"} sur l'implication réciproque du savoir et du pouvoir.

Cette syntaxe étant native à Pandoc, ce dernier est capable de passer l’information correspondante à tous les formats d’export. Pour en tirer parti, c’est là qu’intervient la programmation éditoriale : on ajoute à la conversion un script rédigé exprès pour gérer cette information. Pandoc implémente ceci sous la forme de « filtres » en Lua. Ici, le filtre contiendrait des instructions pour remplacer la syntaxe générique par la bonne syntaxe pour chaque format d’export. Il ne resterait alors plus qu’à exécuter le fameux programme capable de générer l’index.

Dans le cas de ma thèse, j’ai choisi la première option, que je détaille dans la section suivante. En effet, je n’avais pas connaissance de programmes permettant de générer un index pour la version HTML. Or via Antoine Fauchié je sais désormais qu’il existe de tels programmes, notamment celui créé par David Larlet pour les Ateliers de Sens Public et qui est en cours de documentation. Personnellement, je suis convaincu que tout l’intérêt de Pandoc c’est de faire du multiformats à partir d’une source unique, en recherchant une forme d’homogénéité éditoriale. Je suis donc plutôt un partisan de la deuxième méthode, et je mettrai peut-être à jour ce billet lorsque j’aurai pu la tester moi-même.

Ajout du 26/02 : En attendant, les développeurs de Pandoc ont gentiment réagi à la publication de ce billet en proposant un exemple bien pratique de filtre Lua que voici :

function Span (span)
  if span.attributes.index then
    local index_command = string.format('\\index{%s}', span.attributes.index)
    return span.content .. {pandoc.RawInline('latex', index_command)}
  end
end

Si on ajoute ce filtre lors d’une conversion, il transformera la syntaxe générique de Pandoc […]{index="…"} en la commande LaTeX …\index{…}. Si on ne veut pas mélanger LaTeX et Markdown, on peut donc utiliser ce filtre dès maintenant avec la solution ci-dessous. Il suffit de sauvegarder ce filtre sous un nom comme index.lua et ajouter --lua-filter=index.lua lors de la conversion.

Quant à moi, ça me fournit un point de départ sympa si j’ai besoin un jour d’écrire un filtre qui gère simultanément le cas LaTeX et le cas HTML.

Générer l’index du PDF à partir de Markdown

Voici en résumé le processus que j’ai appliqué pour générer l’index de ma thèse au format PDF :

  1. baliser le texte avec les commandes \index{…} ;
  2. passer de Markdown à LaTeX via Pandoc, en utilisant un modèle LaTeX qui inclut les bons packages dans le préambule ;
  3. passer de LaTeX à PDF via XeLaTeX et Xindy.

Je détaille ça en dessous, avec en bonus un tutoriel express sur la manière d’automatiser tout ça sous une forme pratique à utiliser (spoiler : il s’agit de Make).

Étape 1 : balisage

J’ai mentionné plus haut la commande \index{…} et le fait qu’on va l’insérer directement dans le texte en Markdown. Deux niveaux d’écriture se mélangent : il y a la syntaxe propre à l’outil mais il y a aussi la manière de rédiger une entréePour bien comprendre les termes tels qu’entrée, sous-entrée ou encore renvoi, voir le glossaire sur ma page consacrée à l’indexation.
de manière générale. Pour s’y retrouver, voici donc quelques exemples des différentes formes que cela peut prendre en entrée et en sortie. La référence complète de la syntaxe peut être consultée dans la documentation du package TeX imakeidx.

\index{e}
Indique une cible indexée à l’entrée e. Ex : \index{graphe documentaire}.
\index{e!se}
Indique une cible indexée à la sous-entrée se de l’entrée e. Ex : \index{graphique!théorie de la}.
\index{e|(} … \index{e|)}
Indique une cible indexée à l’entrée e et qui s’étale entre les deux commandes \index (qu’on peut voir ici comme des balises ouvrantes et fermantes). Ceci permet d’indexer tout un passage, potentiellement de plusieurs pages.
\index{e1|see{e2}}
Crée un renvoi de type voir de l’entrée e1 vers l’entrée e2. Exemple : \index{graphes, théorie des|see{théorie des graphes}}. C’est une forme de redirection, utilisée pour orienter le lecteur depuis une expression à laquelle il ou elle pense spontanément vers une expression plus conforme au texte indexé, ou issue d’un vocabulaire contrôlé. Contrairement aux deux commandes précédentes, celle-ci peut être placée n’importe où, car elle ne marque pas un emplacement dans le texte mais crée un renvoi entre deux entrées.
\index{e1|seealso{e2}}
Crée un renvoi de type voir aussi de l’entrée e1 vers l’entrée e2. Contrairement à la commande précédente, ce n’est pas une redirection mais une suggestion : on incite le lecteur à aller consulter une autre entrée pertinente. Cette commande aussi peut être placée n’importe où.

L’exemple du renvoi de type voir illustre bien la différence entre ce qui relève de la syntaxe et ce qui relève de la manière d’écrire une entrée d’index en général. Ce n’est pas l’outil qui a décidé automatiquement que « théorie des graphes » pouvait aussi être indexé à « graphes, théorie des ». C’est la personne qui a rédigé l’index qui a anticipé et multiplié les différents points d’accès vers une même information, en jouant sur l’ordre alphabétique (certains lecteurs iront spontanément à T, d’autres à G ; le renvoi permet de s’assurer que l’information est vue par tous).

Le choix des termes, la manière de les regrouper, de les diviser ou de les interrelier constitue tout l’art de l’indexation. Je me suis découvert une certaine affinité pour ce travail, car il résonnait avec mon expérience de la documentation personnelle (lire, identifier des concepts et des idées, les reformuler, les combiner). Mais on n’est pas obligé de devenir un fada de l’indexation non plus : dans le contexte de la thèse, il suffit de se pencher sur un bon manuelPar exemple celui de Mulvany, Indexing books, 2005 ; ou en français, Maniez et Maniez, Concevoir l’index d’un livre, 2009.
pour avoir quelques repères et ainsi créer un index convenable.

Étape 2 : conversion

Une fois le texte indexé, il faut le convertir dans le format ciblé. Dans mon cas, je passe de Markdown à LaTeX puis de LaTeX à PDF. Pourquoi faire cela alors que Pandoc sait convertir de Markdown vers PDF en une seule étape ? Précisément à cause de l’indexation : il faut un programme spécifique pour traiter les commandes \index{…} et générer l’index en sortie. Je ne connais pas d’option Pandoc qui permette d’intégrer cete étape de génération d’index via un programme tiers durant une conversion vers le format PDF via LaTeX. On est donc obligé de décomposer le processus, avec une première phase qui consiste à convertir de Markdown vers LaTeX via Pandoc.

pandoc these.md -o these.tex --template=template.tex

La seule chose importante ici est d’utiliser un modèle LaTeX qui inclue les bons packages pour l’étape d’après. Dans mon cas, j’ai ajouté les lignes suivantes au fichier template.tex :

\usepackage[xindy]{imakeidx}
\makeindex[columns=2, title=Index]

Le package imakeidx est une version plus récente et plus versatile de makeidx ; il permet notamment d’avoir des index séparés, par exemple un index des noms et un index des termes. L’option xindy indique qu’on va utiliser le programme du même nom pour traiter l’index. Xindy est un programme autonome, qui fonctionne avec l’écosystème TeX mais aussi d’autres systèmes de création de documents. C’est lui qui va faire le gros du travail.

Étape 3 : traitement

La dernière étape comporte elle-même trois sous-étapes. Il faut d’abord traiter le fichier LaTeX (« compiler ») une première fois, via le moteur de son choixUne distribution TeX moderne inclut généralement différents moteurs. J’ai utilisé xetex pour accéder plus facilement aux polices de caractères installées sur ma machine, mais ça marcherait aussi avec le moteur classique pdftex.
 :

xelatex these.tex

Ceci crée un pdf… sans index. Pas de panique : si on a bien ajouté le package nécessaire via le modèle lors de l’étape précédente, cela génère aussi un fichier these.idx. C’est ce fichier qui va permettre la création de l’index, par l’intermédiaire de Xindy, avec ici les options qui permettent de régler le codage et la langue :

texindy -C utf8 -L french these.idx

Enfin comme pour les bibliographies, les glossaires, les notes, les figures et plus généralement autre système à base de références croisées en LaTeX, il faut une deuxième compilation pour numéroter correctement les renvois :

xelatex these.tex

Automatisation avec Make

En résumé, voici l’enchaînement des commandes à exécuter (sachant que la commande Pandoc est ici très simplifiée) :

pandoc these.md -o these.tex --template=template.tex
xelatex these.tex
texindy -C utf8 -L french these.idx
xelatex these.tex

Tout ceci peut être automatisé de différentes manières. J’aime beaucoup Make, dont je décris un exemple d’utilisation dans mon billet Publication multiformats avec Pandoc et Make. Alors pour clore ce billet, en voici un tutoriel rapide, adapté à la question qui nous préoccupe. Ajout du 28 mars 2024 : j’ai depuis publié un cours introductif complet consacré à Make.

Make repose sur la création d’un Makefile, un fichier texte dans lequel on liste des instructions. La syntaxe est extrêmement simple :

cible visée : fichiers requis
  commandes à exécuter pour fabriquer la cible visée
  si les fichiers requis existent

Pour exécuter les instructions, il faut rejoindre l’emplacement du Makefile via la ligne de commande puis exécuter make, ce qui déclenche les instructions qui sont contenues dans le Makefile.

Make est très utile pour gérer proprement un processus en plusieurs étapes, car les fichiers requis pour une étape peuvent eux-mêmes être créés via des instructions, et ainsi de suite :

cible finale : fichier intermédiaire requis
  commande qui fabrique la cible finale

fichier intermédiaire : fichiers de base requis
  commande qui fabrique le fichier intermédiaire

Les compilations LaTeX sont réputées pour être assez lentes, surtout quand le document est long et complexe, et encore plus quand on utilise xetex à la place de pdftex (ce qui est mon cas). Dans ce contexte, le fonctionnement de Make inclut deux aspects très utiles, car ils réduisent les risques de lancer accidentellement une longue compilation inutile. D’abord, il ne ré-exécute les instructions pour fabriquer une cible existante que si les fichiers requis ont été modifiés. Et ensuite, on peut définir des cibles « factices » (en anglais phony) qui ne correspondent pas à un fichier réel mais qui constituent une sorte de nom de code pour une série d’opérations qu’on veut exécuter. L’exemple ci-dessous permet d’exécuter les commandes make cible1 et make cible2 pour fabriquer soit le fichier cible 1, soit le fichier cible 2 :

.PHONY : cible1 cible2

cible1 : fichier cible 1

fichier cible 1 : fichiers requis
  instructions

cible2 : fichier cible 2

fichier cible 2 : fichiers requis
  instructions

Si on a plusieurs cibles à fabriquer, ceci permet de lancer de façon sélective le processus concernant une cible mais pas une autre. C’est ce qui me permet de re-fabriquer rapidement la version HTML de ma thèse (quand on me signale des coquilles par exemple…), sans déclencher la fabrication de la version PDF.

Voici donc pour finir une version très simplifiée du Makefile qui me permet de générer ma thèse en HTML via la commande make html et en PDF via make pdf, mais aussi les deux en même temps via make all :

.PHONY : all pdf html

all : pdf html

pdf : these.pdf

these.pdf : these.tex
  xelatex these.tex
  texindy -C utf8 -L french these.idx
  xelatex these.tex

these.tex : these.md
  pandoc these.md -o these.tex --template=template.tex

html : these.html

these.html : these.md
  pandoc these.md -o these.html --template=template.html

Sur cette base, on peut ajouter autant de processus que nécesaire. À titre d’exemple, j’avais aussi un make docx qui générait les versions traitement de texte destinées à la relecture + annotation par mes directeurs de thèse.

Le mot de la fin (pour l’instant)

Ce billet constitue un peu la profession de foi d’un néo-converti : après avoir créé l’index de ma thèse, je suis désormais convaincu qu’il s’agit d’un outil essentiel, trop peu utilisé en France. Mais les ressources pour se lancer sont trop rares, surtout quand on rédige en Markdown. Alors je partage mon expérience en espérant qu’elle serve à d’autres, et j’espère pouvoir prolonger ce premier travail bientôt avec l’indexation en HTML.

Références

Maniez, Jacques et Maniez, Dominique. Concevoir l’index d’un livre: histoire, actualité, perspectives. ADBS éditions, 2009. 978-2-84365-099-4.
Mulvany, Nancy C. Indexing books. 2e éd. University of Chicago Press, 2005. 978-0-226-55276-7.