在 expl3 中定义包选项的正确方法是什么?

在 expl3 中定义包选项的正确方法是什么?

对于编写包来说,定义包选项通常很重要。由于我正在编写的包是在 expl3 中,我想知道是否有一种定义键值包选项的 l3ish 方式。

我知道它是l3keys其中的一部分expl3,但据我所知,它不会直接评估给予包的选项,而是必须使用包装器宏来调用(可以自动完成吗?)。

从源代码来看,fontspec它似乎利用了标准 LaTeX2e 的选项处理功能。由此得出结论,我会将其用于kvoptions键值接口,即使对于 l3,尽管它会创建 l2 构造,例如\newifs。

另一方面,它siunitx使用(文档不全的)包l3keys2e(@DavidCarlisle 我不想进行逆向工程)和l3keyskv-option-processing 的语法。但这是一种安全或推荐的方法吗?l3keys无论如何,我打算在我的包中使用。

为了形象化我想要的东西(典型的无意义的MWE):

\documentclass{article}
\usepackage[
    quack,% should evaluate to quack=true
    font=sffamily,% should set a font token list to sffamily
    logo=false,% should set a boolean to false
    size=3% should set an integer
]{mypack}
\begin{document}
    \quackfig
\end{document}

mypack.sty

\RequirePackage{expl3,xparse}
\ProvidesExplPackage{mypack}{2017-05-26}{v1.0}{Quack}

\RequirePackage{graphicx}

\bool_new:N \l__mypack_optkeys_quack_bool
\bool_set_true:N \l__mypack_optkeys_quack_bool
\tl_new:N \l__mypack_optkeys_font_tl
\bool_new:N \l__mypack_optkeys_logo_bool
\int_new:N \l__mypack_optkeys_size_int
\int_set:Nn \l__mypack_optkeys_size_int {10}

% Process options here
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions\relax

\NewDocumentCommand{\quackfig}{}{
    \begin{figure}[htb]
    \bool_if:NT \l__mypack_optkeys_quack_bool {
        \tl_if_eq:nnT {\l__mypack_optkeys_font} {sffamily} {\sffamily}
        Quack!
    }
    \bool_if:NT \l__mypack_optkeys_logo_bool {
        \includegraphics[height=\l__mypack_optkeys_size_int cm]{example-image}
    }
    \end{figure}
}

问题:使用 l3 进行 kv-option 处理的推荐方法是什么以及mypack.sty看起来如何?

答案1

不管您使用什么密钥处理器,使用包的 keyval 选项都包含两个不同的部分:

  • 定义键
  • 使用 keyval 解析器处理包选项列表

这里需要理解的关键是,keyval 包选项只是在处理选项列表时定义的键。

从 2022-06-01 开始,LaTeX 内核内置了对 keyval 选项处理的支持;在此之前, 提供了非常类似的支持l3keys2e。无论哪种情况,该方法都用于l3keys定义选项。这是通过定义键来完成的然后处理选项

\providecommand \IfFormatAtLeastTF { \@ifl@t@r \fmtversion }
\ExplSyntaxOn
\keys_define:nn { mypkg }
  { pkgopt .tl_set:N = \l__mypkg_pkgopt_tl }
\IfFormatAtLeastTF { 2022-06-01 }
  { \ProcessKeyOptions }
  {
    \RequirePackage { l3keys2e }
    \ProcessKeysOptions { mypkg }
  }
\ProcessKeysOptions { mypkg } % Parses the option list
\keys_define:nn { mypkg }
  { notpkgopt .tl_set:N = \l__mypkg_notopt_tl }

上述代码将为包定义一个 keyval 选项:pkgopt,它将给定的值存储在 中\l__mypkg_pkgopt_tl。第二个键notpkgopt定义为因此,keyval 处理不可用\ProcessKey(s)Options:因此不是套餐选项

如果希望“预先”定义所有键,但只提供一些键作为选项,通常的方法是使用多条路径,比如mypkg / pkgoptsmypkg / otheropts

这种方法的一个常见用途是禁用严格仅在加载时起作用的选项。该选项自 2022-06-01 起内置于内核

\keys_define:nn { mypkg }
  {
    pkgopt .tl_set:N = \l__mypkg_pkgopt_tl ,
    pkgopt .usage:n. = load-only
  }

正如评论中指出的那样,通常最好使用设置命令(\mypkgsetup),它可以用于加载,除非选项直接影响包加载设置,ETC。

相关内容