
Es ist möglich, einen in einem Makro gespeicherten booleschen Schlüsselwert an einen Befehl zu übergeben, wie zum Beispiel
\edef\SomeKeyValue{true}%
\DummyCommand[DummyBooleanKey=\SomeKeyValue]%%%
wobei DummyBooleanKey ein Boolescher Schlüssel ist, der definiert ist über
\define@boolkey{SomeKeys}{DummyBooleanKey}[false]{%%%% etc.
Es schlägt jedoch fehl, wenn ich versuche, folgende MNWE zu kompilieren
\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}
Wie ist es möglich, einen Literalwert true
oder false
Wert als Schlüsselwertparameter zu verwenden? Muss ich verwenden, newtoks
um diese Funktion zu erreichen?
Antwort1
Keyval-Geräteneigen dazu, sehr vorsichtig zu seinnichtum die Eingabe „außerhalb der Reihenfolge“ zu erweitern, und daher ist das Problem, das Sie sehen, nicht xkeyval
-spezifisch. Für Schlüssel, die eine feste Auswahlliste annehmen, die boolesche Schlüssel enthält, bedeutet dieses absichtliche Verhalten, dass
\def\myvariable{some-valid-input}
\KeySettingCommand{valid-key-name=\myvariable}
wird nicht funktionieren. Daher müssen Sie entweder sowohl den Schlüssel als auch den Wert speichern und vorab erweitern:
\def\myvariable{valid-key-name=some-valid-input}
\expandafter\KeySettingCommand\expandafter{\myvariable}
oder speichern Sie die gesamte Keyval-Konstruktion:
\def\myvariable{\KeySettingCommand{valid-key-name=some-valid-input}}
\myvariable
Beachten Sie, dass die Verwendung \edef
hier keinen Unterschied macht: Sie führt die Erweiterung durch beiDefinitionspunkt, nichtVerwendungszweck.
Antwort2
Bei \setkeys
der Untersuchung der Schlüssel-Wert-Paare wirdNEINErweiterung; so etwas wie
\begin{itemize}[label=\arabic*]
würde tragischerweise scheitern, wenn dies verwendet würde. In Ihrem zweiten Fall \SomeKeyValue
wird also ohne Erweiterung als Wert für übergeben DummyBoolKey
und es ist unzulässig, da dieser Schlüssel entweder true
oder verlangt false
(oder gar nichts, was false
nach Ihrer Definition gleichbedeutend mit wäre).
Tun
\edef\SomeKeyValue{true}
hilft nicht, da dies vollkommen gleichwertig zu ist \def\SomeKeyValue{true}
, da keines der Token in true
erweiterbar ist.
Wenn Ihre Werte niemals symbolische Token (eigentlich erweiterbare Token) enthalten, können Sie Folgendes anders definieren \DummyCommand
:
\makeatletter
\newcommand{\DummyCommand}[1][false]{%
\begingroup\protected@edef\x{\endgroup
\noexpand\setkeys{SomeKeys}{#1}}\x
% Do something useful inside this command...
}
\makeatother
itemize
In Fällen, in denen die Optionen denen im Beispiel ähneln, würde dies jedoch schwerwiegende Probleme verursachen.