Quand vous tapez sans cesse la même chose, ou savez que vous voudrez la modifier partout plus tard, vous définissez votre propre commande, une macro. La base est \newcommand. Cette page parcourt les fondements des commandes personnelles : arguments, redéfinition de commandes existantes, \NewDocumentCommand moderne et bonnes pratiques pour éviter les commandes « fragiles ».
Définir des commandes avec \newcommand
L’outil le plus simple est \newcommand{\name}{definition}. Le premier argument est le nom de la commande voulue, le second ce qu’elle représente. Si le nom de votre groupe de recherche revient sans cesse, définissez-le une fois dans le préambule ; ensuite, taper \name dans le texte se développe en definition.
% プリアンブルで定義 / define in the preamble
\newcommand{\grp}{Knuth Typesetting Lab}
% 本文で使う / use it in the body
Welcome to the \grp. The \grp{} was founded in 1978.Remarquez les {} après le second \grp. Une commande faite de lettres, comme \grp, avale l’espace qui suit pour marquer la fin de son nom ; \grp was perd donc l’espace et imprime « Labwas » plutôt que « Lab was ». La correction classique est une paire d’accolades vide {} pour marquer la fin du nom ; voir la page de syntaxe.
Règle importante : \newcommand réussit seulement si le nom n’est pas déjà défini. Utilisé sur un nom existant, y compris du noyau ou d’un package, il s’arrête avec Command \name already defined. C’est une sécurité volontaire contre l’écrasement silencieux. Pour retravailler volontairement une commande existante, utilisez \renewcommand.
Macros avec arguments
Pour faire varier le contenu à chaque appel, donnez des arguments à la commande. Écrivez le nombre d’arguments entre crochets après le nom — \newcommand{\name}[⟨nargs⟩]{... #1 #2 ...} — puis utilisez #1, #2, etc. dans la définition. Les paramètres vont de #1 à #9, neuf au maximum.
\newcommand{\unit}[2]{#1\,\mathrm{#2}}
% \unit{9.8}{m/s^2} → 9.8 m/s^2(数と単位の間に細い空き)
$a = \unit{9.8}{m/s^2}$On peut aussi rendre le premier argument optionnel avec une valeur par défaut. En doublant les crochets — \newcommand{\name}[⟨nargs⟩][⟨default⟩]{...} — #1 devient optionnel et vaut ⟨default⟩ par défaut. On appelle ensuite \name (valeur par défaut) ou \name[x] (#1 vaut x) ; les arguments obligatoires restants commencent à #2.
% 全 2 引数、うち #1 は省略可能で既定値 2
\newcommand{\plusbinomial}[2][2]{(x + y)^{#1}_{#2}}
$\plusbinomial{n}$ % → (x + y)^2_n (#1 は既定の 2)
$\plusbinomial[3]{n}$ % → (x + y)^3_n (#1 を 3 に)Attention au comptage : le ⟨nargs⟩ de [⟨nargs⟩] est le nombre total d’arguments, optionnel compris. L’exemple signifie donc deux arguments dont le premier est optionnel. De plus, omettre [⟨default⟩] n’est pas la même chose qu’écrire [] : ce dernier donne un argument optionnel dont la valeur par défaut est la chaîne vide.
Redéfinir, fournir et rendre robuste
\newcommand a trois variantes aux buts différents. Toutes prennent les arguments comme \newcommand ([⟨nargs⟩][⟨default⟩]) ; seul change leur comportement face à un nom déjà défini.
| Commande | Face à un nom existant | Usage principal |
|---|---|---|
\newcommand | S’arrête avec erreur | Créer une nouvelle commande en sécurité |
\renewcommand | L’écrase (erreur si indéfini) | Retravailler une commande existante |
\providecommand | Ne fait rien (garde l’ancienne) | Fichiers de style pouvant être chargés deux fois |
\DeclareRobustCommand | Écrase et note dans le log | Commandes robustes en arguments mobiles |
\renewcommand redéfinit une commande existante. C’est le miroir de \newcommand : la cible doit déjà être définie, sinon il y a erreur. On l’utilise pour remplacer le contenu d’une commande fournie par LaTeX, par exemple le symbole d’une liste.
% itemize の第 1 階層の記号をダッシュに
\renewcommand{\labelitemi}{--}
% 既存マクロを新しい中身で作り直す
\renewcommand{\grp}{Lamport Typesetting Lab}\providecommand définit une commande seulement si elle n’existe pas encore. Si le nom est indéfini, il agit comme \newcommand; s’il existe déjà, il ne fait rien et garde la définition existante, sans erreur. C’est adapté aux fichiers de style susceptibles d’être chargés plusieurs fois.
\DeclareRobustCommand crée une commande robuste, même si son contenu comprend du code fragile. Contrairement à \newcommand, il ne signale pas d’erreur sur un nom existant ; en cas de redéfinition, il écrit seulement une note dans le log. Les commandes ainsi créées sont un peu moins efficaces : réservez-les aux contenus fragiles utilisés dans des arguments mobiles, sinon préférez \newcommand.
Commandes fragiles et \protect
LaTeX possède des contextes spéciaux appelés arguments mobiles. Le titre de \section{...} n’est pas seulement composé dans le corps : il est aussi écrit dans la table des matières, les en-têtes et le fichier auxiliaire .aux, donc déplacé à plusieurs endroits. Le contenu de \caption{...}, de \thanks{...} et des @{...} de tabular/array est du même genre.
Une commande qui se brise en TeX invalide lorsqu’elle est développée dans un tel contexte est dite fragile ; une commande qui survit est robuste. Le remède classique consiste à placer \protect juste avant une commande fragile pour dire à LaTeX de ne pas la développer ici, mais de l’écrire telle quelle. La protection est par commande : chaque \protect ne protège que celle qui suit.
% 可動引数の中で壊れやすい \verb を保護する
\section{The \protect\verb|\par| primitive}Bonne nouvelle toutefois : depuis LaTeX d’octobre 2019, beaucoup de commandes autrefois fragiles sont robustes. Des commandes avec arguments optionnels comme \raisebox, ainsi que les mathématiques inline \(...\), peuvent désormais aller dans un titre sans \protect. Le résistant le plus courant est \verb, que \protect ne sauve souvent pas ; dans un titre ou une légende, le plus simple est de le remplacer par \texttt{...}. Pour vos macros, \DeclareRobustCommand supprime le problème dès le départ.
Le moderne \NewDocumentCommand
LaTeX moderne offre une méthode plus puissante : \NewDocumentCommand{\name}{⟨arg-spec⟩}{...}. À l’origine fonction du package xparse, elle est désormais dans le noyau LaTeX (ltcmd) et s’utilise sans \usepackage. Au lieu d’écrire un nombre d’arguments, on déclare une spécification d’arguments (arg-spec), une chaîne de lettres décrivant chaque type.
| Spécificateur | Sens | Arrivée dans la définition |
|---|---|---|
m | Argument obligatoire | Un argument ordinaire comme #1 |
o | Argument optionnel [...] | Marqueur « no-value » si absent |
O{default} | Optionnel avec valeur par défaut | default si absent |
s | Étoile * optionnelle | Testée avec \IfBooleanTF |
Elle est plus puissante que \newcommand de deux façons : elle peut prendre plusieurs arguments optionnels, et elle gère proprement les variantes étoilées. L’exemple ci-dessous branche sur l’étoile avec \IfBooleanTF (#1 est l’étoile, #2 l’argument obligatoire). Pour du nouveau code, cette interface moderne est recommandée ; la page xparse la détaille.
\NewDocumentCommand{\diff}{s m}{%
\IfBooleanTF{#1}%
{\frac{\mathrm{d}}{\mathrm{d}#2}}% 星つき: d/dx 形
{\mathrm{d}#2}% 星なし: dx 形
}
$\diff{x}$ % → dx
$\diff*{x}$ % → d/dxBonnes pratiques de macros
Les macros brillent surtout comme macros sémantiques. Nommer les choses par ce qu’elles sont — les réels avec \newcommand{\R}{\mathbb{R}}, le d différentiel avec \newcommand{\dd}{\mathrm{d}} — garde la notation cohérente dans tout le document. Si l’apparence doit changer plus tard, une ligne de définition suffit.
\newcommand{\R}{\mathbb{R}}
\newcommand{\dd}{\mathrm{d}}
% 統一された表記で書ける / write with consistent notation
$\int_{\R} f(x)\,\dd x$Trop de macros nuit toutefois à la lisibilité. Une abréviation extrême comme \newcommand{\x}{\xi} peut devenir un code secret pour vous-même ou un coauteur quelques mois plus tard. Réservez les macros à ce qui est souvent répété, susceptible de changer en bloc ou mérite un nom sémantique ; le reste est souvent plus lisible écrit tel quel.
Enfin, évitez les collisions de noms. Ne réécrivez pas légèrement des commandes du noyau ou de packages avec \renewcommand : les effets de bord peuvent surprendre. Pour vos commandes, évitez les noms trop courts et préférez un préfixe propre au projet, comme \myR ou \bookTitle. En cas de doute, essayez \newcommand : l’erreur already defined signale un nom pris.