在 expl3 中两次扩展的首选方法是什么?

在 expl3 中两次扩展的首选方法是什么?

expl3在将参数传递给基函数之前,分别包括用于单级扩展和两种完全扩展的、和参数说明符。扩展参数的首选方法of什么x两次在将其传递给基本函数之前?

举个例子,我正在尝试为从包中l3keys创建的宏编写一个键值接口。\DeclarePairedDelimitermathtools

\tl_new:N \l__mymodule_size_tl
\keys_define:nn { mymodule }
  {
    size .choices:nn =
      { big , Big , bigg , Bigg }
      {
        \tl_set:Nn \l__mymodule_size_tl
          { [ \use:c { \tl_use:N \l_keys_choice_tl } ] }
      } ,

    size / auto .code:n = 
      \tl_set:Nn \l__mymodule_size_tl {*} ,

    size / none .code:n = 
      \tl_clear:N \l__mymodule_size_tl
  }

\big通常,分隔符的大小作为etc. 或的可选参数传递给宏,*例如\abs[\big]{x}where \DeclarePairedDelimiter\abs{\lvert}{\rvert}。我更喜欢将size = bigetc. 或size = auto作为键值接口,例如\myabs[size=big]{x}

上述代码的问题在于正确设置等\l__mymodule_size_tl选项big:我需要扩展[ \use:c { \tl_use:N \l_keys_choice_tl } ] 两次在将这些标记分配给之前\l__mymodule_size_tl

  • 如果我不使用扩展(即\tl_set:Nn),则对的调用\abs将以错误的形式获取其参数——\l__mymodule_size_tl将保留[ \use:c { \tl_use:N \l_keys_choice_tl } ],而不是[\big]
  • 如果我使用一级扩展(即),并在扩展完成后\tl_set:No添加,将保持,而不是。[\l__mymodule_size_tl[ \cs:w \tl_use:N \l_keys_choice_tl \cs_end: ][\big]
  • 如果我使用fx扩展,\l__mymodule_size_tl将会保存一堆“垃圾”,而不是[\big]

我能做什么?这里有一个想法:使用两个o扩展,中间进行一些杂技。

    \tl_set:No \l__mymodule_size_tl
      { \use:c { \tl_use:N \l_keys_choice_tl } ] }
    \exp_args:NNV \tl_set:No \l__mymodule_size_tl 
      \l__mymodule_size_tl
    \tl_put_left:Nn \l__mymodule_size_tl { [ }

在我看来,这太丑了。我还能做些什么更好的事情吗?

答案1

在过去,有一个d用于双扩展的 -type 参数。然而,几年前它被放弃了,因为很少有地方需要它,特别是当团队决定不再使用toks寄存器时。从记忆中,expl3有两个地方我们必须使用或类似形式的构造\exp_args:NNo \exp_args:No

我们没有保留 -type 参数的原因d有两个。首先,我们希望尽可能避免依赖于了解函数的扩展细节:这对于低级工作是必需的,但理想情况下应该相对有限。另一个原因是,由于我们有 e-TeX,所以很少需要它。要记住的关键是,这使我们能够控制x-type 上下文中的扩展

\tl_set:Nx \l__mymodule_size_tl
  { [ \exp_not:c { \tl_use:N \l_keys_choice_tl } ] }

虽然这里不需要,但我们确实记录了\cs:w需要\cs_end:一次扩展的情况,因此您可以

\tl_set:No \l__mymodule_size_tl
  { \exp_after:wN [ \cs:w \tl_use:N \l_keys_choice_tl \cs_end: ] }

尽管我自己不会在这里使用它。

答案2

我的印象是你想做

\tl_set:Nx \l__mymodule_size_tl
 {
  [ \exp_not:c { \tl_use:N \l_keys_choice_tl } ]
 }

触发x扩展,因此当涉及到时(它是) \exp_not:c,参数会像往常一样完全扩展;然后生成的标记将变得不可扩展,所以如果你有c\csname...\endcsname

size=big

您将进入[\big]您的令牌列表。

相关内容