O valor da chave booleana em xkeyval falha

O valor da chave booleana em xkeyval falha

É possível entregar um valor de chave booleana armazenado em uma macro para um comando como

\edef\SomeKeyValue{true}%

\DummyCommand[DummyBooleanKey=\SomeKeyValue]%%% 

onde DummyBooleanKey é uma chave booleana definida via

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

No entanto, falha quando tento compilar seguindo 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}

Como é possível usar um literal trueou falsevalor como parâmetro de valor-chave? Preciso usar newtokspara obter esse recurso?

Responder1

Implementos Keyvaltendem a ser muito cuidadososnãopara expandir a entrada 'fora de ordem' e, portanto, o problema que você vê não é xkeyvalespecífico. Para chaves que utilizam uma lista fixa de opções, que inclui chaves booleanas, esse comportamento deliberado significa que

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

não funciona. Como resultado, você precisa armazenar a chave e o valor e pré-expandir:

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

ou armazene toda a construção keyval:

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

Observe que using \edefnão faz diferença aqui: ele realiza a expansão emponto de definição, nãoponto de uso.

Responder2

Quando \setkeysexamina os pares de valores-chave, ele faznãoexpansão; algo como

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

falharia tragicamente se isso fosse usado. Então, no seu segundo caso, \SomeKeyValueé passado sem nenhuma expansão como valor para DummyBoolKeye é ilegal, porque essa chave quer ou true( falseou nada, o que seria equivalente a false, pela sua definição).

Fazendo

\edef\SomeKeyValue{true}

não ajuda, porque é perfeitamente equivalente a \def\SomeKeyValue{true}, já que nenhum dos tokens trueé expansível.

Se seus valores nunca contiverem tokens simbólicos (tokens expansíveis, na verdade), você poderá definir de forma diferente \DummyCommand:

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

No entanto, isso quebraria gravemente nos casos em que as opções fossem como as do itemizeexemplo.

informação relacionada