En imbriquant une liste dans une autre, LaTeX change l’étiquette de tête de ligne selon le niveau. Pourtant, un enumerate placé dans une entrée d’itemize — visuellement le deuxième niveau — commence par « 1. » et non par « (a) ». Car LaTeX ne compte pas la profondeur sur la page mais le nombre de listes de même nature qui vous entourent. Écrire des listes imbriquées sans connaître ce seul fait, c’est s’étonner à chaque sortie. Cette page traite du choix de l’étiquette, de la raison pour laquelle un mur nommé Too deeply nested se dresse au quatrième niveau, d’un second plafond que partagent tous les environnements de liste, et de la largeur de ligne perdue sans retour à chaque niveau ajouté.
L’étiquette suit le nombre de listes de même type, pas la profondeur sur la page
LaTeX compte la profondeur avec deux compteurs distincts. Dans latex.ltx, itemize incrémente \@itemdepth et enumerate incrémente \@enumdepth ; chacun construit ensuite, à partir de sa propre valeur, un nom de commande — \labelitem ou \labelenum suivi d’un chiffre romain — et l’appelle. Les deux ne se consultent jamais : un enumerate dans un itemize se trouve donc à \@enumdepth 1, \labelenumi s’applique et la numérotation part de « 1. ». L’affirmation, souvent répétée, selon laquelle l’étiquette découlerait de la profondeur d’imbrication quel que soit le type est fausse. Une seule compilation en décide.
\begin{enumerate}
\item Make the dough
\begin{itemize}
\item Flour
\item Water
\begin{enumerate}
\item Add half
\item Add the rest
\end{enumerate}
\end{itemize}
\item Let it rest
\end{enumerate}Voici ce que ces trois niveaux produisent réellement. L’enumerate extérieur donne « 1. » et « 2. » ; l’itemize qu’il contient reçoit la puce • du premier niveau, et non le tiret – du deuxième ; et l’enumerate le plus intérieur reçoit le (a) du deuxième niveau, et non le i. romain du troisième. Du point de vue de l’itemize, c’est le premier itemize alentour ; du point de vue de l’enumerate intérieur, il y a exactement un enumerate au-dessus. En alternant les types vers le bas, chaque type déroule sa propre suite d’étiquettes de façon indépendante.
| Profondeur | Environnement | Niveau au sein du type | Étiquette obtenue |
|---|---|---|---|
1 | itemize | 1 | • (\labelitemi) |
2 | enumerate | 1 | 1. (\labelenumi) |
3 | itemize | 2 | – (\labelitemii) |
4 | enumerate | 2 | (a) (\labelenumii) |
5 | itemize | 3 | * (\labelitemiii) |
6 | enumerate | 3 | i. (\labelenumiii) |
Le mur au quatrième niveau : ! LaTeX Error: Too deeply nested.
En imbriquant cinq listes du même type, la compilation s’arrête sur ! LaTeX Error: Too deeply nested. Le message n’indique pas la profondeur : il se réduit à ces trois mots, et c’est à vous de compter lequel des \begin est le cinquième ; le numéro de ligne signalé est celui du \begin{itemize} qui l’a ouvert. La raison n’est pas un interdit typographique mais un simple manque de noms : le test dans latex.ltx se borne à \ifnum \@itemdepth >\thr@@, « supérieur à trois ». Les commandes d’étiquette existent pour quatre niveaux, il n’y a aucun nom à donner au cinquième, et cela s’arrête là. Ce qui signifie aussi que charger enumitem ne fait pas tomber le mur : ouvrir un cinquième niveau sans rien configurer produit la même erreur, de la même manière.
% raising the ceiling really does take all four lines
\usepackage{enumitem}
\setlistdepth{9}
\renewlist{itemize}{itemize}{9}
\setlist[itemize]{label=$\cdot$}
\setlist[itemize,1]{label=$\bullet$}Faire tomber le mur demande plus que le seul \setlistdepth d’enumitem. \setlistdepth{9} ne relève que le plafond global des listes ; itemize lui-même s’arrête toujours à quatre. Il faut reconstruire l’environnement pour neuf niveaux avec \renewlist{itemize}{itemize}{9}, puis fournir des étiquettes aux nouveaux niveaux avec \setlist[itemize]{label=…} pour qu’un cinquième niveau se compose enfin. Ouvrir un cinquième niveau sans lui donner d’étiquette ne fait que changer l’erreur en ! Package enumitem Error: Undefined label. Si le besoin réel est une hiérarchie numérotée profonde, un package comme easylist, conçu dès l’origine pour une profondeur quelconque, est l’outil plus honnête. Mais avant d’y recourir, marquez une pause : presque aucun lecteur ne suit cinq niveaux d’imbrication. Une imbrication aussi profonde signale d’ordinaire une structure qui gagnerait à devenir des titres de section.
Un second plafond : le budget de six niveaux partagé par tous les environnements de liste
Au-dessus de la limite de quatre par type se trouve un second plafond de six niveaux, partagé par toutes les listes. itemize comme enumerate reposent sur le même environnement sous-jacent list, lequel porte son propre test : \ifnum \@listdepth >5. Alterner itemize et enumerate mène donc jusqu’au sixième niveau, et le septième échoue tout autant sur Too deeply nested. Le désagrément vient de ce que les listes ne sont pas seules à puiser dans ce budget. En parcourant article.cls, on voit que quote, quotation, verse, description et même thebibliography reposent sur \list. Deux blocs de citation imbriqués dans une liste à puces profonde suffisent à épuiser ce qui reste. Comme le coupable n’a pas l’air d’une liste, c’est la version la plus difficile à diagnostiquer.
Les retraits s’additionnent : au quatrième niveau, un quart de la justification a disparu
Le vrai coût de l’imbrication n’apparaît pas dans les étiquettes mais dans la largeur de la ligne. Chaque ouverture d’un environnement list ajoute son \leftmargin au total courant à gauche : le retrait s’empile niveau après niveau. Dans un article en 10pt composé sur une colonne, \leftmargini vaut 25,0pt, \leftmarginii 22,0pt, \leftmarginiii 18,7pt et \leftmarginiv 17,0pt. Au quatrième niveau, les marges gauches totalisent 82,7pt — environ un quart des 345pt de justification — et il reste 262,3pt de ligne pour écrire. Si les valeurs décroissent légèrement d’un niveau à l’autre, c’est précisément pour freiner cette accumulation ; et malgré cela, quatre niveaux coûtent autant.
| Longueur | Valeur | Cumul | Largeur de ligne restante (textwidth 345pt) |
|---|---|---|---|
\leftmargini | 25,0pt (2,5em) | 25,0pt | 320,0pt |
\leftmarginii | 22,0pt (2,2em) | 47,0pt | 298,0pt |
\leftmarginiii | 18,7pt (1,87em) | 65,7pt | 279,3pt |
\leftmarginiv | 17,0pt (1,7em) | 82,7pt | 262,3pt |
Chiffres en main, la raison pour laquelle une imbrication profonde se lit mal devient concrète. Une justification de 262pt approche celle d’une colonne dans une composition sur deux colonnes ; en y coulant de longues phrases, l’algorithme de coupure dispose de moins de marge, les blancs entre mots s’ouvrent anormalement et les avertissements Overfull \hbox se multiplient. En deux colonnes, \leftmargini est de toute façon réduit à 2em : plus la justification est étroite, moins l’imbrication a de jeu. Pour resserrer la marge de gauche, régler leftmargin= niveau par niveau avec enumitem est la voie pratique. Le plus souvent, cependant, revoir la structure va plus vite : les entrées au-delà du troisième niveau peuvent d’ordinaire être repliées en prose dans l’entrée parente.
Où arrêter l’imbrication
LaTeX autorise quatre niveaux, ce qui ne veut pas dire que quatre niveaux se lisent. L’imbrication profonde communique une hiérarchie, et le lecteur doit la reconstituer à partir de la seule forme du marqueur et de la position du bord gauche. L’astérisque du troisième niveau et le point centré du quatrième se ressemblent, et 17pt de retrait seulement les séparent. Au quatrième niveau, autrement dit, il ne reste presque aucun indice exploitable. Voici une liste de contrôle pour relire une imbrication une fois écrite.
- Vérifier si deux niveaux suffisent. Tout ce qui dépasse le troisième peut généralement être replié en prose dans l’entrée parente.
- Si la profondeur est réellement nécessaire, employer des titres de section plutôt qu’une liste.
\subsectionet\subsubsectionapportent avec eux table des matières et références croisées. - Toujours regarder la sortie quand on mélange les types. L’étiquette dépend du nombre de listes de même type qui entourent, et le marqueur attendu peut ne pas apparaître.
- Tenir
quoteetversehors des imbrications profondes. Ils puisent dans le même budget de six niveaux et provoquent des erreurs dont la source est difficile à voir. - Quand
Too deeply nestedsurvient, recompter la profondeur. Le message ne nomme jamais le niveau : il faut remonter les\beginà partir de la ligne signalée.