Er \ def og \ definere det samme i ConTeXt?

Er det noen forskjell mellom å definere en variabel ved hjelp av \def og å bruke \define, når det brukes uten et tall i parentes, f.eks \def\somecommand{\percent} og \define\somecommand{\percent}? Kan jeg alltid bruke \define på steder der \def kan brukes?

Kommentarer

  • Fra det jeg ser, \define\xyz{...}, når \xyz allerede er definert, utsteder en advarsel, men utfører definisjonen uansett. Selvfølgelig \def gir ikke ' ingen advarsler.

Svar

For referanse: Det er to definisjoner av \define: Den første i syst-aux.mkiv viser atferden Egreg nevnte i sin kommentar: hvis makroen allerede er definert, lar den den være som den er. (En følgesvenn, \redefine lar deg overskrive den gjeldende definisjonen av makro uansett om den er i bruk.) Ironisk nok blir denne foreløpige definisjonen overskrevet uten notat så snart formatet lastes inn core-sys.mkiv (mens \redefine forblir for alltid).

definisjon av \define makroen som er gitt av brukergrensesnittet, sjekker ikke bare for tidligere definerte kontrollsekvenser med samme navn, men fungerer også som en slags kort notasjon for obligatoriske argumenter. Den har skjemaet

\define [<digit>] <macro> {<definition>} 

der det første argumentet, et siffer, angir antall argumenter den nye makroen skal akseptere. Åpenbart kan dette resultere i kortere definisjoner. Til sammenligning krever velgeren

\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7} \starttext \sevenofnine abcdefghi\par \stoptext 

noe mindre å skrive med \define makroen:

\define[9]\sevenofnine{#7} 

Dermed kan disse definisjonene resultere i mer lesbar kode – noe som alltid er bra når du skriver TEX.

Dessverre er \define wrapper tar bort en god del av uttrykksevnen til ren \def. I kontekst vil du ha lagt merke til at makroer som tar valgfrie argumenter er vanlige med hensyn til brukergrensesnittet. For eksempel kan du ganske enkelt ikke erstatte den andre \def inisjonen under kodebiten med et tilsvarende uttrykk ved hjelp av \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 er fordi du med \define ikke kan spesifisere argumentavgrensere (her: parenteser) som er nødvendige for valgfrie argumenter, så i utgangspunktet er makroene dine bare begrenset til å ta obligatoriske argumenter. Av samme grunn er det ingen måte å definere billige \{start|stop}something -miljøer heller:

\let\stopfoo\relax \def\startfoo#1\stopfoo{\bgroup\bold#1\egroup} %%% ^^^^^^^^ not possible \starttext \startfoo bar \stopfoo \stoptext 

(Brukergrensesnittet for dette er \definestartstop (jf. core-sys.mkiv ), uansett.)

Endelig, i dag, den viktigste ulempen med \define er at det ikke tillater argumenter for mkvi -stil. Det er rett og slett ingen måte å referere til en parameter med navn hvis du ikke kan tilordne den i utgangspunktet.

% 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å hvis du vil gjøre seriøs makroskriving, vil du snart lære å unngå \define, mens det er trygt for mindre komplekse oppgaver.

Kommentarer

  • Takk for dette nyttige svaret. Avklaringspunkt: når du sier " argumenter i mkiv-stil ", betyr det da navngitte argumenter, som #optional i eksemplet ditt? Har du en referanse for hvor jeg kan lese mer om disse?
  • @LarsH Ja, Mk VI (ikke MkIV!) Makroer er de med (valgfrie) parameternavn. Jeg er ikke sikker på at det finnes dokumentasjon på brukernivå i tillegg til kilden: forprosessorkoden finner du i luat-mac.lua (for kontekst) og luatex-preprocessor.lua for Luatex-Plain. Hth.
  • Beklager, min feil.
  • Jeg vet ikke ' ikke om dette var tilfelle da jeg skrev dette svaret, men i dag er makroer definert ved hjelp av \define e-TeX beskyttet. For å ha det utvidbart må man bruke \defineexpandable (eller vanlig \def).

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *