
No soy un especialista en TeX/LaTeX, recientemente escribí un paquete sobre 'problemas' y 'soluciones' que pretende mostrarse al final del documento, sin embargo, no se limita a esos propósitos. Para lograr ese comportamiento, entre otras características, utilicé el xkeyval
paquete, con muchas macros de claves y también claves booleanas.
Quiero proporcionar una versión mejor y deshacerme de docenas de líneas de definición de macros clave y definiciones de claves booleanas que básicamente se parecen pero solo configuran algunas banderas, reemplazando la tediosa entrada de código LaTeX por algunos comandos cortos como
\GenerateBoolKey[true]{SomeKeys}{DummyBoolKey}
Esto debería definir la clave booleana DummyBoolKey
perteneciente a la familia SomeKeys
como si se hubiera escrito
\define@boolkey{SomeKeys}{DummyBoolKey}[true]{%
\ifKV@SomeKeys@DummyBoolKey%
%Do something if true%
\else%
%Do something different if false%
\fi%
}%
La xkeyval
documentación (versión 2.6b) dice en la página 7 que hay definida una macro \ifKV@fam@key
como\newif
Bueno, fallé al escribir el comando anterior y al usar la \ifKV
macro. Aquí hay un ejemplo mínimo (que no) funciona, que falla durante la compilación y muestra un mensaje de error.
! Too many }'s.
Aquí hay un ejemplo mínimo.
\documentclass{minimal}
\usepackage{xkeyval}
\makeatletter
\providecommand{\GenerateBoolKey}[3][false]{%
\define@boolkey{#2}{#3}[#1]{%
\csname ifKV@#2@#3 \endcsname%
\typeout{true}% % Do something if true
\else%
\typeout{false}% % Do something different if false
\fi%
}% End of \define@boolkey
}% End of \providecommand
\makeatother
% 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...
}%
\begin{document}
\GenerateBoolKey{SomeKeys}{DummyBoolKey}%
\DummyCommand[DummyBoolKey=true]%
\end{document}
¿Cómo puedo proporcionar el \newif
comando sobre la marcha con mi código 'contenedor' para proporcionar la \ifKV
prueba booleana?
Respuesta1
Esto parece un problema con el anidamiento condicional. Me parece que el mejor enfoque aquí es forzar la expansión del nombre "por adelantado" para que tenga una definición idéntica a la que obtendría "a mano".
\documentclass{article}
\usepackage{xkeyval}
\makeatletter
\providecommand{\GenerateBoolKey}[3][false]{%
\begingroup
\edef\x{\endgroup
\noexpand\define@boolkey{#2}{#3}[#1]{%
\expandafter\noexpand\csname ifKV@#2@#3\endcsname%
\noexpand\typeout{true}% % Do something if true
\noexpand\else%
\noexpand\typeout{false}% % Do something different if false
\noexpand\fi%
}% End of \define@boolkey
}% End of defintion of \x
\x
}% End of \providecommand
\makeatother
% 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...
}%
\begin{document}
\GenerateBoolKey{SomeKeys}{DummyBoolKey}%
\DummyCommand[DummyBoolKey=true]%
\end{document}
Esto funciona definiendo \x
dentro de un grupo que se cierra cuandousar \x
, y que fuerza la expansión del nombre sin expandir nada más (de ahí muchas \noexpand
s).