
É 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 true
ou false
valor como parâmetro de valor-chave? Preciso usar newtoks
para 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 é xkeyval
especí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 \edef
não faz diferença aqui: ele realiza a expansão emponto de definição, nãoponto de uso.
Responder2
Quando \setkeys
examina 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 DummyBoolKey
e é ilegal, porque essa chave quer ou true
( false
ou 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 itemize
exemplo.