有没有办法在定义时扩展“NewDocumentCommand”的主体?

有没有办法在定义时扩展“NewDocumentCommand”的主体?

NewDocumentCommand有没有办法扩展在定义点传递的主体?理想情况下,只扩展一次。

这是我的(最小化的)场景。

\documentclass{minimal}

\newcommand*{\baz}{\foo}
\newcommand*{\expandme}{good}

\ExplSyntaxOn
\exp_args:NV \NewDocumentCommand \baz { s D<>{} } {
    \expandme% Should get expanded once at definition time.
}
\ExplSyntaxOff

\renewcommand*{\expandme}{bad}

\begin{document}

    \foo<bar>% Prints "bad", but I want it to print "good".

\end{document}

进行以下修改会产生Undefined control sequence错误,大概是因为\exp_args参数处理起来很困难{ s D<>{} }

\exp_args:NVNo \NewDocumentCommand \baz { s D<>{} } {
    \expandme% Should get expanded once at definition time.
}

最后,请注意以下解决方案,它在最简单的情况下有效,但当\bar可以采取多个值时会出现问题,并且每个值都会重复此代码(就像我的真实情况一样)。

\exp_args:NNV \cs_set:Npn \tmp \expandme
% alternatively to the above line, I think: \edef\tmp\expandme
\exp_args:NV \NewDocumentCommand \baz { s D<>{} } {
    \tmp
}

答案1

您可以\expanded在最近的 tex 版本中使用:

\documentclass{minimal}

\newcommand*{\baz}{\foo}
\newcommand*{\expandme}{good}

\ExplSyntaxOn
\expanded{\noexpand\NewDocumentCommand\expandafter\noexpand\baz { s D<>{} } {
    \unexpanded\expandafter{\expandme}% Should get expanded once at definition time.
}}
\ExplSyntaxOff

\renewcommand*{\expandme}{bad}

\begin{document}

    \foo<bar>% Prints "bad", but I want it to print "good".

\end{document}

或者您可以将其打包为自定义 VnV 参数列表

\documentclass{minimal}

\newcommand*{\baz}{\foo}
\newcommand*{\expandme}{good}

\ExplSyntaxOn
\exp_args_generate:n{VnV}
\exp_args:NVnV\NewDocumentCommand\baz { s D<>{} } \expandme
\ExplSyntaxOff

\renewcommand*{\expandme}{bad}

\begin{document}

    \foo<bar>% Prints "bad", but I want it to print "good".

\end{document}

答案2

如果由于某种原因所需的\exp_args:N...变体不可用,您可以自行处理\use:n

\documentclass{minimal}

\newcommand*{\baz}{\foo}
\newcommand*{\expandme}{good}

\ExplSyntaxOn
\exp_args:Nno \use:n { \exp_args:NV \NewDocumentCommand \baz { s D<>{} } } {
    \expandme% Should get expanded once at definition time.
}
\ExplSyntaxOff

\renewcommand*{\expandme}{bad}

\begin{document}

    \foo<bar>% Prints "bad", but I want it to print "good".

\end{document}

答案3

您应该为此定义一个接口。

\documentclass{article}

\newcommand*{\expandme}{good}

\ExplSyntaxOn
\cs_new_protected:Npn \NewDocumentCommandExpandOnce
 {
  \exp_args:NNno \NewDocumentCommand
 }
\ExplSyntaxOff

\NewDocumentCommandExpandOnce \foo { s D<>{} } {%
  \expandme% Should get expanded once at definition time.
}

\renewcommand*{\expandme}{bad}

\begin{document}

\foo<bar>% Prints "bad", but I want it to print "good".

\end{document}

您可以检查输出是否“良好”。

相关内容