插入与静态选项混合的宏

插入与静态选项混合的宏

几天来,我一直在断断续续地思考以下问题。我想将宏中定义的选项与静态定义的选项一起插入到另一个宏的选项列表中。我似乎可以做到这一点,前提是我的宏是宏列表中的第一个“选项”(类似于使用宏传递到 \geometry{} 选项 - keyval 错误);但如果我尝试将其作为第二个选项传递,它不起作用。我很困惑为什么会这样。

展示有效方法的示例代码:

\def\opts{align=left,minimum width=10em}
\begin{tikzpicture}
\expandafter\node\expandafter[\opts,draw=none] at (0,0) {
    Some fancy text.
};
\end{tikzpicture}

然而,这是行不通的:

\def\opts{align=left,minimum width=10em}
\begin{tikzpicture}
\expandafter\node\expandafter[draw=none,\opts] at (0,0) {
    Some fancy text.
};
\end{tikzpicture}

这显然是有原因的;但我就是不明白。我认为这可能与 \expandafter 的工作方式有关。有人能给我解释一下吗?

答案1

\expandafter读取其后的两个标记,将第一个标记放在一边,然后导致第二个标记的级别扩展;然后像往常一样评估第一个标记,就好像第二个标记的扩展从一开始就存在一样。

因此你的

\expandafter\node\expandafter[\opts,draw=none]

扩展,\opts因为第二个\expandafter借助第一个而扩展。相反,

\expandafter\node\expandafter[draw=none,\opts]

无法到达\opts,因为第二个后面的两个令牌\expandafter[d。你需要一个不同的策略,因为

\expandafter\node\expandafter[\expandafter d\expandafter r\expandafter a\expandafter w\expandafter =\expandafter n\expandafter o\expandafter n\expandafter e\expandafter ,\opts]

似乎不是一个可行的选择。;-)

您可以做的是调用“全局”一级扩展:

\begingroup\edef\x{\endgroup
\noexpand\node[draw=none,\unexpanded\expandafter{\opts}]}\x

临时宏\x在扩展后就会被遗忘,因为其扩展中的第一个标记是\endgroup;由于,\node它将保持不变,而将被扩展一次,并且由于 ,生成的标记列表将不会进一步扩展。\edef\noexpand\opts\expandafter\unexpanded

没有\unexpanded\expandafter{\opts},但只是\opts危险的,如果\opts包含宏,如\bfseries;在任何情况下,你都希望它的一个级别扩张,而不是“全线扩张”。

答案2

假设(最有可能的情况)你的选项只是纯文本,并且\edef可以安全地执行

 \edef\tmp{\noexpand\node[draw=none,\opts] at (0,0)}\tmp

as\edef将扩展其参数中的所有标记 (\node被阻止扩展,因此当\tmp扩展时,其扩展将是

\node[draw=none,align=left,minimum width=10em] at (0,0) 

如果\opts确实有无法以这种方式完全展开的令牌,则替代方案是

\def\tmp{\node[draw=none,}
\expandafter\tmp\opts] at (0,0)

然后\opts只会被展开一次,\expandafter而不是在中完全展开\edef

相关内容