Les compteurs

Dans ce chapitre nous allons encore une fois rentrer dans la mécanique interne de LaTeX. Mais c’est pour la bonne cause. Les compteurs permettent par exemple de gérer la numérotation.

Certains bouts de code et leurs rendus sont disponibles sur ce PDF qui contient un exemple par page. Bien sûr, tester d’autres codes et voir ce qu’ils donnent est une bonne idée.

Les compteurs

Comme nous l’avons dit, les compteurs nous permettent de gérer tout ce qui possède un numéro (sectionnement, pages, etc.).

Les compteurs par défaut

De base, il existe donc plusieurs compteurs :

  • Des compteurs pour le sectionnement et la structure du document.

part

subsubsection

chapter

paragraph

section

subparagraph

subsection

page

  • Des compteurs pour les énumérations de l’environnement enumerate.

enumi

enumii

enumiii

enumiv

  • Deux compteurs pour les notes de bas de page (le compteur mpfootnote correspond au compteur des notes de bas de page dans un environnement minipage).

footnote

mpfootnote

  • Des compteurs pour la numérotation des flottants.

figure

table

equation

Affichage des compteurs

Pour afficher la valeur d’un compteur, nous pouvons utiliser plusieurs commandes qui prennent en paramètre le compteur dont on veut afficher la valeur.

  • \arabic pour des chiffres arabes.
  • \roman pour utiliser des chiffres romains en minuscule.
  • \Roman pour des chiffres romains en majuscule.
  • \alph pour des lettres minuscules.
  • \Alph pour des lettres majuscules.

Pour \alph et \Alph, les valeurs des compteurs doivent être entre 1 et 26 (entre a et z), sinon nous obtiendrons l’erreur « LaTeX Error: Counter too large ».

\section{Section}
   Section \arabic{section}.
   \subsection{Sous-section}
      Section \roman{section}, sous-section \Roman{subsection}.   
\section{Section}
   Section \alph{section}.   
   \subsection{Sous-section}
      Section \Alph{section}, sous-section \arabic{subsection}.

Un autre style de commande, \the<counter> (\thesection, \thepage, etc.) permet également d’afficher la valeur du compteur, mais sous une autre forme. Pour voir la différence, reprenons le code précédent mais en utilisant \the<counter>.

\section{Section}
   Section \thesection.
   \subsection{Sous-section}
      Section \thesection, sous-section \thesubsection.   
\section{Section}
   Section \thesection.   
   \subsection{Sous-section}
      Section \thesection, sous-section \thesubsection.  

Et là, nous n’obtenons pas « sous-section 1 », mais « sous-section 1.1 » par exemple. En fait, \the<counter> affiche la valeur du compteur avec un formatage choisi au préalable (par exemple section.sous-section. pour \thesubsection).

C’est généralement \the<counter> qui est utilisé pour afficher un compteur, les autres commandes étant utilisées pour définir \the<counter>.

Par exemple, lorsque nous utilisons la commande \subsection, le compteur de sous-section est incrémenté, le nom et le numéro de la sous-section sont affichés. Donc, en gros, on affiche \thesubsection #1 (#1 étant l’argument de \subsection). Pour bien comprendre cela, regardons ce qu’il se passe dans l’exemple suivant (on note que \thesection vaut \arabic{section} et que \thesubsection vaut \thesection.\arabic{subsection}).

\section{Zeste de Savoir}
   \subsection{Tutoriels}
   \subsection{Forums}
  • Avec \section{Zeste de savoir}.
    1. On incrémente le compteur de section : il vaut 1.
    2. On affiche \thesection Zeste de Savoir : 1 Zeste de Savoir
  • Avec \subsection{Tutoriels}.
    1. On incrémente le compteur de sous-section : il vaut 1.
    2. On affiche \thesubsection Tutoriels : 1.1 Tutoriels.
  • Avec \subsection{Forums}.
    1. On incrémente le compteur de sous-section : il vaut 2.
    2. On affiche \thesubsection Forums : 1.2 Forums.

Nous pouvons alors redéfinir \thesubsection pour modifier le nombre affiché quand on utilise \subsection.

\renewcommand{\thesubsection}{[\Alph{section}](\alph{subsection})}

\section{Section}
   Section \arabic{section}.
   \subsection{Sous-section}
      Section \roman{section}, sous-section \Roman{subsection}.   
\section{Section}
   Section \alph{section}.   
   \subsection{Sous-section}
      Section \Alph{section}, sous-section \arabic{subsection}.

Ici, chaque fois que \thesubsection sera utilisé (et donc en particulier avec \subsection), la numérotation obtenue sera formatée en [<section](<subsection>) avec la section en lettre majuscule et la sous-section en lettre minuscule.

Manipuler les compteurs

Modifier un compteur

Plusieurs commandes nous permettent de manipuler les compteurs.

Incrémenter un compteur

Une des opérations que l’on réalise le plus souvent est d’incrémenter un compteur (c’est-à-dire de lui ajouter 1). Par exemple, à chaque fois que nous utilisons la commande \section, le compteur de sections est incrémenté avant d’être affiché. La commande \stepcounter prend en paramètre un compteur et incrémente sa valeur.

\section{Section}
   On est à la section \arabic{section}, mais j'incrémente le compteur 
   de section \stepcounter{section} et donc on est à la section
   \arabic{section}.

Ici, on incrémente le compteur de section à la main. La prochaine fois qu’on utilisera \section, le compteur sera encore incrémenté, et il y aura un trou dans la numérotation des sections.

Donner une valeur

La commande \setcounter prend deux paramètres, le nom du compteur et une valeur à lui donner. Bien sûr, la valeur du compteur peut être négative.

\section{Section}
   On est à la section \arabic{section}, mais je mets le compteur de
   section à -5 \setcounter{section}{-5} et donc on est à la section
   \arabic{section}.

Cette commande peut être utilisée pour remettre un compteur à zéro (par exemple lorsque l’on change de section, il faut remettre à zéro le compteur de tous les niveaux de titres inférieurs).

Ajouter une valeur

Nous pouvons également ajouter une valeur à un compteur avec \addtocounter{<counter>}{<value>}.

\section{Section}
   On est à la section \arabic{section}, mais je rajoute 3 au compteur 
   de section \addtocounter{section}{3} et donc on est à la section
   \arabic{section}.

Là encore, la valeur à ajouter n’est pas nécessairement positive. Ainsi, nous pouvons décrémenter un compteur en lui ajoutant la valeur -1 (bien sûr, si c’est une opération que l’on fera souvent, il pourrait être judicieux de créer une commande pour cette action).

Travailler avec les valeurs des compteurs

Nous pourrions vouloir utiliser les valeurs des compteurs. Par exemple, essayons de donner à un compteur la valeur d’un autre compteur.

\section{Section}
   On est à la section \arabic{section}, mais je donne au compteur de
   section la valeur du compteur de sous-section, et donc on est à la
   section \setcounter{section}{subsection}\arabic{section}.

Et le code précédent ne fonctionne pas. En effet, \setcounter attend un nombre pour la valeur à donner au compteur, et subsection n’est pas un nombre.

La solution à ce problème est donnée par la commande \value qui prend en paramètre un compteur et permet d’obtenir sa vraie valeur, donc un nombre (nous pouvons également utiliser \arabic, mais \value a plus de sens ici).

\section{Section}
   On est à la section \arabic{section}, mais je donne au compteur de
   section la valeur du compteur de sous-section, et donc on est à la
   section \setcounter{section}{\value{subsection}}\arabic{section}.

Il est possible de faire des calculs plus compliqués (notamment à l’aide du package calc), mais nous n’en parlerons pas dans ce chapitre.

Dépendance de compteurs

Nous pouvons nous rendre compte que certains compteurs dépendent d’autres compteurs, dans le sens où le compteur cptr1 est remis à zéro chaque fois que le compteur cptr2 est incrémenté. C’est par exemple le cas des compteurs de sectionnement. De même, les compteurs de figure et de table sont remis à zéro à chaque nouveau chapitre.

LaTeX nous permet de gérer les dépendances entre les compteurs à l’aide des commandes \counterwithin et \counterwithout. La première permet de lier des compteurs, et la seconde de les délier. Elles prennent en paramètre le compteur à lier en premier, et le compteur auquel le lier en deuxième.

Par exemple, le compteur des équations est par défaut lié aux chapitres lorsqu’on utilise la classe report. Dans le code qui suit, nous allons le lier au compteur de parties. Le but est alors qu’il ne soit remis à zéro que lorsque l’on change de parties.

\counterwithin{equation}{part}

\part{Un}

\begin{equation} 1 + 1 = 2. \end{equation}
\begin{equation} 2 + 2 = 4. \end{equation}

\part{Deux}

\begin{equation} 1 + 1 = 2. \end{equation}
\chapter{Chapitre un}
\begin{equation} 1 + 1 = 2. \end{equation}
\chapter{Chapitre deux}
\begin{equation} 1 + 1 = 2. \end{equation}

Ici, nous avons malgré tout un problème ; si le compteur d’équation est remis à zéro lorsqu’on incrémente le compteur de parties, il l’est également lorsqu’on incrémente celui des chapitres !

En fait, ce comportement est tout à fait normal. Nous avons lié le compteur d’équations au compteur de parties, mais nous ne l’avons pas délié au compteur de chapitres. Pour avoir le résultat voulu, il nous faut donc faire ceci.

\counterwithout{equation}{chapter}
\counterwithin{equation}{part}

Nous pouvons de plus remarquer que la numérotation a changé. Ainsi, la numérotation obtenue pour les équations est devenue <partie>.<equation>.

En fait, \counterwithin et \counterwithout changent la numérotation du compteur qu’on lie ou délie.

  • Avec \counterwithin{<cptr1>}{<cptr2>}, \the<cptr1> devient \the<cptr2>.\arabic{cptr1} (c’est une numérotation que l’on devrait a priori vouloir, si l’on lie deux compteurs ensemble).
  • Avec \counterwithout{<cptr1>}{<cptr2>}, \the<cptr1> devient \arabic{cptr1} (on peut voir cela comme une remise à zéro de l’affichage du compteur).

Pour ne pas avoir de modifications des commandes d’affichage de compteur, il nous suffit d’utiliser les versions étoilées de \counterwithin et de \counterwithout. Nous obtenons alors ce code.

\counterwithout*{equation}{chapter}
\counterwithin*{equation}{part}

\part{Un}

\begin{equation} 1 + 1 = 2. \end{equation}
\begin{equation} 2 + 2 = 4. \end{equation}

\part{Deux}

\begin{equation} 1 + 1 = 2. \end{equation}
\chapter{Chapitre un}
\begin{equation} 1 + 1 = 2. \end{equation}
\chapter{Chapitre deux}
\begin{equation} 1 + 1 = 2. \end{equation}

Ici, nous avons finalement le résultat souhaité, la numérotation des équations est remise à zéro à chaque nouvelle partie (et pas à chaque nouveau chapitre), mais l’affichage est inchangé et reste de la forme <chapitre>.<equation>.

La remise à zéro n’a lieu que lors de l’incrémentation ; elle n’a pas lieu lorsque nous modifions le compteur avec \setcounter ou \addtocounter.

Créer des compteurs

La commande de création

La création de compteurs se fait avec la commande \newcounter. Elle prend en paramètre le nom du compteur à créer et nous pouvons également lui donner en option un compteur cptr auquel lier le compteur que l’on crée (notre compteur sera alors remis à zéro à chaque fois que cptr sera incrémenté).

\newcounter{compteur}
\newcounter{compteurLie}[section]

Le compteur « compteur » vaut \arabic{compteur} et 
compteurLie vaut \arabic{compteurLie}.

\stepcounter{compteur}
\stepcounter{compteurLie}
\stepcounter{compteurLie}

Le compteur « compteur » vaut \arabic{compteur} et 
compteurLie vaut \arabic{compteurLie}.

\section{Nouvelle}

Le compteur « compteur » vaut \arabic{compteur} et 
compteurLie vaut \arabic{compteurLie}.

Lorsque nous faisons \newcounter{<counter>}, la commande associée \the<counter> est automatiquement créée et vaut \arabic{<counter>}. En particulier, nous pourrions nous attendre à ce qu’elle donne \arabic{<cptr1>}.\arabic{<cptr2>} si <cptr2> a été créé avec \newcounter{<cptr2>}[<cptr1] (c’est-à-dire en le liant à cptr1), mais ce n’est pas le cas.

thecompteur vaut \thecompteur{} et thecompteurLie vaut \thecompteurLie.
Autour du compteur

Comme nous pouvons le constater, la majorité des compteurs sont incrémentés automatiquement avec une commande du même nom (qui fait parfois d’autres choses). Par exemple, la commande \section incrémente section et affiche le numéro et le nom de la section courante.

C’est plutôt une bonne idée. Cela nous permet d’utiliser facilement le compteur (et de le cacher), et nous donne une commande sémantique pour faire le travail voulu : c’est plus simple d’utiliser \section que d’afficher \thesection suivi du nom voulu pour la section. Ainsi, trois choses peuvent être faites.

  1. Création du compteur counter.
  2. Redéfinition de \thecounter si nécessaire.
  3. Création d’une commande \counter (ou d’un environnement counter, pensons à figure par exemple) associée.

Prenons un petit exemple pratique. Nous allons créer une commande de sectionnement \fiche au-dessus de \section. La numérotation des sections restera cependant continue à travers les fiches (le compteur des sections ne sera pas remis à zéro à chaque nouvelle fiche) même si l’affichage devra contenir le numéro de la fiche.

\newcounter{fiche}
\renewcommand\thefiche{\Roman{fiche}}
\newcommand{\fiche}[1]{
  \stepcounter{fiche}
  \begin{center} \Huge \bfseries Fiche \thefiche{} : #1 \end{center}
}

\renewcommand\thesection{\thefiche.\arabic{section}}

Qu’on utilise dans cet exemple.

\fiche{Les compteurs en LaTeX}
\section{...}
\section{...}
\section{...}

\fiche{Les tableaux en LaTeX}
\section{...}
\section{...}
\section{...}
Références à nos compteurs

Nous pouvons placer des étiquettes après avoir incrémenté un compteur, et nous pourrons alors y faire référence. Cependant, pour profiter de ce système, il nous faut utiliser la commande \refstepcounter à la place de \stepcounter.

Essayons alors ce code.

\fiche{Les compteurs en LaTeX}
\section{...}
\section{...}
\section{...}

\fiche{Les tableaux en LaTeX} \label{fiche:tableau}
\section{...} 
\section{...}
\section{...}
La fiche \ref{fiche:tableau}.

Avec \stepcounter, nous obtenons « La fiche I.3 » (le dernier compteur qui a été incrémenté avant le \label, et donc auquel l’étiquette sera rattachée, est celui de la dernière section). En modifiant \fiche pour y placer \refstepcounter à la place de \stepcounter, nous obtenons le résultat voulu, à savoir « La fiche I ».


Ce chapitre nous permet de gérer les compteurs de LaTeX. Bien sûr, nous aurons rarement à les gérer totalement à la main (par exemple, si nous créons un compteur, nous passerons plutôt par une commande qui incrémente le compteur et fait d’autres opérations si nécessaire).

Nous savons également comment modifier les numérotations de LaTeX en redéfinissant \the<counter> et en modifiant les dépendances entre compteurs.