Я читал этот учебник по программированию TeX:
http://pgfplots.sourceforge.net/TeX-programming-notes.pdf
рекомендовано во 2-м ответе здесь:С чего начать программирование LaTeX?
Там говорится:
\toks<number>
Также есть 255 регистров токенов, которые можно рассматривать как специальные строковые переменные. Конечно, каждое макроприсвоение\def\macro{ content }
также является своего рода строковой переменной, но регистры токенов являются особыми: их содержимое не будет расширено при использовании с\the\toks
number . Это можно использовать для тонкого управления расширением, см. Раздел 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
.
Помимо этих синтаксических различий, расширение регистров токенов отличается от макросов двумя важными способами.
расширение в
\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
Второе отличие заключается в том, что, поскольку регистры токенов не имеют аргументов,
#
не требуется (и не является) специального определения или расширения регистра.\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
).