如何将材料附加到令牌列表?

如何将材料附加到令牌列表?

有几次,浮行包使用\newtoks哪个(根据网站)表示已分配令牌寄存器。示例代码片段如下

\@ifdefinable\FR@everyfloat{\newtoks\FR@everyfloat}
\FR@everyfloat={\let\@footnotetext\@mpfootnotetext
  \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@
  \floatobjectset\floatfont}

假设我想\setlength{\footnotesep}{0.2\baselineskip}在 的定义中添加一些内容(例如 )\FR@everyfloat。我成功应用的一种方法是答案是覆盖原来的定义,即写入

\FR@everyfloat={\let\@footnotetext\@mpfootnotetext
  \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@
  \floatobjectset\floatfont
  \setlength{\footnotesep}{0.2\baselineskip}}

但是,我想避免复制整个标记列表内容;相反,我想以与使用相同的方式将材料附加到列表中\g@addto@macro(或\appto电子工具箱包)。然而,我幼稚的写法

\g@addto@macro{\FR@everyfloat}{\setlength{\footnotesep}{0.2\baselineskip}}

不起作用——显然,标记列表必须与宏区别对待。

那么:如何将材料附加到标记列表中?

答案1

正如其他人指出的那样,\the\mytoks传递令牌寄存器的内容\mytoks。当想要将某些内容附加到令牌寄存器时,通常的方法是

\mytoks=\expandafter{\the\mytoks <tokens>}

这样的代码需要解释一下。令牌寄存器的名称(不在后面\the)开始对该令牌寄存器进行赋值。=后面可以跟一个可选的,然后必须有{<balanced text><right brace>。每次必需的标记列表必须以 开头{(在 TeXbook 的符号学中,这表示类别 1 的明确标记或指向\let它的标记)TeX 扩展它找到的标记以达到{。因此,在

\mytoks=\expandafter{\the\mytoks <tokens>}

\expandafter扩展,提供的内容\mytoks,以便可以执行分配。分配以明确的右括号。此操作的通用宏可以是

\long\def\appendto#1#2{#1=\expandafter{\the#1#2}}

其中#1是令牌寄存器的名称和#2要附加的令牌列表。

稍微复杂一点的是前置标记寄存器的内容。让我们尝试一下;参数#1将表示标记寄存器,#2将是要添加的标记:

\long\def\prependto#1#2{\toks0={#2}%
  #1=\expandafter{\the\toks0\the#1}}

这里我们使用了一个卑鄙的伎俩:\the想知道它必须对什么采取行动;它看到\toks哪个必须以 ;0开头,但 TeX 继续扩展以查看是否还有其他数字跟在后面。因此第二个\the被扩展了。

限制:无法\prependto注册令牌\toks0

有没有办法克服这个限制?有的,有:

\long\def\prependto#1#2{\def\tempa{#2}%
  \edef\tempb{\noexpand\tempa\the#1}%
  #1=\expandafter\expandafter\expandafter{\tempb}}

假设我们有\mytoks={\A\B\C}并且我们调用

\prependto\mytoks{\a\b\c}

然后 TeX 执行\def\tempa{\a\b\c};我们现在利用这样一个事实,即产生的标记列表\the\mytoks不会在 中进一步扩展\edef,因此这相当于说

\def\tempb{\tempa\A\B\C}

下一条指令是

\mytoks=\expandafter\expandafter\expandafter{\tempb}

变成

\mytoks=\expandafter{\tempa\A\B\C}

最后,

\mytoks={\a\b\c\A\B\C}

当然,第一种方法效率更高。\toks0可以使用永久保留的令牌寄存器,例如“\reservedtoks:

\def\prependto#1#2{\reservedtoks={#2}%
  #1=\expandafter{\the\expandafter\reservedtoks\the#1}}

(练习:找出它为什么有效)。用户想说什么\prependto\reservedtoks{abc}就自己说吧。:)

Bruno Le Floch 提出了一种更巧妙的策略,可以避免临时任务:

\def\prependto#1{\expandafter\prependtoaux\expandafter{\the#1}#1} 
\long\def\prependtoaux#1#2#3{#2{#3#1}}

让我们看看使用与之前相同的设置会发生什么\prependto\mytoks{\a\b\c}(每一行都是前一行扩展的结果):

\prependto\mytoks{\a\b\c}
\expandafter\prependtoaux\expandafter{\the\mytoks}\mytoks{\a\b\c}
\prependtoaux{\A\B\C}\mytoks{\a\b\c}
\mytoks{\a\b\c\A\B\C}

=后面的\mytoks是可选的)。

笔记

  1. 查找左括号的扩展不会发生,\def因为左括号界定了替换文本必须要明确。

  2. \mytoks=\bgroup abc}有效的赋值;相反,\mytoks=\bgroup abc\egroup不是:TeX 将继续扫描标记,直到找到明确的(不平衡的)右括号。

  3. \long是必要的,因为要附加或添加的标记列表可能包含\par(感谢 Bruno Le Floch 指出这一点)。

答案2

看看 mbork 的解决方案,并问自己“为什么这不包含在 LaTeX 内核中?”,我发现它实际上。搜索#1=\expandafter{\the #1#2}没有返回任何内容,但搜索#1\expandafter{\the#1#2}(请注意缺少等号和空格)返回(引用来源2e,第 27 章)

我们需要一个宏来将标记添加到钩子中。

485\long\def\addto@hook#1#2{#1\expandafter{\the#1#2}}

这是 TeX 语法,但其他方面与 mbork 的代码相同。所以我的问题的答案是:使用\addto@hook

答案3

令牌寄存器只有在以 为前缀时才会扩展到其内容\the,否则它们本身是不可扩展的,IIRC。您需要使用 来\expandafter扩展令牌寄存器,然后再将其分配给寄存器:

附加操作如下:

\mytoks\expandafter{\the\mytoks<new code>}

这里你不需要\expandafter在开头使用另一个,因为令牌寄存器会在搜索平衡{ }列表时扩展以下令牌。

为代码添加前缀更加复杂,因为你必须跳过它。这通常使用第二个标记寄存器来完成:

\temptoks{<new code>}
\mytoks\expandafter{\the\expandafter\temptoks\the\mytoks}

这利用了正在扩展下一个标记的事实\the来查找寄存器。

答案4

警告:正如约瑟夫赖特在评论部分指出的那样,这在较新版本中不起作用expl3


并使用 LaTeX3(伙计,这是我第一次尝试,所以如果我做错了,请原谅(并纠正)我!):

\documentclass{article}

\usepackage{expl3}

\begin{document}

\ExplSyntaxOn
\toks_new:N\abc_toks
\toks_set:Nn\abc_toks{A. B. C.}
\toks_use:N\abc_toks
\par

\toks_put_right:Nn\abc_toks{X. Y. Z.}
\toks_use:N\abc_toks
\ExplSyntaxOff

\end{document}

相关内容