Boolescher Schlüsselwert in xkeyval schlägt fehl

Boolescher Schlüsselwert in xkeyval schlägt fehl

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 trueoder falseWert als Schlüsselwertparameter zu verwenden? Muss ich verwenden, newtoksum 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 \edefhier keinen Unterschied macht: Sie führt die Erweiterung durch beiDefinitionspunkt, nichtVerwendungszweck.

Antwort2

Bei \setkeysder 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 \SomeKeyValuewird also ohne Erweiterung als Wert für übergeben DummyBoolKeyund es ist unzulässig, da dieser Schlüssel entweder trueoder verlangt false(oder gar nichts, was falsenach 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 trueerweiterbar 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

itemizeIn Fällen, in denen die Optionen denen im Beispiel ähneln, würde dies jedoch schwerwiegende Probleme verursachen.

verwandte Informationen