
可以將儲存在巨集中的布林鍵值移交給命令,例如
\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
。