有没有办法将所有 l3keys 键重置为其初始值?

有没有办法将所有 l3keys 键重置为其初始值?

这是 latex3 的一个通用且有文档记录的功能,但我仍将提供 MWE 来说明问题,见下文。

假设我有一个使用 l3keys 键值接口的函数,并且我希望它在用户不提供密钥时具有合理的默认值。l3keys 提供了defaultinitial选项,其中default用于在提供密钥但没有值时使用,并initial用于初始化密钥。但是,此初始化只发生一次,即在定义密钥时。

\documentclass{standalone}
\begin{document}
\ExplSyntaxOn
\keys_define:nn { mykeys } {
  myvalue .int_set:N = \l_myvalue_int,
  myvalue .initial:n = 0
}
\cs_new:Nn \show_zero_or_myvalue:n {
  \keys_set:nn { mykeys } { #1 }
  \int_use:N \l_myvalue_int
}

show_zero_or_myvalue:n {}
show_zero_or_myvalue:n { myvalue=5 }
show_zero_or_myvalue:n {}
\ExplSyntaxOff
\end{document}

作为用户,由于函数定义隐藏在某个包中,我期望这会导致输出050。当然,一旦你读了 l3keys 文档,你就会知道它实际上会打印055,因为在第三次调用中没有设置密钥myvalue,所以它保留了之前的值。

然而,有些情况下这是不可取的。想象一下你用 TikZ 画了一幅画,代码

\tikz[color=black]{
% define some nodes
\draw[color=red] (a) -- (b);
\draw (b) -- (c);
}

导致出现两条红线。

显然,我可以手动重置后端的密钥,但由于我正在处理在多个地方读取的大量密钥,所以我目前的解决方法是在每一个致电\keys_set:nn { mykeys } { #1 },我发布了一份手册\keys_set:nn { mykeys } { ... },其中...有一长串的按键列表。

有没有更好的方法来做到这一点,要么内置到 l3keys 中,要么通过挂接到set_keys机制中?

不久前有人问过这个问题,但没有一个有明确的答案。由于 latex3 仍在开发中,我认为再次提问是合理的。

相关:如果没有内置方式,提出纳入此功能的标准机制是什么?显然,我不是唯一一个希望看到这样的事情的人。

答案1

针对此问题有两种策略。

其中一个是 Ti 也采用的Z,即分组。

\documentclass{article}
\begin{document}
\ExplSyntaxOn
\keys_define:nn { mykeys } {
  myvalue .int_set:N = \l_myvalue_int,
  myvalue .initial:n = 0
}
\cs_new_protected:Nn \show_zero_or_myvalue:n {
  \group_begin:
  \keys_set:nn { mykeys } { #1 }
  \int_use:N \l_myvalue_int
  \group_end:
}

\show_zero_or_myvalue:n {}
\show_zero_or_myvalue:n { myvalue=5 }
\show_zero_or_myvalue:n {}
\ExplSyntaxOff
\end{document}

由于按键的设置是在本地完成的,因此组结束后将恢复初始值。

第二种策略:保留一份需要重置的密钥列表。

\documentclass{article}
\begin{document}
\ExplSyntaxOn
\keys_define:nn { mykeys } {
  myvalue .int_set:N = \l_myvalue_int,
}
\cs_new_protected:Nn \show_zero_or_myvalue:n {
  \keys_set:nn { mykeys } { myvalue=0,#1 }
  \int_use:N \l_myvalue_int
}

\show_zero_or_myvalue:n {}
\show_zero_or_myvalue:n { myvalue=5 }
\show_zero_or_myvalue:n {}
\ExplSyntaxOff
\end{document}

如果有多个键需要重置,你可以定义一个简写

\cs_new_protected:Nn \betta_reset: {
  \keys_set:nn { mykeys } { myvalue=0 }
}

并在函数\betta_reset:之前添加。\keys_set:nn\show_zero_or_myvalue:n

答案2

另一种选择expl3@egreg 展示的可能性是将标准设置预编译为标记列表。这(原则上)与

第二种策略:保留一份需要重置的密钥列表。

但速度更快。

\documentclass{standalone}
\begin{document}
\ExplSyntaxOn
\tl_new:N \l_bettageorge_defaults_tl
\keys_define:nn { mykeys } {
  myvalue .int_set:N = \l_myvalue_int,
  myvalue .initial:n = 0
}
\keys_precompile:nnN { mykeys } { myvalue=0 } \l_bettageorge_defaults_tl
\cs_new_protected:Nn \show_zero_or_myvalue:n {
  \l_bettageorge_defaults_tl
  \keys_set:nn { mykeys } { #1 }
  \int_use:N \l_myvalue_int
}

\show_zero_or_myvalue:n {}
\show_zero_or_myvalue:n { myvalue=5 }
\show_zero_or_myvalue:n {}
\ExplSyntaxOff
\end{document}

相关内容