---
myst:
html_meta:
keywords: LaTeX, programmation, commandes, macros, nom de commande, définition, catcode, code de catégorie, \def, \gdef
---
# Comment mettre des caractères autres que des lettres dans les noms de commande ?
Les utilisateurs débutants avec LaTeX sont souvent étonnés de voir que des
commandes contenant des caractères autres que des lettres ne fonctionnent
pas. Par exemple :
```{noedit}
\newcommand{\a2main}{À demain !}
```
En effet, contrairement à d'autres langages de programmation, TeX n'autorise que
[des lettres dans les noms de
commandes](/2_programmation/macros/que_sont_les_macros). Il existe cependant des
techniques pour contourner cette limitation mais... à vos risques et périls !
## Utilisation de `\csname` et `\endcsname`
Voici un exemple de la méthode utilisant les commandes `\csname` et `\endcsname`
qui vont encadrer le nom de la notre commande.
```{noedit}
\expandafter\newcommand\csname a2main\endcsname{À demain !}
Je vous dis « \csname a2main\endcsname ».
```
Cette technique a l'unique désavantage de demander bien trop de texte et rend
l'utilisation des chiffres finalement peu intéressante.
## Définition d'un générateur de commande spéciale
En retenant la logique précédente, nous définissons ici une fonction
particulière pour un peu plus d'automatisation :
```{noedit}
\newcommand{\DefCommande}[2]{%
\expandafter\newcommand\csname defcomm-#1\endcsname{#2}%
}
\newcommand{\Commande}[1]{\csname defcomm-#1\endcsname}
...
\DefineRemark{a2main}{À demain !}
...
Je vous dis « \Commande{a2main} ».
```
C'est toutefois une solution indirecte car la commande `\a2main` n'est pas accessible.
## Définition avec la commande `\def`
TeX nous permet, avec la commande `\def`, de définir `\a2main` comme la commande
`\a` toujours suivie de `2main`.
```{noedit}
\def\a2main{À demain !}
Je vous dis « \a2main ».
```
Ici, `\a2main` est directement utilisatble mais cette solution pose deux
problèmes :
- elle crée une source d'erreur : si `\a` est suivi d'autre chose que `2main`,
une erreur se déclenche (*Use of `\a` doesn't match its definition*), par
exemple avec `\a4mains`. Ceci perturberait quelqu'un qui n'aurait pas réalisé
qu'il y a une définition subtile de `\a` dans le document.
- elle redéfinit discrètement la commande `\a`, si elle existe. Par conséquent,
cette technique ne peut pas être utilisée pour définir à la fois une
commande`\a2main` et, par exemple, une commande `\a2mimot` dans le même
document.
## Définition en modifiant un code de catégorie
Nous allons ici indiquer à TeX que `2` est une lettre en changeant le code de
catégorie, ou *catcode*, de ce caractère :
```{noedit}
\catcode`2 = 11
\newcommand{\a2main}{À demain !}
Je vous dis « \a2main ».
```
Si `\a2main` est maintenant utilisable directement, cette manipulation casse
toute autre utilisation de `2`, en particulier comme valeur numérique. La
commande `\setlength{\paperwidth}{2cm}` va en conséquence générer une erreur
indiquant qu'il ne comprend plus de valeur intégrant un `2` (*Missing number,
treated as zero.*).
En règle générale, la modification des catcodes doit être utilisée *en dernier
recours*, après un examen détaillé des autres options. Pour un utilisateur peu
expérimenté, il est concevable que cette solution puisse être utile mais elle
doit rester l'exception.
Il faut noter que cette technique est couramment utilisée --- sous une forme
légèrement différente --- dans la plupart des extensions LaTeX et dans LaTeX
lui-même. La convention est d'utiliser `@` dans les noms des commandes internes
pour les cacher à l'utilisateur et ainsi éviter les conflits de noms. À cette
fin, LaTeX traite automatiquement `@` comme une lettre lors du traitement des
classes et des extensions et comme une non-lettre lors du traitement du document
de l'utilisateur. Sur ce point, la question
"[](makeatletter_et_makeatother.md)" fournit plus d'informations.
Notez qu'une utilisation de cette technique pourrait nous donner une autre
proposition de solution :
```{noedit}
\begingroup
\catcode`2 = 11
\gdef\a2main{À demain !}
\gdef\ademain{\a2main}
\endgroup
Je vous dis « \ademain ».
```
Si cette solution fonctionne, elle va à l'encontre de l'objectif
intial. Toutefois, la commande `\ademain` utilise bien un catcode modifié pour
`2`, même si il est redevenu normal au moment où il est utilisé. Notez également
l'utilisation de la commande primitive `\gdef` car `\newcommand` ne peut pas
faire une commande disponible en dehors de son groupe.
## Recommandation
Il est recommandé de choisir des mécanismes hors modification de catcode (comme
celui faisant intervenir `\DefCommande` ci-dessus) ou de choisir un nom de
commande ne contenant que des lettres ordinaires. Une approche courante consiste
à utiliser des chiffres romains à la place des chiffres arabes :
```{noedit}
\newcommand{\aIImain}{À demain !}
```
Mais convenons que la blague marche ici beaucoup moins bien, forcément...
:::{sources}
[Non-letters in macro names](faquk:FAQ-linmacnames)
:::