Czy jest jakaś różnica między definiowaniem zmiennej za pomocą \def
a użyciem \define
, gdy jest używane bez liczby w nawiasach kwadratowych, np \def\somecommand{\percent}
i \define\somecommand{\percent}
? Czy zawsze mogę używać \define
w miejscach, w których można użyć \def
?
Komentarze
Odpowiedź
Dla porównania: istnieją dwie definicje \define
: pierwsza w syst-aux.mkiv pokazuje zachowanie, o którym Egreg wspomniał w swoim komentarzu: jeśli makro jest już zdefiniowane, pozostawia je tak, jak jest. (Towarzysz, \redefine
umożliwia nadpisanie bieżącej definicji makra niezależnie od tego, czy jest ono używane). Jak na ironię, ta wstępna definicja jest nadpisywana bez notatki, gdy tylko format się załaduje core-sys.mkiv (podczas gdy \redefine
pozostaje na zawsze).
rzeczywiste definicja makra \define
dostarczona przez interfejs użytkownika nie tylko sprawdza wcześniej zdefiniowane sekwencje sterujące o tej samej nazwie, ale służy również jako rodzaj krótkiej notacji dla obowiązkowe argumenty. Ma schemat
\define [<digit>] <macro> {<definition>}
gdzie pierwszy argument, cyfra, określa liczbę argumentów, które przyjmie nowe makro. Oczywiście może to skutkować skróceniem definicji. Dla porównania, selektor
\def\sevenofnine#1#2#3#4#5#6#7#8#9{#7} \starttext \sevenofnine abcdefghi\par \stoptext
wymaga mniej wpisywania za pomocą makra \define
:
\define[9]\sevenofnine{#7}
Dlatego te definicje mogą skutkować bardziej czytelnym kodem – co jest zawsze dobrą rzeczą przy pisaniu TEX-a.
Niestety \define
opakowanie odbiera znaczną część wyrazistości zwykłych \def
. W Context można zauważyć, że makra przyjmujące opcjonalne argumenty są powszechne w odniesieniu do interfejsu użytkownika. Na przykład nie można po prostu zamienić drugiej \def
inition w poniższym fragmencie na równoważne wyrażenie, używając \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
Dzieje się tak, ponieważ w przypadku \define
nie można określić ograniczników argumentów (tutaj: nawiasów) niezbędnych do opcjonalne argumenty, więc w zasadzie twoje makra są ograniczone do przyjmowania tylko argumentów obowiązkowych (napiętych). Z tego samego powodu nie ma możliwości zdefiniowania tanich \{start|stop}something
środowisk:
\let\stopfoo\relax \def\startfoo#1\stopfoo{\bgroup\bold#1\egroup} %%% ^^^^^^^^ not possible \starttext \startfoo bar \stopfoo \stoptext
(Interfejs użytkownika dla to jest \definestartstop
(por. core-sys.mkiv , w każdym razie).
Wreszcie, obecnie najważniejsza wada \define
jest taki, że nie zezwala na argumenty w stylu mkvi . Po prostu nie ma możliwości odniesienia się do parametru za pomocą jego nazwy , jeśli nie można go przypisać w pierwszej kolejności.
% 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
Więc jeśli chcesz pisać poważne makra, wkrótce nauczysz się unikać \define
, podczas gdy jest to bezpieczne w przypadku mniej złożonych zadań.
Komentarze
- Dziękuję za tę pomocną odpowiedź. Punkt do wyjaśnienia: czy kiedy mówisz " argumenty w stylu mkiv ", oznacza to nazwane argumenty, na przykład
#optional
w twoim przykładzie? Czy masz odniesienie, gdzie mogę przeczytać więcej na ten temat? - @LarsH Tak, makra Mk VI (nie MkIV!) To makra z (opcjonalnymi) nazwami parametrów. Nie jestem pewien, czy istnieje jakakolwiek dokumentacja na poziomie użytkownika poza źródłem: kod preprocesora można znaleźć w
luat-mac.lua
(dla Context) iluatex-preprocessor.lua
dla Luatex-Plain. Hth. - Przepraszam, mój błąd.
- Nie ' nie wiem, czy tak było w momencie pisania tej odpowiedzi, ale dziś makra zdefiniowane za pomocą
\define
są chronione przez e-TeX. Aby można było go rozwinąć, należy użyć\defineexpandable
(lub zwykłego\def
).
\define\xyz{...}
, gdy\xyz
jest już zdefiniowane, wyświetla ostrzeżenie, ale wykonuje definicję tak czy siak. Oczywiście\def
nie ' nie wydaje żadnego ostrzeżenia.