Czy \ def i \ definiują to samo w ConTeXt?

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

  • Z tego, co widzę, \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.

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) i luatex-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).

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *