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.
#optional
ve vašem příkladu? Máte odkaz na to, kde si o nich mohu přečíst více?luat-mac.lua
(pro kontext) aluatex-preprocessor.lua
pro Luatex-Plain. Hth.\define
chráněna e-TeX. Chcete-li jej rozšířit, musíte použít\defineexpandable
(nebo prostý\def
).