On garde le plus souvent en mémoire les quatre étiquettes — les marqueurs — que itemize produit dans LaTeX aux niveaux successifs sous la forme « •, -, , · ». Ouvrez pourtant article.cls : les trois derniers sont tous autre chose que ce qu'on imagine. Le niveau 2 n'est pas deux traits d'union mais un tiret demi-cadratin gras (\labelitemfont \bfseries \textendash) ; le niveau 3 n'est pas un astérisque ordinaire mais un astérisque centré verticalement*, \textasteriskcentered ; le niveau 4 est \textperiodcentered. Personnaliser les étiquettes commence par savoir ce que contiennent réellement ces macros. Cette page parcourt les quatre marqueurs de itemize, la répartition des rôles entre \theenumi et \labelenumi dans enumerate, les commandes de représentation de compteur de \arabic à \fnsymbol avec leurs limites, et la véritable borne de l'imbrication — c'est-à-dire à quel moment apparaît vraiment ! LaTeX Error: Too deeply nested.
Ce que sont vraiment les quatre marqueurs par défaut de itemize
Les marqueurs de itemize logent dans quatre macros, une par niveau : \labelitemi, \labelitemii, \labelitemiii, \labelitemiv (les i / ii / iii / iv finaux étant des chiffres romains pour les niveaux 1 à 4). Leurs définitions dans les classes standard figurent au tableau ci-dessous, et toutes quatre débutent par \labelitemfont — un petit crochet que article.cls définit comme \normalfont et qui garantit que le marqueur est composé dans la fonte du texte, même si l'environnement est en italique ou en gras. Seul le niveau 2 fait suivre \labelitemfont d'un \bfseries supplémentaire, de sorte que son tiret demi-cadratin est composé en gras. C'est pourquoi il paraît plus appuyé que ses voisins.
| Macro | Définition dans les classes standard | Ce qui est imprimé |
|---|---|---|
\labelitemi | \labelitemfont \textbullet | • une puce |
\labelitemii | \labelitemfont \bfseries \textendash | – un tiret demi-cadratin gras, non pas deux traits d'union |
\labelitemiii | \labelitemfont \textasteriskcentered | ∗ un astérisque centré verticalement, glyphe distinct de * |
\labelitemiv | \labelitemfont \textperiodcentered | · un point médian |
Pour changer le marqueur d'un niveau entier, redéfinissez la macro correspondante par \renewcommand, placée dans le préambule ou juste avant la portée visée. Un point d'attention : ces macros n'entrent pas en mode mathématique. Sans dollars écrits de votre main, comme dans $\diamond$, \diamond est inutilisable dans le texte et provoque une erreur. Les solutions de rechange courantes sont $\diamond$ (◇), $\ast$ (∗), $\cdot$ (·) et $\triangleright$ (▷) ; en chargeant le package pifont, on dispose en outre d'ornements comme \ding{"6C}. Mieux vaut cependant ne pas s'emballer : des marqueurs trop travaillés rendent les niveaux difficiles à distinguer, aussi est-il généralement plus sûr de ne modifier que le niveau 1.
% the whole of level 1 becomes a diamond -- note the explicit math shift
\renewcommand{\labelitemi}{$\diamond$}
% or, with enumitem, the same thing scoped to one list
\begin{itemize}[label=$\diamond$]
\item this list only
\end{itemize}Remplacer l'étiquette d'un seul élément avec \item[...]
Pour changer le marqueur d'un seul élément, donnez une étiquette entre crochets juste après \item : \item[$\star$] en fait une étoile, \item[--] un tiret. Et il faut ici corriger une croyance répandue. Une étiquette entre crochets n'est pas composée en gras. Écrivez \item[Word] dans un itemize et le PDF produit n'incorpore que le romain du texte ; aucune graisse n'apparaît. Le \makelabel de itemize et enumerate est défini comme \hss\llap{...} : l'étiquette est donc simplement cadrée à droite dans sa boîte, débordant à gauche si elle est trop large — la fonte n'est jamais touchée. Le gras n'intervient que dans description, et uniquement parce que \descriptionlabel porte un \bfseries.
\theenumi contre \labelenumi : le nombre et son habillage
\theenumi décide comment le nombre est représenté — 1, ou I, ou a — tandis que \labelenumi décide comment ce nombre est habillé en tête de ligne, avec des parenthèses ou un point. enumerate emploie un compteur par niveau : enumi, enumii, enumiii, enumiv ; \theenumi convertit la valeur du compteur en caractères, et \labelenumi l'appelle et ajoute la ponctuation. C'est un dispositif à deux étages. Les valeurs par défaut des classes standard figurent au tableau ci-dessous, et elles sont asymétriques : seul le niveau 2 reçoit des parenthèses, les autres un point.
| Compteur | Défaut de \the… | Défaut de l'étiquette | Imprimé en tête |
|---|---|---|---|
enumi | \arabic{enumi} | \theenumi. | 1. 2. 3. … |
enumii | \alph{enumii} | (\theenumii) | (a) (b) (c) … |
enumiii | \roman{enumiii} | \theenumiii. | i. ii. iii. … |
enumiv | \Alph{enumiv} | \theenumiv. | A. B. C. … |
Le dispositif à deux étages prend tout son sens dans les renvois. Ce que \ref restitue, c'est la représentation nue, dépouillée de l'habillage de \labelenumi : autrement dit \theenumi. Aussi, même si vous redéfinissez \labelenumi en (\theenumi) pour imprimer (1) en tête de ligne, \ref renvoie toujours un 1 sans parenthèses ; pour écrire « voir l'étape (1) », il faut ajouter les parenthèses côté renvoi, ou recourir au ref= de enumitem. Plus précisément, LaTeX construit la chaîne de renvoi en préfixant \theenumi par \p@enumi, et les classes standard définissent \p@enumii comme \theenumi et \p@enumiii comme \theenumi(\theenumii). C'est pourquoi un \ref vers un élément de niveau 2 revient sous la forme « 1a », emportant avec lui le numéro parent. La création et l'incrémentation des compteurs en général relèvent de la page sur les compteurs et les longueurs.
% change only the representation: the head reads I. II. III. and \ref gives I
\renewcommand{\theenumi}{\Roman{enumi}}
% change only the dressing: the head reads (1) but \ref still gives a bare 1
\renewcommand{\labelenumi}{(\theenumi)}Les commandes de représentation de compteur, et leurs limites
Pour choisir l'aspect d'un nombre à l'intérieur de \theenumi ou \labelenumi, on emploie les six commandes de représentation de compteur standard de LaTeX. Chacune prend un nom de compteur en argument, comme dans \Roman{enumi}, et imprime la valeur de ce compteur sous la forme choisie. L'essentiel est que trois d'entre elles ont un plafond : \alph et \Alph au-delà de 26, et \fnsymbol hors de 1–9, s'arrêtent sur ! LaTeX Error: Counter too large. Une liste de 27 entrées étiquetées label=\alph* échouera à la vingt-septième, à chaque fois.
| Commande | Imprime | Plage et limites |
|---|---|---|
\arabic | 1, 2, 3 … (chiffres arabes) | Pas de plafond ; les négatifs s'impriment tels quels (−3 donne −3) |
\alph | a, b, c … (minuscules) | 1–26 ; à partir de 27, Counter too large. Zéro ne donne rien, en silence |
\Alph | A, B, C … (majuscules) | 1–26 ; même plafond que \alph |
\roman | i, ii, iii … (chiffres romains minuscules) | Jamais d'erreur, mais zéro et au-dessous ne donnent rien, en silence |
\Roman | I, II, III … (chiffres romains majuscules) | Pas de plafond ; 4000 sort en MMMM, par simple répétition du M |
\fnsymbol | * † ‡ § ¶ ‖ ** †† ‡‡ (symboles de note) | 1–9 seulement ; à partir de 10, ou zéro et au-dessous, Counter too large |
Le délicat, c'est que certains cas échouent bruyamment et d'autres en silence. \alph{0} et \roman{0} renvoient la chaîne vide sans un mot de protestation : renvoyer à un compteur resté à zéro produit donc une liste dont les étiquettes ont purement et simplement disparu, sans le moindre indice. \alph{27}, en revanche, s'arrête au moins sur Counter too large. Les neuf symboles de \fnsymbol — exactement la suite figurant dans la définition de \@fnsymbol — forment une série de notes de bas de page ; détournés en étiquettes de liste, ils cèdent au dixième élément. Réservez-les aux courtes listes d'annotations.
L'écrire avec le label= de enumitem : bâtir une étiquette à partir de compteurs
Redéfinir des macros est puissant, mais peu commode dès que la mise en forme doit varier d'une liste à l'autre. Dans la plupart des cas, le label= de enumitem se lit mieux : essayez-le d'abord. À l'intérieur de label=, les formes étoilées \arabic*, \alph*, \Alph*, \roman* et \Roman* représentent le compteur courant de ce niveau. Le \arabic{...} sans étoile reste utilisable à côté, et le mélange des deux permet de bâtir une étiquette à partir d'un autre compteur : écrivez label=\thesection.\arabic* et les éléments sont numérotés « 3.1 », « 3.2 », le numéro de section en tête, qui suit automatiquement si vous déplacez la section.
\usepackage{enumitem}
\setlist[enumerate,1]{label=\Roman*.} % level 1 becomes I. II. III.
\setlist[enumerate,2]{label=(\alph*)} % level 2 becomes (a) (b)
\setlist[itemize,1]{label=$\diamond$} % itemize level 1 becomes a diamond
% a label built from another counter
\begin{enumerate}[label=\thesection.\arabic*, leftmargin=*]
\item numbered 3.1 inside section 3
\end{enumerate}
% label*= accumulates onto the parent label: 1. then 1.1. 1.2.
\begin{enumerate}[label*=\arabic*.]
\item one
\begin{enumerate}[label*=\arabic*.]
\item one-point-one
\end{enumerate}
\end{enumerate}label*= s'enchaîne sur l'étiquette parente : l'imbrication accumule donc 1., 1.1., 1.2. — composé et vérifié. Notez cependant que cet enchaînement ne vaut que pour l'étiquette imprimée : le numéro parent n'est pas ajouté automatiquement aux renvois. Pour obtenir un renvoi du type « 1.a », il faut l'écrire explicitement avec ref=, comme dans ref=\theenumi.\alph*. Et chaque fois que vous fournissez une étiquette large, pensez à ajouter leftmargin=* : la boîte d'étiquette par défaut ne fait que 20pt, si bien qu'une étiquette longue comme \thesection.\arabic* déborde à gauche. Pour appliquer le style partout, nommez le type et le niveau, comme dans \setlist[enumerate,1]{...}.
Charger le package sous la forme \usepackage[shortlabels]{enumitem} permet en outre d'écrire le laconique \begin{enumerate}[(1)] de l'ancien package enumerate. Placer A, a, I, i ou 1 en premier élément entre crochets signifie alors respectivement \Alph*, \alph*, \Roman*, \roman* ou \arabic*.
Too deeply nested : la véritable limite de l'imbrication
On dit souvent que les listes LaTeX ne s'imbriquent que sur quatre niveaux. Ce n'est qu'à moitié vrai. Il existe deux plafonds distincts, et la lecture de latex.ltx en révèle la structure. itemize garde sa profondeur dans \@itemdepth et enumerate dans \@enumdepth — deux compteurs indépendants — et chacune appelle \@toodeep dès que son propre compteur dépasse 3. La limite de quatre niveaux ne vaut donc que lorsqu'on empile le même environnement. Par-dessus cela, \list porte lui-même une barrière globale, \ifnum \@listdepth >5, et celle-ci ne se soucie pas du type des listes.
À la compilation, c'est exactement ce qui se produit. Empilez cinq environnements itemize et le cinquième déclenche ! LaTeX Error: Too deeply nested. ; cinq enumerate font de même. Mais alternez itemize et enumerate et six niveaux ne provoquent aucune erreur ; seul le septième la déclenche — et cette fois c'est \@listdepth qui arrête tout. Le plafond pratique est donc de quatre niveaux d'un même type, six en alternant. Prenez-le pour un savoir plutôt que pour une autorisation : une imbrication de six niveaux n'est pour ainsi dire jamais lisible. Si vous avez vraiment besoin d'une telle profondeur, tournez-vous vers des titres comme \subsubsection, ou vers le package easylist, plutôt que vers des listes.
Le fâcheux, avec cette erreur, c'est qu'elle n'interrompt pas la composition. Le test de profondeur dans la définition de \itemize a la forme \ifnum ... \@toodeep \else ... \fi : dès que la limite est franchie, LaTeX n'ouvre tout simplement pas de liste et laisse le texte passer tout droit. Il en résulte une casse déroutante : l'erreur est consignée une fois, le PDF est produit, et les éléments de ce niveau ressortent en texte courant ordinaire. Si vous trouvez Too deeply nested dans le journal, corrigez le passage même si un PDF est apparu. Autre conséquence : définir un \labelitemv pour un cinquième niveau ne sert à rien, car le test écarte la liste avant que ce niveau soit atteint.