Y a-t-il une différence entre définir une variable en utilisant \def
et en utilisant \define
, lorsquil est utilisé sans nombre entre crochets, par exemple \def\somecommand{\percent}
et \define\somecommand{\percent}
? Puis-je toujours utiliser \define
dans des endroits où \def
peut être utilisé?
Commentaires
Réponse
Pour référence: Il existe deux définitions de \define
: La première dans syst-aux.mkiv montre le comportement évoqué par Egreg dans son commentaire: si la macro est déjà définie, elle la laisse telle quelle. (Un compagnon, \redefine
vous permet décraser la définition actuelle de macro indépendamment de son utilisation.) Ironiquement, cette définition préliminaire est écrasée sans note dès que le format se charge core-sys.mkiv (alors que \redefine
reste pour toujours).
Le actuel la définition de la macro \define
fournie par linterface utilisateur ne vérifie pas seulement les séquences de contrôle précédemment définies du même nom, mais sert également de sorte de notation courte pour arguments obligatoires. Il a le schéma
\define [<digit>] <macro> {<definition>}
où le premier argument, un chiffre, spécifie le nombre darguments que la nouvelle macro va accepter. Évidemment, cela peut entraîner des définitions plus courtes. A titre de comparaison, le sélecteur
\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7} \starttext \sevenofnine abcdefghi\par \stoptext
nécessite un peu moins de saisie avec la macro \define
:
\define[9]\sevenofnine{#7}
Ainsi, ces définitions peuvent donner un code plus lisible – ce qui est toujours une bonne chose lors de lécriture de TEX.
Malheureusement, le \define
wrapper supprime une bonne partie de lexpressivité des \def
. En contexte, vous laurez remarqué, les macros prenant des arguments optionnels sont monnaie courante vis-à-vis de linterface utilisateur. Par exemple, vous ne pouvez tout simplement pas remplacer la deuxième \def
inition dans lextrait de code ci-dessous par une expression équivalente en utilisant \define
:
\unprotect \def\myfoo{\dosingleempty\do_my_foo} \def\do_my_foo[#1]#2{% \iffirstargument{\bf\WORD#1}\fi #2\par% } \protect \starttext \myfoo{bar} \myfoo[foo]{bar} \stoptext
Cest parce quavec \define
vous ne pouvez pas spécifier les délimiteurs darguments (ici: crochets) nécessaires pour arguments optionnels, donc fondamentalement vos macros sont limitées à prendre uniquement des arguments obligatoires (accolades). Pour la même raison, il nexiste aucun moyen de définir des environnements \{start|stop}something
bon marché:
\let\stopfoo\relax \def\startfoo#1\stopfoo{\bgroup\bold#1\egroup} %%% ^^^^^^^^ not possible \starttext \startfoo bar \stopfoo \stoptext
(Linterface utilisateur pour cest \definestartstop
(cf. core-sys.mkiv ), en tout cas.)
Enfin, de nos jours, linconvénient le plus important de \define
est quil ne permet pas les arguments de style mkvi . Il est tout simplement impossible de faire référence à un paramètre par son nom si vous ne pouvez pas lui en attribuer un en premier lieu.
% macros=mkvi \unprotect \def\foo{\dosingleempty\do_foo} \def\do_foo[#optional]#mandatory{% \bgroup\sansbold#optional\space\egroup #mandatory\par% } \protect \starttext \foo{bar} \foo[foo]{bar} \stoptext
Donc, si vous voulez faire de sérieuses écritures de macros, vous apprendrez bientôt à éviter \define
, alors que cest sûr pour des tâches moins complexes.
Commentaires
- Merci pour cette réponse utile. Point de clarification: lorsque vous dites " arguments de style mkiv ", cela signifie-t-il des arguments nommés, comme
#optional
dans votre exemple? Avez-vous une référence pour en savoir plus à ce sujet? - @LarsH Oui, les macros Mk VI (et non MkIV!) Sont celles avec des noms de paramètres (facultatifs). Je ne suis pas sûr quil existe une documentation de niveau utilisateur en plus de la source: le code du préprocesseur se trouve dans
luat-mac.lua
(pour le contexte) etluatex-preprocessor.lua
pour Luatex-Plain. Hth. - Désolé, mon erreur.
- Je ne ' Je ne sais pas si cétait le cas au moment de la rédaction de cette réponse, mais aujourdhui, les macros définies à laide de
\define
sont protégées par e-TeX. Pour quil soit extensible, il faut utiliser\defineexpandable
(ou plain\def
).
\define\xyz{...}
, lorsque\xyz
est déjà défini, émet un avertissement, mais exécute la définition De toute façon. Bien sûr,\def
ne ' émettre aucun avertissement.