summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-05-05 22:44:01 +0000
committerKarl Berry <karl@freefriends.org>2010-05-05 22:44:01 +0000
commit2efa87d7787e87488d8fee8defb98eecd0dd6054 (patch)
treed2b1b3310a10a25c38c99453c02660f17f6716d1
parenta6e8956148fe576baa6235b67812daa9cfd899f7 (diff)
skeyval 0.7 (4may10)
git-svn-id: svn://tug.org/texlive/trunk@18113 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/skeyval/README4
-rw-r--r--Master/texmf-dist/doc/latex/skeyval/skeyval-bugreport.tex19
-rw-r--r--Master/texmf-dist/doc/latex/skeyval/skeyval-guide.pdfbin580787 -> 597080 bytes
-rw-r--r--Master/texmf-dist/doc/latex/skeyval/skeyval-guide.tex389
-rw-r--r--Master/texmf-dist/tex/latex/skeyval/skeyval.sty994
5 files changed, 793 insertions, 613 deletions
diff --git a/Master/texmf-dist/doc/latex/skeyval/README b/Master/texmf-dist/doc/latex/skeyval/README
index cbe5a526453..97c3cb6d955 100644
--- a/Master/texmf-dist/doc/latex/skeyval/README
+++ b/Master/texmf-dist/doc/latex/skeyval/README
@@ -1,7 +1,7 @@
%+++++++++++++++++++++++++++++++++++ INTRODUCTION +++++++++++++++++++++++++++++++++++%
% %
-% This is the Readme file for the skeyval package, version 0.6. %
-% April 2010 %
+% This is the Readme file for the skeyval package, version 0.7. %
+% May 2010 %
% %
% Copyright (c) 2010 Ahmed Musa (a.musa@rocketmail.com). %
% %
diff --git a/Master/texmf-dist/doc/latex/skeyval/skeyval-bugreport.tex b/Master/texmf-dist/doc/latex/skeyval/skeyval-bugreport.tex
index 9e1c240626a..14256941ea2 100644
--- a/Master/texmf-dist/doc/latex/skeyval/skeyval-bugreport.tex
+++ b/Master/texmf-dist/doc/latex/skeyval/skeyval-bugreport.tex
@@ -1,6 +1,6 @@
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% This is file skeyval-bugreport.tex, the bug report file for the %
-% skeyval package, version 0.6. %
+% skeyval package, version 0.7. %
% %
% (c) Ahmed Musa 2010 (a.musa@rocketmail.com) %
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
@@ -11,24 +11,31 @@
% the sample file, the log file, and the auxiliary file to %
% a.musa@rocketmail.com. %
% %
+% You can use \traceon ... \traceoff to limit the scope of %
+% error tracing. This will be particularly helpful as TeX normally %
+% generates very large trace files. %
+% %
+% %
%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
\documentclass{article}
\listfiles
-% Load your select packages here (the ones
-% that you think are associated with your errors)
+% Load your select packages here (the ones that you suspect are
+% associated with your errors), but if bugs exist in those packages,
+% I am afraid, I can't do much about them.
\usepackage[logonly]{trace} % Please don't move!
\traceon
-% \usepackage[Put your skeyval options here]{skeyval}
+\usepackage[Put your skeyval options here, if any]{skeyval}
% Provide other elements of your preamble here:
\begin{document}
-% Provide sample text and problematic segment of your file here:
+% Provide sample text and problematic segment of your file here, if any:
-\traceoff
\end{document}
+
+%\traceoff
diff --git a/Master/texmf-dist/doc/latex/skeyval/skeyval-guide.pdf b/Master/texmf-dist/doc/latex/skeyval/skeyval-guide.pdf
index 1343d4eb767..0f893afa783 100644
--- a/Master/texmf-dist/doc/latex/skeyval/skeyval-guide.pdf
+++ b/Master/texmf-dist/doc/latex/skeyval/skeyval-guide.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/skeyval/skeyval-guide.tex b/Master/texmf-dist/doc/latex/skeyval/skeyval-guide.tex
index 82a59f63d18..919ebfc7d9e 100644
--- a/Master/texmf-dist/doc/latex/skeyval/skeyval-guide.tex
+++ b/Master/texmf-dist/doc/latex/skeyval/skeyval-guide.tex
@@ -1,5 +1,6 @@
\documentclass[a4paper,10pt,final,language=UKenglish,fancysec,fancyfnote]{amltxdoc}
\makeatletter
+\let\sectionbreak\medbreak
\begin{document}
@@ -8,12 +9,12 @@
\title{The \texttt{\color{blue}skeyval} Package\titleref{t1,t2}}
\titlenote[t1]{The \pkgm{skeyval} was formerly called the \pkgm{keyreader} until
version~0.5. The \asty{keyreader} is now obsolete and no longer supported.}
-\iftog{pdf}{%
+\iftogon{pdf}{%
\titlenote[t2]{The package is available at \url{\@titleurl}.}%
}{%
\titlenote[t2]{The package is available at \url{\@shorttitleurl}.}%
}
-\subtitle{Version 0.6}
+\subtitle{Version 0.7}
\titleurl{http://www.ctan.org/tex-archive/macros/latex/contrib/skeyval/}
\shorttitleurl{http://www.ctan.org/}
\author{Ahmed Musa\Email{a.musa@rocketmail.com}\\Preston, Lancashire, UK}
@@ -29,12 +30,12 @@ version~0.5. The \asty{keyreader} is now obsolete and no longer supported.}
}
\end{abstract}
-\NewLet\licename\licensename
+\NewLet\licname\licensename
\SKV@redef*\licensename{\vspace{-\baselineskip}}
\begin{license}
\frameshade[width=\hsize,fillcolor=white,framesep=2pt,framerule=2pt,
framecolor=brown]{\small
- \vspace{1ex}\centerline{\licename}\endgraf
+ \vspace{1ex}\centerline{\licname}\endgraf
This work (\ie, all the files in the \asty{skeyval} bundle) may be distributed and/or modified under the conditions of the \lppl (LPPL), either version~1.3 of this license or any later version.
\endgraf
The \lppl maintenance status of this software is ``author-maintained''. This software is provided ``as it is,'' without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose.
@@ -53,7 +54,7 @@ version~0.5. The \asty{keyreader} is now obsolete and no longer supported.}
\section{Motivation}
\label{sec:motivation}
-\lletter{T}oggle switches or booleans were introduced by the \pkgm{etoolbox} and have proved attractive mainly for two reasons: unlike the legacy/native \tex switches which require three commands per switch, toggles require only one command per switch, and toggles occupy their own separate namespace, thereby avoiding clashes with other macros. So we can effectively have both the following sets in the same file:
+\lletter{T}oggle booleans were introduced by the \pkgm{etoolbox} and have proved attractive mainly for two reasons: unlike the legacy/native \tex switches which require three commands per switch, toggles require only one command per switch, and toggles occupy their own separate namespace, thereby avoiding clashes with other macros. So we can effectively have both the following sets in the same file:
\begin{example}
|comm(Knuth/native switch:)
\newif\ifmyboolean |tto 3 separate commands:
@@ -62,22 +63,22 @@ version~0.5. The \asty{keyreader} is now obsolete and no longer supported.}
|comm(Toggle switch:)
\newtog{myboolean} |tto only 1 command and no clash with
- commands in other namespaces.
+ commands in other namespaces
\end{example}
\Note A toggle is also a boolean or switch. We refer to it here as \emph{toggle} or \emph{toggle switch} or \emph{toggle boolean}. The term \emph{Knuth/native switch} is reserved here for \tex's legacy boolean or switch.
-The \pkg{xkeyval} can't be used to define and set toggle keys. The present package provides facilities for defining and setting toggle keys. The work relies on some of the macros from the \pkg{xkeyval}.
+The \pkg{xkeyval} can't be used to define and set toggle keys. The present package provides facilities for defining and setting toggle keys. The work relies on some of the internal macros from the \pkg{xkeyval}.
Secondly, the \pkg{xkeyval} can't be used to define and set complementary (bipolar and unipolar) keys, which can be handy in the case of native boolean and toggle keys. Complementary bipolar keys are mutually exclusive keys, \ie, they never assume the same state of a two-valued logic, and they switch states automatically, depending on the state of any one of them. So whenever one of them assumes one of the two states of a two-valued logic, the other one automatically switches its state from whatever state it was previously, such that the two are never in the same state. Simple examples of complementary bipolar keys would be the options \acmd{draft} and \acmd{final} in a document; they are mutually exclusive. Complementary bipolar keys carry equal charge, \ie, each one can equally toggle the other with identical propensity, but the one that represents the default state of a two-valued logic is usually considered the primary, while the other is secondary. In many document classes, for instance, \acmd{final} is considered a default document option and \acmd{draft} would have to be explicitly selected by the user to toggle \acmd{final} to false.
Complementary unipolar keys, on the other hand, are mutually inclusive, \ie, both are always in the same state of a two-valued logic: when one is switched to a particular state, the complement too is automatically toggled to the same state. An example of complementary unipolar keys would be the options \fx{hyperref} and \fx{microtype} in a package or class file. When \pkgm{hyperref} is loaded, we may want \pkgm{microtype} loaded as well, and vice versa. Complementary unipolar keys, like bipolar keys, also carry equal charge, \ie, one can toggle the other with equal propensity, but to the same state for the two keys. For a pair of unipolar keys, the primary key is the one that is associated with the default state.
-The present package introduces these concepts of bipolar and unipolar keys and additionally permits the submission of individual/different custom key macros to complementary (bipolar and unipolar) native boolean and toggle keys. Biunipolar keys are introduced as well.
+The present package introduces these concepts of bipolar and unipolar keys and additionally permits the submission of individual/different custom key macros to complementary (bipolar and unipolar) native boolean and toggle keys. Biunipolar keys, which combines the two concepts of bipolar and unipolar keys, are introduced as well.
The third motivation for this package relates to economy of tokens in style files. The \pkg{xkeyval} provides \acmd{\define@cmdkeys} and \acmd{\define@boolkeys} for defining and setting multiple command keys and boolean keys, but in each category the keys must have the same default value and no key macro/function. This package seeks to lift these restrictions, so that multiple keys of all categories (ordinary keys, command keys, boolean keys, tog keys, and choice/menu keys) can be defined in one go (using only one command) and those keys can have different default values and functions. This greatly minimizes tokens, as hundreds of keys can, in principle, be issued simultaneously by one command.
-Fourthly, macros are introduced for defining all key types without the fear of inadvertently redefining existing keys in the same family and with the same key prefix. This has a philosophy similar to the \acmd{\newcommand} concept in \LaTeX.
+Fourthly, macros are introduced for defining all key types without the fear of inadvertently redefining existing keys in the same family and with the same key prefix. This has a philosophy akin to the \acmd{\newcommand} concept in \LaTeX.
The package also provides facilities for disabling, suspending, restoring and removing keys across multiple families of keys. The pointer system of the \pkg{xkeyval} is also extended by the \pkg{skeyval}, and the notion of ``user-value'' keys is introduced.
@@ -87,7 +88,7 @@ The new macros can be used together with the machinery from the \pkg{xkeyval} fo
The \pkg{xkeyval} strips off up to three levels of braces in the value part of the \acmd{key-value} pair: one by using the \pkgm{keyval}'s leading and trailing space removal command and two in internal parsings (at some known commands). The \asty{keyval} strips off only two levels of braces: one in using its space removal routine and one in internal parsings. The \pkgm{kvsetkeys} strips off only one level of braces. The matter of these differences has not yet been shown to have serious implications for existing or new packages, although it is apparently of concern to the \pkgm{keycommand}.
-The \pkg{skeyval} internally uses a space removal scheme that doesn't strip off braces from its arguments, but since the present package relies, to a good extent, on the engine of the \pkg{xkeyval}, the brace stripping effect has remained.\footnote{We have had to redefine some of the internal macros of the \pkg{xkeyval}, but getting rid of the brace-stripping issue would require even more substantial revision of the internal macros of the \pkg{xkeyval}.} It can easily be solved but there is currently no sufficient reason to do so. If, odd enough, you want at least one level of braces to persist in the value part of the \acmd{key-value} pair throughout parsing, you simply surround the value with four levels of braces in the \acmd{\setkeys} command. If the users of this, or the \pkg{xkeyval}, feel that this issue is of significant concern, then it can be addressed in the future.
+The \pkg{skeyval} internally uses a space removal scheme that doesn't strip off braces from its arguments, but since the present package relies, to a good extent, on the engine of the \pkg{xkeyval}, the brace stripping effect has remained. We have had to redefine a significant number of the internal macros of the \pkg{xkeyval}, but getting rid of the brace-stripping issue would require even more substantial revision of the internal macros of the \pkg{xkeyval}. It can easily be solved but there is currently no sufficient reason to do so. If, odd enough, you want at least one level of braces to persist in the value part of the \acmd{key-value} pair throughout parsing, you simply surround the value with four levels of braces in the \acmd{\setkeys} command. If the users of this, or the \pkg{xkeyval}, feel that this issue is of significant concern, then it can be addressed in the future.
\section{The \texttt{skeyval} package options}
\label{sec:loading-package}
@@ -123,6 +124,7 @@ The \pkg{skeyval} issues a fatal error if it is loaded before (or run without) \
\label{sec:comp-boolkeys}
\subsection{Bipolar native-boolean keys}
+\label{sec:biboolkeys}
As mentioned in \cref{sec:motivation}, complementary bipolar keys are keys that depend inversely on each other: when one of them is in a particular state of a two-valued logic, the other one automatically assumes the opposite or complementary state. For each pair of bipolar keys, one is normally assumed to be the primary key and the other the secondary. The primary boolean key will usually represent the default state of a two-valued logic. Whenever one bipolar key (primary or secondary) is true, its complement is automatically set false; and vice versa: when one bipolar key (primary or secondary) is false, its complement is automatically set true. Generally, the transition of the state of a key from negative (false) to positive (true) is associated with the execution of the key's macro.
@@ -134,12 +136,24 @@ The syntax for creating bipolar native-boolean keys is
{|cang(func for secondary boolean)}
\end{macro}
\acmdm*{\define@biboolkeys}
-This command is robust and can be used in expansion contexts, but expandable commands may need to be protected. When the user doesn't supply the \aang{keyprefix} and/or \aang{macroprefix}, the package will use \aang{KV} and \aang{mp@}, respectively. When the default value for the primary boolean is not supplied, the package will use \acmd{true}. Infinite loops, which are possible in back-linked key settings, are avoided in the \pkg{skeyval}. The machinery of the \pkg{xkeyval}, such as \acmd{\setkeys}, \acmd{\presetkeys}, \acmd{\savekeys}, \acmd{\savevalue}, \acmd{\usevalue}, \etc, are all applicable to complementary bipolar keys.
+This command is robust and can be used in expansion contexts, but expandable commands may need to be protected. When the user doesn't supply the \aang{keyprefix} and/or \aang{macroprefix}, the package will use \aang{KV} and \aang{mp@}, respectively. When the default value for the primary boolean is not supplied, the package will use \acmd{true}. Infinite loops, which are possible in back-linked key settings, are avoided in the \pkg{skeyval}. The machinery of the \pkg{xkeyval}, such as \acmd{\setkeys}, \acmd{\presetkeys}, \acmd{\savekeys}, \acmd{\savevalue}, \acmd{\usevalue}, \etc, are all applicable to all complementary keys.
As an example, we define below two bipolar native-boolean keys \aang{draft} and \aang{final} with different key macros:
\begin{example}
\define@biboolkeys[KV]{fam}[mp@]{draft}[true]{final}%
- {\def\noneofone##1{}}{\def\oneofone##1{##1}}
+{%
+ \ifmp@draft
+ \def\noneofone##1{}%
+ \else
+ \def\oneofone##1{##1}%
+ \fi
+}{%
+ \ifmp@final
+ \def\noneoftwo##1##2{}%
+ \else
+ \def\oneoftwo##1##2{##1}%
+ \fi
+}
\end{example}
The key prefix (default \fx{KV}), macro prefix (default \fx{mp@}), key macros (no default), and the default value of the primary boolean (\fx{true}) can all be empty:
\begin{example}
@@ -148,15 +162,29 @@ The key prefix (default \fx{KV}), macro prefix (default \fx{mp@}), key macros (n
The defined complementary bipolar keys \aang{draft} and \aang{final} can now be set separately as follows:
\begin{example}
-\setkeys[KV]{fam}{draft=true}
+\setkeys[KV]{fam}{draft=true |makered(or) on}
-\setkeys[KV]{fam}{final=true}
+\setkeys[KV]{fam}{final=true |makered(or) on}
\end{example}
The second statement above reverses the boolean \aang{draft} to \aang{false}, which had been set in the first statement to \aang{true}. There is no apparent meaning to the following:
\begin{example}
\setkeys[KV]{fam}{draft=true,final=true}.
\end{example}
+\Note
+In the \pkg{skeyval}, the acceptable values for native-boolean and toggle-boolean keys are \fx{true}, \fx{on}, \fx{false}, and \fx{off}. Toggle-booleans (\cref{sec:toggle-booleans}) and switches (\cref{sec:switches}) also accept these values. The value \fx{on} is synonymous with \fx{true}, whilst \fx{off} is an alias for \fx{false}. Being merely aliases, both \fx{on} and \fx{off} don't increase the number of commands per switch: the number remains three.
+
+The \pkg{skeyval} has the \acmdm{\NewIfs} macro which defines five commands per switch:
+\begin{macro}
+\NewIfs[|cang(optional prefix)]{|cang(boolean list)}[|cang(optional state)]
+\end{macro}
+\acmdm*{\NewIfs}
+This provides, for each member of the comma-separated list \bang{boolean list}, a new native-boolean register if the register didn't already exist, otherwise an error is flagged. Each member of \bang{boolean list} is prefixed with \aang{prefix} upon definition. The optional \aang{state} can be either \fx{true}, \fx{false}, \fx{on} or \fx{off}; the default is \fx{false}. \fx{on} is synonymous with \fx{true}, whilst \fx{off} is equivalent to \fx{false}. After declaring
+\begin{example}
+\NewIfs[bool]{a,b}[true]
+\end{example}
+you can say \fx{\ifboola}, \fx{\boolaon} and \fx{\boolaoff}, just like you would normally do \fx{\boolatrue} and \fx{\boolafalse}. The disadvantage of \fx{\NewIfs} is that it defines five commands per switch; it should therefore be employed only in special circumstances.
+
\subsection{Unipolar native-boolean keys}
Unipolar boolean keys are two keys that are always in the same state: when one is true (or false), the other one is also true (or false). In this regard, the key macro is always executed when a key transits to the ``true'' state. The syntax for creating unipolar native-boolean keys is exactly as that for defining bipolar native-boolean keys:
@@ -169,10 +197,24 @@ Unipolar boolean keys are two keys that are always in the same state: when one i
\acmdm*{\define@uniboolkeys}
This command is robust and can be used in expansion contexts, but expandable commands may need to be protected. Again, if the user doesn't supply the \aang{keyprefix} and/or \aang{macroprefix}, the package will use \aang{KV} and \aang{mp@}, respectively. When the default value for the primary boolean is not supplied, the package will assume it to be \fx{true}.
-The following example constructs two unipolar boolean keys:
+The following example constructs two unipolar native-boolean keys:
\begin{example}
+\NewToks[temptoks]{a,b}
+
\define@uniboolkeys[KV]{fam}[mp@]{pdfmode}[true]{microtype}%
-{\temptoks{Yes, in `pdfmode'}}{\def\temp{`microtype' loaded}}
+{%
+ \ifmp@pdfmode
+ \temptoksa{Yes, in `pdfmode'}%
+ \else
+ \temptoksa{No, not in `pdfmode'}%
+ \fi
+}{%
+ \ifmp@microtype
+ \temptoksb{Yes, `microtype' loaded}%
+ \else
+ \temptoksb{No, `microtype' not loaded}%
+ \fi
+}
\end{example}
\subsection{Biunipolar native-boolean keys}
@@ -198,7 +240,10 @@ The syntax for establishing biuni boolean keys is exactly like that for creating
As an example, consider the arbitrary package or class options \fx{review} and \fx{preprint}. The option \fx{preprint} can automatically toggle \fx{review} to true, but possibly not vice versa: not every \fx{preprint} is a manuscript for \fx{review}. This is depicted below:
\begin{example}
-\define@biuniboolkeys[KV]{fam}[mp@]{preprint}[true]{review}{}{%
+\define@biuniboolkeys[KV]{fam}[mp@]{preprint}[true]{review}{%
+ |comm(No key macro for preprint; otherwise, it would)
+ |comm(have come in here.)
+}{%
\ifmp@review
\SKV@BeforeDocumentStart{%
\linespread{1.5}\selectfont
@@ -229,7 +274,7 @@ As another example, consider the following biuni keys, each with its own macro:
\end{example}
\acmd*{\SKV@AfterDocumentStart}
-\section{Toggle booleans and keys}
+\section{Toggle booleans and toggle keys}
\label{sec:toggles}
In the following \crefrange{sec:toggle-booleans}{sec:toggle-keys} we define toggle booleans/switches and use them to introduce toggle-boolean keys.
@@ -237,72 +282,77 @@ In the following \crefrange{sec:toggle-booleans}{sec:toggle-keys} we define togg
\subsection{Toggle booleans}
\label{sec:toggle-booleans}
-The following toggle switches are defined in the \pkg{skeyval}. They largely mimic those in the \pkg{etoolbox}, except for the commands \acmdm{\deftog} and \acmd{\requiretog}. There is no fear that the commands in this package will interfere with those from the \pkg{etoolbox}, since the internal control sequences and user interfaces of the two packages are different.
+The following toggle switches are defined in the \pkg{skeyval}. They largely mimic those in the \pkg{etoolbox}, except for the commands \acmdm{\deftog} and \acmd{\requiretog}. The internal control sequences and user interfaces of the two packages are, however, different, thus avoiding clashes.
-All the commands in this section are robust and can be used in expansion or moving contexts, but fragile arguments would need to be protected in those settings.
+All the commands in this section are robust and can be used in expansion or moving contexts without fear of premature expansion, but fragile arguments would need to be protected in those settings.
\begin{macro}
-\deftog{|cang(toggle)}
+\deftog[|cang(optional prefix)]{|cang(toggle)}[|cang(optional state)]
\end{macro}
-This defines a new \aang{toggle} whether or not \aang{toggle} is already defined. If \aang{toggle} is already defined, a warning message is logged in the transcript file (if the package option \fx{verbose} is selected) and the new definition is effected.
+This defines a new \aang{toggle}, prefixed with \aang{prefix} upon definition, whether or not \aang{toggle} (with its prefix) is already defined. If \aang{toggle} is already defined, a warning message is logged in the transcript file (if the package option \fx{verbose} is selected) and the new definition is effected. The optional \aang{state} can be either \fx{true}, \fx{false}, \fx{on} or \fx{off}.
\begin{macro}
-\newtog{|cang(toggle)}
+\newtog[|cang(optional prefix)]{|cang(toggle)}[|cang(optional state)]
\end{macro}
\acmdm*{\newtog}
-This defines a new \aang{toggle} if \aang{toggle} is not already defined; otherwise the package issues a fatal error. You can define a set of toggles by the following command:
+This defines a new \aang{toggle}, prefixed with \aang{prefix} upon definition, if \aang{toggle} (with its prefix) is not already defined; otherwise the package issues a fatal error. The optional \aang{state} can be either \fx{true}, \fx{false}, \fx{on} or \fx{off}.
+
+You can define a set of toggles by the following command:
\begin{macro}
\NewTogs[|cang(optional prefix)]{|cang(toggles)}[|cang(optional state)],
\end{macro}
\acmdm*{\NewTogs}
-where \aang{toggles} is a comma-separated list. Each member of \aang{toggles} is prefixed with \aang{prefix} upon definition. The optional \aang{state} can be either \fx{true} or \fx{false}. For example, we may define new toggles \fx{x}, \fx{y}, \fx{z} by the following:
+where \aang{toggles} is a comma-separated list. Each member of \aang{toggles} is prefixed with \aang{prefix} upon definition. The optional \aang{state} can be either \fx{true}, \fx{false}, \fx{on} or \fx{off}. For example, we may define new toggles \fx{togx}, \fx{togy}, \fx{togz} by the following:
\begin{example}
-\NewTogs[skv@]{x,y,z}[true]
+\NewTogs[tog]{x,y,z}[true]
\end{example}
-
\begin{macro}
\providetog{|cang(toggle)}
\end{macro}
\acmdm*{\providetog}
-This defines a new \aang{toggle} if \aang{toggle} is not already defined. If \aang{toggle} is already defined, the command does nothing.
+This defines a new \aang{toggle} if \aang{toggle} is not already defined. If \aang{toggle} is already defined, the command does nothing. Please note that there are no tog prefix here, and that the default state is \fx{false}.
\begin{macro}
\requiretog{|cang(toggle)}
\end{macro}
-\acmdm{\requiretog} takes arguments like \fx{\newtog} and behaves like \fx{\providetog} with the difference: if the toggle is already defined, the command \fx{\requiretog} calls \LaTeX's \acmdm{\CheckCommand} to make sure that the new and existing definitions are identical, whereas \fx{\providetog} assumes that if the toggle is already defined, the existing definition should persist. \fx{\requiretog} assures that a toggle will have the given definition, but (if the package option \fx{verbose} is selected) \fx{\requiretog} also warns the user if there was a previous and different existing definition. For example, if the toggle \aang{toga} is currently \aang{true}, then since all new toggles start out as \aang{false}, a call \fx{\requiretog{toga}} will, if the package option \fx{verbose} is selected, issue a warning in the log file that the new and old definitions of \aang{toga} don't agree and the new definition, therefore, can't go ahead.
+\acmdm{\requiretog} takes arguments like \fx{\newtog} and behaves like \fx{\providetog} with the difference: if the toggle is already defined, the command \fx{\requiretog} calls \LaTeX's \acmdm{\CheckCommand} to make sure that the new and existing definitions are identical, whereas \fx{\providetog} assumes that if the toggle is already defined, the existing definition should persist. \fx{\requiretog} assures that a toggle will have the given definition, but (if the package option \fx{verbose} is selected) \fx{\requiretog} also warns the user if there was a previous and different existing definition. For example, if the toggle \aang{toga} is currently \aang{true}, then since all new toggles start out as \aang{false}, a call \fx{\requiretog{toga}} will, if the package option \fx{verbose} is selected, issue a warning in the log file that the new and old definitions of \aang{toga} don't agree and the new definition, therefore, can't go ahead. Note that there are no tog prefix here, and that the default state is \fx{false}.
The \pkg{skeyval} also provides the command \acmd{\requirecmd}, which has the same logic as \fx{\requiretog} but can be used for general \latex commands, including those with optional arguments (see \cref{sec:misce-commands}).
\begin{macro}
-\settog{|cang(toggle)}{|cang(true |amdvert false)}
+\settog{|cang(toggle)}{|cang(true |amdvert false |amdvert on |amdvert off)}
\end{macro}
\acmdm*{\settog}
-This command sets \aang{toggle} to \aang{value}, where \aang{value} may be either \aang{true} or \aang{false}. This statement will issue an error if \aang{toggle} wasn't previously defined.
+This command sets \aang{toggle} to \aang{value}, where \aang{value} may be either \fx{true}, \fx{false}, \fx{on} or \fx{off}. This statement will issue an error if \aang{toggle} wasn't previously defined.
\begin{macro}
+\togon{|cang(toggle)}
\togtrue{|cang(toggle)}
\end{macro}
-\acmdm*{\togtrue}
-This sets \aang{toggle} to \aang{true}. It will issue an error if \aang{toggle} wasn't previously defined.
+\acmdm*{\togon, \togtrue}
+These set \aang{toggle} to \aang{true} or \fx{on}. They will issue an error if \aang{toggle} wasn't previously defined.
\begin{macro}
+\togoff{|cang(toggle)}
\togfalse{|cang(toggle)}
\end{macro}
-\acmdm*{\togfalse}
-This sets \aang{toggle} to \aang{false}. It will issue an error if \aang{toggle} wasn't previously defined.
+\acmdm*{\togoff, \togfalse}
+These set \aang{toggle} to \aang{false} or \fx{off}. They will issue an error if \aang{toggle} wasn't previously defined.
\begin{macro}
-\iftog{|cang(toggle)}{|cang(true)}{|cang(false)}
+\iftogon{|cang(toggle)}{|cang(true)}{|cang(false)}
+\iftogtrue{|cang(toggle)}{|cang(true)}{|cang(false)}
\end{macro}
-\acmdm*{\iftog}
-This yields the \aang{true} statement if the boolean \aang{toggle} is currently \aang{true}, and \aang{false} otherwise. It will issue an error if \aang{toggle} wasn't previously defined.
+\acmdm*{\iftogon, \iftogtrue}
+These yield the \aang{true} statement if the boolean \aang{toggle} is currently \aang{true}, and \aang{false} otherwise. They will issue an error if \aang{toggle} wasn't previously defined.
\begin{macro}
-\ifnottog{|cang(toggle)}{|cang(not true)}{|cang(not false)}
+\iftogoff{|cang(toggle)}{|cang(not true)}{|cang(not false)}
+\iftogfalse{|cang(toggle)}{|cang(not true)}{|cang(not false)}
\end{macro}
-\acmdm*{\ifnottog}
-This behaves like \fx{\iftog} but reverses the logic of the test. It will issue an error if \aang{toggle} wasn't previously defined.
+\acmdm*{\iftogoff, \iftogfalse}
+These behave like \fx{\iftogon} and \fx{\iftogtrue} but reverse the logic of the test. They will issue an error if \aang{toggle} wasn't previously defined.
\subsection{Toggle-boolean keys}
\label{sec:toggle-keys}
@@ -330,7 +380,7 @@ If the plus (\RedPlus) version of the macro is used, the user can specify two ke
As an example, consider the following:
\begin{example}
\define@togkey{fam}[my@]{frame}{%
- \iftog{my@frame}{%
+ \iftogon{my@frame}{%
\PackageInfo{mypack}{Turning frames on}%
}{%
\PackageInfo{mypack}{Turning frames off}%
@@ -338,7 +388,7 @@ As an example, consider the following:
}
\define@togkey|redplus{fam}{shadow}{%
- \iftog{KV@fam@shadow}{%
+ \iftogon{KV@fam@shadow}{%
\PackageInfo{mypack}{Turning shadows on}%
}{%
\PackageInfo{mypack}{Turning shadows off}%
@@ -374,7 +424,7 @@ This is an abbreviation for
Now we can do
\begin{example}
\define@togkey{fam}[my@]{book}{%
- \iftog{my@book}{\setkeys[KV]{fam}{togc=true}}{}%
+ \iftogon{my@book}{\setkeys[KV]{fam}{togc=true}}{}%
}
\setkeys[KV]{fam}{book=true}
\end{example}
@@ -424,9 +474,10 @@ The defined bipolar toggle keys \aang{xdraft} and \aang{xfinal} can now be set a
\acmd*{\setkeys}
The second statement above reverses the toggle \aang{xdraft} to \aang{false}, which had been set in the first statement to \aang{true}.
-Toggle keys may easily be confused with the conventional (native) boolean keys, especially at the time of key setting. It is, therefore, always safer to use the syntaxes in \cref{sec:redef-keys} for defining keys; they avoid interference between new and existing keys.
+\Note
+Toggle keys may easily be confused with the conventional boolean keys, especially at the time of key setting. It is, therefore, always safer to use the syntaxes in \cref{sec:redef-keys} for defining keys; they avoid interference between new and existing keys.
-\Note If we were to use the key names \acmd{draft} and \acmd{final} as toggle keys above, instead of \fx{xdraft} and \fx{xfinal}, there would have been a clash with the keys \acmd{draft} and \acmd{final} defined as (complementary) native-boolean keys in \cref{sec:comp-boolkeys}---because they share the same family \aang{fam} and prefix \aang{KV}. The names \acmd{draft} and \acmd{final} can be used as toggles only if the family \aang{fam} or prefix \aang{KV} is changed. See \cref{sec:avoiding-redef} for further details.
+If we were to use the key names \acmd{draft} and \acmd{final} as toggle keys above, instead of \fx{xdraft} and \fx{xfinal}, there would have been a clash with the keys \acmd{draft} and \acmd{final} defined as (complementary) native-boolean keys in \cref{sec:comp-boolkeys}---because they share the same family \aang{fam} and prefix \aang{KV}. The names \acmd{draft} and \acmd{final} could safely be used as toggles only if the family \aang{fam} or prefix \aang{KV} is changed. See \cref{sec:avoiding-redef} for further details.
\subsection{Unipolar toggle-boolean keys}
@@ -459,11 +510,11 @@ The interface for creating biuni toggle keys is exactly like that for creating o
\begin{example}
\define@biunitogkeys|redplus[KV]{fam}[mp@]{preprint}[true]{review}{%
- \iftog{mp@preprint}{%
+ \iftogon{mp@preprint}{%
\def\banner{\fbox{\textsf{This is a preprint copy}}}%
}{}%
}{%
- \iftog{mp@review}{%
+ \iftogon{mp@review}{%
\SKV@AtDocumentStart{\linespread{1.5}\selectfont}%
\def\banner{\fbox{\textit{This is a review article}}}%
}{%
@@ -485,7 +536,7 @@ The interface for defining multiple keys of all kinds in one go is the command \
\end{macro}
There are five key types: 1 (ordinary key), 2 (command key), 3 (native-boolean key),
-4 (toggle-boolean key), and 5 (choice/menu key). The key types can be indicated either in numeral format (\fx{1}~to~\fx{5}) or in alphabetic format (\fs{ord}, \fx{cmd}, \fx{bool}, \fx{tog}, \fx{choice}, \fx{menu}). ``Choice'' and ``menu'' key types imply the same thing (key type~5): the user can pick the name he prefers. The key and its attributes are separated by commas; they constitute one ``object'' or ``instance''. The objects are separated by the \aang{keyparser}, which is the semicolon in the above example.
+4 (toggle-boolean key), and 5 (choice/menu key). The key types can be indicated either in numeral format (\fx{1}~to~\fx{5}) or in alphabetic format (\fx{ord}, \fx{cmd}, \fx{bool}, \fx{tog}, \fx{choice}, \fx{menu}). ``Choice'' and ``menu'' key types imply the same thing (key type~5): the user can pick the name he prefers. The key and its attributes are separated by commas; they constitute one ``object'' or ``instance''. The objects are separated by the \aang{keyparser}, which is the semicolon in the above example.
If the key list is available in a macro, say,
\begin{example}
@@ -518,9 +569,9 @@ is being defined via \fx{\define@keylist}. Its syntax is
\choicekeyvalues|redstar[|cang(prefix)][|cang(family)]{|cang(key)}{|cang(list)},
\end{macro}
where \aang{list} is a comma-separated list of admissible key values. Unless the key prefix or family changes, the unstarred variant of \fx{\choicekeyvalues} wouldn't allow you to set two \fx{\choicekeyvalues} for the same choice key. The starred variant \fx{\choicekeyvalues}\unskip\redstar, on the other hand, allows you to overwrite admissible choice values for a key within a specified family and with the given key prefix. The arguments \aang{prefix} and \aang{family} are optional, provided the key prefix and family have been specified before calling \fx{\choicekeyvalues}, using \fx{\skvoptions}. If \aang{prefix} and \aang{family} are not given, the prevailing key prefix and key family are used internally by \fx{\choicekeyvalues} to build distinct alternate values list for the choice key. Therefore, any number of choice keys are allowed to appear in one \acmd{\define@keylist} or \acmd{\define@keylist}\unskip\redstar\ statement, if their lists of alternate/admissible values have been set by \fx{\choicekeyvalues}.
-It doesn't matter which choice key first gets a \fx{\choicekeyvalues}.
+It doesn't matter which choice key first gets a \fx{\choicekeyvalues}.
-To further save tokens, the macro \fx{\choicekeyvalues} may be abbreviated by \acmdm{\CKVS}. It has to be provided for each choice key that is being defined.
+To further save tokens, the macro \fx{\choicekeyvalues} may be abbreviated by \acmdm{\CKVS}. It has to be provided for each choice key that is being defined.
For example, if we want to define two choice keys \fx{align} and \fx{shootingmodes}, then before the call to \acmd{\define@keylist}, we have to set
\begin{example}
@@ -549,7 +600,6 @@ Suppose that the key family and other attributes have been set as
\end{example}
\acmd*{\skvoptions}
Further, suppose we wish to define a set of keys \fx{{color,angle,scale,align}}. The key \fx{color} will be defined as ordinary key, the keys \fx{angle} and \fx{scale} will de defined as command keys, while the key \fx{align} will be defined as a choice key. Assume that the \fx{align} key can only assume one of the values \leftbrace\fx{center} \amdvert\ \fx{right} \amdvert\ \fx{left} \amdvert\ \fx{justified}\rightbrace, where the first three values would further imply \fx{\centering}, \fx{\flushright}, and \fx{\flushleft}, respectively. Moreover, we assume that the key \fx{scale} will be associated with a macro called \fx{\mydo}, which depends on a previously defined macro \fx{\do}. Together with \fx{align}, we would also like to define another choice key: \fx{weather}. The key \fx{color} isn't associated with any macro. Then we can do:
-\acmd*{\CKVS}
\begin{example}
|comm(We use space freely in these examples for the sake)
|comm(of illustration:)
@@ -579,6 +629,7 @@ Further, suppose we wish to define a set of keys \fx{{color,angle,scale,align}}.
}
\setkeys[KV]{fam}{angle=45,scale=1cm,weather=cloudy}
\end{example}
+\acmd*{\CKVS}
Note the number of parameter characters in the definition of \fx{\mydo}. We will return to this matter in \cref{sec:macros-in-keymacros}. The \acmdm{\nr} and \acmdm{\val} macros are bin parameters for choice keys, as defined by the \pkg{xkeyval}. \fx{\val} contains the user input for the current key and \fx{\nr} contains the numeral corresponding to the numerical order of the user input in the \acmd{\CKVS} list, starting from~0 (zero). For example, in the \fx{\CKVS{align}} list, the \fx{\nr} values are \fx{center}~(0), \fx{right}~(1), \fx{left}~(2), and \fx{justified}~(3). These parameters thus refresh with the choice key and its user-supplied value.
@@ -623,7 +674,7 @@ Hundreds of keys can be defined efficiently in this way, using very few tokens.
cmd,textheight,\textheight,\funcfortextheight;
cmd,textwidth,\textwidth,\funcfortextwidth;
ord,evensidemargin,\evensidemargin,;
- tog,togvar,true,\iftog{mp@togvar}{\def\catch####1{####1}}%
+ tog,togvar,true,\iftogon{mp@togvar}{\def\catch####1{####1}}%
{\def\gobble####1{}};
choice,align,center,\funcforalign;
choice,election,congress,\def\electiontype{##1};
@@ -645,7 +696,7 @@ The same set of keys can be defined via the starred form of \acmd{\define@keylis
cmd,textheight,\textheight,\funcfortextheight;
cmd,textwidth,\textwidth,\funcfortextwidth;
ord,evensidemargin,\evensidemargin,;
- tog,togvar,true,\iftog{mp@togvar}{\def\catch####1{####1}}%
+ tog,togvar,true,\iftogon{mp@togvar}{\def\catch####1{####1}}%
{\def\gobble####1{}};
choice,align,center,\funcforalign;
choice,election,congress,\def\electiontype{##1};
@@ -688,7 +739,7 @@ Instead of using macros to pass key macros and functions, it is also possible to
\expandafter\expandafter\expandafter{\expandafter##1%
\expandafter}\expandafter{##2}}}\fi}
-\temptoksb{\iftog{mp@toga}{\def\order#1{Use `#1' now!}}%
+\temptoksb{\iftogon{mp@toga}{\def\order#1{Use `#1' now!}}%
{\def\altorder#1{Don't use `#1' now!}}}
\define@keylist{3,boola,true,\the\temptoksa;
@@ -711,7 +762,7 @@ The examples in \cref{sec:multkeys-examples} would have provided some glimpse of
\tex will flag a fatal error when any of these rules is breached. The following examples illustrate the use of these rules. The commands \fx{\skif}, \fx{\skifx}, \fx{\skelse} and \fx{\skfi} are described in \cref{sec:pseudo-primitives}.
\begin{example}
\define@keylist{%
- tog,toga,true,\iftog{mp@toga}{%
+ tog,toga,true,\iftogon{mp@toga}{%
\def\swear####1{Repeat after me: `####1'!}%
}{%
\let\swear\@gobble
@@ -804,7 +855,7 @@ The examples in \cref{sec:multkeys-examples} would have provided some glimpse of
\def#1##1##2{\expandafter\expandafter\expandafter\in@
\expandafter\expandafter\expandafter{\expandafter##1%
\expandafter}\expandafter{##2}}}\fi}
-\temptoksb{\iftog{mp@togb}{\def\tempa#1{Use #1}}%
+\temptoksb{\iftogon{mp@togb}{\def\tempa#1{Use #1}}%
{\def\tempb#1{Don't use #1}}}
\define@keylist{3,boolc,true,\the\temptoksa;
4,togb,true,\the\temptoksb}
@@ -823,39 +874,61 @@ The examples in \cref{sec:multkeys-examples} would have provided some glimpse of
\setkeys[KV]{fam}{boold=true}
\end{example}
-\subsection{The keycommand interface}
+\subsection{Key commands}
\label{sec:keycommand}
\acmdm*{keycommand}
-The \fx{\define@keylist} macro provides an interface for defining commands in the manner of the \pkg{keycommand}. We haven't developed this interface well enough but the following example shows what is currently obtainable and the possibilities for future enhancements. It is hoped that further work in this direction will be undertaken in the future. I do foresee that the user interface will be made lighter in the future. For now, the \fx{\skvoptions} command needs be reissued only when the key family changes, and in that case we simply have to do \fx{\skvoptions{keyfamily=name}}. Any future enhancement should seek to hide the \fx{\setkeys} command from the user.
+The \fx{\define@keylist} macro provides an interface for defining commands using keys, in the manner of the \pkg{keycommand}, but the user interfaces differ between here and the \pkg{keycommand}. Our interface for introducing new key commands is as follows
+\begin{macro}
+\DeclareKeyCommand|redstar|cang(cmd)[|cang(keyval)][|cang(narg)]{|cang(content)}
+\end{macro}
+\acmdm*{\DeclareKeyCommand}
+Here, \aang{cmd} is the new key command being declared, \aang{keyval} are the default key-value pairs, and \aang{narg} is the number of arguments in \aang{content} plus one. The quantity \aang{narg} has nothing to do with the number of admissible keys, and may also have no relation to the keys themselves. The first argument (\ie, \angledhash{1}) is the \aang{keyval} pairs: this is the reason why in \aang{narg} you have to add one to your number of arguments. In \aang{content} (\ie, the replacement text) the parameter number one \angledhash{1} refers to the \aang{keyval} pairs. You refer to your arguments using parameter number two \angledhash{2} onwards, up to a maximum of \angledhash{9}. This means that \fx{\DeclareKeyCommand} accepts no optional arguments. This is not a limitation, since optional arguments can be entered as keys. Using keys is preferable to using parameters: you don't have to match parameters to arguments and, in principle, there is no limit to the number of keys that are permissible.
+
+The unstarred variant of \fx{\DeclareKeyCommand} gives long macros, as is usual in \latex.
+
+In \aang{content}, you refer to the values of the keys using macros whose first three characters (after the escape character) are the first three letters of the declared key command. The fourth character of the key-value macros is the ``at'' sign (\fx{@}), which should have catcode 11. The family name of the keys defined via a key command is the key command name itself (without the escape character). The key prefix is always ``KV''. The ``at'' sign only serves to visually aid the separation of the macro prefix from the key name and may be deprecated in future versions of the package.
+
+The following examples illustrate these points:
\begin{example}
-\skvoptions{keyparser=;,macroprefix=mp,keyprefix=KV,
- keyfamily=rule}
-\define@keylist{cmd,raise,.5ex,;cmd,width,1em,;
- cmd,thick,.4pt,;bool,proclaim,true,}
-\setkeys[KV]{rule}{raise,width,thick,proclaim=false}
-\newcommand*\Rule[2][Hello]{%
- \setkeys[KV]{rule}{#2}%
- \rule[\mpraise]{\mpwidth}{\mpthick}%
- #1%
- \rule[\mpraise]{\mpwidth}{\mpthick}\hspace*{1em}%
- \ifmpproclaim \color{red}\fi\textdaggerdbl
+|makered(\DeclareKeyCommand*)\demomacro[name=Dummy,height=1.6m,
+ wieght=60kg,employed=false][3]{%
+ \edef\x{\dem@name}\def\y{#2}\def\z{#3}}
+
+|comm(Instruct the user to supply value of `name' in)
+|comm(\demomacro key command:)
+\uservaluekeys[KV]{demomacro}{name}
+
+|comm(Now you can use \demomacro. If you don't supply a key value)
+|comm(here, the macro will use the above defaults:)
+\demomacro[name=John,height=1.55m,wieght=55kg,employed=true]
+ {data1}{data2}
+
+|makered(\DeclareKeyCommand)\Rule[raise=.5ex,width=1em,thick=2pt,
+ proclaim=false][2]{\rule[\Rul@raise]{\Rul@width}{\Rul@thick}%
+ #2%
+ \rule[\Rul@raise]{\Rul@width}{\Rul@thick}\hspace*{1em}%
+ \ifRul@proclaim \color{red}\fi\textdaggerdbl
}
+
|makered(\begin{document})
\parindent\z@
\begin{tabular*}\textwidth{rr}
-\verb+\Rule[width=2em]{hello}+:|ampersand
- \Rule[Hello World]{width=2em,proclaim}\cr
-\verb+\Rule[thick=1pt,width=2em]{hello}+:|ampersand
- \Rule{thick=2pt,width=2em}\cr
-\verb+\Rule{hello}+:|ampersand
- \Rule[Hello World]{proclaim}\cr
-\verb+\Rule[thick=1pt,raise=1ex]{hello}+:|ampersand
- \Rule[Hello World]{thick=1pt,raise=1ex}
+\verb+\Rule[width=2em,thick=4pt]{Hello World}+:|ampersand
+ \Rule[width=2em,thick=4pt]{Hello World}\cr
+\verb+\Rule[width=2em,thick=.5pt,proclaim=true]{Hello}+:|ampersand
+ \Rule[width=2em,thick=.5pt,proclaim=true]{Hello}\cr
+\verb+\Rule[thick=2pt,proclaim=true]{Hello World}+:|ampersand
+ \Rule[thick=2pt,proclaim=true]{Hello World}\cr
+\verb+\Rule[raise=1ex,width=2em,thick=1pt]{Hello World}+:|ampersand
+ \Rule[raise=1ex,width=2em,thick=1pt]{Hello}
\end{tabular*}
|makered(\end{document})
\end{example}
+\acmd*{\begin\{document\}}
+
+The corresponding \fx{\DeclareKeyEnviron} easily follows.
\subsection{Input error}
\label{sec:input-error}
@@ -917,7 +990,7 @@ Token list registers can be used here economically instead of macros. Below we d
\expandafter\expandafter\expandafter{\expandafter##1%
\expandafter}\expandafter{##2}}}\fi}
-\temptoksb{\iftog{mp@toga}{\def\order#1{Use `#1' now!}}{}}
+\temptoksb{\iftogon{mp@toga}{\def\order#1{Use `#1' now!}}{}}
\define@keylist{3,boola,true,\the\temptoksa;
4,toga,true,\the\temptoksb}
@@ -953,11 +1026,11 @@ where the key prefix \fx{KV}, key family \fx{fam}, and the macro prefix \fx{mp@}
\end{example}
\acmdm*{\skif,\skifx,\skelse,\skfi}
\acmd*{\skifcase,\skor,\define@keylist}
-Here we have used \fx{\skif{mp@mybool}}, \fx{\skifx}, \fx{\skelse} and \fx{\skfi} for the commands \fx{\ifmp@mybool}, \fx{\ifx}, \fx{\else} and \fx{\fi}, respectively, to hide the latter four from \TeX's scanning and skipping mechanism. It should be noted that \fx{\skif{mp@mybool}} requires that the argument \aang{mp@mybool} be enclosed in braces. Something like \fx{\skifmp@mybool} will be interpreted by \tex as an undefined control sequence when the key \fx{mybool} is being set. Defining the command \fx{\skif{mp@mybool}} to be \fx{\ifmp@mybool} before hand would have failed because \tex's scanner would then get the hint of the assignment.
+Here we have used the pseudo-primitives \fx{\skif{mp@mybool}}, \fx{\skifx}, \fx{\skelse} and \fx{\skfi} for the commands \fx{\ifmp@mybool}, \fx{\ifx}, \fx{\else} and \fx{\fi}, respectively, to hide the latter four from \TeX's scanning and skipping mechanism. It should be noted that \fx{\skif{mp@mybool}} requires that the argument \aang{mp@mybool} be enclosed in braces. Something like \fx{\skifmp@mybool} will be interpreted by \tex as an undefined control sequence when the key \fx{mybool} is being set. Defining the command \fx{\skif{mp@mybool}} to be \fx{\ifmp@mybool} before hand would have failed because \tex's scanner would then get the hint of the assignment.
-\Note We haven't found any package that has defined \fx{\skif}, \fx{\skifx}, \fx{\skelse}, \fx{\skfi}, \fx{\skifcase} or \fx{\skor}. The \pkgm{xifthen} uses \fx{\OR}, not \fx{\skor}. If the situation changes in the future (\ie, if a package is observed to have defined any of these commands), they will be appropriately modified in the \pkg{skeyval}. Information and feedback from package users is solicited in this regard.
+\Note We haven't found any package that has defined \fx{\skif}, \fx{\skifx}, \fx{\skelse}, \fx{\skfi}, \fx{\skifcase} or \fx{\skor}. The \pkgm{xifthen}, for example, uses \fx{\OR}, not \fx{\skor}. If the situation changes in the future (\ie, if a package is observed to have defined any of these commands), they will be appropriately modified in the \pkg{skeyval}. Information and feedback from package users is solicited in this regard.
-We have redefined the \fx{\setkeys} command of the \pkg{xkeyval} to recognize that \fx{\skif{boolean}}, \fx{\skifx}, \fx{\skelse}, \fx{\skfi}, \fx{\skifcase} and \fx{\skor} stand for \fx{\ifboolean}, \fx{\ifx}, \fx{\else}, \fx{\fi}, \fx{\ifcase} and \fx{\or}, respectively. The redefined \fx{\setkeys} command has the same syntax as as in \pkg{xkeyval}:
+We have redefined the \fx{\setkeys} command of the \pkg{xkeyval} to recognize that \fx{\skif{boolean}}, \fx{\skifx}, \fx{\skelse}, \fx{\skfi}, \fx{\skifcase} and \fx{\skor} stand for \fx{\ifboolean}, \fx{\ifx}, \fx{\else}, \fx{\fi}, \fx{\ifcase} and \fx{\or}, respectively. The redefined \fx{\setkeys} command has the same syntaxes as as in \pkg{xkeyval}:
\begin{macro}
\setkeys[|cang(prefix)]{|cang(families)}[|cang(na)]{|cang(keys=values)}
\setkeys|redstar[|cang(prefix)]{|cang(families)}[|cang(na)]{|cang(keys=values)}
@@ -995,24 +1068,37 @@ The key \fx{focus} can now be readily set: \fx{\setkeys[KV]{fam}{focus=left}}.
\subsubsection[Using switches]{Using switches to submit the conditionals}
\label{sec:switches}
-The approaches of \cref{sec:pseudo-primitives} provide a familiar \tex-like syntax for submitting conditionals to \fx{\define@keylist}. There is yet another approach that we developed. It is related to the native \tex boolean conditional. By \emph{switches} we mean the usual \tex's \fx{\iftrue} and \fx{\iffalse} booleans, but expressed in a different semantics.
+The approaches of \cref{sec:pseudo-primitives} provide a familiar \tex-like syntax for submitting conditionals to \fx{\define@keylist}. There is yet another approach that we developed. It is related to the native \tex boolean conditional. By \emph{switches} we mean the usual \tex's \fx{\iftrue} and \fx{\iffalse} booleans, but expressed in different syntax and semantics.
A new switch can be introduced by using the following command:
+
\begin{macro}
-\newswitch{|cang(switch)}{|cang(value/state)}
+\newswitch[|cang(optional prefix)]{|cang(boolean)}[|cang(optional state)]
\end{macro}
-There should be no \fx{\if} in \aang{switch} when using \fx{\newswitch}. Valid values/states of switches are `true' (or `on') and `false' (or `off'). With this definition you can issue \fx{\if}\unskip\aang{switch}, \bs\aang{switch}\unskip\fx{true}, and \bs\aang{switch}\unskip\fx{false}. One advantage of \fx{\newswitch} is that a switch can start off as either \fx{true} (or \fx{on}) or \fx{false} (or \fx{off}), unlike the classical \tex's case in which all booleans start off as \fx{false}. Also, switches can be used where primitive \tex conditionals may prove impossible. For example, we know that you can't do \fx{\let\ifabc\iftrue} within the body of a conditional text without hiding the assignment from \tex's scanning mechanism.
+\acmdm*{\newswitch}
+This provides a new native-boolean register \fx{\if}\unskip\aang{prefix}\unskip\aang{boolean} if the register didn't already exist; if the register already existed, an error is flagged. The optional \aang{state} can be either \fx{true} (or \fx{on}) or \fx{false} (or \fx{off}); the switch will be initialized to that state. With this definition, you can issue \fx{\if}\unskip\aang{switch}, \bs\aang{switch}\unskip\fx{true}, and \bs\aang{switch}\unskip\fx{false}. One advantage of \fx{\newswitch} is that a switch can start off as either \fx{true} (or \fx{on}) or \fx{false} (or \fx{off}), unlike the classical \tex's case in which all booleans start off as \fx{false}. Also, switches can be used where primitive \tex conditionals may prove impossible. For example, we know that you can't do \fx{\let\ifabc\iftrue} within the body of a conditional text without hiding the assignment from \tex's scanning mechanism.
+
+\begin{example}
+\newswitch{boola} |tto \newif\ifboola
+
+\newswitch[bool]{b}[true] |tto \newif\ifboolb \boolbtrue
+
+\newswitch[bool]{c}[on] |tto \newif\ifboolc \boolctrue
+
+\newswitch[bool]{d}[off] |tto \newif\ifboold \booldfalse
+\end{example}
You can define many switches in a row by the following command:
\begin{macro}
\NewSwitches[|cang(optional prefix)]{|cang(switches)}[|cang(optional state)]
\end{macro}
-Each member of \aang{switches} is prefixed with \aang{prefix} upon definition. The optional \aang{state} can be either \fx{true} or \fx{false}.
+\acmdm*{\NewSwitches}
+Each member of \aang{switches} is prefixed with \aang{prefix} upon definition. The optional \aang{state} can be either \fx{true} (or \fx{on}) or \fx{false} (or \fx{off}).
Here are some examples:
\begin{example}
-\NewSwitches{x,y,z}
+\NewSwitches{x,y,z}[off]
|tto \newswitch{x}{false} \newswitch{y}{false}
\newswitch{z}{false}
@@ -1040,7 +1126,7 @@ Switches may be set and tested using the following commands:
\ifswitchfalse{|cang(switch)}{|cang(not true)}{|cang(not false)}
\end{macro}
-\acmdm*{\newswitch,\NewSwitches,\setswitch,\switchon,\switchoff,\ifswitchon,
+\acmdm*{\newswitch,\setswitch,\switchon,\switchoff,\ifswitchon,
\ifswitchoff,\switchtrue,\switchfalse,\ifswitchtrue,
\ifswitchfalse}
@@ -1057,16 +1143,23 @@ Switches may be set and tested using the following commands:
\ifswitchoff{y}{\def\yy{Off}}{\def\yy{On}}
\end{example}
-Suppose the key prefix is \fx{KV}, the key family is \fx{fam}, and the key macro is \fx{mp@}. The the following works:
+\begin{macro}
+\defswitch[|cang(optional prefix)]{|cang(boolean)}[|cang(optional state)]
+\end{macro}
+\acmdm*{\defswitch}
+This is similar to \fx{\newswitch} but raises no errors even if the register \aang{boolean} already exists.
+
+Now how do we use switches in \fx{\define@keylist}? Suppose the key prefix is \fx{KV}, the key family is \fx{fam}, and the key macro is \fx{mp@}. Then the following works:
\begin{example}
-\define@keylist{3,switcha,true,
- |makered(\ifswitchon){mp@switcha}{\def\say{Swtich `a' is true}}
+\define@keylist{3,swa,true,
+ |makered(\ifswitchon){mp@swa}{\def\say{Swtich `a' is true}}
{\def\say{Swtich `a' is false}}}
-\setkeys[KV]{fam}{switcha=true |makered(or) false}
+\setkeys[KV]{fam}{swa=true |makered(or) false |makered(or) on |makered(or) off}
\end{example}
+\acmd*{\define@keylist}
-\Note Please note that switch keys are boolean keys (type~`3' key). As yet, when setting switch keys you must supply either \fx{true} or \fx{false}, not \fx{on} or \fx{off}.
+\Note Please note that ``switch keys'' are actually native-boolean keys (\fx{bool} or type~\fx{3} key). When setting native-boolean and toggle-boolean keys you can supply either \fx{true}, \fx{false}, \fx{on} or \fx{off} as values. We have modified the relevant internal macros of the \pkg{xkeyval} to make this possible for the native-boolean keys as well.
\subsubsection[Using toggles]{Using toggles to submit the conditionals}
\label{sec:using-toggles}
@@ -1074,12 +1167,12 @@ Suppose the key prefix is \fx{KV}, the key family is \fx{fam}, and the key macro
Toggle booleans, described in \cref{sec:toggles}, can also be used to circumvent the problem of matching \fx{\if} and \fx{\fi} in difficult circumstances, since toggles aren't \tex primitives, and, as noted in \cref{sec:toggles}, toggles are very economical. For example, the following works:
\begin{example}
\define@keylist{4,toga,true,
- |makered(\iftog){mp@toga}{\def\say{Toggle `a' is true}}%
+ |makered(\iftogon){mp@toga}{\def\say{Toggle `a' is true}}%
{\def\say{Toggle `a' is false}}}
\setkeys[KV]{fam}{toga= true |makered(or) false}
\end{example}
-\acmd*{\define@keylist,\iftog}
+\acmd*{\define@keylist,\iftogon}
where the key prefix, key family, and macro prefix are still assumed to be \fx{KV}, \fx{fam}, \fx{mp@}, respectively. Recall that toggle keys are type~`4' keys.
\section{Checking and redefining keys}
@@ -1431,12 +1524,12 @@ Instead of using the macro \fx{\uservaluekeys} to accumulate user-value keys, th
\define@togkey|redplus[KV]{fam}[mp@]{|makered(\guservalue{|makemac(toga)})}[true]%
{%
- \iftog{mp@toga}{\def\x{#1}}{}%
+ \iftogon{mp@toga}{\def\x{#1}}{}%
}{%
\@latex@error{Value `#1' not valid}\@ehc
}
\end{example}
-\acmd*{\newordkey,\define@togkey,\iftog}
+\acmd*{\newordkey,\define@togkey,\iftogon}
As these examples show, the newly introduced pointers (namely, \fx{\uservalue} and \fx{\guservalue}) can be used to dynamically build a list of user-value keys. See \cref{sec:pointer-mech} for more comments on pointer systems.
@@ -1492,9 +1585,9 @@ The following provide examples of new pointer features enabled by the \pkg{skeyv
\newtogkey|redplus[KV]{fam}[mp@]{|makered(\savevalue\uservalue{|makemac(toga)})}[true]%
{
- \iftog{mp@toga}{\def\x{#1}}{}%
+ \iftogon{mp@toga}{\def\x{#1}}{}%
}{%
- \@latex@error{Value '#1' not valid}\@ehc
+ \@latex@error{Value `#1' not valid}\@ehc
}
\define@cmdkey[KV]{fam}[mp@]{|makered(\uservalue\savevalue{|makemac(keyc)})}%
@@ -1504,7 +1597,7 @@ The following provide examples of new pointer features enabled by the \pkg{skeyv
[true]{%
\ifmp@boola\def\x{#1}\fi
}{%
- \@latex@error{Value '#1' not valid}\@ehc
+ \@latex@error{Value `#1' not valid}\@ehc
}
\define@cmdkey[KV]{fam}[mp@]{|makered(\guservalue\savevalue{|makemac(keyd)})}%
@@ -1527,7 +1620,7 @@ The following provide examples of new pointer features enabled by the \pkg{skeyv
\setkeys[KV]{fam}{keya=Hello World,keyb=|makered(\usevalue{|makemac(keya)})}
\end{example}
\acmd*{\define@key,\define@cmdkey,\newchoicekey,\newordkey,
-\newtogkey,\setkeys,\iftog}
+\newtogkey,\setkeys,\iftogon}
With the new mechanism of the \pkg{skeyval}, the \acmd{\gsavevalue} pointer in the command on \macref{mac:pointers:a} will ensure that \fx{\global{keyb}} (not \fx{keyb}) is inserted in the container \fx{\XKV@KV@fam@save} and that this container is updated globally after \fx{\global{keyb}} has been inserted. At \acmd{\setkeys}, in view of the entry \fx{\global{keyb}}, the value of \fx{keyb} will be saved globally. The same applies to keys \fx{boola} and \fx{align}. This thus has a double effect. Keys \fx{keyc} and \fx{keyd} will be saved locally.
@@ -1619,16 +1712,16 @@ This can be used to test whether or not one is using the \fx{\newdef} (or any ot
New definable variables can be introduced in sets by the following commands.
\begin{macro}
-\NewIfs[|cang(optional prefix)]{|cang(boolean list)}[|cang(optional state)]
+\NewBooleans[|cang(optional prefix)]{|cang(boolean list)}[|cang(optional state)]
\end{macro}
-\acmdm*{\NewIfs}
-This provides, for each member of the comma-separated list \bang{boolean list}, a new native-boolean register if the register didn't already exist, otherwise an error is flagged. Each member of \bang{boolean list} is prefixed with \aang{prefix} upon definition. The optional \aang{state} can be either \fx{true} or \fx{false}.
+\acmdm*{\NewBooleans}
+This provides, for each member of the comma-separated list \bang{boolean list}, a new native-boolean register if the register didn't already exist, otherwise an error is flagged. Each member of \bang{boolean list} is prefixed with \aang{prefix} upon definition. The optional \aang{state} can be either \fx{true}, \fx{false}, \fx{on} or \fx{off}. \fx{on} is synonymous with \fx{true}, whilst \fx{off} is equivalent to \fx{false}.
\begin{example}
-\NewIfs[bool]{a,b,c}[true]
+\NewBooleans[bool]{a,b,c}[true]
|tto \newif\ifboola \newif\ifboolb \newif\ifboolc
\boolatrue \boolbtrue \boolctrue
-\NewIfs{boold} |tto \newif\ifboold
+\NewBooleans{boold} |tto \newif\ifboold
\end{example}
Notice that members of the list \bang{boolean list} don't have \fx{\if} in their names.
@@ -1636,11 +1729,11 @@ Notice that members of the list \bang{boolean list} don't have \fx{\if} in their
\NewTogs[|cang(optional prefix)]{|cang(tog list)}[|cang(optional state)]
\end{macro}
\acmdm*{\NewTogs}
-This provides a new toggle register for each member of the comma-separated list \bang{tog list} if the register didn't already exist, otherwise an error is flagged. Each member of \bang{tog list} is prefixed with \aang{prefix} upon definition. The optional \aang{state} can be either \fx{true} or \fx{false}.
+This provides a new toggle register for each member of the comma-separated list \bang{tog list} if the register didn't already exist, otherwise an error is flagged. Each member of \bang{tog list} is prefixed with \aang{prefix} upon definition. The optional \aang{state} can be either \fx{true}, \fx{false}, \fx{on} or \fx{off}. \fx{on} is synonymous with \fx{true}, whilst \fx{off} is equivalent to \fx{false}.
\begin{example}
\NewTogs[tog]{a,b,c}[true]
|tto \newtog{toga} \newtog{togb} \newtog{togc}
- \togtrue{toga} \togtrue{togb} \togtrue{togc}
+ \togon{toga} \togon{togb} \togon{togc}
\NewTogs{togd} |tto \newtog{togd}
\end{example}
@@ -1694,7 +1787,7 @@ This allocates a new output stream for each member of the comma-separated list \
\NewWrites{writed} |tto \newwrite\writed
\end{example}
-All the macros \fx{\NewIfs}, \fx{\NewToks}, \fx{\NewCounts}, \fx{\NewDimens}, \fx{\NewBoxes}, and \fx{\NewWrites} are non-outer, unlike their primitive counterparts.
+The macros \fx{\NewBooleans}, \fx{\NewToks}, \fx{\NewCounts}, \fx{\NewDimens}, \fx{\NewBoxes}, and \fx{\NewWrites} are non-outer, unlike their primitive counterparts.
\macrosection{Defining new names}
@@ -1705,9 +1798,7 @@ All the macros \fx{\NewIfs}, \fx{\NewToks}, \fx{\NewCounts}, \fx{\NewDimens}, \f
\SKV@csxdef|redplus{|cang(name)}{|cang(definition)}
\end{macro}
\acmdm*{\SKV@csdef,\SKV@csgdef,\SKV@csedef,\SKV@csxdef}
-The unsigned variants of these turn \aang{name} into a control sequence in terms of \aang{definition} whether or not the control was already defined. No error or warning messages are issued. The plus (\RedPlus) variants turn \aang{name} into a control sequence if it wasn't already defined; if it is already defined, an error message is flagged. These derive from a concept based on that of \acmd{\newcommand}, but (i)~\relaxed\ commands are considered undefined in this regard, and (ii)~these commands retain the powerful machinery of plain \tex.
-
-\Note The \pkg{skeyval} contains other undocumented tools for defining new commands.
+The unsigned variants of these turn \aang{name} into a control sequence in terms of \aang{definition} whether or not the control was already defined. No error or warning messages are issued. The plus (\RedPlus) variants turn \aang{name} into a control sequence if it wasn't already defined; if it is already defined, an error message is flagged. These derive from a concept based on that of \acmd{\newcommand}, but (i)~\relaxed\ commands are considered undefined in this regard, and (ii)~these commands retain the powerful machinery of plain \tex.\footnote{The \pkg{skeyval} contains other undocumented tools for defining new commands.}
\macrosection{Name use}
@@ -1762,6 +1853,7 @@ The plus sign (\RedPlus) means that \fx{\SKV@dimdef} takes a control sequence na
\begin{macro}
\SKV@ifdefinable|cang(cs){|cang(function)}
+\SKV@csifdefinable|cang(cs name){|cang(function)}
\end{macro}
\acmdm*{\SKV@ifdefinable}
\latex kernel's \fx{\@ifdefinable} fills up the hash table and also considers commands that are \fx{\relax}'ed as defined. Moreover, if the command being tested (\aang{cs} in the above example) is definable, the \fx{\@ifdefinable} macro begins executing \aang{function} while still in the \fx{\if} \textellipsis \fx{\fi} conditional. You can't do \fx{\let\ifabc\iftrue} in such conditionals. The command \fx{\SKV@ifdefinable}, which is robust, seeks to avoid these problems.
@@ -1895,7 +1987,7 @@ This is similar to \fx{\SKV@exptx} but accepts control sequence name \aang{name}
\item If \aang{n} is 1, then both \aang{arg1} and \aang{arg2} are nonempty but only \aang{arg2} will be expanded before \aang{function} is executed.
\item When \aang{n} is 2, then both \aang{arg1} and \aang{arg2} are nonempty and both will be expanded before \aang{function} is executed. This is equivalent to \LaTeX's \fx{\@expandtwoargs}.
\item If \aang{n} is 3, then both \aang{arg1} and \aang{arg2} are nonempty but only \aang{arg1} is expanded before \aang{function} is executed.
-\item If \aang{n} isn't in the list \sx{0,1,2,3}, then an error message is flagged.
+\item If \aang{n} isn't in the list \hv{0,1,2,3}, then an error message is flagged.
\end{enum}
Because \aang{arg2} is delimited, it can be empty. The command \fx{\SKV@expargs} can be used to save \fx{\expandafter}'s, but caution should be exercised in deploying it: for example, the \fx{\edef} it uses may expand too deeply in some cases. Also, precaution may be necessary when the expanded arguments (\aang{arg1} and/or \aang{arg2}) involve the \tex primitive \fx{\if}. When invoking \fx{\SKV@expargs}, the macros \fx{\SKV@expox} and \fx{\SKV@exptx} can be used to control the level of expansion.
@@ -1949,28 +2041,34 @@ The reader may wish to do \fx{\show\tempa} to see what \fx{\tempa} gets upon set
\SKV@in@{|cang(substring)}{|cang(string)}
\end{macro}
\acmdm*{\SKV@in@}
-This is similar to the \latex kernel's \sz{\in@}{substring}{string} which tests if \aang{substring} is in \aang{string}, but the present test avoids the problem of false result, which is typified by the following test:
+This is similar to the \latex kernel's \hy{\in@}{substring}{string} which tests if \aang{substring} is in \aang{string}, but the present test avoids the problem of false result, which is typified by the following test:
\begin{example}
\in@{aa}{ababba}
\end{example}
This incorrectly returns \acmdm{\ifin@} as \fx{\iftrue}. The macro \fx{\SKV@in@}, on the other hand, correctly gives \fx{\ifin@} as \fx{\iffalse} in this case. The command \fx{\SKV@in@} is robust.
\begin{macro}
+\SKV@in@o{|cang(substring)}{|cang(string)}{|cang(true text)}{|cang(false text)}
+\end{macro}
+\acmdm*{\SKV@in@o}
+This is similar to \fx{\SKV@in@} but the returned result has a different syntax.
+
+\begin{macro}
\in@tog{|cang(substring)}{|cang(string)}
\end{macro}
\acmdm*{\in@tog}
In this case the returned boolean is the toggle switch \aang{in@} instead of the kernel's \aang{in@} switch which is used as \fx{\ifin@}. The toggle \aang{in@} can be used in the following way and in other manners that toggles can be employed:
\begin{example}
-\iftog{in@}{|cang(true)}{|cang(false)}.
+\iftogon{in@}{|cang(true text)}{|cang(false text)}.
\end{example}
-\acmd*{\iftog}
+\acmd*{\iftogon}
The command \fx{\in@tog} is robust.
\begin{macro}
\in@tok{|cang(substring)}{|cang(string)}
\end{macro}
\acmdm*{\in@tok}
-Sometimes you want to use the \latex kernel's \sz{\in@}{substring}{string} to test if \aang{substring} is in \aang{string} irrespective of their catcodes. The robust command \sz{\in@tok}{substring}{string} makes this possible, and eliminates the tokens that would have been necessary if the user was required to first detokenize the two arguments. It returns the same switch \fx{\ifin@} as the kernel's \sz{\in@}{substring}{string}. Actually, it calls \fx{\SKV@in@} to avoid false returns.
+Sometimes you want to use the \latex kernel's \hy{\in@}{substring}{string} to test if \aang{substring} is in \aang{string} irrespective of their catcodes. The robust command \hy{\in@tok}{substring}{string} makes this possible, and eliminates the tokens that would have been necessary if the user was required to first detokenize the two arguments. It returns the same switch \fx{\ifin@} as the kernel's \hy{\in@}{substring}{string}. Actually, it calls \fx{\SKV@in@} to avoid false returns.
\macrosection{Testing equality of strings}
@@ -2011,15 +2109,15 @@ These macros test if the argument is blank or not. The first of these is from \p
\SKV@ifnotdraft{|cang(not true)}{|cang(not false)}
\SKV@iffinal{|cang(true)}{|cang(false)}
\SKV@ifnotfinal{|cang(not true)}{|cang(not false)}
-\iftog{draft}{|cang(true)}{|cang(false)}
-\ifnottog{draft}{|cang(not true)}{|cang(not false)}
-\iftog{final}{|cang(true)}{|cang(false)}
-\ifnottog{final}{|cang(not true)}{|cang(not false)}
+\iftogon{draft}{|cang(true)}{|cang(false)}
+\iftogoff{draft}{|cang(not true)}{|cang(not false)}
+\iftogon{final}{|cang(true)}{|cang(false)}
+\iftogoff{final}{|cang(not true)}{|cang(not false)}
\end{macro}
-\acmdm*{\SKV@ifdraft,\SKV@ifnotdraft,\SKV@iffinal,\SKV@ifnotfinal,\iftog\{draft\},
-\ifnottog\{draft\},\iftog\{final\},\ifnottog\{final\}}
+\acmdm*{\SKV@ifdraft,\SKV@ifnotdraft,\SKV@iffinal,\SKV@ifnotfinal,\iftogon\{draft\},
+\iftogoff\{draft\},\iftogon\{final\},\iftogoff\{final\}}
-These execute \aang{true} or \aang{false} depending on whether \fx{draft} or \fx{final} appears as \fx{true} in the options list of \acmd{\documentclass} or \sxx{\usepackage}{skeyval}.
+These execute \aang{true} or \aang{false} depending on whether \fx{draft} or \fx{final} appears as \fx{true} in the options list of \acmd{\documentclass} or \hx{\usepackage}{skeyval}.
The default is that \fx{final} is true, which implies that \fx{draft} is false by default. The keys \fx{draft} and \fx{final} are complementary native-boolean keys (see \cref{sec:comp-boolkeys}), which reduces the risk of mixing them. These commands are robust.
\begin{macro}
@@ -2036,10 +2134,10 @@ These are also defined in the \pkg{skeyval}, but because packages such as \pkgm{
\begin{macro}
\SKV@ifpdf{|cang(true)}{|cang(false)}
\SKV@ifnotpdf{|cang(not true)}{|cang(not false)}
-\iftog{pdf}{|cang(true)}{|cang(false)}
-\ifnottog{pdf}{|cang(not true)}{|cang(not false)}
+\iftogon{pdf}{|cang(true)}{|cang(false)}
+\iftogoff{pdf}{|cang(not true)}{|cang(not false)}
\end{macro}
-\acmdm*{\SKV@ifpdf,\SKV@ifnotpdf,\iftog\{pdf\},\ifnottog\{pdf\}}
+\acmdm*{\SKV@ifpdf,\SKV@ifnotpdf,\iftogon\{pdf\},\iftogoff\{pdf\}}
These execute \aang{true} or \aang{false} depending on whether \fx{dvi} or \fx{pdf} output is being produced. These commands are robust and may be used in expansion contexts.
\begin{macro}
@@ -2049,7 +2147,7 @@ These execute \aang{true} or \aang{false} depending on whether \fx{dvi} or \fx{p
\acmdm*{\ifpdf,\ifnotpdf}
These are available only if they haven't been previously defined by another package. If they existed outside the \pkg{skeyval}, a warning is logged in the transcript log file (if the package option \fx{verbose} is selected), but only once, and the commands are not redefined. In particular, the above \fx{\ifpdf} is available only at \acmd{\AtBeginDocument} and is defined only if it doesn't already exist. The reason is that the popular \pkg{hyperref} loads the \pkg{ifpdf} and the \pkg{ifpdf} will abort if it detects that \fx{\ifpdf} has been defined by a package loaded earlier.
-\Note The \fx{\ifpdf} command of the \pkg{ifpdf} is used in the \fx{\if} \ldots \fx{\else} \ldots \fx{\fi} conditional, while the above \fx{\ifpdf} command is used as indicated above. You can use the \acmd{\TestProvidedCommand} macro to check the version of the \fx{\ifpdf} that you are using.
+\Note The \fx{\ifpdf} command of the \pkg{ifpdf} is used in the \fx{\if} \ldots \fx{\else} \ldots \fx{\fi} conditional, while the above \fx{\ifpdf} command is used as indicated above. You can use the \acmd{\TestProvidedCommand} macro to check the version of the \fx{\ifpdf} command that you are using.
\macrosection{Tests related to package loading}
@@ -2100,7 +2198,7 @@ The function \fx{\SKV@onlypackage} may be used to restrict commands to packages
\end{macro}
\acmdm*{\SKV@aftergroup,\SKV@aftergroup*,\SKV@afterassignment,\SKV@afterassignment*}
-\tex's \fx{\aftergroup} and \fx{\afterassignment} don't accept arbitrary code. These commands execute the arbitrary \aang{code} after a group or assignment. The starred variants expand \aang{code} once before the assignment or before exiting the group. These commands don't accumulate the group and assignment counters indefinitely: the counters are initialized after each group or each assignment.
+\tex's \fx{\aftergroup} and \fx{\afterassignment} don't accept arbitrary code. The commands \fx{\SKV@aftergroup} and \fx{\SKV@afterassignment} execute the arbitrary \aang{code} after a group or assignment. The starred variants expand \aang{code} once before the assignment or before exiting the group. These commands don't accumulate the group and assignment counters indefinitely: the counters are initialized after each group or each assignment.
Some examples follow:
\begin{example}
@@ -2127,8 +2225,8 @@ Some examples follow:
\endgroup
\endgroup
|makered(\end{document})
-
\end{example}
+\acmd*{\begin\{document\}}
\macrosection{List processing}
@@ -2137,13 +2235,13 @@ Some examples follow:
\SKV@for@b|cang(listcmd)|cang(cmd){|cang(function)}
\end{macro}
\acmdm*{\SKV@for@a,\SKV@for@b}
-These are fast for-loops that accept general list parsers and allow for list breaks, as well as give the remainder of the list if a break occurs within the list. Elements of \aang{list} are stored in \aang{cmd}, and \aang{function} is executed for each element of \aang{list}. The \aang{list}, which is populated by parser-separated elements, is not expanded before the iteration, but \aang{listcmd} is expanded once before the commencement of the loop. The list parser is dynamically declarable via
+These are fast for-loops that accept general list parsers and allow for list breaks, as well as give the remainder of the list if a break occurs within the list. Elements of \aang{list} are stored in \aang{cmd}, and \aang{function} is executed for each element of \aang{list}. \aang{list}, which is populated by parser-separated elements, is not expanded before the iteration; \aang{listcmd}, on the other hand, is expanded once before the commencement of the loop. The list parser is dynamically declarable via
\begin{macro}
\SKV@CommandGenParser{|cang(parser)} |orr
-\skvoptions{genparser=|cang(parser)},
+\skvoptions{genparser=|cang(parser)}
\end{macro}
\acmdm*{\SKV@CommandGenParser}
-Also, these iteration macros use the more powerful \acmd{\SKV@ifblank} to check whether or not \aang{list} is empty or blank. The commands \fx{\SKV@for@a} and \fx{\SKV@for@b} are robust, but in expansion contexts, both \aang{cmd} and \aang{function} will need to be protected. In the \fx{\SKV@for@b} command, \aang{listcmd} is expanded once before the iteration commences. The \aang{parser} persists in effect until it is changed by another call to \fx{\SKV@CommandGenParser} or \acmd{\skvoptions} as above.
+Also, these iteration macros use the more powerful \acmd{\SKV@ifblank} to check whether or not \aang{list} is empty or blank. The commands \fx{\SKV@for@a} and \fx{\SKV@for@b} are robust, but in expansion contexts, both \aang{cmd} and \aang{function} will need to be protected. The \aang{parser} persists in effect until it is changed by another call to \fx{\SKV@CommandGenParser} or \acmd{\skvoptions} as above.
\Note One snag with a generic list parser like \fx{\SKV@CommandGenParser} is that the user must always remember to call it and set the right parser before beginning an iteration, otherwise there might be unpleasant results, since a previous call to \fx{\SKV@CommandGenParser} might have set a parser that is no longer valid. To obviate this type of situation, the following commands are also provided in the \pkg{skeyval}:
\begin{macro}
@@ -2329,7 +2427,7 @@ The following change history highlights significant changes that affect user uti
\begin{versionhist}
\begin{version}{0.1}{2010/01/01}
- \item First public release under the name \pkg{keyreader}\xecref
+ \item First public release under the name \pkg{keyreader}\xsecref
\item Introduced complementary native-boolean keys \secref{sec:comp-boolkeys}
\item Provided machinery for reading multiple keys of all kinds from just one command \secref{sec:multiplekeys}
\end{version}
@@ -2347,7 +2445,7 @@ The following change history highlights significant changes that affect user uti
\end{version}
\begin{version}{0.5}{2010/02/23}
- \item Changed the name of the package from \pkg{keyreader} to \pkg{skeyval}\xecref
+ \item Changed the name of the package from \pkg{keyreader} to \pkg{skeyval}\xsecref
\item Introduced the following macros\secref{sec:status-keys}
\begin{veritem}
\ifkeydefined, \ifkeyreserved, \ifkeysuspended
@@ -2363,6 +2461,7 @@ The following change history highlights significant changes that affect user uti
\define@biuniboolkeys, \newbiuniboolkeys,
\define@biunitogkeys, \newbiunitogkeys
\end{veritem}
+
\acmd*{\newordkey,\newcmdkey,\newboolkey,\newchoicekey,\newtogkey,
\define@biboolkeys,\newbiboolkeys,\define@bitogkeys,\newbitogkeys,
\define@uniboolkeys,\newuniboolkeys,\define@unitogkeys,\newunitogkeys,
@@ -2370,7 +2469,7 @@ The following change history highlights significant changes that affect user uti
\item Provided mechanisms for disabling, localizing, reserving, unreserving, suspending, restoring, and removing keys \secref{sec:disable-reserv-keys}
- \item Redefined a few of \pkg{xkeyval}'s internal macros
+ \item Redefined a few of \pkg{xkeyval}'s internal macros \xsecref
\item Normalization of key-value lists before parsing \secref{sec:list-normal}
@@ -2384,6 +2483,7 @@ The following change history highlights significant changes that affect user uti
\ReserveMacroPrefixNames, \ReserveMacroPrefixNames|redstar,
\ReserveFamilyNames, \ReserveFamilyNames|redstar
\end{veritem}
+
\acmd*{\ReserveKeyPrefixNames,\ReserveMacroPrefixNames,\ReserveFamilyNames,
\ReserveKeyPrefixNames*,\ReserveMacroPrefixNames*,\ReserveFamilyNames*}
@@ -2396,8 +2496,9 @@ The following change history highlights significant changes that affect user uti
\SKV@AfterDocumentEnd, \SKV@onlypreamble,
\SKV@onlypackage, \SKV@ifdraft, \SKV@iffinal,
\SKV@ifpdf, \@ensurepackageloaded, \InputFileOnce,
- \newswitch, etc.
+ \newswitch, \defswitch, etc.
\end{veritem}
+
\acmd*{\SKV@AtPackageEnd,\SKV@BeforePackageEnd,\SKV@AfterPackageEnd,
\SKV@AtDocumentEnd,\SKV@BeforeLastPage,\SKV@AfterLastPage,\InputFileOnce,
\SKV@AfterDocumentEnd,\SKV@onlypreamble,\SKV@ifdraft,\SKV@iffinal,\SKV@ifpdf,
@@ -2408,13 +2509,23 @@ The following change history highlights significant changes that affect user uti
\item Introduced ``user-value'' keys \secref{sec:uservaluekeys}
\item Extended the pointer system of the \pkg{xkeyval} \secref{sec:pointer-mech}
- \item Corrected a bug in the \pkg{xkeyval} which, if \acmd{\setkeys} are nested in a class file, gives non-empty \acmdm{\@unusedoptionlist} even if all the options of \acmd{\documentclass} have been used \xecref
+ \item Corrected a bug in the \pkg{xkeyval} which, if \acmd{\setkeys} are nested in a class file, gives non-empty \acmdm{\@unusedoptionlist} even if all the options of \acmd{\documentclass} have been used \xsecref
+ \end{version}
+
+ \begin{version}{0.7}{2010/05/05}
+ \item Native-boolean and toggle-boolean keys now accept \fx{on} and \fx{off} as values,
+ in addition to \fx{true} and \fx{false} \secref*{sec:toggle-booleans}{sec:switches}
+
+ \item Replaced the former \acmd{\NewIfs} with \acmd{\NewBooleans} and redefined \fx{\NewIfs} \secref{sec:biboolkeys}
+
+ \item Introduced \acmd{\DeclareKeyCommand} \secref{sec:keycommand}
+
\end{version}
\end{versionhist}
\IndexPreamble{Index numbers refer to page numbers.}
-\IndexPreambleAlign{\centering}
+\IndexPreambleFormat{\centering}
\IndexColumns\tw@
\printindex
\end{document}
diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval.sty b/Master/texmf-dist/tex/latex/skeyval/skeyval.sty
index 203a412dbc4..3178e0be5e4 100644
--- a/Master/texmf-dist/tex/latex/skeyval/skeyval.sty
+++ b/Master/texmf-dist/tex/latex/skeyval/skeyval.sty
@@ -1,6 +1,6 @@
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% %
-% This is file 'skeyval.sty', version 0.6. %
+% This is file 'skeyval.sty', version 0.7. %
% %
% This package and accompanying files may be distributed and/or %
% modified under the conditions of the LaTeX Project Public License, %
@@ -71,7 +71,7 @@
\SKV@setcode{126}{13}% ~
\def\SKV@rcsid$#1: #2 #3 #4 #5${#4 v#3}
\ProvidesPackage{skeyval}%
- [\SKV@rcsid $Id: skeyval.sty,v 0.6 2010/04/20 09:00:00 Ahmed Musa $
+ [\SKV@rcsid $Id: skeyval.sty,v 0.7 2010/05/05 09:00:00 Ahmed Musa $
Extensions to the xkeyval parser (AM)]
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\ifnum0=0%
@@ -83,17 +83,18 @@
\fi
\newtoks\SKV@toks
\newcount\SKV@depth
-\def\@nil{\@unexpandable@protect\@nil}
+\protected\def\@nil{\@nil}
\def\@nnil{\@nil}
+\long\def\@gobblethree#1#2#3{}
\long\def\SKV@car#1#2\@nil{#1}
\long\def\SKV@cdr#1#2\@nil{#2}
\long\def\SKV@carcube#1#2#3#4\@nil{#1#2#3}
\long\def\@firstofthree#1#2#3{#1}
\long\def\@secondofthree#1#2#3{#2}
\long\def\@thirdofthree#1#2#3{#3}
-\newcommand*\@threeexpafter{\expandafter\expandafter\expandafter}
+\def\SKV@threeafter{\expandafter\expandafter\expandafter}
\def\SKV@aftercs#1#2{\expandafter#1\csname#2\endcsname}
-\def\SKV@xaftercs#1#2{\@threeexpafter#1\csname#2\endcsname}
+\def\SKV@xaftercs#1#2{\SKV@threeafter#1\csname#2\endcsname}
\SKV@aftercs\let{SKV@1of1}\@firstofone
\SKV@aftercs\let{SKV@1of2}\@firstoftwo
\SKV@aftercs\let{SKV@2of2}\@secondoftwo
@@ -111,10 +112,11 @@
\def\SKV@unifxcs#1#2{\begingroup\expandafter\endgroup\expandafter
\SKV@unifx\expandafter#1\csname#2\endcsname}
\def\SKV@ifdefined#1{\@nameuse{SKV@\ifdefined#11\else2\fi of2}}
-\def\SKV@unifdefined#1{\@nameuse{SKV@\ifdefined#12\else1\fi of2}}
+\def\SKV@unifdefined#1{\@nameuse{SKV@\SKV@ifdefined{#1}{2}{1}of2}}
\def\SKV@ifcsname#1{\@nameuse{SKV@\ifcsname#1\endcsname1\else2\fi of2}}
-\def\SKV@unifcsname#1{\@nameuse{SKV@\ifcsname#1\endcsname2\else1\fi of2}}
-\def\SKV@iftest#1#2{\@nameuse{SKV@\@nameuse{#1}#21\else2\fi of2}}
+\def\SKV@unifcsname#1{\@nameuse{SKV@\SKV@ifcsname{#1}{2}{1}of2}}
+\def\SKV@iftest#1#2{\@nameuse{SKV@\@nameuse{if#1}#21\else2\fi of2}}
+\def\SKV@uniftest#1#2{\@nameuse{SKV@\SKV@iftest{#1}{#2}{2}{1}of2}}
\begingroup
\def\SKV@tempa{%
\def\SKV@nodocerr{%
@@ -153,6 +155,12 @@
\def\SKV@ifdefinable#1{%
\begingroup\escapechar92\afterassignment\endgroup
\xdef\reserved@a{\expandafter\@gobble\string#1}%
+ \edef\resvd@a{\expandafter\SKV@car\string#1\@nil}%
+ \SKV@ifx\resvd@a\@backslashchar{}{%
+ \PackageError{skeyval}{Backslash required}{Backslash
+ required in argument of '\string\SKV@ifdefinable'.}%
+ }%
+ \let\resvd@a\SKV@undefined
\SKV@ifdefined#1{%
\SKV@ifx{#1}\relax\@firstofone\@notdefinable
}{%
@@ -161,34 +169,33 @@
{\SKV@ifx\reserved@a\@qrelax\@notdefinable\@firstofone}%
}%
}
+\def\SKV@csifdefinable#1{\begingroup\expandafter\endgroup
+ \expandafter\SKV@ifdefinable\csname#1\endcsname}
\newcommand*\@ifpackagecurrent[2]{%
- \@nameuse{SKV@\SKV@iftest{ifnum}{\@threeexpafter\@parse@version
+ \@nameuse{SKV@\SKV@iftest{num}{\SKV@threeafter\@parse@version
\csname ver@#1.\@pkgextension\endcsname//00\@nil
<\expandafter\@parse@version#2//00\@nil}{2}{1}of2}}
\newcommand*\@ifpackagenotcurrent[2]{%
\@nameuse{SKV@\@ifpackagecurrent{#1}{#2}{2}{1}of2}}
\@ifpackageloaded{xkeyval}{%
\@ifpackagecurrent{xkeyval}{2008/08/13}{}{%
- \PackageError{skeyval}{%
- Your loaded version of xkeyval package is not current
- }{%
- You need version 2.6a (or higher) of xkeyval package.
+ \PackageError{skeyval}{Your loaded version of xkeyval
+ package is not current}{You need version 2.6a
+ (or higher) of xkeyval package.
}%
\endinput
}%
}{\RequirePackage{xkeyval}[2008/08/13]}
-\SKV@ifdefinable\SKV@ifdefinable@n\relax
-\protected\def\SKV@ifdefinable@n#1{%
+\newcommand\SKV@ifdefinable@n[1]{%
\XKV@sp@deflist\SKV@tempa{#1}%
\XKV@for@o\SKV@tempa\SKV@tempa{%
- \edef\resvd@a{\@threeexpafter\SKV@car
+ \edef\resvd@a{\SKV@threeafter\SKV@car
\expandafter\string\SKV@tempa\@nil}%
- \ifx\resvd@a\@backslashchar
+ \SKV@unifx\resvd@a\@backslashchar{}{%
\PackageError{skeyval}{Backslash not allowed}{Backslash not
allowed in argument of '\string\SKV@ifdefinable@n'.}%
- \fi
- \@threeexpafter\SKV@ifdefinable
- \expandafter\csname\SKV@tempa\endcsname\relax
+ }%
+ \SKV@csifdefinable\SKV@tempa\relax
}%
}
\SKV@ifdefinable@n{SKV@def,SKV@@def,SKV@pdef,SKV@@pdef,
@@ -283,7 +290,7 @@
\SKV@def*\SKV@savstate{\SKV@state{1}{@\romannumeral\SKV@depth}{}}
\SKV@def*\SKV@resstate{\SKV@state{1}{}{@\romannumeral\SKV@depth}}
\def\XKV@srstate#1#2{\SKV@state{0}{#1}{#2}}
-\def\SKV@scantoks#1#2{%
+\def\SKV@scantoksa#1#2{%
\begingroup
\edef\SKV@tempa{\endgroup
\unexpanded{%
@@ -296,47 +303,34 @@
}%
\SKV@tempa
}
-\SKV@def\SKV@newcs#1#2{%
+\def\SKV@scantoksb#1{%
+ \begingroup
+ \everyeof{\noexpand}%
+ \endlinechar\m@ne
+ \xdef#1{\scantokens\expandafter{#1}}%
+ \endgroup
+}
+\SKV@def*\SKV@newcs#1#2{%
\SKV@ifcsname{#2}{%
\SKV@csifx{#2}\relax{}{\def\reserved@a{#2}\@notdefinable}%
}{\SKV@aftercs{#1}{#2}}%
}
-\SKV@pdef*\SKV@csdef{\SKV@savstate\SKV@t@st@pta\SKV@@csdef}
-\SKV@def*\SKV@@csdef#1{%
+\SKV@def*\SKV@n@wcs#1#2{%
\ifSKV@pl
- \let\SKV@n@xt\SKV@newcs
+ \let\SKV@next\SKV@newcs
\else
- \let\SKV@n@xt\SKV@aftercs
+ \let\SKV@next\SKV@aftercs
\fi
- \SKV@resstate\SKV@n@xt\def{#1}%
+ \SKV@resstate\SKV@next#1{#2}%
}
+\SKV@pdef*\SKV@csdef{\SKV@savstate\SKV@t@st@pta\SKV@@csdef}
+\SKV@def*\SKV@@csdef#1{\SKV@n@wcs\def{#1}}
\SKV@pdef*\SKV@csgdef{\SKV@savstate\SKV@t@st@pta\SKV@@csgdef}
-\SKV@def*\SKV@@csgdef#1{%
- \ifSKV@pl
- \let\SKV@n@xt\SKV@newcs
- \else
- \let\SKV@n@xt\SKV@aftercs
- \fi
- \SKV@resstate\SKV@n@xt\gdef{#1}%
-}
+\SKV@def*\SKV@@csgdef#1{\SKV@n@wcs\gdef{#1}}
\SKV@pdef*\SKV@csedef{\SKV@savstate\SKV@t@st@pta\SKV@@csedef}
-\SKV@def*\SKV@@csedef#1{%
- \ifSKV@pl
- \let\SKV@n@xt\SKV@newcs
- \else
- \let\SKV@n@xt\SKV@aftercs
- \fi
- \SKV@resstate\SKV@n@xt\edef{#1}%
-}
+\SKV@def*\SKV@@csedef#1{\SKV@n@wcs\edef{#1}}
\SKV@pdef*\SKV@csxdef{\SKV@savstate\SKV@t@st@pta\SKV@@csxdef}
-\SKV@def*\SKV@@csxdef#1{%
- \ifSKV@pl
- \let\SKV@n@xt\SKV@newcs
- \else
- \let\SKV@n@xt\SKV@aftercs
- \fi
- \SKV@resstate\SKV@n@xt\xdef{#1}%
-}
+\SKV@def*\SKV@@csxdef#1{\SKV@n@wcs\xdef{#1}}
\SKV@def*\SKV@csuse#1{\SKV@ifcsname{#1}{\@nameuse{#1}}{}}
\SKV@pdef\SKV@expargs#1#2#3#4\@nil{%
\begingroup
@@ -397,7 +391,7 @@
}
\SKV@pdef\SKV@ifbrack#1#2{\SKV@ifnextchar[{#1}{#2}}
\SKV@pdef\SKV@ifparen#1#2{\SKV@ifnextchar({#1}{#2}}
-\SKV@pdef*\SKV@testopt#1#2{\SKV@ifnextchar[{#1}{#1[{#2}]}}
+\SKV@pdef*\SKV@testopt#1#2{\SKV@ifbrack{#1}{#1[{#2}]}}
\SKV@pdef*\SKV@testopta#1{\SKV@t@stopta{\SKV@t@st@pta{#1}}}
\SKV@pdef*\SKV@t@stopta#1{\SKV@ifstar{\SKV@sttrue#1}{\SKV@stfalse#1}}
\SKV@pdef*\SKV@t@st@pta#1{\SKV@ifplus{\SKV@pltrue#1}{\SKV@plfalse#1}}
@@ -422,38 +416,86 @@
\SKV@pdef*\SKV@NewWrites[#1]#2{%
\SKV@for[,]{#2}\SKV@tempa{%
\SKV@expnext\SKV@ensurenoscape\SKV@tempa
- \SKV@aftercs\SKV@ifdefinable{#1\SKV@tempa}{%
+ \SKV@csifdefinable{#1\SKV@tempa}{%
\@nameuse{newwrite\SKV@aftercs}{#1\SKV@tempa}%
}%
}%
}
\SKV@pdef*\NewIfs{\SKV@testopt\SKV@NewIfs{}}
-\SKV@pdef*\SKV@NewIfs[#1]#2{\SKV@testopt{\SKV@NewIf@[#1]{#2}}{false}}
-\SKV@pdef*\SKV@NewIf@[#1]#2[#3]{%
+\SKV@pdef*\SKV@NewIfs[#1]#2{\SKV@testopt{\SKV@New@Ifs[#1]{#2}}{false}}
+\SKV@pdef*\SKV@New@Ifs[#1]#2[#3]{%
+ \SKV@for[,]{#2}\SKV@tempa{%
+ \SKV@expnext\SKV@ensurenoscape\SKV@tempa
+ \begingroup
+ \SKV@oifstrequal{\SKV@tempa}{x}{\SKV@swnameerr{x}}%
+ {\SKV@oifstrequal{\SKV@tempa}{on}{\SKV@swnameerr{on}}%
+ {\SKV@oifstrequal{\SKV@tempa}{off}{\SKV@swnameerr{off}}%
+ {\SKV@oifstrequal{\SKV@tempa}{tog}{\SKV@swnameerr{tog}}%
+ {\SKV@oifstrequal{\SKV@tempa}{switch}{\SKV@swnameerr{switch}}%
+ {}}}}}\endgroup
+ \SKV@csifdefinable{if#1\SKV@tempa}{%
+ \SKV@aftercs\SKV@New@If@{if#1\SKV@tempa}%
+ \@nameuse{#1\SKV@tempa#3}%
+ }%
+ }%
+}
+\def\SKV@New@If@#1{%
+ \@tempcnta\escapechar\escapechar\m@ne
+ \let#1\iffalse
+ \SKV@If#1\iftrue
+ \SKV@If#1\iffalse
+ \let\ifon\iftrue
+ \let\ifoff\iffalse
+ \SKV@If#1\ifon
+ \SKV@If#1\ifoff
+ \escapechar\@tempcnta
+}
+\def\SKV@If#1#2{%
+ \SKV@aftercs\def{\expandafter\@gobbletwo\string#1%
+ \expandafter\@gobbletwo\string#2}{\let#1#2}%
+}
+\SKV@pdef*\csnewif{\SKV@aftercs\newif}
+\SKV@pdef*\csnewtoks{\SKV@aftercs\newtoks}
+\SKV@pdef*\csnewcount{\SKV@aftercs\newcount}
+\SKV@pdef*\csnewdimen{\SKV@aftercs\newdimen}
+\SKV@pdef*\csnewbox{\SKV@aftercs\newbox}
+\SKV@pdef*\NewBooleans{\SKV@testopt\SKV@NewBooleans{}}
+\SKV@pdef*\SKV@NewBooleans[#1]#2{%
+ \SKV@testopt{\SKV@New@Booleans[#1]{#2}}{false}}
+\SKV@pdef*\SKV@New@Booleans[#1]#2[#3]{%
+ \SKV@getswstate\NewBooleans{#3}%
\SKV@for[,]{#2}\SKV@tempa{%
\SKV@expnext\SKV@ensurenoscape\SKV@tempa
- \SKV@aftercs\SKV@ifdefinable{if#1\SKV@tempa}{%
- \@nameuse{newif\SKV@aftercs}{if#1\SKV@tempa}%
- \@nameuse{#1\SKV@tempa#3}%
+ \SKV@oifstrequal{\SKV@tempa}{tog}{%
+ \SKV@err{'tog' not allowed as a boolean name}\@ehc
+ }{%
+ \SKV@oifstrequal{\SKV@tempa}{switch}{%
+ \SKV@err{'switch' not allowed as a boolean name}\@ehc
+ }{}%
+ }%
+ \SKV@csifdefinable{if#1\SKV@tempa}{%
+ \csnewif{if#1\SKV@tempa}%
+ \@nameuse{#1\SKV@tempa\SKV@resvd}%
}%
}%
}
\SKV@pdef*\NewTogs{\SKV@testopt\SKV@NewTogs{}}
\SKV@pdef*\SKV@NewTogs[#1]#2{\SKV@testopt{\SKV@NewT@gs[#1]{#2}}{false}}
\SKV@pdef*\SKV@NewT@gs[#1]#2[#3]{%
+ \SKV@getswstate\NewTogs{#3}%
\SKV@for[,]{#2}\SKV@tempa{%
\SKV@expnext\SKV@ensurenoscape\SKV@tempa
\edef\SKV@tempa{#1\SKV@tempa}%
\SKV@expnext\newtog\SKV@tempa
- \@nameuse{tog#3\SKV@expnext}\SKV@tempa
+ \@nameuse{tog\SKV@resvd\SKV@expnext}\SKV@tempa
}%
}
\SKV@pdef*\NewToks{\SKV@testopt\SKV@NewToks{}}
\SKV@pdef*\SKV@NewToks[#1]#2{%
\SKV@for[,]{#2}\SKV@tempa{%
\SKV@expnext\SKV@ensurenoscape\SKV@tempa
- \SKV@aftercs\SKV@ifdefinable{#1\SKV@tempa}{%
- \@nameuse{newtoks\SKV@aftercs}{#1\SKV@tempa}%
+ \SKV@csifdefinable{#1\SKV@tempa}{%
+ \csnewtoks{#1\SKV@tempa}%
}%
}%
}
@@ -461,8 +503,8 @@
\SKV@pdef*\SKV@NewCounts[#1]#2{%
\SKV@for[,]{#2}\SKV@tempa{%
\SKV@expnext\SKV@ensurenoscape\SKV@tempa
- \SKV@aftercs\SKV@ifdefinable{#1\SKV@tempa}{%
- \@nameuse{newcount\SKV@aftercs}{#1\SKV@tempa}%
+ \SKV@csifdefinable{#1\SKV@tempa}{%
+ \csnewcount{#1\SKV@tempa}%
}%
}%
}
@@ -470,8 +512,8 @@
\SKV@pdef*\SKV@NewDimens[#1]#2{%
\SKV@for[,]{#2}\SKV@tempa{%
\SKV@expnext\SKV@ensurenoscape\SKV@tempa
- \SKV@aftercs\SKV@ifdefinable{#1\SKV@tempa}{%
- \@nameuse{newdimen\SKV@aftercs}{#1\SKV@tempa}%
+ \SKV@csifdefinable{#1\SKV@tempa}{%
+ \csnewdimen{#1\SKV@tempa}%
}%
}%
}
@@ -479,8 +521,8 @@
\SKV@pdef*\SKV@NewBoxes[#1]#2{%
\SKV@for[,]{#2}\SKV@tempa{%
\SKV@expnext\SKV@ensurenoscape\SKV@tempa
- \SKV@aftercs\SKV@ifdefinable{#1\SKV@tempa}{%
- \@nameuse{newbox\SKV@aftercs}{#1\SKV@tempa}%
+ \SKV@csifdefinable{#1\SKV@tempa}{%
+ \csnewbox{#1\SKV@tempa}%
}%
}%
}
@@ -491,33 +533,15 @@
\SKV@ifblank{#2}{%
\SKV@err{Arguments of '\string\SKV@expnext' can't be empty}\@ehc
}{%
- \SKV@iftest{if}{@\detokenize\expandafter{\SKV@cdr#1\@nil}@}{%
+ \SKV@iftest{}{@\detokenize\expandafter{\SKV@cdr#1\@nil}@}{%
\expandafter#1\expandafter{#2}%
}{%
\SKV@err{Invalid arguments '\string#1' for
- '\string\SKV@expnext'\SKV@MB}\@ehc
+ '\string\SKV@expnext'}\@ehc
}%
}%
}%
}
-\SKV@pdef*\SKV@DelayedAfterPackageEnd#1{%
- \AtEndOfPackage{\SKV@AfterPackageEnd{#1}}}
-\SKV@def\DeclarePackageCommand#1#2{%
- \SKV@ensurescape{#2}%
- \SKV@ifdefined#2{%
- \edef\resvd@a{\expandafter\@gobble\string#2}%
- \SKV@aftercs\let{Saved\resvd@a}#2%
- \edef\resvd@a##1{%
- \SKV@DelayedAfterPackageEnd{##1Saved\resvd@a\noexpand\endcsname}%
- }%
- \resvd@a{\expandafter\let\expandafter#2\csname}%
- \let\resvd@a\relax
- }{\SKV@DelayedAfterPackageEnd{\SKV@gundef#2}}%
- #1#2%
-}
-\DeclarePackageCommand{\protected\def}\@namegdef{\SKV@aftercs\gdef}
-\DeclarePackageCommand{\protected\def}\@nameedef{\SKV@aftercs\edef}
-\DeclarePackageCommand{\protected\def}\@namexdef{\SKV@aftercs\xdef}
\SKV@pdef*\SKV@ifnew{\SKV@savstate\SKV@t@stopte\SKV@@ifnew}
\SKV@def*\SKV@@ifnew[#1]#2{%
\ifSKV@st
@@ -570,26 +594,28 @@
\expandafter\endgroup\expandafter\afterassignment
\csname SKV@aft@rassignm@nt\SKV@no\endcsname
}
-\SKV@def*\SKV@trailead#1#2{%
- \edef\SKV@trail{\the\SKV@toks}%
- \SKV@toks\expandafter{\romannumeral-`\q\SKV@tr@ilead\noexpand#1& &}%
+\SKV@def*\SKV@sp@def#1#2{%
+ \edef\@sp@def{\the\SKV@toks}%
+ \SKV@toks\expandafter{%
+ \romannumeral-`\q\SKV@@sp@def\noexpand\noexpand#1& &}%
\edef#2{\the\SKV@toks}%
- \SKV@toks\expandafter{\SKV@trail}%
- \SKV@undef\SKV@trail
+ \SKV@toks\expandafter{\@sp@def}%
+ \SKV@undef\@sp@def
}
-\SKV@def*\SKV@tr@ilead#1 &{\SKV@tr@ile@d#1&}
-\SKV@def*\SKV@tr@ile@d#1&#2{\romannumeral-`\q#1}
+\SKV@def*\SKV@@sp@def#1 &{\SKV@@sp@d@f#1&}
+\SKV@def*\SKV@@sp@d@f#1&#2{\romannumeral-`\q#1}
\SKV@def*\SKV@expox#1{\unexpanded\expandafter{#1}}
\SKV@def*\SKV@expcsox#1{\SKV@aftercs\SKV@expox{#1}}
-\SKV@def*\SKV@exptx#1{\unexpanded\@threeexpafter{#1}}
+\SKV@def*\SKV@exptx#1{\unexpanded\SKV@threeafter{#1}}
\SKV@def*\SKV@expcstx#1{\SKV@aftercs\SKV@exptx{#1}}
\SKV@pdef*\SKV@undef#1{\let#1\SKV@undefined}
\SKV@pdef\SKV@gundef{\global\SKV@undef}
\SKV@pdef*\SKV@csundef#1{\SKV@aftercs\SKV@undef{#1}}
\SKV@pdef*\SKV@csgundef{\global\SKV@csundef}
-\SKV@pdef*\SKV@undeflt#1#2{%
- \SKV@ifempty{#1}{\let\glob@lrel@x\relax}{\let\glob@lrel@x\global}%
- \SKV@for[,]{#2}\SKV@resvd{%
+\SKV@pdef*\SKV@undeflist/#1/#2/{%
+ \SKV@ifempty{#1}%
+ {\let\glob@lrel@x\relax}{\let\glob@lrel@x\global}%
+ \XKV@for@n{#2}\SKV@resvd{%
\SKV@expnext\SKV@ensurescape\SKV@resvd
\glob@lrel@x\expandafter\SKV@undef\SKV@resvd
}%
@@ -613,7 +639,7 @@
\ifSKV@pl
\SKV@despace\SKV@ndl
\ifSKV@ask\expandafter\global\fi
- \@threeexpafter\let
+ \SKV@threeafter\let
\expandafter\csname\SKV@ndl\endcsname\SKV@undefined
\else
\ifSKV@ask\expandafter\global\fi
@@ -633,6 +659,20 @@
\relax{2}{1}of2}}\@secondoftwo
}
\SKV@def*\SKV@ifcsundef#1{\@nameuse{SKV@\SKV@ifcsdef{#1}{2}{1}of2}}
+\SKV@pdef*\SKV@AtEndAfterPackageEnd#1{%
+ \AtEndOfPackage{\SKV@AfterPackageEnd{#1}}}
+\SKV@def\DeclarePackageCommand#1#2{%
+ \SKV@ensurescape{#2}%
+ \SKV@ifdef#2{%
+ \edef\resvd@a{\expandafter\@gobble\string#2}%
+ \SKV@cslet{Saved\resvd@a}#2%
+ \edef\resvd@a##1{%
+ \SKV@AtEndAfterPackageEnd{##1Saved\resvd@a\noexpand\endcsname}}%
+ \resvd@a{\expandafter\let\expandafter#2\csname}%
+ \SKV@undef\resvd@a
+ }{\SKV@AtEndAfterPackageEnd{\SKV@Undef?#2}}%
+ #1#2%
+}
\SKV@pdef*\SKV@providedef{\@star@or@long\SKV@@providedef}
\SKV@def\SKV@@providedef#1{%
\edef\SKV@prov@d{\expandafter\@gobble\string#1}%
@@ -729,9 +769,10 @@
}
\SKV@def*\SKV@despace#1{%
\SKV@ensurescape{#1}%
- \SKV@expnext\SKV@trailead{#1}#1%
+ \SKV@expnext\SKV@sp@def{#1}#1%
}
-\SKV@def\SKV@detokdespace#1#2{\edef#2{\detokenize{#1}}\SKV@despace#2}
+\SKV@def\SKV@detokdespace#1{%
+ \edef#1{\detokenize\expandafter{#1}}\SKV@despace#1}
\SKV@def\SKV@ifblank#1{\SKV@ifbl@nk#1&&\@secondoftwo\@firstoftwo:}
\SKV@def\SKV@ifbl@nk#1#2&#3#4#5:{#4}
\SKV@def\SKV@ifnotblank#1{\SKV@ifbl@nk#1&&\@firstoftwo\@secondoftwo:}
@@ -739,7 +780,8 @@
\SKV@def\SKV@xifblank#1{\SKV@expargs{0}\SKV@ifblank{#1}\@nil}
\SKV@def\SKV@ifstrequal#1#2{%
\begingroup
- \SKV@detokdespace{#1}\resvd@a\SKV@detokdespace{#2}\resvd@b
+ \def\resvd@a{#1}\def\resvd@b{#2}%
+ \SKV@detokdespace\resvd@a\SKV@detokdespace\resvd@b
\expandafter\aftergroup
\csname SKV@\SKV@ifx\resvd@a\resvd@b{1}{2}of2\endcsname
\endgroup
@@ -762,7 +804,7 @@
}%
\def\SKV@t@mp##1\@nil{%
\ifx\@temptoks\@sptoken
- \SKV@expnext\SKV@trailead{#2}#2%
+ \SKV@expnext\SKV@sp@def{#2}#2%
\expandafter\SKV@tempa\expandafter#1#2\@nil
\else
\if#1\@temptoks\expandafter\SKV@tempa#2\@nil\fi
@@ -772,76 +814,28 @@
\fi
\endgroup
}
-\SKV@pdef*\SKV@appto{\SKV@savstate\SKV@testoptb\SKV@@appto}
-\SKV@def\SKV@@appto#1#2{%
- \ifSKV@st
- \let\@unexp@expox\SKV@expox
- \else
- \let\@unexp@expox\unexpanded
- \fi
- \SKV@ap@to{#1}{#2}%
- \SKV@resstate
-}
-\SKV@def*\SKV@ap@to#1#2{%
+\SKV@pdef*\SKV@appto{\SKV@savstate\SKV@testoptb{\SKV@apprepto{appto}}}
+\SKV@pdef*\SKV@prepto{\SKV@savstate\SKV@testoptb{\SKV@apprepto{prepto}}}
+\SKV@def\SKV@apprepto#1#2#3{%
+ \def\tempa##1{\def\tempb####1{\SKV@aftercs##1{####1}}}%
+ \ifSKV@st\let\tempc\SKV@expox\else\let\tempc\unexpanded\fi
\ifSKV@pl
- \ifSKV@ask
- \let\SKV@n@xt\SKV@csxdef
- \else
- \let\SKV@n@xt\SKV@csedef
- \fi
- \SKV@ifcsundef{#1}{%
- \SKV@n@xt{#1}{\@unexp@expox{#2}}%
- }{%
- \SKV@n@xt{#1}{\SKV@expcsox{#1}\@unexp@expox{#2}}%
- }%
+ \let\@ifundef\SKV@ifcsundef\let\tempd\SKV@expcsox
+ \ifSKV@ask\tempa\xdef\else\tempa\edef\fi
\else
- \ifSKV@ask
- \let\SKV@n@xt\xdef
- \else
- \let\SKV@n@xt\edef
- \fi
- \SKV@ifundef{#1}{%
- \SKV@n@xt#1{\@unexp@expox{#2}}%
- }{%
- \SKV@n@xt#1{\SKV@expox{#1}\@unexp@expox{#2}}%
- }%
+ \let\@ifundef\SKV@ifundef\let\tempd\SKV@expox
+ \ifSKV@ask\def\tempb##1{\xdef##1}\else\def\tempb##1{\edef##1}\fi
\fi
-}
-\SKV@pdef*\SKV@prepto{\SKV@savstate\SKV@testoptb\SKV@@prepto}
-\SKV@def\SKV@@prepto#1#2{%
- \ifSKV@st
- \let\@unexp@expox\SKV@expox
- \else
- \let\@unexp@expox\unexpanded
- \fi
- \SKV@pr@pto{#1}{#2}%
+ \@ifundef{#2}{%
+ \tempb{#2}{\tempc{#3}}%
+ }{%
+ \SKV@ifstrequal{#1}{appto}%
+ {\tempb{#2}{\tempd{#2}\tempc{#3}}}%
+ {\tempb{#2}{\tempc{#3}\tempd{#2}}}%
+ }%
+ \SKV@undeflist//\tempa,\tempb,\tempc,\tempd/%
\SKV@resstate
}
-\SKV@def*\SKV@pr@pto#1#2{%
- \ifSKV@pl
- \ifSKV@ask
- \let\SKV@n@xt\SKV@csxdef
- \else
- \let\SKV@n@xt\SKV@csedef
- \fi
- \SKV@ifcsundef{#1}{%
- \SKV@n@xt{#1}{\@unexp@expox{#2}}%
- }{%
- \SKV@n@xt{#1}{\@unexp@expox{#2}\SKV@expcsox{#1}}%
- }%
- \else
- \ifSKV@ask
- \let\SKV@n@xt\xdef
- \else
- \let\SKV@n@xt\edef
- \fi
- \SKV@ifundef{#1}{%
- \SKV@n@xt#1{\@unexp@expox{#2}}%
- }{%
- \SKV@n@xt#1{\@unexp@expox{#2}\SKV@expox{#1}}%
- }%
- \fi
-}
\SKV@pdef\apptomac#1#2{%
\SKV@ifundef{#1}{\edef#1{\unexpanded{#2}}}%
{\edef#1{\SKV@expox{#1}\unexpanded{#2}}}%
@@ -859,22 +853,17 @@
\SKV@pdef*\SKV@addtolist{\SKV@savstate\SKV@testoptf\SKV@@addtolist}
\SKV@def*\SKV@@addtolist[#1]{%
\def\parser{#1}%
+ \ifSKV@ask
+ \let\glob@l@or@def\xdef
+ \else
+ \let\glob@l@or@def\edef
+ \fi
\ifSKV@pl
- \def\SKV@n@xt##1{\SKV@aftercs\SKV@addt@list{##1}}%
- \ifSKV@ask
- \let\glob@l@or@def\xdef
- \else
- \let\glob@l@or@def\edef
- \fi
+ \def\SKV@next##1{\SKV@aftercs\SKV@addt@list{##1}}%
\else
- \let\SKV@n@xt\SKV@addt@list
- \ifSKV@ask
- \let\glob@l@or@def\xdef
- \else
- \let\glob@l@or@def\edef
- \fi
+ \let\SKV@next\SKV@addt@list
\fi
- \SKV@resstate\SKV@n@xt
+ \SKV@resstate\SKV@next
}
\SKV@def\SKV@addt@list#1#2{%
\SKV@ifundef{#1}{%
@@ -974,22 +963,22 @@
}%
}
\SKV@ifcsdef{ver@#1.\@pkgextension}{%
- \let\SKV@n@xt\@firstofone
+ \let\SKV@next\@firstofone
}{%
- \def\SKV@n@xt{\SKV@appto+{#1.\@pkgextension-skvh@@k}}%
+ \def\SKV@next{\SKV@appto+{#1.\@pkgextension-skvh@@k}}%
}%
- \SKV@n@xt
+ \SKV@next
}
\let\SKV@steno\z@
\SKV@pdef*\SKV@for{\SKV@savstate\SKV@testoptd\SKV@@for}
\SKV@pdef*\SKV@@for[#1]{%
\let\SKV@steno\@ne
\ifSKV@st
- \def\SKV@n@xt{\SKV@for@b[#1]}%
+ \def\SKV@next{\SKV@for@b[#1]}%
\else
- \def\SKV@n@xt{\SKV@CommandGenParser{#1}\SKV@for@a}%
+ \def\SKV@next{\SKV@CommandGenParser{#1}\SKV@for@a}%
\fi
- \SKV@n@xt
+ \SKV@next
}
\SKV@pdef*\SKV@CommandGenParser#1{%
\def\parser{#1}%
@@ -1034,15 +1023,15 @@
\SKV@def\SKV@tforloop#1#2&#3#4{%
\long\def#3{#1}%
\SKV@ifstrequal{#1}{\listbreak}{%
- \let\SKV@n@xt\SKV@tforrema
+ \let\SKV@next\SKV@tforrema
}{%
\SKV@ifstrequal{#1}{\@nil}{%
- \let\SKV@n@xt\SKV@tfornoop
+ \let\SKV@next\SKV@tfornoop
}{%
- #4\relax\let\SKV@n@xt\SKV@tforloop
+ #4\relax\let\SKV@next\SKV@tforloop
}%
}%
- \SKV@n@xt#2&#3{#4}%
+ \SKV@next#2&#3{#4}%
}
\SKV@def\SKV@tfornoop#1&#2#3{}
\SKV@pdef*\SKV@tforrema#1\@nil\@nil&#2#3{%
@@ -1053,8 +1042,8 @@
\SKV@pdef*\SKV@onlypreamble#1{%
\SKV@tfor{#1}\SKV@resvd{%
\SKV@expnext\SKV@ensurescape\SKV@resvd
- \expandafter\gapptomac\expandafter\SKV@preamblecmds
- \expandafter{\expandafter\SKV@do@a\SKV@resvd}%
+ \edef\SKV@resvd##1##2{\SKV@appto?##1{##2\SKV@expox{\SKV@resvd}}}%
+ \SKV@resvd\SKV@preamblecmds\SKV@do@a
}%
}
\SKV@AfterDocumentStart{%
@@ -1074,7 +1063,7 @@
}
\SKV@def*\SKV@CommandKeyParser#1{%
\long\def\SKV@define@keylist##1{%
- \SKV@undeflt{g}{\skif,\skifx,\skifcase,\skor,\skelse,\skfi}%
+ \SKV@undeflist/g/\skif,\skifx,\skifcase,\skor,\skelse,\skfi/%
\ifswitchon{SKV@st}{%
\long\edef\@keylist{\SKV@expox{##1}}%
}{%
@@ -1106,8 +1095,8 @@
\SKV@expargs{3}{\XKV@checkchoice[\val\nr]}{{#1}{#2}}{{#3}{#4}}\@nil
}
\SKV@pdef*\SKV@inputerr#1#2{%
- \SKV@err{Erroneous value '#1' for key '#2'}{%
- Please use the correct value for key '#2'.}%
+ \SKV@err{Erroneous value '#1' for key '#2'}%
+ {Please use the correct value for key '#2'.}%
}
\SKV@def*\SKV@despacelist{\SKV@savstate\SKV@testoptd\SKV@despac@list}
\SKV@def*\SKV@despac@list[#1]#2{%
@@ -1160,9 +1149,9 @@
\SKV@pdef*\SKV@cslet{\SKV@savstate\SKV@t@stopta\SKV@@cslet}
\SKV@def*\SKV@@cslet#1#2{%
\ifSKV@st
- \def\SKV@n@xt{\SKV@aftercs\let{#1}#2}%
+ \def\SKV@next{\SKV@aftercs\let{#1}#2}%
\else
- \def\SKV@n@xt{%
+ \def\SKV@next{%
\SKV@ifdef{#2}{%
\SKV@aftercs\let{#1}#2%
}{%
@@ -1171,17 +1160,17 @@
}%
}%
\fi
- \SKV@resstate\SKV@n@xt
+ \SKV@resstate\SKV@next
}
\SKV@pdef*\SKV@letcs{\SKV@savstate\SKV@t@stopta\SKV@@letcs}
\SKV@def*\SKV@@letcs#1#2{%
\ifSKV@st
- \def\SKV@n@xt{%
+ \def\SKV@next{%
\begingroup\expandafter\endgroup
\expandafter\let\expandafter#1\csname#2\endcsname
}%
\else
- \def\SKV@n@xt{%
+ \def\SKV@next{%
\SKV@ifcsdef{#2}{%
\expandafter\let\expandafter#1\csname#2\endcsname
}{%
@@ -1190,17 +1179,17 @@
}%
}%
\fi
- \SKV@resstate\SKV@n@xt
+ \SKV@resstate\SKV@next
}
\SKV@pdef*\SKV@csletcs{\SKV@savstate\SKV@t@stopta\SKV@@csletcs}
\SKV@def*\SKV@@csletcs#1#2{%
\ifSKV@st
- \def\SKV@n@xt{%
+ \def\SKV@next{%
\begingroup\expandafter\endgroup
\expandafter\let\csname#1\SKV@aftercs\endcsname{#2}%
}%
\else
- \def\SKV@n@xt{%
+ \def\SKV@next{%
\SKV@ifcsdef{#2}{%
\SKV@aftercs\let{#1\SKV@aftercs}{#2}%
}{%
@@ -1209,60 +1198,38 @@
}%
}%
\fi
- \SKV@resstate\SKV@n@xt
+ \SKV@resstate\SKV@next
}
-\SKV@pdef*\SKV@numdef{\SKV@savstate\SKV@testoptc\SKV@@numdef}
-\SKV@pdef*\SKV@@numdef{%
- \ifSKV@pl
- \def\SKV@n@xt##1{\SKV@aftercs\SKV@numd@f{##1}}%
- \ifSKV@ask
- \let\glob@lrel@x\global
- \else
- \let\glob@lrel@x\relax
- \fi
+\SKV@pdef*\SKV@numdef{\SKV@savstate\SKV@testoptc{\SKV@numdimdef{num}}}
+\SKV@pdef*\SKV@dimdef{\SKV@savstate\SKV@testoptc{\SKV@numdimdef{dim}}}
+\SKV@def*\SKV@numdimdef#1{%
+ \ifSKV@ask
+ \let\glob@lrel@x\global
\else
- \let\SKV@n@xt\SKV@numd@f
- \ifSKV@ask
- \let\glob@lrel@x\global
- \else
- \let\glob@lrel@x\relax
- \fi
+ \let\glob@lrel@x\relax
\fi
- \SKV@resstate\SKV@n@xt
-}
-\SKV@pdef*\SKV@numd@f#1#2{%
- \SKV@ensurescape@notempty{#1}{#2}%
- \SKV@ifundef{#1}{%
- \newcount#1\glob@lrel@x#1=\numexpr#2\relax
- }{%
- \glob@lrel@x#1=\numexpr#2\relax
- }%
-}
-\SKV@pdef*\SKV@dimdef{\SKV@savstate\SKV@testoptc\SKV@@dimdef}
-\SKV@pdef*\SKV@@dimdef{%
\ifSKV@pl
- \def\SKV@n@xt##1{\SKV@aftercs\SKV@dimd@f{##1}}%
- \ifSKV@ask
- \let\glob@lrel@x\global
- \else
- \let\glob@lrel@x\relax
- \fi
+ \def\SKV@next##1{%
+ \edef\resvd@a####1{####1{#1}\SKV@expcsox{##1}}%
+ \resvd@a\SKV@numdimd@f
+ }%
\else
- \let\SKV@n@xt\SKV@dimd@f
- \ifSKV@ask
- \let\glob@lrel@x\global
- \else
- \let\glob@lrel@x\relax
- \fi
+ \def\SKV@next{\SKV@numdimd@f{#1}}%
\fi
- \SKV@resstate\SKV@n@xt
+ \SKV@resstate\SKV@next
}
-\SKV@pdef*\SKV@dimd@f#1#2{%
- \SKV@ensurescape@notempty{#1}{#2}%
- \SKV@ifundef{#1}{%
- \newdimen#1\glob@lrel@x#1=\dimexpr#2\relax
+\SKV@def*\SKV@numdimd@f#1#2#3{%
+ \SKV@ensurescape@notempty{#2}{#3}%
+ \SKV@ifstrequal{#1}{num}{%
+ \def\resvd@a{count}%
}{%
- \glob@lrel@x#1=\dimexpr#2\relax
+ \def\resvd@a{dimen}%
+ }%
+ \SKV@ifundef{#2}{%
+ \@nameuse{new\resvd@a}#2%
+ \glob@lrel@x#2=\@nameuse{#1expr}#3\relax
+ }{%
+ \glob@lrel@x#2=\@nameuse{#1expr}#3\relax
}%
}
\SKV@def*\SKV@ensurescape@notempty#1#2{%
@@ -1286,7 +1253,7 @@
\SKV@xifblank\SKV@keyparser\SKV@keylistparser@err\relax
\SKV@despace\SKV@keyparser
\begingroup
- \SKV@detokdespace{,}\SKV@tempa
+ \def\SKV@tempa{,}\SKV@detokdespace\SKV@tempa
\SKV@ifx\SKV@keyparser\SKV@tempa
{\aftergroup\SKV@keylistparser@err}{}%
\endgroup
@@ -1335,8 +1302,8 @@
\define@boolkey+[KV]{skeyval}[SKV@]{draft}[true]{%
\ifSKV@draft
\setkeys[KV]{skeyval}{final=false}%
- \SKV@AtPackageEnd{\ifSKV@draft\togtrue{draft}\else
- \togfalse{draft}\fi}%
+ \SKV@AtPackageEnd{\ifSKV@draft\togon{draft}\else
+ \togoff{draft}\fi}%
\fi
}{%
\SKV@inputerr{#1}{draft}%
@@ -1344,8 +1311,8 @@
\define@boolkey+[KV]{skeyval}[SKV@]{final}[true]{%
\ifSKV@final
\setkeys[KV]{skeyval}{draft=false}%
- \SKV@AtPackageEnd{\ifSKV@final\togtrue{final}\else
- \togfalse{final}\fi}%
+ \SKV@AtPackageEnd{\ifSKV@final\togon{final}\else
+ \togoff{final}\fi}%
\fi
}{%
\SKV@inputerr{#1}{final}%
@@ -1355,11 +1322,32 @@
keyfamily,macroprefix,final}
\ProcessOptionsX*[KV]<skeyval>\relax
\SKV@pdef*\skvoptions#1{\setkeys[KV]{skeyval}{#1}}
-\SKV@pdef*\SKV@ifdraft{\@nameuse{@\ifSKV@draft first\else second\fi oftwo}}
-\SKV@pdef*\SKV@iffinal{\@nameuse{@\ifSKV@final first\else second\fi oftwo}}
-\SKV@pdef*\SKV@ifnotdraft{\SKV@ifdraft\@secondoftwo\@firstoftwo}
-\SKV@pdef*\SKV@ifnotfinal{\SKV@iffinal\@secondoftwo\@firstoftwo}
+\SKV@pdef*\SKV@ifdraft{\@nameuse{SKV@\ifSKV@draft1\else2\fi of2}}
+\SKV@pdef*\SKV@iffinal{\@nameuse{SKV@\ifSKV@final1\else2\fi of2}}
+\SKV@pdef*\SKV@ifnotdraft{\@nameuse{SKV@\SKV@ifdraft2\else1\fi of2}}
+\SKV@pdef*\SKV@ifnotfinal{\@nameuse{SKV@\SKV@iffinal2\else1\fi of2}}
\def\SKV@useinfo#1{Not using '\@backslashchar#1' of 'skyeval' package}
+\SKV@pdef*\SKV@in@#1#2{%
+ \def\in@@##1#1##2##3\in@@{\ifx\in@##2\in@false\else\in@true\fi}%
+ \in@@#2\@mil#1\in@\in@@
+}
+\SKV@pdef*\SKV@in@o#1#2{%
+ \SKV@in@{#1}{#2}%
+ \@nameuse{SKV@\ifin@1\else2\fi of2}%
+}
+\SKV@pdef*\in@tog#1#2{%
+ \SKV@in@{#1}{#2}%
+ \ifin@\togon{in@}\else\togoff{in@}\fi
+}
+\AtEndOfPackage{\deftog{in@}}
+\SKV@pdef*\in@tok#1#2{%
+ \begingroup
+ \SKV@expnext\SKV@sp@def{\detokenize{#1}}\SKV@tempa
+ \SKV@expnext\SKV@sp@def{\detokenize{#2}}\SKV@tempb
+ \@expandtwoargs\SKV@in@\SKV@tempa\SKV@tempb
+ \global\let\ifin@\ifin@
+ \endgroup
+}
\AtBeginDocument{%
\SKV@ifundef\ifdraft
{\SKV@pdef*\ifdraft{\SKV@ifdraft}}%
@@ -1393,37 +1381,57 @@
* I haven't redefined '\string#1' *}%
}%
}
-\SKV@pdef*\newswitch#1#2{%
- \SKV@ensurenoscape{#1}%
- \SKV@ifstrequal{#2}{true}{\def\SKV@resvd{true}}{%
- \SKV@ifstrequal{#2}{false}{\def\SKV@resvd{false}}{%
- \SKV@ifstrequal{#2}{on}{\def\SKV@resvd{true}}{%
- \SKV@ifstrequal{#2}{off}{\def\SKV@resvd{false}}{%
- \SKV@swvalerr{#1}{#2}%
- }%
- }%
- }%
+\SKV@def*\SKV@getswstate#1#2{%
+ \SKV@ifstrequal{#2}{true}{\def\SKV@resvd{true}}%
+ {\SKV@ifstrequal{#2}{false}{\def\SKV@resvd{false}}%
+ {\SKV@ifstrequal{#2}{on}{\def\SKV@resvd{true}}%
+ {\SKV@ifstrequal{#2}{off}{\def\SKV@resvd{false}}%
+ {\SKV@swvalerr{#1}{#2}}}}}%
+}
+\SKV@pdef*\newswitch{\SKV@testopt\SKV@newswitch{}}
+\SKV@pdef*\SKV@newswitch[#1]#2{\SKV@testopt{\SKV@n@wswitch[#1]{#2}}{false}}
+\SKV@pdef*\SKV@n@wswitch[#1]#2[#3]{%
+ \SKV@in@o{,}{#2}{%
+ \SKV@err{Command '\string\newswitch' doesn't accept list}%
+ {Please submit only one switch to '\string\newswitch' at a time.}%
+ }{}%
+ \SKV@ensurenoscape{#2}%
+ \SKV@ifstrnotequal{#1#2}{x}{}{%
+ \SKV@err{'\string\ifx' is a TeX primitive}%
+ {You can't redefine '\string\ifx'? This is dangerous.}%
+ }%
+ \SKV@getswstate\newswitch{#3}%
+ \SKV@csifdefinable{if#1#2}{%
+ \csnewif{if#1#2}%
+ \@nameuse{#1#2\SKV@resvd}%
+ }%
+}
+\SKV@pdef*\defswitch{\SKV@testopt\SKV@defswitch{}}
+\SKV@pdef*\SKV@defswitch[#1]#2{\SKV@testopt{\SKV@d@fswitch[#1]{#2}}{false}}
+\SKV@pdef*\SKV@d@fswitch[#1]#2[#3]{%
+ \SKV@ensurenoscape{#2}%
+ \SKV@in@o{,}{#2}{%
+ \SKV@err{Command '\string\defswitch' doesn't accept list}%
+ {Please submit only one switch to '\string\defswitch' at a time.}%
+ }{}%
+ \SKV@ifcsundef{if#1#2}{}{%
+ \SKV@vbsmsg{warn}{Switch '\@backslashchar if#1#2' redefined\on@line}%
}%
- \expandafter\SKV@ifdefinable\csname if#1\endcsname{%
- \csname newif\expandafter\endcsname\csname if#1\endcsname
- \csname #1\SKV@resvd\endcsname
+ \SKV@ifstrnotequal{#1#2}{x}{}{%
+ \SKV@err{'\string\ifx' is a TeX primitive}%
+ {Why do you want to redefine '\string\ifx'? This is dangerous.}%
}%
+ \SKV@getswstate\defswitch{#3}%
+ \csnewif{if#1#2}%
+ \@nameuse{#1#2\SKV@resvd}%
}
-\SKV@newlet\NewSwitches\NewIfs
+\SKV@newlet\NewSwitches\NewBooleans
\SKV@def*\setswitch#1#2{%
\SKV@ensurenoscape{#1}%
\SKV@ifcsundef{if#1}{%
\SKV@noswerr{#1}%
}{%
- \SKV@ifstrequal{#2}{true}{\def\SKV@resvd{true}}{%
- \SKV@ifstrequal{#2}{false}{\def\SKV@resvd{false}}{%
- \SKV@ifstrequal{#2}{on}{\def\SKV@resvd{true}}{%
- \SKV@ifstrequal{#2}{off}{\def\SKV@resvd{false}}{%
- \SKV@swvalerr{#1}{#2}%
- }%
- }%
- }%
- }%
+ \SKV@getswstate\setswitch{#2}%
\csname#1\SKV@resvd\endcsname
}%
}
@@ -1440,86 +1448,107 @@
\SKV@def*\ifswitchon#1{%
\SKV@ensurenoscape{#1}%
\SKV@ifcsundef{if#1}{\SKV@noswerr{#1}\@gobbletwo}%
- {\@nameuse{@\@nameuse{if#1}first\else second\fi oftwo}}%
+ {\@nameuse{SKV@\@nameuse{if#1}1\else2\fi of2}}%
}
\SKV@newlet\ifswitchtrue\ifswitchon
\SKV@def*\ifswitchoff#1{%
\SKV@ensurenoscape{#1}%
\SKV@ifcsundef{if#1}{\SKV@noswerr{#1}\@gobbletwo}%
- {\@nameuse{@\@nameuse{if#1}second\else first\fi oftwo}}%
+ {\@nameuse{SKV@\@nameuse{if#1}2\else1\fi of2}}%
}
\SKV@newlet\ifswitchfalse\ifswitchoff
\SKV@pdef*\SKV@noswerr#1{%
\SKV@err{Switch '\string#1' is undefined}%
{You need to first define the switch '\string#1'.}%
}
+\SKV@pdef*\SKV@swnameerr#1{%
+ \SKV@err{'\string\if#1' not allowed as a boolean}%
+ {Invalid boolean name '\string#1'.}%
+}
\SKV@def*\SKV@swvalerr#1#2{%
- \SKV@err{Invalid switch value '#2' for switch '\string#1'}%
- {Valid switch values are 'true', 'on', 'false', and 'off'.}%
+ \SKV@err{\string#1\space error: invalid boolean value '#2'}%
+ {Valid boolean values are 'true', 'on', 'false', and 'off'.}%
}
\SKV@pdef*\SKV@undeftog@err#1{%
\SKV@err{Toggle '#1' undefined}%
{You need to first define '#1' before use.}%
}
-\SKV@pdef*\deftog#1{%
- \SKV@ifcsundef{SKV@toggle@#1}{}{%
- \SKV@vbsmsg{warn}{Toggle '#1' redefined\on@line}%
+\SKV@pdef*\newtog{\SKV@testopt\SKV@newtog{}}
+\SKV@pdef*\SKV@newtog[#1]#2{\SKV@testopt{\SKV@n@wtog[#1]{#2}}{false}}
+\SKV@pdef*\SKV@n@wtog[#1]#2[#3]{%
+ \SKV@in@o{,}{#2}{%
+ \SKV@err{Command '\string\newtog' doesn't accept list}%
+ {Please submit only one tog to '\string\newtog' at a time.}%
+ }{}%
+ \SKV@ensurenoscape{#2}%
+ \SKV@ifcsdef{SKV@toggle@#1#2}{%
+ \SKV@err{Toggle '#1#2' already defined}%
+ {Please provide a new toggle or redefine '#1#2'.}%
+ }{\SKV@csletcs{SKV@toggle@#1#2}{SKV@t@ggle#3}}%
+}
+\SKV@pdef*\deftog{\SKV@testopt\SKV@deftog{}}
+\SKV@pdef*\SKV@deftog[#1]#2{\SKV@testopt{\SKV@d@ftog[#1]{#2}}{false}}
+\SKV@pdef*\SKV@d@ftog[#1]#2[#3]{%
+ \SKV@in@o{,}{#2}{%
+ \SKV@err{Command '\string\deftog' doesn't accept list}%
+ {Please submit only one tog to '\string\deftog' at a time.}%
+ }{}%
+ \SKV@ensurenoscape{#2}%
+ \SKV@ifcsundef{SKV@toggle@#1#2}{}{%
+ \SKV@vbsmsg{warn}{Toggle '#1#2' redefined\on@line}%
}%
- \SKV@aftercs\let{SKV@toggle@#1}\@secondoftwo
-}
-\SKV@pdef*\newtog#1{%
- \SKV@ifcsdef{SKV@toggle@#1}{%
- \SKV@err{Toggle '#1' already defined}%
- {Please provide a new toggle or redefine '#1'.}%
- }{\SKV@aftercs\let{SKV@toggle@#1}\@secondoftwo}%
+ \SKV@csletcs{SKV@toggle@#1#2}{SKV@t@ggle#3}
}
\SKV@pdef*\providetog#1{%
\SKV@ifcsdef{SKV@toggle@#1}{%
\SKV@vbsmsg{info}%
{Toggle '#1' already defined.\SKV@MB Not redefined\on@line}%
- }{\SKV@aftercs\let{SKV@toggle@#1}\@secondoftwo}%
+ }{\SKV@cslet{SKV@toggle@#1}\@secondoftwo}%
}
\SKV@pdef*\requiretog#1{\SKV@aftercs\requirecmd{SKV@toggle@#1}[2]{##2}}
\SKV@def*\settog#1#2{%
\SKV@ifcsdef{SKV@toggle@#1}{%
\SKV@ifcsdef{SKV@t@ggle#2}{%
- \SKV@aftercs\let{SKV@toggle@#1\expandafter}%
- \csname SKV@t@ggle#2\endcsname
+ \SKV@csletcs{SKV@toggle@#1}{SKV@t@ggle#2}%
}{%
\SKV@err{Inadmissible value '#2' for toggle '#1'}%
- {Valid values for toggles are 'true' and 'false'.}%
+ {Valid values for toggles are 'true', 'or', 'false', and 'off'.}%
}%
}{\SKV@undeftog@err{#1}}%
}
-\SKV@def*\togtrue#1{%
+\SKV@def*\togon#1{%
\SKV@ifcsdef{SKV@toggle@#1}{%
- \expandafter\let\csname SKV@toggle@#1\endcsname\SKV@t@ggletrue
+ \SKV@cslet{SKV@toggle@#1}\SKV@t@ggleon
}{\SKV@undeftog@err{#1}}%
}
-\SKV@def*\togfalse#1{%
+\SKV@def*\togoff#1{%
\SKV@ifcsdef{SKV@toggle@#1}{%
- \expandafter\let\csname SKV@toggle@#1\endcsname\SKV@t@gglefalse
- }{%
- \SKV@undeftog@err{#1}%
- }%
+ \SKV@cslet{SKV@toggle@#1}\SKV@t@ggleoff
+ }{\SKV@undeftog@err{#1}}%
}
+\SKV@newlet\togtrue\togon
+\SKV@newlet\togfalse\togoff
+\SKV@newlet\SKV@t@ggleon\@firstoftwo
+\SKV@newlet\SKV@t@ggleoff\@secondoftwo
\SKV@newlet\SKV@t@ggletrue\@firstoftwo
\SKV@newlet\SKV@t@gglefalse\@secondoftwo
-\SKV@def*\iftog#1{%
+\SKV@def*\iftogon#1{%
\SKV@ifcsdef{SKV@toggle@#1}{\@nameuse{SKV@toggle@#1}}%
{\SKV@undeftog@err{#1}}%
}
-\SKV@def*\ifnottog#1{%
+\SKV@def*\iftogoff#1{%
\SKV@ifcsdef{SKV@toggle@#1}{%
\@nameuse{SKV@toggle@#1}\@secondoftwo\@firstoftwo}%
{\SKV@undeftog@err{#1}\@gobbletwo}%
}
+\SKV@newlet\iftogtrue\iftogon
+\SKV@newlet\iftogfalse\iftogoff
\deftog{pdf}
\SKV@ifundef\pdfoutput{}{%
\ifnum\pdfoutput<\@ne
\SKV@pdef*\SKV@ifpdf{\@secondoftwo}%
\else
- \togtrue{pdf}%
+ \togon{pdf}%
\SKV@pdef*\SKV@ifpdf{\@firstoftwo}%
\fi
\SKV@pdef*\SKV@ifnotpdf{\SKV@ifpdf\@secondoftwo\@firstoftwo}%
@@ -1539,49 +1568,49 @@
}%
}
\SKV@pdef*\define@menukey{\define@choicekey}
-\SKV@pdef*\define@togkey{\XKV@t@stopta{\XKV@testoptd\SKV@define@togkey{}}}
+\SKV@pdef*\define@togkey{%
+ \XKV@t@stopta{\XKV@testoptd\SKV@define@togkey{}}}
\SKV@def*\SKV@define@togkey#1#2[#3]{%
\SKV@findkeypointers{#2}%
\SKV@ifcsundef{\XKV@header\SKV@resa}{}{%
\SKV@vbsmsg{warn}{%
Key '\SKV@resa' in family '\XKV@tfam' with\SKV@MB
prefix '\SKV@pref' redefined\on@line}
- \SKV@csundef{\XKV@header\SKV@resa}%
- \SKV@csundef{SKV@toggle@#1\SKV@resa}%
+ \SKV@Undef+{\XKV@header\SKV@resa,SKV@toggle@#1\SKV@resa}%
}%
\SKV@expnext\SKV@reservkey@err\SKV@resa
\SKV@expnext\SKV@suspkey@err\SKV@resa
\ifXKV@pl
- \def\SKV@n@xt{\SKV@aftercs\SKV@d@f@ne@togkey}%
+ \def\SKV@next{\SKV@aftercs\SKV@d@f@ne@togkey}%
\else
- \def\SKV@n@xt{\SKV@aftercs\SKV@d@fine@togkey}%
+ \def\SKV@next{\SKV@aftercs\SKV@d@fine@togkey}%
\fi
\begingroup
\edef\SKV@tempa{\endgroup
{\XKV@header\SKV@resa}{\SKV@resa}{#1\SKV@resa}{#3}}%
- \aftergroup\SKV@n@xt\SKV@tempa
+ \aftergroup\SKV@next\SKV@tempa
}
\SKV@def*\SKV@d@fine@togkey#1#2#3#4#5{%
- \SKV@d@f@ne@t@gkey#1{#2}{#3}{#4}{{\settog{#3}{\XKV@resa}#5}}%
+ \SKV@d@f@ne@t@gkey#1{#2}{#3}{#4}%
+ {{\SKV@expargs{0}{\SKV@getswstate{}}\XKV@resa\@nil
+ \settog{#3}{\SKV@resvd}#5}}%
}
\SKV@def*\SKV@d@f@ne@togkey#1#2#3#4#5#6{%
\SKV@d@f@ne@t@gkey#1{#2}{#3}{#4}%
- {{\settog{#3}{\XKV@resa}#5}{#6}}%
+ {{\SKV@expargs{0}{\SKV@getswstate{}}\XKV@resa\@nil
+ \settog{#3}{\SKV@resvd}#5}{#6}}%
}
\SKV@def*\SKV@d@f@ne@t@gkey#1#2#3#4#5{%
\deftog{#3}%
\ifXKV@st\XKV@define@default{#2}{#4}\fi
- \ifXKV@pl
- \def#1##1{\XKV@pltrue\XKV@sttrue
- \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5%
- }%
- \else
- \def#1##1{\XKV@plfalse\XKV@sttrue
- \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5%
- }%
- \fi
+ \def#1##1{%
+ \def#1####1{##1\XKV@sttrue
+ \XKV@checkchoice[\XKV@resa]{####1}{true,false,on,off}#5}%
+ }%
+ \ifXKV@pl#1\XKV@pltrue\else#1\XKV@plfalse\fi
}
-\SKV@pdef*\define@togkeys{\XKV@plfalse\XKV@testoptd\SKV@define@togkeys{}}
+\SKV@pdef*\define@togkeys{%
+ \XKV@plfalse\XKV@testoptd\SKV@define@togkeys{}}
\SKV@def*\SKV@define@togkeys#1#2[#3]{%
\SKV@despacelist{#2}%
\SKV@for*[,]\SKV@resa\SKV@tempa{%
@@ -1595,17 +1624,15 @@
\SKV@vbsmsg{warn}{%
Key '\SKV@resa' in family '\XKV@tfam' with\SKV@MB
prefix '\SKV@pref' redefined\on@line}
- \SKV@csundef{\XKV@header\SKV@resa}%
- \SKV@csundef{SKV@toggle@#2\SKV@resa}%
+ \SKV@Undef+{\XKV@header\SKV@resa,SKV@toggle@#2\SKV@resa}%
}%
\SKV@expnext\SKV@reservkey@err\SKV@resa
\SKV@expnext\SKV@suspkey@err\SKV@resa
- \edef\SKV@tempa{%
- \noexpand\SKV@d@f@ne@t@gkey\@nameuse{\XKV@header\SKV@resa}%
- {\SKV@resa}{#2\SKV@resa}{#3}%
- {{\noexpand\settog{#2\SKV@resa}{\noexpand\XKV@resa}}}%
+ \edef\SKV@tempa##1##2##3{%
+ ##1\@nameuse{\XKV@header\SKV@resa}%
+ {\SKV@resa}{#2\SKV@resa}{#3}{{##2{#2\SKV@resa}{##3}}}%
}%
- \SKV@tempa
+ \SKV@tempa\SKV@d@f@ne@t@gkey\settog\XKV@resa
}
\SKV@pdef*\newordkey{\XKV@testoptb\SKV@newordkey}
\SKV@def*\SKV@newordkey#1{%
@@ -1655,12 +1682,12 @@
\SKV@findkeypointers{#2}%
\SKV@expnext\SKV@definedkey@err\SKV@resa
\ifXKV@pl
- \def\SKV@n@xt{\SKV@aftercs\XKV@d@f@ne@boolkey}%
+ \def\SKV@next{\SKV@aftercs\XKV@d@f@ne@boolkey}%
\else
- \def\SKV@n@xt{\SKV@aftercs\XKV@d@fine@boolkey}%
+ \def\SKV@next{\SKV@aftercs\XKV@d@fine@boolkey}%
\fi
\edef\SKV@tempa{{\XKV@header\SKV@resa}{\SKV@resa}{#1\SKV@resa}{#3}}%
- \expandafter\SKV@n@xt\SKV@tempa
+ \expandafter\SKV@next\SKV@tempa
}
\SKV@pdef*\newboolkeys{\XKV@plfalse\XKV@testoptd\SKV@newboolkeys{}}
\SKV@def*\SKV@newboolkeys#1#2[#3]{%
@@ -1676,14 +1703,14 @@
\SKV@findkeypointers{#2}%
\SKV@expnext\SKV@definedkey@err\SKV@resa
\ifXKV@pl
- \def\SKV@n@xt{\SKV@aftercs\SKV@d@f@ne@togkey}%
+ \def\SKV@next{\SKV@aftercs\SKV@d@f@ne@togkey}%
\else
- \def\SKV@n@xt{\SKV@aftercs\SKV@d@fine@togkey}%
+ \def\SKV@next{\SKV@aftercs\SKV@d@fine@togkey}%
\fi
\begingroup
\edef\SKV@tempa{\endgroup
{\XKV@header\SKV@resa}{\SKV@resa}{#1\SKV@resa}{#3}}%
- \aftergroup\SKV@n@xt\SKV@tempa
+ \aftergroup\SKV@next\SKV@tempa
}
\SKV@pdef*\newtogkeys{\XKV@plfalse\XKV@testoptd\SKV@newtogkeys{}}
\SKV@def*\SKV@newtogkeys#1#2[#3]{%
@@ -1777,22 +1804,22 @@
\SKV@def*\SKV@bitogkeys[#1]#2[#3]#4[#5]#6#7#8{%
\@namedef{#1@#2@#4@func}{%
#7\relax
- \iftog{#3#4}{\togfalse{#3#6}}{\togtrue{#3#6}#8\relax}%
+ \iftogon{#3#4}{\togoff{#3#6}}{\togon{#3#6}#8\relax}%
}%
\@namedef{#1@#2@#6@func}{%
#8\relax
- \iftog{#3#6}{\togfalse{#3#4}}{\togtrue{#3#4}#7\relax}%
+ \iftogon{#3#6}{\togoff{#3#4}}{\togon{#3#4}#7\relax}%
}%
\SKV@compk@y{#1}{#2}{#3}{#4}{#5}{#6}%
}
\SKV@def*\SKV@unitogkeys[#1]#2[#3]#4[#5]#6#7#8{%
\@namedef{#1@#2@#4@func}{%
#7\relax
- \iftog{#3#4}{\togtrue{#3#6}#8\relax}{\togfalse{#3#6}}%
+ \iftogon{#3#4}{\togon{#3#6}#8\relax}{\togoff{#3#6}}%
}%
\@namedef{#1@#2@#6@func}{%
#8\relax
- \iftog{#3#6}{\togtrue{#3#4}#7\relax}{\togfalse{#3#4}}%
+ \iftogon{#3#6}{\togon{#3#4}#7\relax}{\togoff{#3#4}}%
}%
\SKV@compk@y{#1}{#2}{#3}{#4}{#5}{#6}%
}
@@ -1801,21 +1828,21 @@
\ifswitchon{SKV@st}{%
\ifswitchon{SKV@pl}{%
\@namedef{#1@#2@#4@func}{%
- #7\relax\ifnottog{#3#4}{\togfalse{#3#6}}{}%
+ #7\relax\iftogoff{#3#4}{\togoff{#3#6}}{}%
}%
}{%
\@namedef{#1@#2@#4@func}{%
- #7\relax\ifnottog{#3#4}{\togtrue{#3#6}#8\relax}{}%
+ #7\relax\iftogoff{#3#4}{\togon{#3#6}#8\relax}{}%
}%
}%
}{%
\ifswitchon{SKV@pl}{%
\@namedef{#1@#2@#4@func}{%
- #7\relax\iftog{#3#4}{\togfalse{#3#6}}{}%
+ #7\relax\iftogon{#3#4}{\togoff{#3#6}}{}%
}%
}{%
\@namedef{#1@#2@#4@func}{%
- #7\relax\iftog{#3#4}{\togtrue{#3#6}#8\relax}{}%
+ #7\relax\iftogon{#3#4}{\togon{#3#6}#8\relax}{}%
}%
}%
}%
@@ -1868,7 +1895,7 @@
{Problem with \string\choicekeyvalues\space for key '#3'}%
{You have attempted to set two \string\choicekeyvalues\SKV@MB
for choice key '#3' in the same family '#2'\SKV@MB
- with the same prefix '#1'. You can only do\SKV@MB
+ with the same prefix '#1'. You can only do\SKV@MB
that if you use the starred variant of \string\choicekeyvalues.}%
}%
\fi
@@ -1884,8 +1911,8 @@
\SKV@for*[,]#1\SKV@tempa{%
\edef\SKV@tempa{\detokenize\expandafter{\SKV@tempa}\space}%
\edef\SKV@tempa{\expandafter\zap@space\SKV@tempa\@empty}%
- \SKV@aftercs\xdef{SKV@zsp@\expandafter
- \@gobble\SKV@tempa}{\SKV@expox{\SKV@tempa}}%
+ \SKV@csxdef{SKV@zsp@\expandafter\@gobble\SKV@tempa}%
+ {\SKV@expox{\SKV@tempa}}%
}%
\endgroup
}
@@ -1895,8 +1922,8 @@
\SKV@for*[,]#1\SKV@tempa{%
\edef\SKV@tempa{\detokenize\expandafter{\SKV@tempa}}%
\SKV@despace\SKV@tempa
- \SKV@aftercs\xdef{SKV@dsp@\expandafter
- \@gobble\SKV@tempa}{\SKV@expox{\SKV@tempa}}%
+ \SKV@csxdef{SKV@dsp@\expandafter\@gobble\SKV@tempa}%
+ {\SKV@expox{\SKV@tempa}}%
}%
\endgroup
}
@@ -1908,16 +1935,20 @@
}
\SKV@def\SKV@define@multkeys#1,#2,#3,#4\@nil{%
\let\SKV@altlisterr\z@
- \SKV@trailead{#1}\SKV@tempa
+ \SKV@sp@def{#1}\SKV@tempa
\SKV@checkchoice{\SKV@tempa}{ord,cmd,bool,tog,choice,menu}{%
- \edef\SKV@keytype{\the\numexpr\nr+1}%
+ \SKV@iftest{num}{\nr=6}{%
+ \edef\SKV@keytype{\the\numexpr\nr-1}%
+ }{%
+ \edef\SKV@keytype{\the\numexpr\nr+1}%
+ }%
}{%
\SKV@checkchoice{\SKV@tempa}{1,2,3,4,5}{%
\edef\SKV@keytype{\the\numexpr\nr+1}%
}{%
\SKV@err{Unknown key type/identifier '\string#1'}%
{Valid key types are 'ord', 'cmd', 'bool', 'tog',
- 'choice', 'menu'\SKV@MB and '1', '2', '3', '4', '5'}%
+ 'choice', 'menu',\SKV@MB and '1', '2', '3', '4', '5'}%
}%
}%
\SKV@ifnotempty{#2}{}{%
@@ -1970,13 +2001,6 @@
[\unexpanded{\val\nr}]{%
\SKV@csuse{\SKV@keyprefix @\SKV@keyfamily @#2@altlist}%
}[#3]{\unexpanded{#4}}{\unexpanded{\SKV@inputerr{##1}{#2}}}%
- \or
- \SKV@ifcsdef{\SKV@keyprefix @\SKV@keyfamily @#2@altlist}{}%
- {\let\SKV@altlisterr\@ne}%
- \noexpand\SKV@def@choicekey*+[\SKV@keyprefix]{\SKV@keyfamily}{#2}%
- [\unexpanded{\val\nr}]{%
- \SKV@csuse{\SKV@keyprefix @\SKV@keyfamily @#2@altlist}%
- }[#3]{\unexpanded{#4}}{\unexpanded{\SKV@inputerr{##1}{#2}}}%
\fi
}%
\SKV@tempa
@@ -1992,25 +2016,8 @@
}%
\fi
}
-\SKV@pdef*\SKV@in@#1#2{%
- \def\in@@##1#1##2##3\in@@{\ifx\in@##2\in@false\else\in@true\fi}%
- \in@@#2\@mil#1\in@\in@@
-}
-\SKV@pdef*\in@tog#1#2{%
- \SKV@in@{#1}{#2}%
- \ifin@\togtrue{in@}\else\togfalse{in@}\fi
-}
-\deftog{in@}
-\SKV@pdef*\in@tok#1#2{%
- \begingroup
- \SKV@expnext\SKV@trailead{\detokenize{#1}}\SKV@tempa
- \SKV@expnext\SKV@trailead{\detokenize{#2}}\SKV@tempb
- \@expandtwoargs\SKV@in@\SKV@tempa\SKV@tempb
- \global\let\ifin@\ifin@
- \endgroup
-}
\def\XKV@makepf#1{%
- \SKV@trailead{#1}\XKV@prefix
+ \SKV@sp@def{#1}\XKV@prefix
\ifSKV@sk\else
\SKV@expnext\XKV@checksanitizeb\SKV@rkpnames\SKV@tempa
\SKV@despacelist*\SKV@tempa
@@ -2028,7 +2035,7 @@
\edef\XKV@prefix{\ifx\XKV@prefix\@empty\else\XKV@prefix @\fi}%
}
\def\XKV@makehd#1{%
- \SKV@expargs{3}\SKV@trailead{{#1}}\XKV@header\@nil
+ \SKV@expargs{3}\SKV@sp@def{{#1}}\XKV@header\@nil
\ifSKV@sk\else
\SKV@expnext\XKV@checksanitizeb\SKV@rfnames\SKV@tempa
\SKV@despacelist*\SKV@tempa
@@ -2069,54 +2076,26 @@
}
\SKV@def*\SKV@findkeypointers#1{%
\SKV@resolvekey{#1}\uservalue\savevalue\@nil\SKV@resa
- {%
- \SKV@addtouserval\SKV@addtosave
- }{%
- \SKV@resolvekey{#1}\guservalue\savevalue\@nil\SKV@resa
- {%
- \SKV@gaddtouserval\SKV@addtosave
- }{%
- \SKV@resolvekey{#1}\savevalue\uservalue\@nil\SKV@resa
- {%
- \SKV@addtouserval\SKV@addtosave
- }{%
- \SKV@resolvekey{#1}\gsavevalue\uservalue\@nil\SKV@resa
- {%
- \SKV@addtouserval\SKV@gaddtosave
- }{%
- \SKV@resolvekey{#1}\guservalue\gsavevalue\@nil\SKV@resa
- {%
- \SKV@gaddtouserval\SKV@gaddtosave
- }{%
- \SKV@resolvekey{#1}\gsavevalue\guservalue\@nil\SKV@resa
- {%
- \SKV@gaddtouserval\SKV@gaddtosave
- }{%
- \SKV@resolvekey{#1}\uservalue\@nil\SKV@resa
- {%
- \SKV@addtouserval
- }{%
- \SKV@resolvekey{#1}\guservalue\@nil\SKV@resa
- {%
- \SKV@gaddtouserval
- }{%
- \SKV@resolvekey{#1}\savevalue\@nil\SKV@resa
- {%
- \SKV@addtosave
- }{%
- \SKV@resolvekey{#1}\gsavevalue\@nil\SKV@resa
- {%
- \SKV@gaddtosave
- }{}%
- }%
- }%
- }%
- }%
- }%
- }%
- }%
- }%
- }%
+ {\SKV@addtouserval\SKV@addtosave}%
+ {\SKV@resolvekey{#1}\guservalue\savevalue\@nil\SKV@resa
+ {\SKV@gaddtouserval\SKV@addtosave}%
+ {\SKV@resolvekey{#1}\savevalue\uservalue\@nil\SKV@resa
+ {\SKV@addtouserval\SKV@addtosave}%
+ {\SKV@resolvekey{#1}\gsavevalue\uservalue\@nil\SKV@resa
+ {\SKV@addtouserval\SKV@gaddtosave}%
+ {\SKV@resolvekey{#1}\guservalue\gsavevalue\@nil\SKV@resa
+ {\SKV@gaddtouserval\SKV@gaddtosave}%
+ {\SKV@resolvekey{#1}\gsavevalue\guservalue\@nil\SKV@resa
+ {\SKV@gaddtouserval\SKV@gaddtosave}%
+ {\SKV@resolvekey{#1}\uservalue\@nil\SKV@resa
+ {\SKV@addtouserval}%
+ {\SKV@resolvekey{#1}\guservalue\@nil\SKV@resa
+ {\SKV@gaddtouserval}%
+ {\SKV@resolvekey{#1}\savevalue\@nil\SKV@resa
+ {\SKV@addtosave}%
+ {\SKV@resolvekey{#1}\gsavevalue\@nil\SKV@resa
+ {\SKV@gaddtosave}%
+ {}}}}}}}}}}%
}
\def\XKV@define@key#1{%
\SKV@findkeypointers{#1}%
@@ -2146,8 +2125,7 @@
\SKV@vbsmsg{warn}{%
Key '\SKV@resa' in family '\XKV@tfam' with\SKV@MB
prefix '\SKV@pref' redefined\on@line}
- \SKV@csundef{\XKV@header\SKV@resa}%
- \SKV@csundef{#1\SKV@resa}%
+ \SKV@Undef+{\XKV@header\SKV@resa,#1\SKV@resa}%
}%
\SKV@expnext\SKV@reservkey@err\SKV@resa
\SKV@expnext\SKV@suspkey@err\SKV@resa
@@ -2158,7 +2136,7 @@
\begingroup
\def\SKV@tempa{%
\expandafter\def\csname\XKV@header\SKV@resa\endcsname####1}%
- \@threeexpafter\endgroup\expandafter\SKV@tempa\expandafter%
+ \SKV@threeafter\endgroup\expandafter\SKV@tempa\expandafter%
{\expandafter\def\csname#1\SKV@resa\endcsname{##1}#4}%
}
\def\XKV@define@choicekey#1{%
@@ -2182,19 +2160,37 @@
\SKV@ifcsundef{\XKV@header\SKV@resa}{}{%
\SKV@vbsmsg{warn}{%
Key '\SKV@resa' in family '\XKV@tfam' with\SKV@MB
- prefix '\SKV@pref' redefined\on@line}
- \SKV@csundef{\XKV@header\SKV@resa}%
- \SKV@csundef{#1\SKV@resa}%
+ prefix '\SKV@pref' redefined\on@line}%
+ \SKV@Undef+{\XKV@header\SKV@resa,#1\SKV@resa}%
}%
\SKV@expnext\SKV@reservkey@err\SKV@resa
\SKV@expnext\SKV@suspkey@err\SKV@resa
\ifXKV@pl
- \def\SKV@n@xt{\SKV@aftercs\XKV@d@f@ne@boolkey}%
+ \def\SKV@next{\SKV@aftercs\XKV@d@f@ne@boolkey}%
\else
- \def\SKV@n@xt{\SKV@aftercs\XKV@d@fine@boolkey}%
+ \def\SKV@next{\SKV@aftercs\XKV@d@fine@boolkey}%
\fi
\edef\SKV@tempa{{\XKV@header\SKV@resa}{\SKV@resa}{#1\SKV@resa}{#3}}%
- \expandafter\SKV@n@xt\SKV@tempa
+ \expandafter\SKV@next\SKV@tempa
+}
+\def\XKV@d@fine@boolkey#1#2#3#4#5{%
+ \XKV@d@f@ne@b@olkey#1{#2}{#3}{#4}%
+ {{\SKV@expargs{0}{\SKV@getswstate{}}\XKV@resa\@nil
+ \csname#3\SKV@resvd\endcsname#5}}%
+}
+\def\XKV@d@f@ne@boolkey#1#2#3#4#5#6{%
+ \XKV@d@f@ne@b@olkey#1{#2}{#3}{#4}%
+ {{\SKV@expargs{0}{\SKV@getswstate{}}\XKV@resa\@nil
+ \csname#3\SKV@resvd\endcsname#5}{#6}}%
+}
+\def\XKV@d@f@ne@b@olkey#1#2#3#4#5{%
+ \csnewif{if#3}%
+ \ifXKV@st\XKV@define@default{#2}{#4}\fi
+ \def#1##1{%
+ \def#1####1{##1\XKV@sttrue
+ \XKV@checkchoice[\XKV@resa]{####1}{true,false,on,off}#5}%
+ }%
+ \ifXKV@pl#1\XKV@pltrue\else#1\XKV@plfalse\fi
}
\def\XKV@d@fine@boolkeys#1#2#3{%
\SKV@findkeypointers{#1}%
@@ -2202,17 +2198,15 @@
\SKV@vbsmsg{warn}{%
Key '\SKV@resa' in family '\XKV@tfam' with\SKV@MB
prefix '\SKV@pref' redefined\on@line}
- \SKV@csundef{\XKV@header\SKV@resa}%
- \SKV@csundef{#2\SKV@resa}%
+ \SKV@Undef+{\XKV@header\SKV@resa,#2\SKV@resa}%
}%
\SKV@expnext\SKV@reservkey@err\SKV@resa
\SKV@expnext\SKV@suspkey@err\SKV@resa
- \edef\SKV@tempa{%
- \noexpand\XKV@d@f@ne@b@olkey\@nameuse{\XKV@header\SKV@resa}%
- {\SKV@resa}{#2\SKV@resa}{#3}{{\noexpand\@nameuse{#2\SKV@resa
- \noexpand\XKV@resa}}}%
+ \edef\SKV@tempa##1##2##3{%
+ ##1\@nameuse{\XKV@header\SKV@resa}{\SKV@resa}%
+ {#2\SKV@resa}{#3}{{##2{#2\SKV@resa##3}}}%
}%
- \SKV@tempa
+ \SKV@tempa\XKV@d@f@ne@b@olkey\@nameuse\XKV@resa
}
\SKV@pdef*\reserve@keys{\@testopt\SKV@reserve@keys{KV}}
\SKV@def*\SKV@reserve@keys[#1]#2#3{%
@@ -2276,7 +2270,7 @@
\XKV@makepf{#1}%
\XKV@checksanitizeb{#2}\XKV@fams
\SKV@despacelist*\XKV@fams
- \SKV@trailead{#3}\XKV@tkey
+ \SKV@sp@def{#3}\XKV@tkey
\XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{%
\XKV@makehd\XKV@tfam
\SKV@ifcsdef{\XKV@header\XKV@tkey @reser}{\XKV@knffalse}{}%
@@ -2296,7 +2290,7 @@
\XKV@makepf{#1}%
\XKV@checksanitizeb{#2}\XKV@fams
\SKV@despacelist*\XKV@fams
- \SKV@trailead{#3}\XKV@tkey
+ \SKV@sp@def{#3}\XKV@tkey
\XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{%
\XKV@makehd\XKV@tfam
\SKV@ifcsdef{\XKV@header\XKV@tkey @susp}{\XKV@knffalse}{}%
@@ -2316,7 +2310,7 @@
\XKV@makepf{#1}%
\XKV@checksanitizeb{#2}\XKV@fams
\SKV@despacelist*\XKV@fams
- \SKV@trailead{#3}\XKV@tkey
+ \SKV@sp@def{#3}\XKV@tkey
\XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{%
\XKV@makehd\XKV@tfam
\SKV@ifcsdef{\XKV@header\XKV@tkey}{\XKV@knffalse}{}%
@@ -2569,12 +2563,12 @@
\SKV@aftercs\XKV@merge{SKV@\XKV@header uservalue}{#1}\XKV@getsg
}%
}
-\def\setkeys{%
+\protected\def\setkeys{%
\def\skif##1{%
\SKV@ensurenoscape{##1}%
\SKV@ifcsdef{if##1}{}{%
\SKV@err{Undefined boolean '##1'}%
- {Boolean '##1' undefined: This is an '\string\skif' error.}%
+ {'\string\skif' error: boolean '##1' undefined.}%
}%
\csname if##1\endcsname
}%
@@ -2609,7 +2603,7 @@
\SKV@ifnotblank{#1}{}{%
\SKV@err{You're required to supply a value\SKV@MB
for key '\XKV@tkey'}%
- {Supply a value for key '\XKV@tkey' before continuing.}%
+ {Supply a value for key '\XKV@tkey' and rerun.}%
}%
\fi
}%
@@ -2639,11 +2633,11 @@
}%
}
\SKV@def*\SKV@testuservaluekey#1#2{%
- \let\SKV@st@aux\ifSKV@st\SKV@sttrue\SKV@uvfalse
+ \let\SKV@staux\ifSKV@st\SKV@sttrue\SKV@uvfalse
\XKV@whilist#1\SKV@tempa\ifSKV@st\fi{%
\ifx#2\SKV@tempa\SKV@uvtrue\SKV@stfalse\fi
}%
- \let\ifSKV@st\SKV@st@aux\SKV@relax\SKV@st@aux
+ \let\ifSKV@st\SKV@staux\SKV@undef\SKV@staux
}
\SKV@def*\SKV@remspaceletter#1#2{%
\begingroup
@@ -2726,7 +2720,7 @@
\ifnum\escapechar<0\else
\expandafter\expandafter
\csname @gobble\ifnum\escapechar=32 space\fi
- \@threeexpafter\endcsname
+ \SKV@threeafter\endcsname
\fi\fi
\string%
}
@@ -2753,7 +2747,7 @@
\SKV@ensurescape{#1}%
\edef\SKV@tempa{saved\SKV@gobblescape#1}%
\SKV@ifcsdef\SKV@tempa{%
- \def\SKV@n@xt{\SKV@letcs#1\SKV@tempa\SKV@csundef\SKV@tempa}%
+ \def\SKV@next{\SKV@letcs#1\SKV@tempa\SKV@csundef\SKV@tempa}%
}{%
\SKV@err{%
'\@nameuse\SKV@tempa' is undefined:\SKV@MB
@@ -2764,13 +2758,13 @@
undefines\SKV@MB the saved command.
}%
}%
- \SKV@n@xt
+ \SKV@next
}
\SKV@providedef*\input@path{}
\SKV@pdef*\InputFileOnce{%
\def\SKV@inputfile##1##2{%
\InputIfFileExists{##2}{%
- \SKV@aftercs\let{##2@read}\@empty
+ \SKV@cslet{##2@read}\@empty
\let\SKV@inp@tfile\relax
}{%
\typein[\Answer]{^^J! File '\string##2' does not exist.^^J
@@ -2780,10 +2774,7 @@
}{%
\def\SKV@inp@tfile{%
\SKV@expargs{0}{\SKV@InputFileOnce[##1]}\Answer\@nil
- }%
- }%
- }%
- }%
+ }}}}%
\let\SKV@no\z@
\SKV@save\input@path
\SKV@t@stopta{\SKV@testopt\SKV@InputFileOnce{.}}%
@@ -2806,10 +2797,10 @@
\ifnum\SKV@no=\z@\SKV@restore\input@path\fi
\let\SKV@no\@ne
}
-\SKV@pdef\SKV@notloaded@err#1{%
+\SKV@pdef*\SKV@notloadederr#1{%
\SKV@ifcsdef{ver@#1.\@pkgextension}{}{%
\SKV@err{Package '#1' wasn't loaded}%
- {Document has started and package '#1' wasn't loaded.}%
+ {Document has begun and package '#1' wasn't loaded.}%
}%
}
\SKV@def*\SKV@notloaded{}
@@ -2820,10 +2811,81 @@
}%
}
\SKV@AtDocumentStart{%
- \let\SKV@do@b\SKV@notloaded@err
+ \let\SKV@do@b\SKV@notloadederr
\SKV@notloaded
\global\let\SKV@do@b\@gobble
}
+\SKV@pdef*\DeclareKeyCommand{\@star@or@long\SKV@keycommand}
+\SKV@def\SKV@keycommand#1{%
+ \SKV@ifdefinable#1\relax
+ \def\SKV@keycmdname{#1}%
+ \edef\resvd@a{\expandafter\@gobble\string#1}%
+ \edef\resvd@b{\expandafter\expandafter\expandafter\SKV@carcube
+ \expandafter\@gobble\string#1\@nil}%
+ \SKV@scantoksb\resvd@a
+ \SKV@scantoksb\resvd@b
+ \edef\resvd##1{\skvoptions{##1,keyfamily=\resvd@a,macroprefix=\resvd@b @}}%
+ \resvd{keyparser=;,keyprefix=KV}%
+ \SKV@testopt\SKV@k@ycommand{}%
+}
+\def\SKV@keycmdlist{}\def\SKV@k@ycmdlist{}
+\SKV@def\SKV@k@ycommand[#1]{%
+ \SKV@ifnotempty{#1}{}{%
+ \SKV@err{\string\DeclareKeyCommand\space error: no keys declared}\@ehc
+ }%
+ \SKV@k@yc@mmand{#1}%
+ \define@keylist*\SKV@keycmdlist
+ \edef\resvd{\setkeys[KV]{\resvd@a}{\SKV@k@ycmdlist}}%
+ \resvd
+ \SKV@testopt\SKV@k@yc@mm@nd{1}%
+}
+\SKV@def\SKV@k@yc@mmand#1{%
+ \def\SKV@keycmdlist{}\def\SKV@k@ycmdlist{}%
+ \XKV@checksanitizea{#1}\SKV@tempa
+ \SKV@normalizea\SKV@tempa
+ \SKV@for*[,]\SKV@tempa\SKV@tempa{%
+ \expandafter\SKV@getkeyname\SKV@tempa==\@nil
+ \SKV@addtokeycmdlist\SKV@tkey\SKV@tval
+ }%
+}
+\SKV@def\SKV@k@yc@mm@nd[#1]#2{%
+ \edef\resvd##1##2{##1{\setkeys[KV]{\resvd@a}{####1}##2}}%
+ \ifx\l@ngrel@x\relax
+ \def\resvd@b{\newcommand*}%
+ \else
+ \let\resvd@b\newcommand
+ \fi
+ \resvd{\expandafter\resvd@b\SKV@keycmdname[#1][]}{#2}%
+}
+\SKV@def\SKV@getkeyname#1=#2=#3\@nil{%
+ \XKV@g@tkeyname#1=\@nil\SKV@tkey
+ \SKV@expnext\SKV@sp@def\SKV@tkey\SKV@tkey
+ \def\SKV@tval{#2}%
+ \ifx\SKV@tkey\@empty
+ \SKV@ifnotempty{#2}{}%
+ {\XKV@err{No key specified for value '#2'}\@ehc}%
+ \fi
+ \SKV@ifnotempty{#3}{}%
+ {\XKV@err{No value specified for key '#1'}\@ehc}%
+}
+\SKV@def\SKV@addtokeycmdlist#1#2{%
+ \SKV@oifstrequal{#2}{true}{%
+ \def\tempa{bool}%
+ }{%
+ \SKV@oifstrequal{#2}{false}{%
+ \def\tempa{bool}%
+ }{%
+ \def\tempa{cmd}%
+ }%
+ }%
+ \SKV@oifempty{#1}{}{%
+ \edef\resvd##1{\gapptomac##1{\tempa,\SKV@expox{#1},\SKV@expox{#2},;}}%
+ \resvd\SKV@keycmdlist
+ \edef\resvd##1{\gapptomac##1{\SKV@expox{#1}=\SKV@expox{#2},}}%
+ \resvd\SKV@k@ycmdlist
+ }%
+ \SKV@undef\tempa
+}
\SKV@onlypreamble{%
\SKV@preamblecmds\SKV@onlypreamble
\@afterpackageloaded\@ifpackagecurrent\@ifpackagenotcurrent