在增强和构建其他人提供的包的密钥时的最佳做法是什么

在增强和构建其他人提供的包的密钥时的最佳做法是什么

情况是,我正在开发自己的命令和环境,这些命令和环境基于另一个包提供的命令和环境:为了方便讨论,我们称之为其他包裹第一个模块。 这第一个模块为我提供了一个可以使用键值设置参数的环境:

\begin{<first-module-env>}[<key-values>]
    .... various content .....
\end{<first-module-env>}

我希望在此环境的基础上进一步补充早期软件包允许的键值范围。

如果第一个模块为我提供了一个直接处理密钥的命令,那么事情就会相当简单。例如,如果我得到类似这样的命令,

\firstmodulekeysetter{<key-values>}

然后我可以构建类似的东西

\keys_define:nn { acellett/augmentation } { ..... }
\NewDocumentEnvironment{acellett}{ O{} }
  {  \keys_set_known:nnN { acellett/augmentation } { #1 } \l_tmpa_clist
     \exp_args:NV \firstmodulekeysetter \l_tmpa_clist
     .... }
   { .... }

第一个模块可能不太方便用户使用。它可能只允许我通过环境的可选参数来访问密钥。

下面是一个示例,显示了我如何处理增强允许的键值第一个模块

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
%----------------------------------------------------------------------
%% module "first_module"
\tl_new:N \l_first_module_a_tl
\tl_new:N \l_first_module_b_tl

\keys_define:nn { first/module/set }
  {
    a .code:n = { \tl_set:Nn \l_first_module_a_tl { #1 } },
    b .code:n = { \tl_set:Nn \l_first_module_b_tl { #1 } },
  }

\NewDocumentEnvironment{firstenv}{ O{} }
  { 
    \par
    \keys_set:nn { first/module/set } { #1 }
    \begin{tabular}{rl}
    a & \l_first_module_a_tl \\
    b & \l_first_module_b_tl \\
  }
  {
    \end{tabular}\par
  }
%----------------------------------------------------------------------
%% module "augmented_module"
\tl_new:N \l_ae_augmented_module_x_tl
\tl_new:N \l_ae_augmented_module_y_tl

\keys_define:nn { ae/augmented/module/set }
  {
    x .code:n = { \tl_set:Nn \l_ae_augmented_module_x_tl { #1 } },
    y .code:n = { \tl_set:Nn \l_ae_augmented_module_y_tl { #1 } },
  }

\cs_new:Npn \__ae_augmented_calling_first:n #1 
  {
    \begin{firstenv}[#1]
  }

\NewDocumentEnvironment{augmentedenv}{ O{} }
  {
    \keys_set_known:nnN { ae/augmented/module/set }{ #1 } \l_tmpa_clist
    \exp_args:NV \__ae_augmented_calling_first:n \l_tmpa_clist
    x & \l_ae_augmented_module_x_tl \\
    y & \l_ae_augmented_module_y_tl \\
  }
  {
    \end{firstenv}
  }
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}

  \textbf{First Environment}
  \begin{firstenv}[a={A},b={is for Apple}]
  \end{firstenv}

  \textbf{Augmented Environment}
  \begin{augmentedenv}[a={B},b={is for Banana},x={X},y={is for Xylophone  }]

  \end{augmentedenv}

\end{document}

之前提到过\exp_args不鼓励使用。有没有更好的方法?我是否需要创建函数\__ae_augmented_calling_first来允许我传递\l_tmpa_clist

答案1

我想说这是扩充选项集的正确方法,甚至可以改变已经存在的键的行为(不是在示例中,但我想你明白了)。

我对代码做了一些修改,使用了正确定义键的方式,这.code:n应该是最后的手段。

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
%----------------------------------------------------------------------
%% module "first_module"

\keys_define:nn { first/module/set }
  {
    a .tl_set:N = \l_first_module_a_tl,
    b .tl_set:N = \l_first_module_b_tl,
  }

\NewDocumentEnvironment{firstenv}{ O{} }
  { 
    \par
    \keys_set:nn { first/module/set } { #1 }
    \begin{tabular}{rl}
    a & \l_first_module_a_tl \\
    b & \l_first_module_b_tl \\
  }
  {
    \end{tabular}\par
  }
%----------------------------------------------------------------------
%% module "augmented_module"
\clist_new:N \l_ae_augmented_options_clist

\keys_define:nn { ae/augmented/module/set }
  {
    x .tl_set:N = \l_ae_augmented_module_x_tl,
    y .tl_set:N = \l_ae_augmented_module_y_tl,
  }

\cs_new:Npn \__ae_augmented_calling_first:n #1 
  {
    \firstenv[#1]
  }
\cs_generate_variant:Nn \__ae_augmented_calling_first:n { V }

\NewDocumentEnvironment{augmentedenv}{ O{} }
  {
    \keys_set_known:nnN { ae/augmented/module/set }{ #1 } \l_ae_augmented_options_clist
    \__ae_augmented_calling_first:V \l_ae_augmented_options_clist
    x & \l_ae_augmented_module_x_tl \\
    y & \l_ae_augmented_module_y_tl \\
  }
  {
    \endfirstenv
  }
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}

  \textbf{First Environment}
  \begin{firstenv}[a={A},b={is for Apple}]
  \end{firstenv}

  \textbf{Augmented Environment}
  \begin{augmentedenv}[a={B},b={is for Banana},x={X},y={is for Xylophone  }]

  \end{augmentedenv}

\end{document}

请注意,尽管结果完全相同,但\__ae_augmented_calling_first:V最好使用变体定义:函数名称更清楚地表达了预期参数的性质。\exp_args:NV

使用\firstenv\endfirstenv避免了新级别的分组(如果augmentedenv没有正确关闭,则会有更好的错误消息。

在此处输入图片描述

相关内容