Är \ def och \ samma i ConTeXt?

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

  • Från vad jag ser, \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.

    Kommentarer

    • Tack för det här hjälpsamma svaret. Förtydligande: när du säger " mkiv-stilargument " betyder det namngivna argument, som #optional i ditt exempel? Har du en referens för var jag kan läsa mer om dessa?
    • @LarsH Ja, Mk VI (inte MkIV!) -Makron är de med (valfria) parameternamn. Jag är inte säker på att det finns någon dokumentation på användarnivå förutom källan: förprocessorkoden finns i luat-mac.lua (för sammanhang) och luatex-preprocessor.lua för Luatex-Plain. Hth.
    • Tyvärr, mitt misstag.
    • Jag vet inte ' vet inte om detta var fallet när jag skrev svaret men idag är makron definierade med \define e-TeX-skyddade. För att den ska kunna expanderas måste man använda \defineexpandable (eller vanlig \def).

    Lämna ett svar

    Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *