Макротехнологии с использованием e-TeX

Макротехнологии с использованием e-TeX

Расширения e-TeX были предназначены для устранения некоторых недостатков оригинального TeX Кнута, и поскольку они требуются LaTeX2e уже некоторое время, большинство авторов пакетов могут рассчитывать на их наличие. Сейчас, хотя есть некоторые ресурсы, доступные для изучения чистых идиом макросов TeX, включаяэто обсуждениена этом сайте, а также напреимущества e-TeXв целом, я хотел бы увидеть конкретные примеры того, как расширения e-TeX могут облегчить жизнь авторам макросов.

В частности, некоторые практические советы/приемы по использованию команд , связанных с расширением и анализом \protected, \unexpandedи\detokenize\scantokens весьма признательны. Они кажутся мне полезными, но я никогда не понимаю, когда я мог бы использовать их для упрощения вещей (руководство по e-Texтакже очень лаконичен в отношении них).


Масштаб вопроса довольно широк, но меня больше всего интересуют расширения, перечисленные выше. Ниже приведены некоторые дальнейшие мысли о других расширениях, которые я также с удовольствием обсужу.

Для меня полезность некоторых расширений очевидна сразу, в том числе:

  • не нужно беспокоиться о выделении новых регистров из-за увеличенного количества слотов на 32767 для каждого типа
  • удобные \numexprи \dimexprт. д. команды выражений, облегчающие арифметические операции
  • \unlessкак отрицание \if, особенно в сочетании с \loops, где в противном случае пришлось бы определить новые условные операторы, если бы цикл выполнялся до тех пор, пока условия были ложными
  • различные новые команды и опции трассировки, помогающие в диагностике

Но некоторые функции заставляют меня задуматься, используются ли они на самом деле существующими пакетами или их заменили более «современные» подходы, такие как

  • смешанное направление набора с \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вариант разделителя или нет, как \currentgrouptype16 в группе, открытой \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.

Связанный контент