El valor de clave booleana en xkeyval falla

El valor de clave booleana en xkeyval falla

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 trueo falseun valor como parámetro de valor clave? ¿Tengo que usarlo newtokspara 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 xkeyvalespecí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 \edefno hace ninguna diferencia aquí: lleva a cabo la expansión enpunto de definición, nopunto de uso.

Respuesta2

Cuando \setkeysexamina 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, \SomeKeyValuese pasa sin ninguna expansión como el valor de DummyBoolKeyy es ilegal, porque esta clave quiere o true( falseo 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 truees 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 itemizeejemplo.

información relacionada