使用 \toks 暫存器

使用 \toks 暫存器

我正在閱讀 TeX 程式設計教學:

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

這裡的第二個答案推薦:我該從哪裡開始 LaTeX 程式設計?

它說:

\toks<number>還有 255 個令牌暫存器,可以將其視為特殊的字串變數。當然,每個宏賦值 \def\macro{ content }也是某種字串變量,但令牌暫存器很特殊:與 number 一起使用時,它們的內容不會擴展 \the\toks。這可用於細粒度擴展控制,請參閱下面的 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)。

相關內容