![Расширяемость: LaTeX3 против LaTeX](https://rvso.com/image/328469/%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D0%B5%D0%BC%D0%BE%D1%81%D1%82%D1%8C%3A%20LaTeX3%20%D0%BF%D1%80%D0%BE%D1%82%D0%B8%D0%B2%20LaTeX.png)
Расширяемость — это сердце макросов/функций. Интересно узнать:
- Если лучшее понимание расширяемости в
LaTeX3
может быть достигнуто только через хороший фон расширяемости вLaTeX
. Насколько их можно считать независимыми? - Точнее, если функции, предлагаемые
l3expan
достаточны для удовлетворения всех потребностей в расширении. Другими словами, в пределахLaTeX3
, "LaTeX
расширяемость " поддерживается, но может бытьполностьюзаменено. - Есть ли способ проверить промежуточные шаги во время выполнения процесса расширения (т. е. некоторые выходные файлы, параметры профилирования, ...)
решение1
Поскольку я сам этого не делал, я считаю, что для нового программиста LaTeX проще начать с функций, определенных загрузкой expl3
(иначе известной как ядро LaTeX3, или l3kernel
), чем сначала изучать основы программирования TeX и двигаться дальше.
Причина этого в том, что это expl3
дает вам очень хороший уровень абстракции, который является мощным и внутренне согласованным. С программированием TeX вам очень быстро придется перейти к изучению «трюков», чтобы делать довольно простые вещи.
Например, если вы говорите о двух командах \foo
и \baz
, чтобы сделать \foo
копию, \baz
вы пишете
\let\foo\baz
Но что, если вам нужно ссылаться на них по имени, а не по последовательности управления? Например, вы можете определить что-то, чтобы сделать это:
\defineacronym{baz}{BAZ}
\useacronym{baz} % => \textsc{\MakeLowercase{BAZ}}
Это можно определить с помощью
\makeatletter
\newcommand\defineacronym[2]{%
\@namedef{acronym@#1}{\textsc{\MakeLowercase{BAZ}}}%
}
\newcommand\useacronym[1]{%
\@nameuse{acronym@#1}%
}
\makeatother
Пока все хорошо. Но чтобы определить команду типа \copyacronym{foo}{baz}
, нужно написать:
\newcommand\copyacronym[2]{%
\expandafter\let\csname acronym@#1\expandafter\endcsname\csname acronym@#2\endcsname
}
Это легко понять опытному программисту TeX, но не слишком удобно для новичка.
В expl3
этом случае это будет записано так:
\ExplSyntaxOn
\newcommand\copyacronym[2]{
\cs_set_eq:cc {acronym@#1} {acronym@#2}
}
\ExplSyntaxOff
Цель состоит в expl3
том, чтобы сделать программирование TeX более структурированным и, следовательно, более простым. Мынадеятьсячто это касается даже в большей степени новых программистов TeX, чем старых.
На ваш последний вопрос ответ будет вроде как. Бруно Ле Флок написал пакет unravel
, который, безусловно, может показать вам, что происходит с расширением. После написания
\usepackage{unravel}
\def\baz{BAZ}
\unravel{\expandafter\let\csname foo\expandafter\endcsname\csname baz\endcsname}
он возвращает следующее:
======== Welcome to the unravel package ========
"<|" denotes the output to TeX's stomach.
"||" denotes tokens waiting to be used.
"|>" denotes tokens that we will act on.
Press <enter> to continue; 'h' <enter> for help.
||
|> \expandafter \let \csname foo\expandafter \endcsname \csname baz\endcsname
[===== Step 1 =====] \expandafter \let
[===== Step 2 =====] \csname = \csname
|| \expandafter \let
|| \csname
|> foo\expandafter \endcsname \csname baz\endcsname
[===== Step 3 =====] \expandafter \endcsname
|| \expandafter \let
|| \csname foo
|| \expandafter \endcsname
|> \csname baz\endcsname
[===== Step 4 =====] \csname = \csname
|| \expandafter \let
|| \csname foo
|| \expandafter \endcsname
|| \csname
|> baz\endcsname
[===== Step 5 =====] \endcsname
|| \expandafter \let
|| \csname foo
|| \expandafter \endcsname
|| \csname baz\endcsname
|>
[===== Step 6 =====] \csname baz\endcsname =\baz
|| \expandafter \let
|| \csname foo
|| \expandafter \endcsname
|> \baz
[===== Step 7 =====] back_input: \expandafter \endcsname
|| \expandafter \let
|| \csname foo
|> \endcsname \baz
[===== Step 8 =====] \endcsname
|| \expandafter \let
|| \csname foo\endcsname
|> \baz
[===== Step 9 =====] \csname foo\endcsname =\foo
|| \expandafter \let
|> \foo \baz
[===== Step 10 =====] back_input: \expandafter \let
||
|> \let \foo \baz
[===== Step 11 =====] \let \foo
|| \let \foo
|> \baz
[===== Step 12 =====] Set \foo=macro:->BAZ
||
|>
[===== End =====]
Как видите, даже в простом случае это дает вам довольно много информации. (Легко усвоить, но все же.) Особенно при отладке expl3
в качестве нового пользователя, это может быть полезно только в определенных ситуациях.