Jsou \ def a \ v ConTeXtu stejné?

Existuje nějaký rozdíl mezi definováním proměnné pomocí \def a použitím \define, pokud je použito bez čísla uvnitř hranatých závorek, např \def\somecommand{\percent} a \define\somecommand{\percent}? Mohu vždy použít \define na místech, kde lze použít \def?

Komentáře

  • Podle toho, co vidím, \define\xyz{...}, když je \xyz již definován, vydá varování, ale provede definici tak jako tak. \def samozřejmě nevydává žádné varování.

Odpovědět

Odkaz: Existují dvě definice \define: první v syst-aux.mkiv ukazuje chování, které Egreg uvedl ve svém komentáři: pokud je makro již definováno, ponechá jej tak, jak je. (Společník \redefine umožňuje přepsat aktuální definici makra bez ohledu na to, jak je právě používá.) Je ironií, že tato předběžná definice je přepsána bez poznámky, jakmile se načte formát core-sys.mkiv (zatímco \redefine zůstane navždy).

aktuální definice makra \define poskytované uživatelským rozhraním nejen kontroluje dříve definované kontrolní sekvence stejného jména, ale slouží také jako určitý druh krátké notace pro povinné argumenty. Má schéma

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

, kde první argument, číslice, určuje počet argumentů, které nové makro přijme. To samozřejmě může mít za následek kratší definice. Pro srovnání selektor

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

vyžaduje méně psaní pomocí makra \define:

\define[9]\sevenofnine{#7} 

Tyto definice tedy mohou vést k čitelnějšímu kódu – což je při psaní TEXu vždy dobré.

Bohužel \define Obálka odebírá značnou část expresivity obyčejných \def. V kontextu si všimnete, že makra používající volitelné argumenty jsou vzhledem k uživatelskému rozhraní běžná. Například jednoduše nemůžete nahradit druhou \def inici v úryvku níže ekvivalentním výrazem pomocí \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 

Je to proto, že u \define nemůžete určit oddělovače argumentů (zde: závorky) potřebné pro volitelné argumenty, takže v zásadě jsou vaše makra omezena pouze na přijímání povinných (složených) argumentů. Ze stejného důvodu neexistuje způsob, jak definovat levné prostředí \{start|stop}something:

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

(Uživatelské rozhraní pro toto je \definestartstop (srov. core-sys.mkiv ), stejně.)

A konečně, v dnešní době nejdůležitější nevýhoda \define spočívá v tom, že neumožňuje argumenty ve stylu mkvi . Jednoduše neexistuje způsob, jak odkazovat na parametr podle jeho názvu , pokud jej nejprve nemůžete přiřadit.

% 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 

Pokud tedy chcete udělat nějaké vážné psaní maker, brzy se naučíte vyhnout se \define, i když je to bezpečné pro méně složité úkoly.

Komentáře

  • Děkujeme vám za tuto užitečnou odpověď. Bod objasnění: když řeknete " argumenty ve stylu mkiv ", znamená to pojmenované argumenty, jako #optional ve vašem příkladu? Máte odkaz na to, kde si o nich mohu přečíst více?
  • @LarsH Ano, makra Mk VI (ne MkIV!) Jsou makra s (volitelnými) názvy parametrů. Nejsem si jistý, zda kromě zdroje existuje nějaká dokumentace na úrovni uživatele: preprocesorový kód najdete v luat-mac.lua (pro kontext) a luatex-preprocessor.lua pro Luatex-Plain. Hth.
  • Omlouvám se, má chyba.
  • Nevím ' v době psaní této odpovědi vědět, jestli tomu tak bylo, ale dnes jsou makra definovaná pomocí \define chráněna e-TeX. Chcete-li jej rozšířit, musíte použít \defineexpandable (nebo prostý \def).

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *