Există vreo diferență între definirea unei variabile utilizând \def
și utilizarea \define
, atunci când este utilizat fără un număr între paranteze pătrate, de ex \def\somecommand{\percent}
și \define\somecommand{\percent}
? Pot folosi întotdeauna \define
în locurile în care se poate utiliza \def
?
Comentarii
Răspundeți „36361e4488″>
h2>
Pentru referință: există două definiții ale \define
: prima din syst-aux.mkiv arată comportamentul menționat de Egreg în comentariul său: dacă macro-ul este deja definit, îl lasă așa cum este. (Un însoțitor, \redefine
vă permite să suprascrieți definiția curentă a macro-ului, indiferent dacă este utilizată.) În mod ironic, această definiție preliminară este suprascrisă fără notă imediat ce formatul se încarcă core-sys.mkiv (în timp ce \redefine
rămâne pentru totdeauna).
actual definiția a macro-ului \define
furnizat de interfața utilizatorului nu numai că verifică secvențele de control definite anterior cu același nume, ci servește și ca un fel de notație scurtă pentru argumente obligatorii. Are schema
\define [<digit>] <macro> {<definition>}
unde primul argument, o cifră, specifică numărul de argumente pe care noua macro va accepta. Evident, acest lucru poate duce la definiții mai scurte. Pentru comparație, selectorul
\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7} \starttext \sevenofnine abcdefghi\par \stoptext
necesită mai puține tastări cu macrocomanda \define
:
\define[9]\sevenofnine{#7}
Astfel, aceste definiții pot avea ca rezultat un cod mai lizibil – ceea ce este întotdeauna un lucru bun atunci când scriem TEX.
Din păcate, \define
wrapper îndepărtează o mare parte din expresivitatea simplelor \def
. În context, veți observa că macrocomenzile care iau argumente opționale sunt obișnuite în ceea ce privește interfața utilizatorului. De exemplu, pur și simplu nu puteți înlocui a doua inițiune \def
din fragmentul de mai jos cu o expresie echivalentă folosind \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
Asta pentru că cu \define
nu puteți specifica delimitatorii de argumente (aici: paranteze) necesare pentru argumente opționale, deci practic macrourile dvs. se limitează la luarea numai a argumentelor obligatorii (corelate). Din același motiv, nu există nici o modalitate de a defini medii \{start|stop}something
ieftine:
\let\stopfoo\relax \def\startfoo#1\stopfoo{\bgroup\bold#1\egroup} %%% ^^^^^^^^ not possible \starttext \startfoo bar \stopfoo \stoptext
(Interfața utilizatorului pentru acesta este \definestartstop
(cf. core-sys.mkiv ), oricum.)
În cele din urmă, în zilele noastre cel mai important dezavantaj al \define
este că nu permite argumentele stilului mkvi . Pur și simplu nu există nicio modalitate de a face referire la un parametru prin numele său, dacă nu îl puteți atribui unul în primul rând.
% 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
Deci, dacă doriți să faceți o scriere macro serioasă, veți învăța în curând să evitați \define
, în timp ce este sigur pentru sarcini mai puțin complexe.
Comentarii
- Vă mulțumim pentru acest răspuns util. Punct de clarificare: atunci când spui " argumente în stil mkiv ", înseamnă asta argumente numite, cum ar fi
#optional
în exemplul dvs.? Aveți o referință pentru unde pot citi mai multe despre acestea? - @LarsH Da, macro-urile Mk VI (nu MkIV!) Sunt cele cu nume de parametri (opțional). Nu sunt sigur că există vreo documentație la nivel de utilizator în afară de sursă: codul preprocesatorului poate fi găsit în
luat-mac.lua
(pentru Context) șiluatex-preprocessor.lua
pentru Luatex-Plain. Hth. - Ne pare rău, greșeala mea.
- Nu ' nu știu dacă acesta era cazul în momentul scrierii acestui răspuns, dar astăzi macro-urile definite folosind
\define
sunt protejate prin e-TeX. Pentru a-l extinde trebuie să utilizați\defineexpandable
(sau simplu\def
).
\define\xyz{...}
, când\xyz
este deja emis, emite un avertisment, dar execută definiția oricum. Desigur,\def
nu emite niciun avertisment.