我需要将一个宏的结果作为字符串传递给另一个宏(我正在使用xparse
)。这是一个最小工作示例:
\documentclass{minimal}
\usepackage{xparse}
\NewDocumentCommand{\TwoVarFunction}{mm}{#1 is a #2}
\NewDocumentCommand{\foo}{}{this;string}
\NewDocumentCommand{\foobar}{>{\SplitArgument{1}{;}}m}{\TwoVarFunction #1}
\begin{document}
\foo
\TwoVarFunction{this}{string}
\foobar{this;string}
\foobar{\foo}
\end{document}
我期望最后三行的输出在 pdf 中是相同的(即this is a string
)。但是,并没有按照我期望的方式\foo
被解析为输入; 的实际输出是“ ”。\foobar
\foobar{\foo}
this;string is a -No Value-
请 (1) 解释为什么 LaTeX 不能读懂我的想法,以及 (2) 帮我找到一种处理方法\foo
以便输出相同。
答案1
当一个参数被吸收时,它不会以任何方式被处理(除非应用处理器),因此您的代码\foo
被看到并且它在上层不包含分号。
您可以定义自己的处理器。xparse
参数处理器通过设置\ProcessedArgument
所需的标记列表来工作;在这种情况下,您需要借助\tl_set:No
(o
表示“once”) 来扩展参数一次。
因此,链首先应用\ExpandArg
,然后\SplitArgument
,所以
\foo
→ 此;字符串 → {此}{字符串}
这就是#1
替换文本中的含义以及所见的内容\TwoVarFunction
。
如果没有\ExpandArg
,外层就不会出现分号,我们会得到
\foo
→ {\foo}{-无值-}
\SplitArgument
因为当看到的分隔符数量少于规定数量时,这就是如何规范输出的。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new_protected:Nn \__user_expand_arg:n
{
\tl_set:No \ProcessedArgument { #1 }
}
\cs_set_eq:NN \ExpandArg \__user_expand_arg:n
\ExplSyntaxOff
\NewDocumentCommand{\TwoVarFunction}{mm}{#1 is a #2}
\NewDocumentCommand{\foobar}{>{\SplitArgument{1}{;}}>{\ExpandArg}m}{%
\TwoVarFunction #1%
}
\newcommand{\foo}{this;string}
\begin{document}
\foo
\TwoVarFunction{this}{string}
\foobar{this;string}
\foobar{\foo}
\end{document}
请注意,您必须用 来定义\foo
,\newcommand
因为\NewDocumentCommand
会引入(大量)层,直到扩展为this;arg
。