4

It is possible to hand over a boolean key value stored in a macro to a command such as

\edef\SomeKeyValue{true}%

\DummyCommand[DummyBooleanKey=\SomeKeyValue]%%% 

where DummyBooleanKey is a boolean key defined via

\define@boolkey{SomeKeys}{DummyBooleanKey}[false]{%%%% etc.

However, it fails when I try to compile following 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}

How is it possible to use a literal true or false value as key value parameter? Do I have to use newtoks in order to achieve this feature?

7

Keyval implements tend to be very careful not to expand input 'out of order', and thus the problem you see is not xkeyval-specific. For keys which take a fixed list of choices, which includes boolean keys, this deliberate behaviour means that

\def\myvariable{some-valid-input}
\KeySettingCommand{valid-key-name=\myvariable}

will not work. As a result, you need to either store both the key and value and pre-expand:

\def\myvariable{valid-key-name=some-valid-input}
\expandafter\KeySettingCommand\expandafter{\myvariable}

or store the entire keyval construct:

\def\myvariable{\KeySettingCommand{valid-key-name=some-valid-input}}
\myvariable

Note that using \edef makes no difference here: it carries out expansion at point of definition, not point of use.

|improve this answer|||||
7

When \setkeys examines the key-value pairs it does no expansion; something like

\begin{itemize}[label=\arabic*]

would tragically fail if this was used. So, in your second case, \SomeKeyValue is passed without any expansion as the value for DummyBoolKey and it's illegal, because this key wants either true or false (or nothing at all, which would be equivalent to false, by your definition).

Doing

\edef\SomeKeyValue{true}

doesn't help, because this is perfectly equivalent to \def\SomeKeyValue{true}, since none of the tokens in true is expandable.

If your values never contain symbolic tokens (expandable tokens, actually), you can define differently \DummyCommand:

\makeatletter
\newcommand{\DummyCommand}[1][false]{%
  \begingroup\protected@edef\x{\endgroup
    \noexpand\setkeys{SomeKeys}{#1}}\x
  % Do something useful inside this command...
}
\makeatother

However, this would break badly in cases the options are like those in the itemize example.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy