![使用参数文本和签名定义新函数](https://linux22.com/image/469512/%E4%BD%BF%E7%94%A8%E5%8F%82%E6%95%B0%E6%96%87%E6%9C%AC%E5%92%8C%E7%AD%BE%E5%90%8D%E5%AE%9A%E4%B9%89%E6%96%B0%E5%87%BD%E6%95%B0.png)
一直在阅读expl3
文档interfaces3.pdf
以了解如何声明和使用函数。虽然我了解到有三种主要方法(new
、、 ) set
,gset
其中每种方法都有特定的用例和对参数参数的限制。
在某些情况下,还很好地介绍了受保护的扩展变体。
我希望能够解释一下使用参数文本定义新函数与使用签名定义新函数之间的区别,如和节4.3.2
所述4.3.3
。
答案1
下面的代码示例来自Joseph Wright 或源自 Joseph Wright 的代码回答我之前的问题。
在标准情况下,区别仅在于您指定函数的方式。在参数化情况下,您可以明确指定函数的参数:
\cs_new_protected_nopar:Npn \__chronos_set_minoryearformat:n #1
{
\tl_set:Nn \l__chronos_minoryearformat_tl { #1 }
\tl_replace_all:Nnn \l__chronos_minoryearformat_tl { ~ } { \c_space_token }
}
也就是说,#1
告诉 LateX 该函数接受一个参数,就像\def\formatyear#1{ ... }
一样。
在非参数化的情况下,LaTeX 从新函数的签名中推断参数:
\cs_new_protected_nopar:Nn \__chronos_set_minoryearformat:n
{
\tl_set:Nn \l__chronos_minoryearformat_tl { #1 }
\tl_replace_all:Nnn \l__chronos_minoryearformat_tl { ~ } { \c_space_token }
}
这就是n
告诉 LaTeX 该函数接受一个参数,就像1
在\newcommand*\formatyear[1]{ ... }
或m
在 中所做的一样\NewDocumentCommand\formatyear{m}{ ... }
。
但在某些情况下,您需要参数化版本,因为您想特别处理传递给函数的参数。
\cs_new_protected_nopar:Npn \__chronos_set_date_aux_ce:w #1 - #2 - #3 - #4 @#5 \q_stop
{
\__chronos_set_date:nnnn {#1} {#2} {#3} {#5}
}
所以这个函数不期望混合使用标记和标记的括号列表。它期望使用非标准语法形式。
这样就可以解析用户输入的日期,这些日期提供的信息量有所不同。基本上,用户可以说
date={1066-08-09}
或者
date=1066
或者
date={1066-03}
然后,该包将添加到用户指定的输入
<user-specified date>-01-01-0@start \q_stop
代码将传递相应的信息。如果用户仅指定了年份,则会添加月份和日期。如果用户仅指定了年份和月份,则会添加日期。如果用户指定了完整日期,则除了用于start
创建变量名称的日期外,不会添加任何内容。
这就是为什么w
.w
代表‘奇怪’。
这基本上就像 TeX 级别的类似定义。
\def\mydateparser@aux#1-#2-#3-#4@#5\@nil{ ... }
会以类似的方式工作(除了这不受保护并且没有检查以确保定义不会抹去一些关键的东西)。