Finns det någon skillnad mellan att definiera en variabel med \def
och att använda \define
, när det används utan ett nummer inom hakparenteser, t.ex. \def\somecommand{\percent}
och \define\somecommand{\percent}
? Kan jag alltid använda \define
på platser där \def
kan användas?
Kommentarer
\define\xyz{...}
, när \xyz
redan är definierad, ger en varning men utför definitionen i alla fall. Naturligtvis \def
' t ger någon varning. Svar
För referens: Det finns två definitioner av \define
: Den första i syst-aux.mkiv visar beteendet som Egreg nämnde i sin kommentar: om makrot redan är definierat lämnar det det som det är. (En följeslagare, \redefine
låter dig skriva över den nuvarande definitionen av makro oavsett om den används.) Ironiskt nog skrivs denna preliminära definition utan anteckning så snart formatet laddas core-sys.mkiv (medan \redefine
stannar för alltid).
definition av \define
makrot som tillhandahålls av användargränssnittet kontrollerar inte bara efter tidigare definierade styrsekvenser med samma namn, utan fungerar också som någon form av kort notation för obligatoriska argument. Det har schemat
\define [<digit>] <macro> {<definition>}
där det första argumentet, en siffra, anger antalet argument som det nya makrot ska acceptera. Uppenbarligen kan detta resultera i kortare definitioner. För jämförelse kräver väljaren
\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7} \starttext \sevenofnine abcdefghi\par \stoptext
mindre skrivning med \define
makro:
\define[9]\sevenofnine{#7}
Således kan dessa definitioner resultera i mer läsbar kod – vilket alltid är bra när man skriver TEX.
Tyvärr \define
wrapper tar bort en hel del uttrycksfullhet för vanliga \def
. I sammanhang har du lagt märke till att makron som tar valfria argument är vanliga när det gäller användargränssnittet. Till exempel kan du helt enkelt inte ersätta den andra \def
initionen nedanför utdraget med ett motsvarande uttryck med \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
Det beror på att med \define
kan du inte ange de argumentavgränsare (här: parenteser) som behövs för valfria argument, så i grund och botten är dina makron begränsade till att bara ta obligatoriska (avstängd) argument. Av samma anledning finns det inget sätt att definiera billiga \{start|stop}something
-miljöer heller:
\let\stopfoo\relax \def\startfoo#1\stopfoo{\bgroup\bold#1\egroup} %%% ^^^^^^^^ not possible \starttext \startfoo bar \stopfoo \stoptext
(Användargränssnittet för det här är \definestartstop
(jfr. core-sys.mkiv ), ändå.)
Slutligen, numera den viktigaste nackdelen med \define
är att det inte tillåter mkvi -argument. Det finns helt enkelt inget sätt att hänvisa till en parameter med dess namn om du inte kan tilldela den i första hand.
% 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
Så om du vill göra en seriös makroskrivning lär du dig snart att undvika \define
, medan det är säkert för mindre komplexa uppgifter.
#optional
i ditt exempel? Har du en referens för var jag kan läsa mer om dessa?luat-mac.lua
(för sammanhang) ochluatex-preprocessor.lua
för Luatex-Plain. Hth.\define
e-TeX-skyddade. För att den ska kunna expanderas måste man använda\defineexpandable
(eller vanlig\def
).