Generieren Sie xkeyval Boolesche Schlüssel „on the fly“

Generieren Sie xkeyval Boolesche Schlüssel „on the fly“

Ich bin kein TeX/LaTeX-Spezialist, habe aber vor kurzem ein Paket zu „Problemen“ und „Lösungen“ geschrieben, das am Ende des Dokuments angezeigt werden soll, aber nicht auf diesen Zweck beschränkt ist. Um dieses Verhalten zu erreichen, habe ich unter xkeyvalanderem das Paket mit vielen Tastenmakros und Booleschen Tasten verwendet.

Ich möchte eine bessere Version bereitstellen und Dutzende von Schlüsselmakrodefinitionszeilen und Boolesche Schlüsseldefinitionen loswerden, die im Grunde gleich aussehen, aber nur einige Flags setzen und die mühsame Eingabe von LaTeX-Code durch einige kurze Befehle ersetzen wie

\GenerateBoolKey[true]{SomeKeys}{DummyBoolKey}

Dies sollte den Booleschen Schlüssel definieren, DummyBoolKeyder zur Familie gehört SomeKeys, als ob man geschrieben hätte

\define@boolkey{SomeKeys}{DummyBoolKey}[true]{%
\ifKV@SomeKeys@DummyBoolKey%
%Do something if true%
\else%
%Do something different if false%
\fi%
}%

In der Dokumentation (Version 2.6b) heißt es auf Seite 7, dass ein Makro wie folgt xkeyvaldefiniert ist :\ifKV@fam@key\newif

Nun, ich habe es nicht geschafft, den obigen Befehl zu schreiben und das \ifKV Makro zu verwenden. Hier ist ein minimales (nicht) funktionierendes Beispiel, das beim Kompilieren mit der Fehlermeldung fehlschlägt

     ! Too many }'s.

Hier ist ein Minimalbeispiel

\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}

Wie kann ich den \newifBefehl im laufenden Betrieb mit meinem Wrapper-Code bereitstellen, um den \ifKVBooleschen Test bereitzustellen?

Antwort1

Dies scheint ein Problem mit bedingter Verschachtelung zu sein. Der beste Ansatz scheint mir hier zu sein, die Erweiterung des Namens „im Voraus“ zu erzwingen, sodass Sie eine Definition erhalten, die mit der identisch ist, die Sie „von Hand“ erhalten würden.

\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}

Dies funktioniert, indem wir \xinnerhalb einer Gruppe definieren, was geschlossen ist, wenn wirverwenden \x, und das erzwingt die Erweiterung des Namens, ohne etwas anderes zu erweitern (daher viele \noexpands).

verwandte Informationen