enumerate

Les nombres [1], [2], [3] alignés dans la bibliographie d’un document LaTeX proviennent du compteur de quatrième niveau de enumerate. Plutôt que de définir son propre compteur, thebibliography dans article.cls écrit simplement \usecounter{enumiv} et emprunte le niveau le plus profond d’une liste numérotée. La mécanique des listes s’enfonce ainsi jusque dans la charpente du document. Cette page parcourt enumerate dans l’ordre : les compteurs enumi à enumiv qui portent les nombres, la famille \theenumi qui les transforme en texte, la manière de désigner un élément avec \label et \ref, et la façon de poursuivre la numérotation après une interruption.

Les nombres résident dans des compteurs, pas dans l’environnement : de enumi à enumiv

enumerate ne détient pas les nombres lui-même. latex.ltx définit quatre compteurs LaTeX ordinaires — enumi, enumii, enumiii, enumiv — et l’environnement se contente d’en choisir un selon la profondeur courante. Le travail se répartit en trois couches : \begin{enumerate} appelle \usecounter, qui remet le compteur à zéro ; \item l’incrémente de un avec \refstepcounter avant de composer l’entrée ; et la famille \theenumi transforme la valeur obtenue en texte. Garder cet ordre en tête rend limpide la bizarrerie qui suit : écrire 4 pour que la liste commence à 5.

NiveauCompteurFormat par défautÉtiquette en tête de ligneSortie
enumi1\theenumi = \arabic{enumi}\labelenumi = \theenumi.1.
enumii2\theenumii = \alph{enumii}\labelenumii = (\theenumii)(a)
enumiii3\theenumiii = \roman{enumiii}\labelenumiii = \theenumiii.i.
enumiv4\theenumiv = \Alph{enumiv}\labelenumiv = \theenumiv.A.

Confondre les troisième et quatrième colonnes de ce tableau se paie plus tard. \theenumi décide de la façon d’écrire le nombre lui-même ; \labelenumi décide de l’ornement posé en tête de ligne. Le niveau 2 rend la différence évidente : \theenumii ne dit que a, et ce sont les parenthèses de \labelenumii qui l’entourent. Pour un autre style de nombre, on modifie \theenumi ; pour une autre ponctuation autour, \labelenumi. Cinq commandes transforment un décompte en caractères — \arabic (1, 2, 3), \alph (a, b, c), \Alph (A, B, C), \roman (i, ii, iii) et \Roman (I, II, III) — et chacune fonctionne avec n’importe quel compteur.

latex
% style of the number itself
\renewcommand{\theenumi}{\Roman{enumi}}
% punctuation around it: I) II) instead of I. II.
\renewcommand{\labelenumi}{\theenumi)}

Désigner un élément avec \label et \ref — et pourquoi la référence ne correspond pas à l’étiquette

Placer \label{clé} au début du corps d’un \item permet à \ref{clé} d’imprimer le numéro de cette entrée depuis n’importe où dans le document. Le \refstepcounter qu’utilise \item pour avancer le numéro enregistre en même temps que « l’objet actuellement référençable est cette entrée » : c’est ce qui lie la \label au \item qui la précède immédiatement. D’où le suivi automatique de la référence lorsqu’on réordonne les étapes. Les valeurs transitent par le fichier .aux : lors de la passe où l’on ajoute une nouvelle \label, le numéro n’est pas encore fixé et il faut compiler deux fois. Avec hyperref chargé, la même référence devient un lien cliquable. Si c’est la page où figure l’élément qui intéresse plutôt que son numéro, \pageref{clé} accepte la même clé.

latex
\begin{enumerate}
  \item Bring the sample to room temperature
  \item \label{step:weigh} Record the weight
  \item Add solvent and stir
\end{enumerate}
Use the value from step~\ref{step:weigh} in the yield calculation.

Voici un comportement qui déroute tout le monde : référencer un élément imbriqué renvoie une chaîne différente de l’étiquette visible sur la ligne. Une entrée de deuxième niveau est composée « (a) », mais \ref renvoie 2a ; au troisième niveau on lit « i. » tandis que la référence donne 2(a)i. Ce n’est pas un défaut : une commande de préfixe nommée \p@enumii opère en coulisse. article.cls définit \p@enumii comme \theenumi, et la chaîne renvoyée se compose de préfixe + \theenum…. \labelenumii, qui fabrique l’étiquette en tête de ligne, n’intervient pas du tout dans le référencement : voilà pourquoi les parenthèses qu’il ajoute n’apparaissent jamais dans la référence.

NiveauNuméro visible sur la ligneChaîne renvoyée par \refDéfinition du préfixe
enumi2.2aucun préfixe
enumii(a)2a\p@enumii = \theenumi
enumiiii.2(a)i\p@enumiii = \theenumi(\theenumii)
enumivA.2(a)iA\p@enumiv = \p@enumiii\theenumiii

Le principe se défend : un simple « a » laisserait le lecteur ignorer sous quel élément parent se trouve ce (a). Reste que « 2a » heurte souvent les conventions d’un document. Pour supprimer le parent et renvoyer un a nu, on écrit \renewcommand{\p@enumii}{} ; pour séparer sous la forme « 2.1 », \renewcommand{\p@enumii}{\theenumi.}. Ce qu’il ne faut surtout pas faire ici, c’est toucher à \theenumii : le modifier réécrit aussi l’étiquette en tête de ligne en « 2.1 » et abîme l’aspect de la liste. Quand seule la référence doit être corrigée, la commande à modifier est \p@enum….

Poursuivre la numérotation après une coupure : pourquoi écrire 4 pour commencer à 5

Si un paragraphe explicatif ou une figure interrompt une procédure et que la liste est refermée, l’enumerate suivant repart à 1 — inévitablement, puisque le \usecounter appelé par \begin{enumerate} remet le compteur à zéro à chaque entrée dans l’environnement. Pour poursuivre la numérotation, on réinscrit la valeur avec \setcounter juste après l’ouverture de la liste. C’est ici que l’ordre en trois couches vu plus haut se révèle utile : \item incrémente le compteur avant de composer l’entrée, donc pour commencer à 5 on inscrit 4. Ce « moins un » n’est pas une formule magique : c’est la conséquence directe du fait que \refstepcounter s’exécute en premier.

latex
\newcounter{savedstep}

\begin{enumerate}
  \item first
  \item second
\end{enumerate}
\setcounter{savedstep}{\value{enumi}}

An interrupting paragraph.

\begin{enumerate}
  \setcounter{enumi}{\value{savedstep}}
  \item this one is numbered 3
\end{enumerate}

Cette tournure est fiable parce que enumi conserve sa valeur finale après \end{enumerate}. En la rangeant dans un compteur personnel juste après la fermeture de la liste, la numérotation survit à autant de paragraphes et de figures que l’on veut. Pour les niveaux plus profonds, on traite enumii, enumiii et enumiv de la même façon. Cela dit, plutôt que de recopier cette structure à chaque fois, mieux vaut charger enumitem : \begin{enumerate}[resume] reprend là où la liste précédente s’était arrêtée, et \begin{enumerate}[start=7] démarre à 7 — avec start=, plus de « moins un ». Pour un long document de procédure, il vaut la peine de charger enumitem dès le départ.

Quand la numérotation se justifie, et quand elle induit en erreur

On ne choisit pas enumerate parce que les nombres font propre. Un numéro est un contrat avec le lecteur : il déclare qu’ici l’ordre, la priorité ou la référence signifient réellement quelque chose. Numéroter des éléments sans ordre, c’est inviter le lecteur à y lire une chronologie ou une hiérarchie, et donc affirmer ce que l’auteur n’a jamais voulu dire. À l’inverse, dans une véritable procédure, les numéros sont ce qui permet de dire « revenez à l’étape 3 ». Et cette référence doit être confiée à \label et \ref plutôt que tapée en clair dans le texte : les numéros saisis à la main deviennent tous faux dès qu’un élément est inséré.

  • enumerate pour les procédures, la chronologie et la priorité. Que le lecteur puisse dire « revenez au numéro 3 » est la seule raison de numéroter.
  • itemize pour les conditions et propriétés sans ordre. Les numéroter affirme une hiérarchie ou une séquence non voulue.
  • Toujours poser un \label sur un élément appelé ailleurs. Un numéro tapé dans le texte devient faux dès qu’une entrée s’ajoute.
  • Vérifier ce que renvoie \ref pour les éléments imbriqués. La ligne affiche « (a) » mais la référence revient en 2a.
  • Faire passer la numérotation par-dessus une coupure. En LaTeX pur avec \setcounter, avec enumitem grâce à resume.