![expl3/xparse:扩展,比较标记和 xparse 定义的宏](https://linux22.com/image/470307/expl3%2Fxparse%EF%BC%9A%E6%89%A9%E5%B1%95%EF%BC%8C%E6%AF%94%E8%BE%83%E6%A0%87%E8%AE%B0%E5%92%8C%20xparse%20%E5%AE%9A%E4%B9%89%E7%9A%84%E5%AE%8F.png)
什么是正确的(首选的?)方法来比较特定的标记---在我的例子中,它通常是一个字符,但它可能是类似\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
定义时起作用的变体。\NewDocumentCommand
NewExpandableDocumentCommand
我确信我在\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
哪个内部定义正是这样做的)