使用文档 catcodes 扫描 l3key 吗?

使用文档 catcodes 扫描 l3key 吗?

与 TikZ 尝试使用未知键作为键的值的方式类似color,我想将未知键解释为我自己的一个键的值decoration(不要与 TikZ 中同名的键混淆),使用 编写expl3

我天真地尝试使用

\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\keys_define:nn { mymodule } {
  decoration .tl_set:N = \l_mymodule_decoration_tl ,
  unknown    .code:n   = {
    \tl_set:NV \l_mymodule_decoration_tl \l_keys_key_tl }
}

\NewDocumentCommand \mymathmacro { O{} m } {
  \mymodule_mathmacro:nn {#1} {#2}
}

\cs_new:Npn \mymodule_mathmacro:nn #1#2 {
  \keys_set:nn { mymodule } {#1}
  #2 \tl_use:N \l_mymodule_decoration_tl
}

\ExplSyntaxOff

这种方法效果很好,只是我有时会给出未知的键^2,例如$\mymathmacro[^2]{x}$,希望修饰符为上标2。但实际上,我得到的修饰符是一个^字符,后面跟着2

假设问题是 catcode 分配,我现在正在使用

\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn

\cs_generate_variant:Nn \tl_set_rescan:Nnn { NnV }

\keys_define:nn { mymodule } {
  decoration .tl_set:N = \l_mymodule_decoration_tl ,
  unknown    .code:n   = {
    \tl_set_rescan:NnV \l_mymodule_decoration_tl
      { \char_set_catcode_math_subscript:N _
        \char_set_catcode_math_superscript:N ^ }
     \l_keys_key_tl
  }
}

...

\ExplSyntaxOff

到目前为止,这种方法效果很好,但我的问题是:我怎么知道我没有错过重要的 catcode 分配?我真正想要的是扫描未知密钥,就像将其直接作为密钥的值赋值一样decoration

另外,我听说应该避免使用 和 堂兄弟。除了使用 之外,\tl_rescan:nn有没有更好的方法来编写 代码?unknown\tl_set_rescan:NnV

答案1

我认为你误用了键值系统。存储\l_keys_key_tl键名,不是值,因此它被规范化为字符串;引用文档(第十九部分第四节末尾),

该信息存储在\l_keys_key_tl,并将由 处理\tl_to_str:n

因此,这种行为是预料之中的,我认为你这样说不会有什么好处

$\mymathmacro[^2]{x}$

代替

$\mymathmacro[decoration=^2]{x}$

对于前一种语法,只需使用标准可选参数,而不是键值系统。命令应该将键值列表作为参数或将要使用的标记列表。同时存在这两种可能性会造成混淆。


如果你确实坚持使用键名作为值,你可以这样做

\keys_define:nn { mymodule } {
  decoration .tl_set:N = \l_mymodule_decoration_tl ,
  unknown    .code:n   =
   {
    \tl_set_rescan:NnV \l_mymodule_decoration_tl {} \l_keys_key_tl
   },
}

没有必要在 的第二个参数中指定任何类别代码更改\tl_set_rescan:NnV,因为当调用该函数时,标记将在正常类别代码制度下重新扫描,因此^是上标(类别 7),_是下标(类别 8)。

相关内容