Que font \makeatletter et \makeatother ?#

1.  Être ou ne pas être une lettre : le cas de @#

Comme indiqué dans la question « Comment bien nommer ses commandes et environnements ? », le caractère @ est normalement traité comme un chiffre ou un symbole de ponctuation. En particulier, il ne peut pas apparaître dans le nom d’une commande. De fait, si vous écrivez par exemple \cejour@midi, il ne s’agit pas d’un nom d’une commande isolée, mais de la commande \cejour suivie des caractères @, m, i, etc.

Pourtant, si vous lisez les sources d’une extension, d’un fichier de classe ou même du noyau vous constaterez que beaucoup de noms de commandes y contiennent au moins un @. Il s’agit d’une convention standard de (déjà utilisée par le format plain d’ailleurs) qui sert à empêcher l’utilisateur d’utiliser directement ces commandes dans le document principal : il pourra par exemple pas appeler \cejour@midi car ne comprendra que \cejour suivi du texte @midi.

Ceci repose que le fait que peut être paramétrée pour considérer ou pas @ (ou tout autre caractère) comme une lettre. Par défaut avec @ est une lettre à l’intérieur des fichiers de style (extensions) ou de classe (les commandes \documentclass et \usepackage gèrent comportement), et n’est pas une lettre dans les documents .

2.  Modifier le sens de @#

Si vous souhaitez néanmoins modifier ou définir une telle commande, il faut, au préalable, dire à de considérer @ comme une lettre, afin que ce dernier puisse être utilisé dans les noms de commandes. C’est le rôle de \makeatletter (autrement dit, « faire de at [c’est ainsi que se prononce @ en anglais courant] une lettre »). Il ne faut pas oublier par la suite de rétablir l’ordre naturel des choses avec la commande \makeatother.

Le livre The Companion donne de nombreux exemples (disponibles sur le CTAN) de cet usage. Voici un exemple qu’il donne (en page 29 de la 2e édition). L’auteur y modifie la présentation de la sous-section.

\makeatletter
\renewcommand\subsection{\@startsection
  {subsection}{2}{0mm}%name, level, indent
  {-\baselineskip}%             beforeskip
  {0.5\baselineskip}%            afterskip
  {\normalfont\normalsize\itshape}}% style
\makeatother

La question « Comment définir une commande ou un environnement étoilé ? » donne un autre exemple d’utilisation de ces commandes.

3.  Une solution alternative à ces commandes#

À l’intérieur d’une extension, le @ est toujours considéré comme une lettre. Il est donc, dans ce cas, inutile d’utiliser \makeatletter pour définir des commandes dont le nom contient un @.

Ce principe conduit à une bonne alternative à l’utilisation des commandes \makeatletter et \makeatother lorsque ces dernières se multiplient : regrouper tous ces fragments de code pour en faire une extension en les plançant dans un fichier sty (de préférence placé dans le même répertoire que votre fichier tex) et en appelant votre nouvelle extension avec la commande \usepackage. Ainsi, vous regroupez dans un fichier votre code un peu plus complexe et rendez votre code mieux organisé. Ce principe est décrit dans la question « Comment créer une extension ? ».