![xkeyval 中的布尔键值失败](https://linux22.com/image/281688/xkeyval%20%E4%B8%AD%E7%9A%84%E5%B8%83%E5%B0%94%E9%94%AE%E5%80%BC%E5%A4%B1%E8%B4%A5.png)
可以将存储在宏中的布尔键值交给以下命令:
\edef\SomeKeyValue{true}%
\DummyCommand[DummyBooleanKey=\SomeKeyValue]%%%
其中 DummyBooleanKey 是通过以下方式定义的布尔键
\define@boolkey{SomeKeys}{DummyBooleanKey}[false]{%%%% etc.
然而,当我尝试按照 MNWE 进行编译时,它失败了
\documentclass{minimal}
\usepackage{xkeyval}
\usepackage{etoolbox}
\makeatletter
\define@boolkey{SomeKeys}{DummyBoolKey}[false]{%
\ifKV@SomeKeys@DummyBoolKey%
\typeout{true}%
\else%
\typeout{false}%
\fi%
}%
% Key Family is called SomeKeys
% Use a fake command for testing purposes
\providecommand{\DummyCommand}[1][false]{%
\setkeys{SomeKeys}{#1}%
% Do something useful inside this command...
}%
\edef\SomeKeyValue{true}%
\begin{document}
% Works
\DummyCommand[DummyBoolKey=true]%
% Does not work!
\DummyCommand[DummyBoolKey={\SomeKeyValue}]%
\end{document}
如何使用文字true
或false
值作为键值参数?我必须使用newtoks
才能实现此功能吗?
答案1
Keyval 工具往往非常小心不是以“无序”方式扩展输入,因此您看到的问题不是xkeyval
- 特定的。对于采用固定选择列表的键(包括布尔键),这种故意的行为意味着
\def\myvariable{some-valid-input}
\KeySettingCommand{valid-key-name=\myvariable}
将不起作用。因此,您需要存储键和值并预扩展:
\def\myvariable{valid-key-name=some-valid-input}
\expandafter\KeySettingCommand\expandafter{\myvariable}
或者存储整个 keyval 构造:
\def\myvariable{\KeySettingCommand{valid-key-name=some-valid-input}}
\myvariable
请注意,使用\edef
这里没有区别:它在定义点, 不是使用点。
答案2
当\setkeys
检查键值对时不扩展;类似于
\begin{itemize}[label=\arabic*]
如果使用这个,就会悲剧性地失败。所以,在你的第二种情况下,\SomeKeyValue
不经过任何扩展就作为 的值传递DummyBoolKey
,这是非法的,因为这个键需要 或true
(false
或者什么都不需要,按照你的定义,这相当于false
)。
正在做
\edef\SomeKeyValue{true}
没有帮助,因为这完全等同于\def\SomeKeyValue{true}
,因为中的标记都true
不可扩展。
如果您的值从不包含符号标记(实际上是可扩展标记),您可以进行不同的定义\DummyCommand
:
\makeatletter
\newcommand{\DummyCommand}[1][false]{%
\begingroup\protected@edef\x{\endgroup
\noexpand\setkeys{SomeKeys}{#1}}\x
% Do something useful inside this command...
}
\makeatother
然而,如果选项与示例中的类似,则会出现严重问题itemize
。