
Расширения e-TeX были предназначены для устранения некоторых недостатков оригинального TeX Кнута, и поскольку они требуются LaTeX2e уже некоторое время, большинство авторов пакетов могут рассчитывать на их наличие. Сейчас, хотя есть некоторые ресурсы, доступные для изучения чистых идиом макросов TeX, включаяэто обсуждениена этом сайте, а также напреимущества e-TeXв целом, я хотел бы увидеть конкретные примеры того, как расширения e-TeX могут облегчить жизнь авторам макросов.
В частности, некоторые практические советы/приемы по использованию команд , связанных с расширением и анализом \protected
, \unexpanded
и\detokenize
\scantokens
весьма признательны. Они кажутся мне полезными, но я никогда не понимаю, когда я мог бы использовать их для упрощения вещей (руководство по e-Texтакже очень лаконичен в отношении них).
Масштаб вопроса довольно широк, но меня больше всего интересуют расширения, перечисленные выше. Ниже приведены некоторые дальнейшие мысли о других расширениях, которые я также с удовольствием обсужу.
Для меня полезность некоторых расширений очевидна сразу, в том числе:
- не нужно беспокоиться о выделении новых регистров из-за увеличенного количества слотов на 32767 для каждого типа
- удобные
\numexpr
и\dimexpr
т. д. команды выражений, облегчающие арифметические операции \unless
как отрицание\if
, особенно в сочетании с\loop
s, где в противном случае пришлось бы определить новые условные операторы, если бы цикл выполнялся до тех пор, пока условия были ложными- различные новые команды и опции трассировки, помогающие в диагностике
Но некоторые функции заставляют меня задуматься, используются ли они на самом деле существующими пакетами или их заменили более «современные» подходы, такие как
- смешанное направление набора с
\beginL
и\beginR
т.д. - запросы статуса, такие как
\currentgrouptype
,\currentiftype
,\lastnodetype
и т.д. - возможность сохранения отброшенных элементов из верхней части страниц, встраиваемых
\pagediscards
- определенные штрафы
\interlinepenalties
и т.п.
решение1
Взяв «крупные» пункты в e-TeX:
\protected
позволяет нам создавать макросы, которые не расширяются внутри\edef
или похожи:\protected\def\foo{\let\baz\bong} \edef\test{Some text\foo}
обычно выдает ошибку (предполагая, что нет определения для
\baz
/\bong
), но здесь это «безопасно». Если вы посмотрите на механизм LaTeX2e\protect
, то вышеприведенное — этомного проще в использовании и надежнее:\protected
макросыникогдарасширить внутреннееx
определение типа, тогда как при подходе LaTeX2e требуется\protected@edef
и т. д.\unexpanded
позволяет нам защищать произвольные токены от расширения без необходимости использования токенов\edef\test{Some text\unexpanded{lots of \textbf{stuff}}}
что очень полезно при произвольном вводе данных пользователем. Это также позволяет делать такие вещи, как
\edef\demo{\unexpanded{tokens #}}
что означает, что их можно легко сохранить
#
внутри макроса (см.expl3
tl
тип данных).\detokenize
хорошо подходит для того, чтобы сделать что-то «безопасным», например, если в нем могут быть активные символы\csname Tokens\detokenize{&_~^\foo}\endcsname
что особенно актуально, например, при использовании активных символов для ввода UTF-8 в LaTeX.
\numexpr
и т. д. отлично подходят для легкого выполнения расширяемых вычислений
решение2
Просматривая исходные файлы в TeX Live, я могу добавить некоторые сведения об использовании, по крайней мере, на мой взгляд, менее распространенных функций e-TeX.
Для некоторых иззапрос статусапримитивы, пакеты Хайко Обердика предоставляют некоторую иллюстрацию их применения. Пакет atbegshi
показывает изящный трюк, как примитив, принимающий поле в качестве аргумента, может быть переопределен ( \shipout
в данном случае), принимая во внимание, что если аргумент должен быть перехвачен с помощью \setbox
и \afterassignment
, токен, который должен быть вставлен после назначения, может или не может оказаться внутри поля в зависимости от того, задано ли поле как box0
или как \hbox{...}
. Выглядит это примерно так:
\def\shipout{%
\edef\saved@grouplevel{\number\currentgrouplevel}
\afterassignment\@test
\setbox\mybox=}
\def\@test{%
\ifnum\saved@grouplevel<\currentgrouplevel
\expandafter\aftergroup
\fi
\output
}
Он использует e-TeX \currentgrouplevel
для определения того, \@test
приземлился ли объект внутри коробки (которая открыла группу), в этом случае последующая \output
операция откладывается до момента, когда объект окажется после коробки.
Другим полезным фактом является то, что \lastnodetype
значение меньше 11 для всех невыбрасываемых вещей и -1, если текущий список все еще пуст (см., например, примеры setouterhbox
их применения).
Как указывает egreg в комментариях, \currentgrouptype
можно сделать запрос в математическом режиме, чтобы решить, использовать ли \middle
вариант разделителя или нет, как \currentgrouptype
16 в группе, открытой \left
(например,здесь).
e-TeX'sдвунаправленный набор текстаВозможности в форме TeX--XeT используются XeTeX, для которого пакет bidi
предоставляет интерфейс к этим функциям. Также для некоторых стандартных пакетов LaTeX babel-hebrew
это, похоже, выход. Однако LuaTeX отказался от примитивов и \beginL
т \beginR
. д. и вместо этого интегрирует расширение Omega TeX.
С другой стороны, для нескольких функций я не нашел реальных применений. Единственные места, где они появляются, это те, где, вероятно, будут появляться все примитивы, например, ядро LaTeX3, ConTeXt MkIV и пакет unravel
, и в нескольких других местах, где авторы пытались повысить совместимость с другими пакетами, использующими их. Эти функции включают \currentif{type,branch,level}
запросы, \pagediscards
функциональность и специфичные для строк \{inter,club,widow}linepenalties
.