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
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 \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) enluatex-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.
\define\xyz{...}
, wanneer\xyz
al is gedefinieerd, een waarschuwing af, maar voert de definitie uit in ieder geval. Natuurlijk\def
geeft ' geen enkele waarschuwing.