我正在编写一个小包,并用它kvoptions
来解析传递给它的 key-val 选项:
\RequirePackage{kvoptions}
\SetupKeyvalOptions{family=my,prefix=my@}
\DeclareStringOption[bar]{foo}
\DeclareStringOption[5.75]{len}
...
\ProcessKeyvalOptions*
此时(\ProcessKeyvalOptions*
调用后),我想获取已定义的所有键的列表,并在循环中对它们执行某些操作,例如将字符串“yes”附加到所有键。我知道我可以手动添加\edef\my@<option>{\my@<option> yes}
每个键,但我想自动完成。
我所说的“定义的键”是指使用声明的所有键\Declare*Option
,而不仅仅是传递给包的键——但我也很感激有关如何执行后者的意见。
我简单看了一下kvoptions.sty
,它定义并使用了\KVO@GetClassOptionsList
,但调用后似乎为空\ProcessKeyvalOptions*
。有,\KVO@classoptionslist
但那是类的选项。我可以在 kvoptions 代码中看到 @for 循环...我可能应该花一些时间研究一下。任何专家的帮助都将不胜感激。
答案1
在实现层面,键只是以特定名称模式存储的宏。因此,键查找就是检查名称是否已定义的问题。TeX 没有提供“列出所有已定义宏,其名称与模式 XXX 匹配”的方法,因此如果需要可以以这种方式查询的键列表,则必须在宏级别进行。
由于您自己定义键,因此最明显的方法就是手动创建一个列表
\newcommand*\my@options@list{foo,bar,...}
并使用此列表检查(稍后)已定义的内容。可以通过创建助手来自动执行此操作,例如
\newcommand*\my@options@list{}
\newcommand\my@declare@option[3][]{%
\ifx\my@options@list\@empty
\def\my@options@list{#2}%
\else
\edef\my@options@list{\my@options@list,#2}%
\fi
#3[#1]{#2}%
}
\my@declare@option[bar]{foo}\DeclareStringOption
(此处的语法可以设置为遵循\DeclareStringOption
,ETC。,直接,只需多花点力气。)
跟踪已设置哪些选项是一项完全独立的任务。最明显的方法是向密钥实现添加适当的代码。可以通过使用\newcommand
而不是系统创建密钥来手动设置所有内容kvoptions
,或者我们可以利用我们知道实现密钥的宏的事实。例如,对于问题中的设置,密钥宏是\KV@my@foo
和\KV@my@bar
,因此我们可以用它们进行修补etoolbox
:
\SetupKeyvalOptions{family=my,prefix=my@}
\DeclareStringOption[bar]{foo}
\DeclareStringOption[5.75]{len}
\newcommand*\my@given@options{}
\RequirePackage{etoolbox}
\pretocmd\KV@my@foo{\edef\my@given@options{\my@given@options,#1}}{}{\ERROR}
或者我们可以手动完成
\newcommand\KV@my@len[1]{%
\edef\my@given@options{\my@given@options,#1}%
\def\my@foo{#1}%
}