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
#optionalin 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.luavoor 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\xyzal is gedefinieerd, een waarschuwing af, maar voert de definitie uit in ieder geval. Natuurlijk\defgeeft ' geen enkele waarschuwing.