使用 N 类型作为自己的宏

使用 N 类型作为自己的宏

背景
在 LaTeX3 中,我正在编写一些宏来存储和读取变量的内容,就像\tl_set:Nndoes 一样。因此,我使用类型生成变体N,这会导致警告。警告建议改用,V这对阅读\tobiw_use_thing,但感觉不对写作\tobiw_save_thing。手册上说(我重点标出):

V 和 v 说明符用于得到变量的内容[…]

平均能量损失

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\cs_new:Nn \tobiw_save_thing:nn {
   \tl_set:Nn #1 { #2 }
}
\cs_generate_variant:Nn \tobiw_save_thing:nn { Nn }

\cs_new:Nn \tobiw_use_thing:n {
   \tl_use:N #1
}
\cs_generate_variant:Nn \tobiw_use_thing:n { N }

\NewDocumentCommand{\saveanduse}{ m }{
   \tobiw_save_thing:Nn \l_tmpa_tl { #1 }
   \fbox { \tobiw_use_thing:N \l_tmpa_tl }
}

\ExplSyntaxOff

\begin{document}
   Test
   \saveanduse{Tokens}
\end{document}

问题
那么,创建此类宏的最佳方法是什么?这里应该使用哪些参数类型?

答案1

一定不在这里使用变体。

当基本函数的签名仅由Nn说明符组成(或在包容意义上,要清楚),并且在执行操作之前需要某种类型的参数扩展时,就需要变体:

  • V是 的变体n,其中变体函数将接收单个标记(应该是合适变量的名称)并且基本函数将接收n该值作为其参数。

  • fx是 的变体n,其中括号中的内容将被f- 或x-扩展。

  • o是 的变体n,其中括号中的内容将“扩展一次”,即列表中的第一个标记将扩展一次。

  • c是 的变体N,其中括号中的内容将被转换为单个标记作为参数N

您正在定义两个基本函数,并且都期望单个标记作为它们的第一个(或唯一)参数:这要求一个类型的参数N

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\cs_new_protected:Nn \tobiw_save_thing:Nn
 {
   \tl_set:Nn #1 { #2 }
 }

\cs_new:Nn \tobiw_use_thing:N
 {
   \tl_use:N #1
 }

\NewDocumentCommand{\saveanduse}{ m }
 {
   \tobiw_save_thing:Nn \l_tmpa_tl { #1 }
   \fbox { \tobiw_use_thing:N \l_tmpa_tl }
 }

\ExplSyntaxOff

\begin{document}
   Test
   \saveanduse{Tokens}
\end{document}

请注意,第一个函数应使用 来定义_protected,因为它一些变量。

定义设施的函数\cs_new_...\cs_set_...具有基本签名:Nn:Npn。定义函数的签名应仅由Nn(包含意义)的字符串组成;w仅在情况下才允许:Npn

例如,你有\tobiw_use_thing:N,但你可能想要

\cs_new:Nn \tobiw_use_thing:n
 {
  Do something with #1
 }
\cs_generate_variant:Nn \tobiw_use_thing:n { V }

允许如下调用

\tobiw_use_thing:n {whatever}

或者

\tobiw_use_thing:V \l_tmpa_tl

但最终这取决于你的功能应该做什么。

答案2

这里不需要任何变体,只需定义N带有类型参数的函数即可。如果您主要关心的是允许分组输入(如 csname),c则随后生成一个变体。

n您的函数使用代表一组标记的说明符。您可以将它们(作为变体)转换为V类型参数,因为这样可以保留获取一组标记的想法。另一方面,您有一对cN,前者接受一组标记(但从中形成一个控制字),后者接受一个标记,即一个控制字。

在设计函数时,你应该考虑到参数的目的。如果你希望将控制序列作为参数,请使用N或之一c。如果你希望获得某个值,请使用noxf或。Vv

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\cs_new:Nn \tobiw_save_thing:Nn {
   \tl_set:Nn #1 { #2 }
}
\cs_generate_variant:Nn \tobiw_save_thing:Nn { cn }

\cs_new:Nn \tobiw_use_thing:N {
   \tl_use:N #1
}
\cs_generate_variant:Nn \tobiw_use_thing:N { c }

\NewDocumentCommand{\saveanduse}{ m }{
   \tobiw_save_thing:Nn \l_tmpa_tl { #1 }
   \fbox { \tobiw_use_thing:N \l_tmpa_tl }
}

\ExplSyntaxOff

\begin{document}
   Test
   \saveanduse{Tokens}
\end{document}

相关内容