我正在尝试找到一种方法来\scantokens
在 [等同于] 中使用 e-TeX 命令\edef
(好吧,实际上是\xdef
,但这可能没有什么实际区别,因为那只是\global
的版本\edef
)。我这样做的原因是似乎需要回答关于 hyperref 和 pdf outlines 的问题。
问题似乎在于,它\scantokens
实际上并没有扩展到扫描的标记;它实际上扩展到零,但安排从名为“ ”的伪文件中读取下一个标记,然后将其几乎完全像真实文件一样处理,包括检查“失控”条件。(参见e-TeX 手册。
但这个解释有一个问题:为什么\input
工作,就像另一个问题中明显出现的那样?
无论如何,这是一个相当简单的例子:
%&eplain
% make \scantokens pseudo-files show up with name " " in the output
\tracingscantokens=1
\edef\foo{\scantokens{Test}}
输出结果
使用“pdftex -interaction=nonstopmode "\input" "scantokens-in-edef-minimal"”在“scantokens-in-edef-minimal”上运行“TeX” 这是 pdfTeX,版本 3.1415926-1.40.11(MiKTeX 2.9) 进入扩展模式 (e:\home\tex\scantokens-in-edef-minimal.tex( ) 失控的定义? ->测试 ! 扫描 \foo 的定义时文件结束。 <插入文本> } l.6 \edef\foo{\scantokens{测试} } !} 太多了。 l.6 \edef\foo{\scantokens{测试}} ) !紧急停止。 <*> \输入 scantokens-in-edef-minimal !==> 发生致命错误,未生成输出 PDF 文件! 抄录在 scantokens-in-edef-minimal.log 上。 TeX 于 1 月 27 日星期四 12:24:57 异常退出,代码为 1
是否有可能以某种方式使用宏进行扩展,然后执行\def
而不是\edef
,这样扩展就会在定义开始之前完成,从而避免“失控定义”的情况?
答案1
简而言之,是的。试试
\edef\foo{\scantokens{Test\noexpand}}
或者
\everyeof={\noexpand}
\edef\foo{\scantokens{text}}
其中,\noexpand
通过将 EOF 标记转变为 来“隐藏”它\relax
。
您可能想看一下 expl3 和 的定义\tl_rescan:nn
,\tl_set_rescan:Nnn
这两个包装器都\scantokens
基于 Heiko Oberdiek 包中的想法catchfile
。
然后你可以写
\tl_set_rescan:Nnn \foo { «catcode setup» } { «rescanned tokens» }
或者
\tl_rescan:nn { «catcode setup» } { «tokens to re-scan (in a group)» }
后者不能在内部使用,\edef
但在处理已标记化的宏参数时会派上用场。在实践中,我发现该set_rescan
版本更方便一些。