---
myst:
html_meta:
keywords: LaTeX,LaTeX3,newcommand
---
# Comment passer à la définition des commandes de LaTeX3 ?
LaTeX3 est un projet ancien puisque c'est en 1999 que et détaillaient les
motivations, les réalisations et le futur du _LaTeX3 Project_[^1].
Le projet a bien évolué et, depuis un certain temps déjà, l'idée de
produire un nouveau format existant en parallèle de LaTeX2e a été abandonnée :
les membres du _LaTeX3 Project_[^2] ont décidé d'améliorer et de moderniser en intégrant
graduellement dans son *noyau* les nouveautés, tout en veillant au
maintien de la compatibilité descendante pour les anciens documents.
C'est ainsi que désormais, en 2022, nous avons accès aux mécanismes de
sans rien charger de plus.
Cet article[^3] se limitera à montrer quelques commandes, par le passé
fournies par le package mais désormais nativement présentes
dans le format LaTeX,
permettant de définir des commandes[^4]. Il faudra se référer à la
documentation pour davantage d'informations.
En réalité, nous nous limiterons à illustrer le passage de la classique
commande `\newcommand` à `\NewDocumentCommand`, bien plus puissante. On
sait en effet qu'une macro créée avec `\newcommand` a au plus
9 arguments obligatoires, dont au plus un (le premier) optionnel. Toutes
les autres possibilités nécessitent, en LaTeX2e, pas mal de programmation ou
des appels à d'autres packages. La commande `\NewDocumentCommand` permet
de créer *facilement* des macros avec un mélange de différents types
d'arguments.
Enfin, les macros créées avec `\newcommand` ne sont pas *robustes*. Sans
rentrer dans les détails, disons que c'est la raison pour laquelle ces
macros doivent dans certaines situations être précédées de la primitive
`\protect`. En revanche, les macros créées avec `\NewDocumentCommand`
sont par défaut robustes, ce qui augmente en général leur fiabilité.
## Description de la commande `\NewDocumentCommand`
Pour créer des macros au niveau utilisateur[^5], on dispose donc (entre
autres) de :
1. la commande `\newcommand` dont la syntaxe est la suivante :
```{noedit}
\newcommand{\⟨nom⟩}[⟨narg⟩]{⟨définition de la commande⟩}
```
Nous ne rentrerons pas dans le détail des explications de cette
commande très classique ;
2. la commande `\NewDocumentCommand` qui offre un nouveau paradigme de
programmation :
```{noedit}
\NewDocumentCommand{\⟨nom⟩}{⟨spéc. arg.⟩}{⟨définition dela commande⟩}
```
Dans les deux cas, les arguments successifs de la macro créée sont, dans
la `⟨définition dela commande⟩`, indiqués sous la forme `#1`, `#2`, etc.
Contrairement à `\newcommand`, `\NewDocumentCommand` ne doit pas
seulement connaître le nombre d'arguments de la macro créée, mais aussi
la *nature* de chacun. C'est dans son argument obligatoire `⟨spéc. arg.⟩` de
spécification des arguments que ces natures seront spécifiées et, comme
il est nécessaire de bien en comprendre le principe, nous allons y
consacrer quelques lignes.
La forme générique de `⟨spéc. arg.⟩` est une liste de lettres où chacune déclare
un
type d'argument. Nous n'allons ici décrire que les plus communs et nous
renvoyons vers la documentation pour avoir l'ensemble des
types
d'arguments.
:`m`: déclare un argument obligatoire *standard* qui peut-être une simple
unité lexicale (_token_) ou un ensemble d'unités lexicales encapsulées
entre accolades. C'est le type classique d'un argument TeX normal.
:`o`: déclare un argument optionnel à fournir entre crochets dont la
valeur sera `-NoValue-` s'il n'est pas fourni lors de l'utilisation.
C'est l'équivalent de l'argument optionnel classique de LaTeX.
:`O{⟨défaut⟩}`: déclare un argument optionnel, comme la spécification `o`, mais
affecte la valeur s'il n'est pas fourni lors de l'utilisation. C'est
donc l'argument optionnel avec valeur par défaut.
:`s`: permet de déclarer une variante étoilée de la commande. L'argument
aura pour valeur `\BooleanTrue` si la commande est appelée dans sa
version étoilée, et `\BooleanFalse` sinon.
On constate donc que, contrairement au cas de `\newcommand`, on peut
avoir autant d'arguments optionnels que l'on souhaite, et que tous
peuvent avoir une valeur par défaut.
## Par l'exemple
Illustrons par des exemples les quelques éléments introduits jusque-là.
### Commande sans argument
Le cas le plus simple est celui d'une macro sans argument, typiquement
une substitution de texte. À la sauce LaTeX2e, on écrit :
```{noedit}
\newcommand\insertion{du texte à insérer}
```
Avec LaTeX3, on fait comme expliqué précédemment, et comme la macro que l'on
définit n'a pas d'argument, la liste de spécification des arguments est
vide. Cela donne :
```{noedit}
\NewDocumentCommand\insertion{}{du texte à insérer}
```
### Un ou plusieurs arguments obligatoires
Regardons comment traiter en pratique les cas où l'on souhaite avoir un
ou plusieurs arguments obligatoires.
En LaTeX2e, on peut créer les macros suivantes, respectivement à 1 et
2 arguments :
```{noedit}
\newcommand\unargument[1]{Mon argument est #1}
\newcommand\deuxarguments[2]{Mes deux arguments sont #1 et #2}
```
Pour créer des macros équivalentes avec LaTeX3, on va utiliser l'argument de
spécification des arguments pour indiquer combien d'arguments
obligatoires on souhaite.
```{noedit}
\NewDocumentCommand\UnArgument{m}{Mon argument est #1}
\NewDocumentCommand\DeuxArguments{m m}{Mes deux arguments sont #1 et #2}
```
Il est d'usage de séparer les spécifications d'arguments par des
espaces, mais ce n'est pas obligatoire.
Pour l'instant, les exemples ci-dessous montrent que tout ceci est très
similaire au paradigme LaTeX2e, et c'est tant mieux. Nous allons voir que la
puissance de cette nouvelle commande va se révéler lorsque les choses se
compliquent.
### Un ou plusieurs arguments optionnels
Avec la syntaxe de LaTeX2e, on peut avoir un seul argument optionnel qui se
trouve entre crochets en première position. Pour cela, il faut utiliser
le mécanisme de valeur par défaut du premier argument de la commande
`\newcommand`.
```
\newcommand\unargopt[1][]{Mon argument est peut-être #1.}
\unargopt\par\unargopt[ceci]
```
Avec LaTeX3, on va utiliser la spécification d'argument `o`. Ainsi, on écrira
:
```{noedit}
\NewDocumentCommand\UnArgOpt{o}{Mon argument est peut-être #1.}
```
Jusqu'ici, rien d'extraordinaire, mais LaTeX3 fournit des mécanismes de test
pour savoir si l'argument optionnel a été donné. Alors qu'avec LaTeX2e, on peut
avoir besoin de packages supplémentaires (comme et
), nous disposons ici
de la commande `\IfNoValueTF` qui nous permet de faire des choses
différentes suivant que l'argument optionnel a été renseigné ou non. Par
exemple :
```
\NewDocumentCommand\UnArgOpt{o}{%
Commande appelée
\IfNoValueTF{#1}{%true
\emph{sans} argument.%
}%
{%false
\emph{avec} l'argument \og{}#1\fg{}.%
}
}
\UnArgOpt\par\UnArgOpt[essai]
```
Avec ce nouveau mécanisme, il devient même très simple de créer une
macro à deux arguments optionnels, par exemple se plaçant avant et après
un argument obligatoire. Pour ce faire, on spécifiera les arguments à
l'aide de la suite `o m o`.
```
\NewDocumentCommand\ExempleOMO{o m o}{%
L'argument \emph{obligatoire} est \emph{#2}.%
\IfNoValueF{#1}{%
\par L'argument \emph{optionnel} \no1 est \emph{#1}.%
}%
\IfNoValueF{#3}{%
\par L'argument \emph{optionnel} \no2 est \emph{#3}.%
}
}
\ExempleOMO[chat]{chien}[lapin]
```
### Arguments optionnels avec valeur par défaut
Avec `\newcommand`, il est certes possible de déclarer un argument
optionnel pourvu d'une valeur par défaut (qui peut être vide) mais on
est limité à un unique tel argument. Avec LaTeX3, on dispose de la
spécification `O{⟨défaut⟩}` pouvant être employée plusieurs fois, comme l'illustre
l'exemple suivant.
```
\NewDocumentCommand\Animal{O{le chien} O{beau}}{%
Mon animal préféré est #1 car il est #2.%
}
\Animal\par\Animal[la baleine][gros]
```
### Commandes étoilées
Avec LaTeX en général, une macro peut avoir une version spéciale, portant le
même `\⟨nom⟩`, mais *étoilée* : `\⟨nom⟩*`. Créer ces versions spéciales avec
`\newcommand` est quelque peu délicat alors qu'avec
`\NewDocumentCommand` et la spécification d'argument `s`, cela devient
très simple. Nous avons vu que la spécification `s` renvoie un booléen
et, à l'instar de `\IfNoValueTF` vu précédemment, on dispose de
`\IfBooleanTF`.
```
\NewDocumentCommand\DeuxVersions{s m}{%
Version
\IfBooleanTF{#1}{%true
étoilée
}{%false
classique
}%
qui utilise #2.%
}
\DeuxVersions*{étoile}\par\DeuxVersions{soleil}
```
## Pour aller plus loin
Dans ce petit article, nous n'avons fait qu'effleurer les possibilités
offertes par LaTeX3 et, pour les nombreuses spécifications d'arguments
disponibles, nous vous invitons à aller parcourir la documentation
offerte par le .
Il s'agissait de présenter la commande`\NewDocumentCommand` par quelques
exemples de base et de donner à imaginer ses potentialités, notamment
concernant les simplifications qu'elle permet, et donc la
complexification à moindre frais des commandes ainsi créées.
Notons qu'il existe la commande équivalente `\NewDocumentEnvironment`
pour créer de nouveaux environnements, des commandes permettant de
redéfinir des macros existantes, de nombreux autres *tests* (`\If...`),
et bien plus encore.
Pour finir cette mise en bouche, un petit exemple illustrant un
spécificateur d'argument optionnel permettant de spécifier ce par quoi
cet argument doit être encadré.
```
\NewDocumentCommand\OptBarre{d<> o m}{%
Nos arguments sont #3%
\IfValueT{#1}{, #1}%
\IfValueT{#2}{, #2}%
.%
}
\OptBarre{chien}\par
\OptBarre{chien}\par
\OptBarre[lapin]{chien}
```
[^1]: Voir
.
[^2]:
[^3]: Très fortement inspiré de celui, *From* `\\newcommand` *to*
`\\NewDocumentCommand`, publié en 2010 par sur son blog :
.
[^4]: Que nous appellerons ici aussi "macros", même si ces termes ne
recouvrent pas tout à fait les mêmes objets (cf.
).
[^5]: C'est-à-dire destinées à être utilisées dans les documents de tout
le monde, et pas uniquement pour le développement de packages ou de
classes.
:::{sources}
[Denis Bitouzé et Maxime Chupin, _Passer à la définition de
commandes de LaTeX3_, la _Lettre GUTenberg_, numéro 49, p. 19-24](https://publications.gutenberg-asso.fr/lettre/article/view/113/106)
:::