Использование регистров \toks

Использование регистров \toks

Я читал этот учебник по программированию TeX:

http://pgfplots.sourceforge.net/TeX-programming-notes.pdf

рекомендовано во 2-м ответе здесь:С чего начать программирование LaTeX?

Там говорится:

\toks<number>Также есть 255 регистров токенов, которые можно рассматривать как специальные строковые переменные. Конечно, каждое макроприсвоение \def\macro{ content }также является своего рода строковой переменной, но регистры токенов являются особыми: их содержимое не будет расширено при использовании с \the\toksnumber . Это можно использовать для тонкого управления расширением, см. Раздел 2.3 ниже.

Но нет примеров использования \toksрегистров. Что он имеет в виду: "специальные строковые переменные"? Для 2 предыдущих видов регистров я мог бы присвоить значение:

\count0=12
\dimen0=1.102pt

И распечатайте это:

Value1: \the\count0
Value2: \the\dimen0

Но я не понимаю, как пользоваться \toks.

решение1

Регистр токена очень похож на макрос без аргументов, но есть различия в синтаксисе и правилах расширения.

Используя простое и латексное определение \toks@for \toks 0 вы можете хранить токены abcчерез

\toks@{abc}

или

\def\tmp{abc}

Обратите внимание, что макрос имеет определенную команду для установки макроса ( \defили обертки вокруг нее, например \newcommand), но регистры токенов просто используют имя регистра, за которым следуетсбалансированныйтекстовая группа.

И наоборот, в отличие от макросов, которые расширяются просто путем ссылки на их имя, регистры токенов, как и другие регистры, не расширяются, и доступ к их содержимому осуществляется путем расширения \the.

Так

\the\toks@

и

\tmp

каждый расширяется до abc.

Помимо этих синтаксических различий, расширение регистров токенов отличается от макросов двумя важными способами.

  1. расширение в \edefи других контекстах, где требуется только расширение, ограничено одним уровнем:

    \def\tmp{aaa}
    
    \def\tmpb{xx \tmp}
    
    \toks@{xx \tmp}
    
    \edef\A{\tmpb}
    
    \edef\B{\the\toks@}
    

    Теперь \tmpbи \toks@содержат тот же список токенов xx \tmp, но \Aопределяются полностью расширяемыми расширяемыми токенами и поэтому имеют определение , xx aaaно токены, возвращаемые с помощью , \theдалее не расширяются в \edefи поэтому \Bимеют определениеxx \tmp

  2. Второе отличие заключается в том, что, поскольку регистры токенов не имеют аргументов, #не требуется (и не является) специального определения или расширения регистра.

    \toks@{#1}
    

    — это просто регистр токенов, состоящий из списка из двух токенов #и 1.

Это используется в \g@addto@macroмакросе LaTeX.

\g@addto@macro@\foo{abc}

предполагается добавить abcв конец текущего определения \foo.

Простое (и если я правильно помню оригинальное) определение могло бы быть таким:

\makeatletter

\gdef\foo{123}

\def\gaA#1#2{%
  \expandafter\gdef\expandafter#1\expandafter{#1#2}}

\gaA\foo{abc}

\show\foo

Это работает отлично и показывает определение как 123abc. Однако попробуйте

\gaA\foo{#}

и вы получаете

! Illegal parameter number in definition of \foo.

Однако мы можем использовать тот факт, что #это не является чем-то особенным в регистре toks и что содержимое регистра расширяется только один раз.

\long\def\g@addto@macro#1#2{%
  \begingroup
    \toks@\expandafter{#1#2}%
    \xdef#1{\the\toks@}%
  \endgroup}

Сначала \toks@регистр определяется как содержащий расширение макроса, переданного в первом аргументе, за которым следует содержимое второго аргумента. #безопасно использовать в назначении toks. Затем макрос глобально определяется как расширение, \thetoksкоторое является в точности содержимым \toks@без дальнейшего расширения, даже если оно содержит #токены:

\makeatletter

\gdef\foo{123}

\g@addto@macro\foo{abc}

\show\foo

\g@addto@macro\foo{#}

\show\foo

производит

> \foo=macro:
->123abc.
l.7 \show\foo
             
? 
> \foo=macro:
->123abc##.
l.11 \show\foo

где #был добавлен, как и предполагалось ( #был добавлен только один, удвоение ##является артефактом использования \show).

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