Structure, titres et table des matières

Ce que fait vraiment \section n’est pas de grossir le texte : la commande déclare un seul entier, le niveau du titre. LaTeX propose sept niveaux de sectionnement, de \part à \subparagraph, numérotés de −1 à 5, et les deux questions qui suivent — ce titre doit-il être numéroté (secnumdepth) ? doit-il figurer dans la table des matières (tocdepth) ? — ne sont que des comparaisons avec cet entier. Choisir la hiérarchie, c’est donc déjà choisir presque entièrement la numérotation et la table. Cette page parcourt les sept niveaux, les formes étoilées, la raison pour laquelle \tableofcontents exige une seconde compilation, et la façon dont \appendix et les trois parties d’un book réorganisent la numérotation en dessous.

Les sept niveaux de titres et leur valeur de niveau

De haut en bas, les sept sont \part, \chapter, \section, \subsection, \subsubsection, \paragraph et \subparagraph. La « valeur de niveau » n’est pas une métaphore. En ouvrant le code des classes standard, on trouve \section défini comme \@startsection{section}{1}{…} : ce deuxième argument, 1, est le niveau. \subsection reçoit 2, \subsubsection 3, \paragraph 4, \subparagraph 5. Le code du noyau qui décide d’imprimer ou non un numéro tient dans la ligne \ifnum #2>\c@secnumdepth, où #2 désigne exactement ce chiffre. Un titre n’est pas une décoration destinée à mettre du texte en gras : c’est un repère qui situe le lecteur dans le raisonnement et, en même temps, une déclaration qui fixe le système de numérotation du document entier.

CommandeNiveauUnitéClasses disponibles
\part−1 (book/report), 0 (article)PartieToutes les classes
\chapter0Chapitrebook / report seulement
\section1SectionToutes les classes
\subsection2Sous-sectionToutes les classes
\subsubsection3Sous-sous-sectionToutes les classes (sans numéro par défaut dans book/report)
\paragraph4Titre au fil du texte (le texte suit sur la même ligne)Toutes les classes (sans numéro par défaut)
\subparagraph5Sous-titre au fil du texte (le texte suit sur la même ligne)Toutes les classes (sans numéro par défaut)

Les deux dernières lignes se comportent autrement parce que toute la mise en forme tient dans un seul signe. Le cinquième argument de \@startsection indique « combien d’espace laisser après le titre » : pour \section c’est 2.3ex, positif ; pour \paragraph et \subparagraph c’est -1em, négatif. Le noyau lit ce signe : positif signifie couper la ligne après le titre, négatif signifie ne pas la couper mais insérer cette espace horizontale et poursuivre. Ainsi \paragraph{Point clé} donne « Point clé le texte continue ici » : un titre au fil du texte qui se fond dans le corps. C’est l’outil pour une étiquette courte en tête de paragraphe ; pour un titre sur sa propre ligne, il faut s’arrêter à \subsubsection.

latex
\documentclass{report}   % \chapter is available here
\begin{document}
\chapter{Introduction}
\section{Background}
\subsection{Related work}
\paragraph{Key point}The body text continues on this same line.
\end{document}

Pourquoi \chapter n’existe que dans book et report

La classe article ne possède pas \chapter. La commande n’est tout simplement pas définie : l’écrire dans le corps d’un article interrompt la compilation avec ! Undefined control sequence. Il ne manque aucun package ; la classe a été conçue sans unité « chapitre ». Le titre de plus haut niveau d’un article est donc \section, et si des chapitres sont nécessaires, on passe à report (chapitres et résumé) ou à book (chapitres, recto verso par défaut, avec pages liminaires et finales). \part existe dans toutes les classes, mais pas au même rang : niveau 0 dans article, niveau −1 — au-dessus de \chapter — dans book et report.

Sauter un niveau laisse une trace dans la numérotation. Dans report, une \subsection placée juste après un \chapter donne le numéro 1.0.1. Ce 0 central est le compteur de section, jamais incrémenté. LaTeX ne comble pas le trou en silence : il imprime la valeur du niveau sauté. De même, commencer par \section dans un report ou un book avant tout \chapter donne 0.1. Lorsqu’un 0 inattendu apparaît dans un numéro de titre, le premier soupçon doit porter sur un niveau sauté.

Supprimer les numéros : formes étoilées et secnumdepth

La profondeur de la numérotation dans l’ensemble du document dépend d’un seul compteur : secnumdepth. Sa valeur est le niveau de l’unité la plus profonde qui reçoit encore un numéro ; dans les classes standard livrées avec TeX Live 2024, elle vaut 3 dans article et 2 dans book et report. C’est pourquoi article numérote jusqu’aux sous-sous-sections (niveau 3) alors que book s’arrête aux sous-sections (niveau 2). Pour numéroter les sous-sous-sections d’un book, on met \setcounter{secnumdepth}{3} dans le préambule. À l’inverse, \setcounter{secnumdepth}{0} supprime les numéros à partir des sections, et -2 les retire de tous les titres.

Pour supprimer le numéro à un seul endroit, on emploie la forme étoilée. \section*{Remerciements} donne un titre sans numéro qui, de plus, n’atteint jamais la table des matières. Les deux effets vont de pair parce que la macro du noyau chargée de la forme étoilée n’écrit tout simplement pas l’entrée de table. Pour des titres qui se lisent mal avec un numéro — « Introduction », « Remerciements », « Conclusion » —, c’est exactement ce que l’on veut ; si l’entrée est néanmoins souhaitée, on ajoute \addcontentsline{toc}{section}{Remerciements} juste après le titre. Un titre étoilé laisse aussi le compteur intact : la numérotation suivante ne se décale pas.

L’autre point à connaître est l’argument optionnel. \section[Titre court]{Le titre long imprimé dans le corps} place la forme longue dans le titre du corps et la forme courte entre crochets dans la table des matières et le titre courant. Les titres de section des articles tiennent rarement sur une ligne : c’est l’échappatoire pratique qui garde la table et les titres courants lisibles. Sans crochets, le titre long sert aux trois endroits.

latex
\setcounter{secnumdepth}{3}          % number subsubsections too
\section{Results and discussion}      % numbered, e.g. "3 Results and discussion"
\section*{Acknowledgements}           % no number, and no TOC entry
\addcontentsline{toc}{section}{Acknowledgements}   % put it back in the TOC
\section[Method]{A detailed formulation of the proposed method}

Pourquoi \tableofcontents exige une seconde compilation

La table des matières apparaît dès qu’on écrit \tableofcontents — mais pas lors de la compilation où on l’écrit. TeX lit le document une seule fois, du début à la fin : au moment où il compose la table, il ignore quels titres viendront ensuite. LaTeX écrit donc, à chaque titre rencontré, une ligne du type \contentsline{section}{\numberline {1}First}{1}{} dans le fichier auxiliaire .toc, puis la relit au début de la compilation suivante. D’où le minimum de deux passages. Le plus gênant est que le premier passage se contente d’un No file document.toc. dans le journal : il n’y a aucun véritable avertissement. C’est ainsi que des tables vides ou périmées finissent dans des documents rendus. Un outil comme latexmk répète les passages nécessaires et supprime le problème à la racine.

Les listes de figures et de tableaux reposent sur le même mécanisme : \listoffigures passe par .lof, \listoftables par .lot, et toutes deux exigent aussi plusieurs compilations. Pour ajouter une entrée qui n’est pas listée automatiquement, on emploie \addcontentsline{ext}{unit}{text} : le premier argument ext est l’extension visée (toc, lof, lot), unit le type d’entrée (section, chapter, figure, …) et text la chaîne à inscrire. Pour du matériel qui n’est pas une entrée — un espace supplémentaire entre groupes de titres, par exemple —, on utilise \addtocontents{ext}{text}, qui verse son contenu tel quel dans le fichier auxiliaire ; les commandes comme \vspace demandent donc un \protect.

latex
\tableofcontents
\setcounter{tocdepth}{2}                       % list down to subsections

\section*{Introduction}                        % starred: never listed
\addcontentsline{toc}{section}{Introduction}   % list it by hand

\listoffigures                                % goes through the .lof file
\addtocontents{lof}{\protect\vspace{2ex}}      % extra space inside that list

tocdepth et secnumdepth : la différence

La profondeur de la table est fixée par tocdepth. Sa valeur désigne le même niveau que secnumdepth, et les valeurs par défaut coïncident — 3 dans article, 2 dans book et report —, mais les deux sont indépendants : numéroter jusqu’aux sections tout en listant les sous-sections dans la table est un réglage très ordinaire. La différence décisive tient au moment où chacun agit. secnumdepth décide sur-le-champ si un numéro est composé. tocdepth, non : LaTeX inscrit tous les titres dans le fichier .toc, quelle que soit leur profondeur, et tocdepth se contente de filtrer ces lignes à la relecture du fichier. On peut le vérifier : la ligne de \paragraph figure bien dans le .toc d’un article par défaut ; elle n’est simplement pas imprimée. Ce choix a un avantage concret : augmenter tocdepth n’oblige jamais à régénérer le .toc, si bien qu’une compilation supplémentaire suffit.

\appendix et les trois parties d’un book

\appendix s’écrit une seule fois, à l’endroit où commencent les annexes. Ce n’est pas une commande de titre mais un commutateur de numérotation. Dans article, il remet à zéro les compteurs de section et de sous-section et redéfinit \thesection en lettres. Dans book et report, il remet à zéro les compteurs de chapitre et de section, passe \thechapter en lettres et remplace le mot précédant un titre de chapitre, Chapter, par Appendix. Après \appendix, on continue donc d’écrire \chapter{Notations} et l’on obtient « Appendix A Notations ». Écrit deux fois, ou devant chaque titre d’annexe, il réinitialise les compteurs à chaque occurrence : il ne se place qu’une fois.

La classe book ajoute des commandes qui découpent l’ouvrage en trois. \frontmatter ouvre les pages liminaires (préface, table des matières) : la pagination passe en chiffres romains minuscules et repart à 1, et les chapitres cessent d’être numérotés, même si leurs titres figurent toujours dans la table. \mainmatter commence le corps, rétablit les chiffres arabes, repart à 1 et réactive les numéros de chapitre. \backmatter marque la partie finale (bibliographie, index) : la pagination se poursuit sans rupture et seuls les numéros de chapitre s’arrêtent de nouveau. L’asymétrie est ce qu’il faut retenir : seuls \frontmatter et \mainmatter réinitialisent le compteur de page.

latex
\documentclass{book}
\begin{document}
\frontmatter            % i, ii, ... and unnumbered chapters
\tableofcontents
\mainmatter             % 1, 2, ... and numbered chapters again
\chapter{Introduction}
\appendix               % chapters now read "Appendix A", "Appendix B"
\chapter{Notation}
\backmatter             % bibliography, index: page numbers keep running
\end{document}

C’est Leslie Lamport qui a conçu tout cet ensemble de commandes de sectionnement. Il a reçu le prix Turing de l’ACM en 2013, non pas pour LaTeX, mais pour ses travaux sur les systèmes répartis : horloges logiques, sûreté et vivacité, machines à états répliquées. Ce que des étudiants du monde entier tapent chaque jour, \section, ne figure nulle part dans la citation du jury.

Quand la numérotation ou la table paraissent fausses

  • Un 0 dans le numéro (1.0.1 et consorts) — un niveau a été sauté. Vérifiez la présence d’une \subsection juste après un \chapter dans report/book, ou d’une \section avant tout \chapter.
  • La table est vide ou périmée — le .toc affiché a été écrit par la compilation précédente. Compilez deux fois. Aucun avertissement n’est émis : la solution fiable est de laisser faire latexmk.
  • ! Undefined control sequence. sur \chapter — le document est un article. Passez à report ou book, ou prenez \section comme niveau supérieur.
  • Un titre étoilé n’apparaît pas dans la table — c’est voulu. Placez \addcontentsline{toc}{section}{…} juste après le titre.
  • Les sous-sections manquent dans la tabletocdepth est simplement trop faible. Mettez \setcounter{tocdepth}{2} et recompilez une fois ; le .toc n’a pas besoin d’être régénéré.
  • La numérotation des annexes ne correspond pas\appendix est un commutateur, pas un titre. Placez-le une seule fois, juste avant le premier titre d’annexe.