
Eu estava lendo este tutorial para programação TeX:
http://pgfplots.sourceforge.net/TeX-programming-notes.pdf
recomendado na 2ª resposta aqui:Por onde começo a programação LaTeX?
Diz:
\toks<number>
Existem também 255 registros de token que podem ser considerados variáveis de string especiais. É claro que toda atribuição de macro\def\macro{ content }
também é algum tipo de variável de string, mas os registradores de token são especiais: seu conteúdo não será expandido quando usados com\the\toks
number . Isso pode ser usado para controle de expansão granular, consulte a Seção 2.3 abaixo.
Mas não há exemplos de uso \toks
de registros. O que ele quer dizer com "variáveis de string especiais"? Para 2 tipos de registros anteriores eu poderia atribuir o valor:
\count0=12
\dimen0=1.102pt
E imprima:
Value1: \the\count0
Value2: \the\dimen0
Mas não entendo como usar \toks
.
Responder1
Um registro de token é muito semelhante a uma macro sem argumentos, mas existem diferenças na sintaxe e nas regras de expansão.
Usando a definição simples e látex de \toks@
for \toks 0
você pode armazenar os tokens abc
via
\toks@{abc}
ou
\def\tmp{abc}
Observe que uma macro possui um comando específico para definir a macro ( \def
ou wrappers em torno dela, como \newcommand
), mas os registradores de token apenas usam o nome do registrador seguido por umequilibradogrupo de texto.
Por outro lado, ao contrário das macros que se expandem apenas referenciando o seu nome, os registos de token, como outros registos, não são expansíveis e o seu conteúdo é acedido através da expansão \the
.
Então
\the\toks@
e
\tmp
cada um se expande para abc
.
Além dessas diferenças sintáticas, a expansão dos registradores de tokens difere das macros de duas maneiras importantes.
a expansão em
\edef
e outros contextos apenas de expansão é limitada a um nível:\def\tmp{aaa} \def\tmpb{xx \tmp} \toks@{xx \tmp} \edef\A{\tmpb} \edef\B{\the\toks@}
Agora
\tmpb
e\toks@
contém a mesma lista de tokens,xx \tmp
mas\A
é definido por tokens expansíveis totalmente expandidos e, portanto, tem definição,xx aaa
mas os tokens retornados por\the
não são mais expandidos no\edef
e também\B
tem definiçãoxx \tmp
A segunda diferença é que como os registradores token não possuem argumentos
#
não precisa ser (e não é) especial ao definir ou expandir o registrador.\toks@{#1}
é apenas um registro de token que consiste em uma lista de dois tokens
#
e1
.
Isso é usado na \g@addto@macro
macro do LaTeX.
\g@addto@macro@\foo{abc}
deve ser adicionado abc
ao final da definição atual de \foo
.
Uma definição simples (e se bem me lembro original) poderia ser
\makeatletter
\gdef\foo{123}
\def\gaA#1#2{%
\expandafter\gdef\expandafter#1\expandafter{#1#2}}
\gaA\foo{abc}
\show\foo
Isso funciona bem e mostra a definição como 123abc
. No entanto, tente
\gaA\foo{#}
e você consegue
! Illegal parameter number in definition of \foo.
No entanto, podemos aproveitar o fato de que isso #
não é especial em um registro toks e que o conteúdo do registro só é expandido uma vez
\long\def\g@addto@macro#1#2{%
\begingroup
\toks@\expandafter{#1#2}%
\xdef#1{\the\toks@}%
\endgroup}
Primeiro o \toks@
registrador é definido para conter a expansão da macro passada no primeiro argumento, seguido pelo conteúdo do segundo argumento. #
é seguro para uso em uma tarefa de toks. Em seguida, a macro é definida globalmente como sendo a expansão da \thetoks
qual é exatamente o conteúdo de \toks@
sem expansão adicional, mesmo que contenha #
tokens:
\makeatletter
\gdef\foo{123}
\g@addto@macro\foo{abc}
\show\foo
\g@addto@macro\foo{#}
\show\foo
produz
> \foo=macro:
->123abc.
l.7 \show\foo
?
> \foo=macro:
->123abc##.
l.11 \show\foo
onde #
foi adicionado conforme pretendido (apenas um #
foi adicionado, o duplicado ##
é um artefato de uso \show
).