我是 LaTeX3 的菜鸟,我尝试理解这门语言。当我读到这里 可以使用以下方法定义新的宏\cs_new:
\cs_new:Npn \SayHello #1
{ \prg_replicate:nn {#1} { Hello~World!~ } }
其中N
关于\SayHello
、p
---#1
和n
--- 至{...}
好的,我尝试创建函数来显示某个数字的平方:
\cs_new:Npn \Show #1
{
\int_eval:n {#1*#1}
}
宏\Show{number}
工作正常。但如果我尝试定义宏\Show
,它应该显示一些整数:
\cs_new:Nn \Show
{
\int_eval:n {2+2}
}
我得到一个LaTeX error: "kernel/missing-colon"
。
好的,然后我添加一个冒号:
\cs_new:Nn \Show:n
{
\int_eval:n {2+2}
}
并且我 agein 收到错误,但是现在它只是! Undefined control sequence
。
我不清楚这种行为。我哪里违反了规则?
下面的 MWE。
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Nn \Show:n
{
\int_eval:n {2+2}
}
\ExplSyntaxOff
\begin{document}
\Show{}
\end{document}
答案1
你\cs_new:Nn
只能定义一个具有签名,即冒号后面的参数类型列表。
您\cs_new:Npn
没有这个限制,因为您必须明确输入参数文本(这就是p
签名中的意思)。
例如,\cs_new:Nn
需要一个单个标记参数(N
)和一个括号参数(n
)。相反,\cs_new:Npn
需要一个单个标记参数,即“参数参数”(参见参数文本在 TeXbook 或 TeX by topic 中)后跟一个带括号的参数。
代码
\cs_new:Nn \sergio_show:n { \int_eval:n { #1+#1 } }
和
\cs_new:Npn \sergio_show:n #1 { \int_eval:n { #1+#1 } }
完全等价,因为\cs_new:Nn
可以从签名中构建合适的参数文本。
如果你要定义的命令没有签名,你必须\cs_new:Npn
用或 来定义它\cs_new_protected:Npn
。
或者你可以这样做
\cs_new:Nn \sergio_show:n { \int_eval:n { #1+#1 } }
\cs_set_eq:NN \Show \sergio_show:n
然而,对于用户空间命令,xparse
建议使用接口。
你不能做
\cs_new:Nn \Show:n { \int_eval:n { #1+#1 } }
然后\Show
在文档中使用,因为您从未定义过\Show
。
请注意,当代码包含不可扩展函数(手册中没有红色实心或空心星号的函数)时,应使用\cs_new_protected:Npn
或(适用相同规则)。这里不是这种情况,因为是完全可扩展的。\cs_new_protected:Nn
\int_eval:n