有几次,浮行包使用\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
是可选的)。
笔记
查找左括号的扩展不会发生,
\def
因为左括号界定了替换文本必须要明确。\mytoks=\bgroup abc}
是有效的赋值;相反,\mytoks=\bgroup abc\egroup
不是:TeX 将继续扫描标记,直到找到明确的(不平衡的)右括号。\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}