使用 \toks 寄存器

使用 \toks 寄存器

我正在阅读这个 TeX 编程教程:

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

在第二个答案中推荐:我应该从哪里开始 LaTeX 编程?

它说:

\toks<number>还有 255 个令牌寄存器,可以将其视为特殊的字符串变量。当然,每个宏赋值 \def\macro{ content }也都是某种字符串变量,但令牌寄存器是特殊的:当与 \the\toksnumber 一起使用时,其内容不会被扩展。这可用于细粒度扩展控制,请参阅下面的第 2.3 节。

但没有使用寄存器的示例\toks。他的意思是什么:“特殊字符串变量”?对于前两种类型的寄存器,我可以分配以下值:

\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

这在 LaTeX 的宏中得到使用\g@addto@macro

\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)。

相关内容