为了帮助我学习,l3keys
我创建了两个小演示。
第一个用于l3keys
命令,据我所知,它似乎工作正常。
% !TEX program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\ExplSyntaxOn
\prop_gput:Nnn \g_msg_module_type_prop { foo }{ Command }
\msg_new:nnnn { foo }{ unknownoption }
{ Unknown~option. }{ Try~again~but~with~a~known~option. }
\tl_new:N \l__foo_thing_tl
\tl_new:N \l__foo_towhom_tl
\keys_define:nn { foo }
{
thing .tl_set:N = \l__foo_thing_tl ,
thing .default:n = door ,
thing .initial:n = ice ,
towhom .tl_set:N = \l__foo_towhom_tl ,
towhom .default:n = Dana ,
towhom .initial:n = Ina ,
unknown .code:n = \msg_fatal:nn { foo }{ unknownoption }
}
\cs_new_protected:Npn \__foo_foo:nn #1#2
{
\group_begin:
\keys_set:nn { foo } { #1 }
#2~\l__foo_thing_tl \c_space_tl to~\l__foo_towhom_tl.
\group_end:
}
\DeclareDocumentCommand{ \foosetup } { m }
{ \keys_set:nn { foo } { #1 } }
\DeclareDocumentCommand{ \foo } { O{} m }
{
\__foo_foo:nn { #1 } { #2 }
}
\ExplSyntaxOff
\begin{document}
This demo shows how to use \texttt{l3keys} for a command.
\foo{Give the} \par
\foo[thing]{Give the} \par
\foo[thing,towhom]{Give the} \par
\foo[thing=car,towhom=Tom]{Give the} \par
\foosetup{thing=apple}
\foo{Give the} \par
\foo[towhom]{Give the} \par
\end{document}
输出如下:
第二个用于l3keys
包,似乎工作正常,除了密钥无法正确初始化的情况。
% !TEX program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\begin{filecontents}[overwrite,noheader]{foopkg.sty}
\ProvidesExplPackage{foopkg}{}{}{}
\msg_new:nnnn { foopkg }{ unknownoption }
{ Unknown~option. }{ Try~again~but~with~a~known~option. }
\tl_new:N \l__foopkg_thing_tl
\tl_new:N \l__foopkg_towhom_tl
\keys_define:nn { foopkg }
{
thing .tl_set:N = \l__foopkg_thing_tl ,
thing .default:n = door ,
thing .initial:n = ice ,
towhom .tl_set:N = \l__foopkg_towhom_tl ,
towhom .default:n = Dana ,
towhom .initial:n = Ina ,
unknown .code:n = \msg_fatal:nn { foopkg }{ unknownoption }
}
\ProcessKeyOptions[foopkg]
\DeclareDocumentCommand{ \foosetup } { m }
{ \keys_set:nn { foopkg } { #1 } }
\cs_new_protected:Npn \__foopkg_foo:nn #1#2
{
\group_begin:
\keys_set:nn { foopkg } { #1 }
#2~\l__foopkg_thing_tl \c_space_tl to~\l__foopkg_towhom_tl.
\group_end:
}
\DeclareDocumentCommand{ \foo } { O{} m }
{
\__foopkg_foo:nn { #1 } { #2 }
}
\end{filecontents}
\documentclass{article}
%\usepackage[thing=vase,towhom=Val]{foopkg}
\usepackage{foopkg}
\begin{document}
This demo shows how to use \texttt{l3keys} for a package.
\foo{Give the} \par
\foosetup{thing=door}
\foo{Give the} \par
\foosetup{thing,towhom}
\foo{Give the} \par
\foosetup{thing=car,towhom=Tom}
\foo{Give the} \par
\foosetup{thing=apple}
\foo{Give the} \par
\foosetup{towhom}
\foo{Give the} \par
\end{document}
输出如下:
在第二个演示中,第二次出现Tom
应该是理想情况,Ina
但我不明白为什么密钥没有重置。这个问题似乎相关,但我认为我已经在使用那里的解决方案,要么我做错了,要么我没有理解一些简单的事情。这两个演示能给出相同的结果吗?
答案1
属性initial:n
是变量被设置为\keys_define:nn
是执行IE相当于应用\keys_set:nn
。因此它只应用一次。如果要在 开始之前重置键,\keys_set:nn
如果键未设置在组中,请将键添加到列表的开头:
\keys_set:nn { foopkg } { towhom = Ina , #1 }
答案2
原因在约瑟夫的回答:.initial:n
仅设置一次密钥。
您不必每次都向列表中添加键并引入解析开销,只需解析一次 key=value 对,并将结果编译成用于重置键的标记列表:
% !TEX program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\begin{filecontents}[overwrite,noheader]{foopkg.sty}
\ProvidesExplPackage{foopkg}{}{}{}
\msg_new:nnnn { foopkg }{ unknownoption }
{ Unknown~option. }{ Try~again~but~with~a~known~option. }
\tl_new:N \l__foopkg_thing_tl
\tl_new:N \l__foopkg_towhom_tl
\tl_new:N \l__foopkg_reset_defaults_tl
\keys_define:nn { foopkg }
{
thing .tl_set:N = \l__foopkg_thing_tl ,
thing .default:n = door ,
thing .initial:n = ice ,
towhom .tl_set:N = \l__foopkg_towhom_tl ,
towhom .default:n = Dana ,
towhom .initial:n = Ina ,
unknown .code:n = \msg_fatal:nn { foopkg }{ unknownoption }
}
\ProcessKeyOptions[foopkg]
\keys_precompile:nnN { foopkg } { towhom = Ina } \l__foopkg_reset_defaults_tl
\DeclareDocumentCommand{ \foosetup } { m }
{
\l__foopkg_reset_defaults_tl
\keys_set:nn { foopkg } { #1 }
}
\cs_new_protected:Npn \__foopkg_foo:nn #1#2
{
\group_begin:
\keys_set:nn { foopkg } { #1 }
#2~\l__foopkg_thing_tl \c_space_tl to~\l__foopkg_towhom_tl.
\group_end:
}
\DeclareDocumentCommand{ \foo } { O{} m }
{
\__foopkg_foo:nn { #1 } { #2 }
}
\end{filecontents}
\documentclass{article}
%\usepackage[thing=vase,towhom=Val]{foopkg}
\usepackage{foopkg}
\begin{document}
This demo shows how to use \texttt{l3keys} for a package.
\foo{Give the} \par
\foosetup{thing=door}
\foo{Give the} \par
\foosetup{thing,towhom}
\foo{Give the} \par
\foosetup{thing=car,towhom=Tom}
\foo{Give the} \par
\foosetup{thing=apple}
\foo{Give the} \par
\foosetup{towhom}
\foo{Give the} \par
\end{document}
一个小小的变化,我认为这比使用tl
重置值更正确:
% !TEX program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\begin{filecontents}[overwrite,noheader]{foopkg.sty}
\ProvidesExplPackage{foopkg}{}{}{}
\msg_new:nnnn { foopkg }{ unknownoption }
{ Unknown~option. }{ Try~again~but~with~a~known~option. }
\tl_new:N \l__foopkg_thing_tl
\tl_new:N \l__foopkg_towhom_tl
\keys_define:nn { foopkg }
{
thing .tl_set:N = \l__foopkg_thing_tl ,
thing .default:n = door ,
thing .initial:n = ice ,
towhom .tl_set:N = \l__foopkg_towhom_tl ,
towhom .default:n = Dana ,
towhom .initial:n = Ina ,
unknown .code:n = \msg_fatal:nn { foopkg }{ unknownoption }
}
\ProcessKeyOptions[foopkg]
\group_begin:
\keys_precompile:nnN { foopkg } { towhom = Ina } \l_tmpa_tl
\exp_args:NNV \cs_new_protected:Npn \__foopkg_reset_defaults: \l_tmpa_tl
\group_end:
\DeclareDocumentCommand{ \foosetup } { m }
{
\__foopkg_reset_defaults:
\keys_set:nn { foopkg } { #1 }
}
\cs_new_protected:Npn \__foopkg_foo:nn #1#2
{
\group_begin:
\keys_set:nn { foopkg } { #1 }
#2~\l__foopkg_thing_tl \c_space_tl to~\l__foopkg_towhom_tl.
\group_end:
}
\DeclareDocumentCommand{ \foo } { O{} m }
{
\__foopkg_foo:nn { #1 } { #2 }
}
\end{filecontents}
\documentclass{article}
%\usepackage[thing=vase,towhom=Val]{foopkg}
\usepackage{foopkg}
\begin{document}
This demo shows how to use \texttt{l3keys} for a package.
\foo{Give the} \par
\foosetup{thing=door}
\foo{Give the} \par
\foosetup{thing,towhom}
\foo{Give the} \par
\foosetup{thing=car,towhom=Tom}
\foo{Give the} \par
\foosetup{thing=apple}
\foo{Give the} \par
\foosetup{towhom}
\foo{Give the} \par
\end{document}