
Es posible entregar un valor de clave booleana almacenado en una macro a un comando como
\edef\SomeKeyValue{true}%
\DummyCommand[DummyBooleanKey=\SomeKeyValue]%%%
donde DummyBooleanKey es una clave booleana definida mediante
\define@boolkey{SomeKeys}{DummyBooleanKey}[false]{%%%% etc.
Sin embargo, falla cuando intento compilar siguiendo 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}
¿Cómo es posible utilizar un literal true
o false
un valor como parámetro de valor clave? ¿Tengo que usarlo newtoks
para lograr esta característica?
Respuesta1
Implementos Keyvaltienden a ser muy cuidadososnopara expandir la entrada "fuera de servicio" y, por lo tanto, el problema que ve no es xkeyval
específico. Para claves que toman una lista fija de opciones, que incluye claves booleanas, este comportamiento deliberado significa que
\def\myvariable{some-valid-input}
\KeySettingCommand{valid-key-name=\myvariable}
no trabajará. Como resultado, debe almacenar tanto la clave como el valor y realizar una expansión previa:
\def\myvariable{valid-key-name=some-valid-input}
\expandafter\KeySettingCommand\expandafter{\myvariable}
o almacenar la construcción keyval completa:
\def\myvariable{\KeySettingCommand{valid-key-name=some-valid-input}}
\myvariable
Tenga en cuenta que el uso \edef
no hace ninguna diferencia aquí: lleva a cabo la expansión enpunto de definición, nopunto de uso.
Respuesta2
Cuando \setkeys
examina los pares clave-valor, lo haceNoexpansión; algo como
\begin{itemize}[label=\arabic*]
fracasaría trágicamente si se utilizara esto. Entonces, en su segundo caso, \SomeKeyValue
se pasa sin ninguna expansión como el valor de DummyBoolKey
y es ilegal, porque esta clave quiere o true
( false
o nada en absoluto, lo que sería equivalente a false
, según su definición).
Haciendo
\edef\SomeKeyValue{true}
no ayuda, porque esto es perfectamente equivalente a \def\SomeKeyValue{true}
, ya que ninguno de los tokens true
es expandible.
Si sus valores nunca contienen tokens simbólicos (tokens expandibles, en realidad), puede definirlos de manera diferente \DummyCommand
:
\makeatletter
\newcommand{\DummyCommand}[1][false]{%
\begingroup\protected@edef\x{\endgroup
\noexpand\setkeys{SomeKeys}{#1}}\x
% Do something useful inside this command...
}
\makeatother
Sin embargo, esto fallaría gravemente en los casos en que las opciones sean como las del itemize
ejemplo.