expl3/xparse:扩展,比较标记和 xparse 定义的宏

expl3/xparse:扩展,比较标记和 xparse 定义的宏

什么是正确的(首选的?)方法来比较特定的标记---在我的例子中,它通常是一个字符,但它可能是类似\mathcal{A}\mathbf{b}类似的字符---与用\NewDocumentCommand和朋友定义的宏?

这里有一些示例,如果结果符合预期,则每个示例都会给我一个完全由单词“YES”组成的文档,如果结果不符合预期,则完全由单词“NO”组成的文档。示例中的比较是\foo在执行比较时是否扩展为字母“n”。

示例 1(无效):

\documentclass{minimal}
\NewDocumentCommand{\foo}{}{n}
\begin{document}
\ExplSyntaxOn
\tl_if_eq:NnTF \foo {n}
{ YES }
{ NO }
\ExplSyntaxOff
\end{document}

(请注意,里面的 ExplSyntaxOn 部分\begin{document}...\end{document}不是我通常会做的事情;它只是为了制作一个最小的例子)。

示例 2(有效):

\documentclass{minimal}
\newcommand*{\foo}{n}
\begin{document}
\ExplSyntaxOn
\tl_if_eq:NnTF \foo {n}
{ YES }
{ NO }
\ExplSyntaxOff
\end{document}

我尝试过各种变化,包括\foo\cs_new:Npn\cs_new_protected:Npn和变化定义,如果我这样做,这些变化就会起作用:

\documentclass{minimal}
\ExplSyntaxOn
\cs_new:Npn \foo {n}
%\cs_new_protected:Npn \foo {n} % this works, too
\tl_new:N \l__foo_tl
\tl_set:NV \l__foo_tl \foo
\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn
\tl_if_eq:NnTF \l__foo_tl {n}
{ YES }
{ NO }
\ExplSyntaxOff
\end{document}

但是,我无法想出让它在用或\foo定义时起作用的变体。\NewDocumentCommandNewExpandableDocumentCommand

我确信我在\tl_if_eq比较时做错了什么,我也知道问题可以追溯到事物的扩展方式,但我不确定对于由 定义的命令来说,执行此操作的“正确”方法是什么\NewDocumentCommand

答案1

\NewExpandableDocumentCommand 是用于扩展为任何定义的“文档快捷方式”,因此您可以在比较之前进行扩展:

在此处输入图片描述

\documentclass{minimal}
\NewExpandableDocumentCommand\foo{}{n}
\begin{document}
\ExplSyntaxOn
\tl_if_eq:enTF {\foo} {n}
{ YES }
{ NO }
\ExplSyntaxOff
\end{document}

然而,\NewDocumentCommand它会创建一个新命令,并且其定义n或多或少被有意视为实现细节。您必须转到 ltcmd/xparse 内部来提取内部定义(这并非不可能,您可以查看\ShowCommand哪个内部定义正是这样做的)

相关内容