[How-to] LaTeX : Éviter la répétition d’un même numéro de page dans la table des matières

Pendant plusieurs semaines, j’ai erré à la recherche d’une solution pour n’afficher qu’une seule fois un numéro de page dans la table des matières en LaTeX. Habituellement, la table des matières affiche tous les numéros de page, même si ceux-ci se répètent.

Une solution, utilisant le package tocloft, ne fonctionne pas si la taille de la police est de 12pt et l’interligne de 1.5.

Voici donc une autre solution qui permet de palier à ce problème, quelque soit l’interligne, la taille de la police… dans un document de type “article”.

Nous verrons donc dans un premier temps les macros nécessaires pour éviter de répéter les numéros de page. Une fois les mains sorties du cambouis, quelques explications sur la façon dont afficher les différentes tables.

Nous avons besoin d’utiliser le package titletoc, qui permet de gérer plus finement les tables des matières, les sections.

La documentation du package titletoc est disponible sur le site du CTAN.

Il convient de ne pas utiliser tocloft afin d’éviter un conflit entre les deux packages.

Voici la partie principale du code à placer en préambule de votre document, c’est à dire après le \documentclass[12pt]{…} et \begin{document}. Les explications sont à découvrir en dessous :

\makeatletter
\let\old@l@section\l@section
\def\l@section#1#2{
\def\l@lastnumber{#2}
\old@l@section{#1}{#2}
}
\let\old@dottedtocline\@dottedtocline
\def\@dottedtocline#1#2#3#4#5{
\begingroup
\def\l@thisnumber{#5}
\ifx\l@thisnumber\l@lastnumber
\let\leaders\@gobbletwo
\let\l@thisnumber\relax
\fi
\old@dottedtocline{#1}{#2}{#3}{#4}{\l@thisnumber}
\endgroup
\def\l@lastnumber{#5}
}
\makeatother

Quelques explications : Les commandes \makeatletter et \makeatother sont nécessaires afin de redéfinir certaines macros.

\def\l@thisnumber{#5}

Le numéro de page est stocké afin de pouvoir le comparer avec le suivant.

\ifx\l@thisnumber\l@lastnumber

On compare alors le numéro de page actuel et le précédent. S’ils sont égaux :

\let\leaders\@gobbletwo

On supprime la ligne de points.

\let\l@thisnumber\relax

Et on supprime le numéro de page en fin de ligne.

Afin de réinitialiser les compteurs à la fin des tables, les trois lignes suivantes peuvent être utilisées :

\g@addto@macro{\tableofcontents}{\let\l@lastnumber\relax}
\g@addto@macro{\listoftables}{\let\l@lastnumber\relax}
\g@addto@macro{\listoffigures}{\let\l@lastnumber\relax}

Afficher les tables

Il est nécessaire d’utiliser deux ou trois lignes selon votre besoin au lieu d’un simple \tableofcontents.

Une première permet d’initialiser la table des matières partielle :

\startcontents[sections]

Selon votre document, “sections” peut être modifié par “parts” ou “chapters”.

\renewcommand\contentsname{Table des matières}

Cette ligne est facultative. Elle permet simplement de mettre un titre à la table. Ici, la table est question est une table des matières, d’où son nom.

\printcontents[sections]{l}{1}{\section*{\contentsname}}

Enfin, cette commande permet d’afficher la table. Elle utilise différents arguments :

  • Le premier fait référence aux entrées principales (sections, parts, chapters..);
  • Le second est un préfixe qui peut être utilisé pour définir le type des entrées principales. Par exemple, dans le cas présent, l est le préfixe, sections est le type des entrées principales. Si lsections est définie, c’est cette définition qui sera utilisée au lieu du type section par défaut;
  • Le troisième paramètre définit le plus haut niveau de la table des matières
    • 0 for chapters;
    • 1 for section.
  • Enfin, le dernier paramètre permet de changer de multiples éléments comme la profondeur de la table des matières, les marges.. Ici, c’est simplement le nom Table des matières qui est placé comme titre.

Créer une seconde table

Il peut être nécessaire d’afficher une ou plusieurs autres tables, comme une table des annexes par exemple.

Pour cela, rien de plus simple, les commandes sont les mêmes :

\addcontentsline{toc}{section}{Annexes}

On créé l’entrée Annexes dans la table des matières.

\startcontents[sections]

On initalise la seconde table des matières.

\renewcommand\contentsname{Table des annexes}

On définit “Table des annexes” comme titre.

\printcontents[sections]{l}{1}{\section*{\contentsname}}

Enfin, on affiche la table des annexes avec son titre définit ci-dessus.

Un grand merci à Zilkos et Maxauvy pour leur relecture, et à tohecz pour son exemple sur stackexchange :-)