如何使用 \NewDocumentCommand

如何使用 \NewDocumentCommand

我遇到了此功能,并对xparse它的用法有一些疑问:

  1. 文档说它定义了一个健壮的函数。所以我猜想如果用 定义的函数\NewDocumentCommand调用内部函数,那么内部函数就不必是健壮的(如果没有其他要求)?我的意思是我们可以使用\cs_new:而不是\cs_new_protected:来表示内部函数?

  2. 此命令适用于文档编写者、软件包编写者还是两者?我们可以在正文中使用它吗?

  3. 如果我们在一份文档中混合使用\NewDocumentCommand和,会出现问题吗?\newcommand

答案1

对您的问题的简短回答(请随意在评论中询问更多详细信息):

  1. \protected如果必须执行不可扩展的代码,您确实应该定义每个函数(内部或非内部) (或健壮)。因此,\cs_new_protected:Npn对于不可扩展的内部函数,即使它们仅在定义的宏内调用\NewDocumentCommand(但请参阅egreg 的回答为了更好地描述何时定义受保护的内容或不定义受保护的内容,例如,像宏这样的宏\multicolumn必须可扩展以将其放置\omit在单元格的开头,即使下一步处理不可扩展并且进行分配)。

  2. 文档作者和软件包维护者都可能使用\NewDocumentCommand和朋友。但最好只在序言中使用,而不是在里面\begin{document}...\end{document}(为了结构和惯例,除此之外没有什么可以阻止你以后使用它)。

  3. 不,只要没有命名冲突(这无论如何都会引发错误),就不会出现任何问题。如果您使用的是 LaTeX 和类似的软件包,那么siunitx您已经混合了使用两个接口定义的宏。请记住,\newcommand没有定义强大的命令,因此结果可能会在上下文中失败\edef,而\NewDocumentCommand不会(但是 LaTeX 中有接口可以在不使用的情况下定义强大的命令xparse)。

答案2

是否使用\cs_new:Npn\cs_new_protected:Npn(或其变体)取决于我们定义的函数应该做什么。

任何执行将值赋给变量或将含义赋给函数的函数都应受到保护。protected例如,所有newset或函数都应受到保护,并且任何使用它们的函数也应受到保护。clearzero

protected但是,只要外部函数本身不执行赋值,也可以在“不受保护”的函数中使用函数。

例如,如果你有一个函数,根据或\__cyker_purify:n改变其参数,则必须用 来定义它。但是,你可以这样做\tl_replace_all:Nn\regex_replace_all:nnN\cs_new_protected:Npn

\cs_new:Npn \__cyker_process:n
 {
  \clist_map_function:nN { #1 } \__cyker_purify:n
 }

因此可以在另一个使用或扩展的\__cyker_process:n函数中使用,比如ex

\tl_put_right:Nx \l__cyker_tablebody_tl { \__cyker_process:n { #1 } }

最后,\NewDocumentCommand\newcommand只是定义命令的不同方式。混合使用这两者没有问题。

相关内容