Zijn \ def en \ definieer hetzelfde in ConTeXt?

Is er een verschil tussen het definiëren van een variabele met \def en het gebruik van \define, indien gebruikt zonder een nummer tussen vierkante haken, bijv \def\somecommand{\percent} en \define\somecommand{\percent}? Kan ik \define altijd gebruiken op plaatsen waar \def kan worden gebruikt?

Opmerkingen

  • Van wat ik zie, geeft \define\xyz{...}, wanneer \xyz al is gedefinieerd, een waarschuwing af, maar voert de definitie uit in ieder geval. Natuurlijk \def geeft ' geen enkele waarschuwing.

Antwoord

Ter referentie: er zijn twee definities van \define: de eerste in syst-aux.mkiv toont het gedrag dat Egreg noemde in zijn commentaar: als de macro al gedefinieerd is, laat hij deze zoals hij is. (Een begeleidende, \redefine stelt u in staat om de huidige definitie van macro te overschrijven, ongeacht of deze in gebruik is.) Ironisch genoeg wordt deze voorlopige definitie zonder notitie overschreven zodra het formaat core-sys.mkiv (terwijl \redefine eeuwig blijft).

De actuele definitie van de \define macro zoals geleverd door de gebruikersinterface controleert niet alleen op eerder gedefinieerde besturingsreeksen met dezelfde naam, maar dient ook als een soort korte notatie voor verplichte argumenten. Het heeft het schema

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

waarbij het eerste argument, een cijfer, het aantal argumenten specificeert dat de nieuwe macro zal accepteren. Dit kan uiteraard resulteren in kortere definities. Ter vergelijking: de selector

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

vereist wat minder typen met de \define macro:

\define[9]\sevenofnine{#7} 

Deze definities kunnen dus resulteren in beter leesbare code – wat altijd een goede zaak is bij het schrijven van TEX.

Helaas is de \define wrapper neemt een groot deel van de expressiviteit weg van gewone \def s. In Context, zul je gemerkt hebben, zijn macros die optionele argumenten gebruiken alledaags met betrekking tot de gebruikersinterface. U kunt bijvoorbeeld eenvoudigweg de tweede \def -initie in het onderstaande fragment niet vervangen door een equivalente uitdrukking met \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 

Dat komt doordat u met \define de argumentscheidingstekens (hier: haakjes) die nodig zijn voor optionele argumenten, dus in principe zijn uw macros beperkt tot het nemen van alleen verplichte (accolades) argumenten. Om dezelfde reden is er ook geen manier om goedkope \{start|stop}something omgevingen te definiëren:

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

(De gebruikersinterface voor dit is \definestartstop (cf. core-sys.mkiv ), hoe dan ook.)

Eindelijk, tegenwoordig het belangrijkste nadeel van \define is dat het geen mkvi -stijl argumenten toestaat. Er is simpelweg geen manier om naar een parameter te verwijzen met zijn naam als je er überhaupt niet een kunt toewijzen.

% 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 

Dus als je serieus macro wilt schrijven, zul je snel leren om \define te vermijden, terwijl het veilig is voor minder complexe taken.

Opmerkingen

  • Bedankt voor dit nuttige antwoord. Ter verduidelijking: als u " argumenten in mkiv-stijl " zegt, betekent dat dan benoemde argumenten, zoals #optional in uw voorbeeld? Heb je een referentie waar ik meer over kan lezen?
  • @LarsH Ja, Mk VI (niet MkIV!) Macros zijn degene met (optionele) parameternamen. Ik weet niet zeker of er naast de bron documentatie op gebruikersniveau bestaat: de preprocessorcode is te vinden in luat-mac.lua (voor context) en luatex-preprocessor.lua voor Luatex-Plain. Hth.
  • Sorry, mijn fout.
  • Ik weet niet ' of dit het geval was op het moment dat ik dit antwoord schreef, maar Today-macros die zijn gedefinieerd met \define, zijn e-TeX-beveiligd. Om het uitbreidbaar te maken, moet je \defineexpandable (of gewoon \def) gebruiken.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *