您如何测试我们是否处于仅扩展的上下文中(即,,,,... \edef
)?我能想到的唯一方法就是留下一些东西(但那些额外东西的完整扩展是空的)。\xdef
\write
有没有一种干净的方法来测试这个?
\documentclass{article}
\def\expiffalse{\expandafter\iffalse}
\protected\def\mygobble#1{\ifx\iftrue#1\expiffalse\fi}
\def\ifexpanding{\mygobble\iftrue\relax}
\begin{document}
We test that it sort of works: first, we are
\ifexpanding expanding\else not expanding\fi.
Then, we are%
\edef\foo{\ifexpanding expanding\else not expanding\fi}
\show\foo
\foo.
\end{document}
答案1
我认为不是,因此在 pdfTeX(和 XeTeX,我认为)中添加了\ifincsname
。这是很久以前在检测/测试所有不同扩展上下文时讨论的,但我记得 csname 扩展是唯一一个易于实现或可能明确实现的扩展。
呃,抱歉我的回答比较模糊;如果他们能找到我的话,我会查阅一些参考资料。
答案2
简短回答:不。详细回答:要检测这种情况,需要一个“知道”扩展的原语。但是,编写一个原语并非易事:请参阅相关问题,了解\ifincsname
为什么检测此类事情很困难。
如果您查看 LaTeX 内核,就会发现该\protect
机制与扩展有关。要正常工作,必须正确设置并\protect
重新定义所有内容。这就是为什么 LaTeX2e 的“强大”命令仍然需要\protected@edef
使用类似的命令:在内核中\edef
更改任何内容都为时已晚。
答案3
是也不是。我通常的技巧是这样的:
\def\voodoo#1#2{\relax\relax\Expansionstuff}
[...]
\let\voodoo\voodoo\Realstuff
如果我没弄错的话:在扩展上下文中,
\let\voodoo\voodoo\RealStuff
从左到右扩展到
\let\relax\relax\Expansionstuff
,继续扩展\Expansionstuff
因为\let
和\relax
是原始的,但无论哪种情况,你都会剩下相当无害的\let\x\x
东西。