summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Master/texmf-dist/doc/latex/keyreader/README10
-rw-r--r--Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdfbin116648 -> 163944 bytes
-rw-r--r--Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex513
-rw-r--r--Master/texmf-dist/tex/latex/keyreader/keyreader.sty596
4 files changed, 851 insertions, 268 deletions
diff --git a/Master/texmf-dist/doc/latex/keyreader/README b/Master/texmf-dist/doc/latex/keyreader/README
index 4431b02d8c3..05ce01dab87 100644
--- a/Master/texmf-dist/doc/latex/keyreader/README
+++ b/Master/texmf-dist/doc/latex/keyreader/README
@@ -14,14 +14,8 @@
% this concept and additionally permits the submission of individual/different %
% key macros to the complementary keys. %
% %
-% Some user guide is available in file 'keyreader-test.tex'. %
-% %
%+++++++++++++++++++++++++++++++++++++ LICENSE ++++++++++++++++++++++++++++++++++++++%
% %
-% This is file 'keyreader.sty', version 0.1. %
-% %
-% This package reads multiple keys to be defined by xkeyval.sty. %
-% %
% This package and accompanying files may be distributed and/or modified under %
% the conditions of the LaTeX Project Public License, either version 1.3 of %
% this license or any later version. The latest version of this license is in %
@@ -34,6 +28,8 @@
% expressed or implied, including, but not limited to, the implied warranties of %
% merchantability and fitness for a particular purpose. %
% %
-% Copyright (c) 2010 Ahmed Musa (a.musa@rocketmail.com). %
+% Version 0.3 %
+% %
+% Copyright (c) 2010 Ahmed Musa (a.musa@rocketmail.com). %
% %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% \ No newline at end of file
diff --git a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf
index f7d1027006a..d4e53c521a5 100644
--- a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf
+++ b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex
index 5b1cd3b34d6..214e129f09f 100644
--- a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex
+++ b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex
@@ -6,31 +6,43 @@
\usepackage{multicol}
\usepackage{hyperref}
\usepackage[parser=;,macroprefix=mp@,keyprefix=KV,
- keyfamily=myfamily]{keyreader}
+ keyfamily=fam]{keyreader}
\makeatletter
\newcommand*\email[1]{\href{mailto:#1}{#1}}
\skip\footins20pt\relax
\xglobal\definecolorset{rgb}{x}{1}{green,0.00,0.59,0.00;%
- teal,0.00,0.82,0.82;magenta,0.50,0.00,1.00;purple,0.50,0.00,0.25}
-\def\eg{\kr@ifnextchar.{e.g}{e.g.}\xspace}
-\def\ie{\kr@ifnextchar.{i.e}{i.e.}\xspace}
-\def\etc{\kr@ifnextchar.{etc}{etc.}\xspace}
-\date{\textcolor{purple}{\today}\vadjust{\kern0ex}}
-\newcommand*\krsty[1]{\textcolor{xgreen1}{\texttt{#1}}\xspace}
-\newcommand*\krcmd[1]{\textcolor{xteal1}{\texttt{\@backslashchar#1}}\xspace}
+ brown,0.50,0.00,0.50;teal,0.00,0.82,0.82;%
+ magenta,0.50,0.00,1.00;purple,0.50,0.00,0.25}
+\colorlet{verbcolor}{blue}
+\def\eg{\KR@ifnextchar.{e.g}{e.g.}\xspace}
+\def\ie{\KR@ifnextchar.{i.e}{i.e.}\xspace}
+\def\etc{\KR@ifnextchar.{etc}{etc.}\xspace}
+\def\bparen{\textup{(}\unskip}
+\def\eparen{\unskip\textup{)}\xspace}
+\def\krvert{$\vert$}
+\date{\textcolor{blue}{\small\today}}
\hypersetup{colorlinks=true,linkcolor=red,pdfpagemode=UseThumbs,
implicit=true,breaklinks=true,pagebackref=true,backref=true,
bookmarks=true,bookmarksnumbered=true,hyperfootnotes=true,debug=true,
naturalnames=false,citecolor=purple,pdfview=FitH,pdfstartview=FitH}
-\def\krverblabel{\textcolor{green}{\fboxrule1pt\fcolorbox{red}{gray!45}{\hspace{1cm}}}}
+\def\krverblabel{%
+ \textcolor{green}{\fboxrule1pt\fcolorbox{red}{gray!45}{\hspace{1cm}}}}
\CustomVerbatimEnvironment{krverbatim}{Verbatim}{numbers=left,
label={\krverblabel},labelposition=topline,numberblanklines=false, firstnumber=last,frame=single,rulecolor=\color{xmagenta1},framerule=1pt,
- framesep=7pt,formatcom=\color{blue},xrightmargin=0pc,commandchars=\|\(\),
- commentchar=&}
+ framesep=7pt,formatcom=\color{verbcolor},xrightmargin=0pc,
+ commandchars=\|\(\),commentchar=&}
+\renewcommand\theenumi{\alph{enumi}}
+\renewcommand\labelenumi{\theenumi\textup{)}}
+\renewcommand\theenumii{\roman{enumii}}
+\renewcommand\labelenumii{\theenumii\textup{)}}
+\renewcommand\p@enumii{\theenumi--}
+\newcommand*\sty[1]{\KR@cs{#1}{xgreen1}}
+\newcommand*\cs[1]{\KR@cs{#1}{xbrown1}}
+\newcommand*\cx[1]{\KR@cx{#1}{xbrown1}}
\begin{document}
\DefineShortVerb{\+}
-\title{The \texttt{\color{blue}keyreader} Package\footnote{Version 0.2.}}
+\title{The \texttt{\color{blue}keyreader} Package\footnote{\color{red}Version 0.3.}}
\author{Ahmed Musa\\\email{a.musa@rocketmail.com}}
\maketitle
\thispagestyle{empty}
@@ -45,11 +57,23 @@
\section{Motivation}
-The elaborate and powerful \krsty{xkeyval} package provides \krcmd{define@cmdkeys} and \krcmd{define@boolkeys} for defining and setting multiple command keys and boolean keys, but in each category those keys must have the same default value and no key macro/function. This package seeks to remove these restrictions, so that multiple keys of all categories (ordinary keys, command keys, boolean keys, and choice keys) can be set at one go 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.
+Toggle switches or booleans were introduced by the \sty{etoolbox} package and have proved very useful mainly for two reasons: unlike the legacy \TeX{} switches which require three commands per switch, toggles require only one command per switch, and toggles occupy their own separate name space, thereby avoiding clashes with other macros. So we can effectively have both the following sets in the same file:
+\begin{krverbatim}
+\newif\ifmyboolean -> 3 separate commands:
+ \if<myboolean> <myboolean>true
+ <myboolean>false
+
+\newtoggle{myboolean} -> only 1 command and no clash with
+ commands in other name spaces.
+\end{krverbatim}
-Also, the \krsty{xkeyval} package doesn't have the notion of complementary keys, which can be handy in the case of boolean keys. The present package introduces this concept and additionally permits the submission of individual/different key macros to the complementary keys.
+However, the \sty{xkeyval} package can't be used to define and set toggle keys. The present package fills this gap, by providing facilities for defining and setting toggle keys. The work relies on some of the macros from the \sty{xkeyval} package.
-\section{Usage}
+Secondly, the \sty{xkeyval} package can't be used to define and set complementary keys, which can be handy in the case of boolean keys. The present package introduces this concept and additionally permits the submission of individual/different custom key macros to the complementary keys.
+
+The third motivation for this package relates to economy of tokens in style files. The \sty{xkeyval} package provides \cs{\define@cmdkeys} and \cs{\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 remove these restrictions, so that multiple keys of all categories (ordinary keys, command keys, boolean keys, tog keys, and choice 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.
+
+\section{Package loading}
The package can be loaded in style and class files by
\begin{krverbatim}
@@ -61,88 +85,290 @@ and in document files via
\end{krverbatim}
where the options and their default values are
\begin{krverbatim}
-parser=;, macroprefix=mp@, keyprefix=KV, keyfamily=myfamily,
+parser=;, macroprefix=mp@, keyprefix=KV, keyfamily=fam,
xchoicelist=false.
\end{krverbatim}
-The \krsty{parser} is the separator between the keys in the key list to be defined in one go (see examples in section~\ref{sec:examples}). All these options can be set dynamically by using the \krcmd{krsetup} macro:
+The \cs{parser} is the separator between the keys in the key list to be defined in one go (see examples in section~\ref{sec:examples}). All these options can be set dynamically by using the \cs{\krsetup} macro:
\begin{krverbatim}
\krsetup{parser=;, macroprefix=mp@, keyprefix=KV,
- keyfamily=myfamily, xchoicelist=false}.
+ keyfamily=fam, xchoicelist=false}.
+\end{krverbatim}
+
+\section{Complementary boolean keys}
+
+The syntax of complementary boolean keys is
+\begin{krverbatim}
+\define@comp@boolkeys[<key-prefix>]{<family>}[<macro-prefix]
+ {<primary boolean>}[<default value for primary boolean>]
+ {<secondary boolean>}{<func for primary boolean>}
+ {<func for secondary boolean>}.
+\end{krverbatim}
+
+When the user doesn't supply the \cs{<key-prefix>} and/or \cs{<macro-prefix>}, the package will use \cs{<KV>} and \cs{<mp@>}, respectively. When one boolean (primary or secondary) is true, the other is automatically set false. Infinite loops, which are possible in back-linked key settings, are avoided in the \sty{keyreader} package.
+
+As an example, we define below two complementary keys \cs{<draft>} and \cs{<final>} with different key macros:
+\begin{krverbatim}
+\define@comp@boolkeys[KV]{fam}[mp@]{draft}[true]{final}%
+ {%
+ \def\gobble##1{}%
+ }{%
+ \def\notgobble##1{##1}%
+ }.
+\end{krverbatim}
+The key prefix (default \cs{<KV>}), macro prefix (default \cs{<mp@>}), and key macros (no default) can be empty:
+\begin{krverbatim}
+\define@comp@boolkeys{fam}{draft}[true]{final}{}{}.
+\end{krverbatim}
+
+The defined complementary keys \cs{<draft>} and \cs{<final>} can now be set as follows:
+\begin{krverbatim}
+\setkeys[KV]{fam}{draft=true}
+
+\setkeys[KV]{fam}{final=true}
+\end{krverbatim}
+The second statement above reverses the boolean \cs{<draft>} to \cs{<false>}, which had been set in the first statement to \cs{<true>}. There is no meaning to the following:
+\begin{krverbatim}
+\setkeys[KV]{fam}{draft=true,final=true}.
+\end{krverbatim}
+
+Most applications of the \sty{xkeyval} package do indeed use key and macro prefixes; so it presumably makes sense here to assume that all uses of the present package will involve key and macro prefixes.
+
+\section{Toggle switches and keys}
+\label{sec:toggles}
+
+\subsection{Toggle switches}
+
+The following toggle switches are defined in the \sty{keyreader} package. They largely mimic those in the \sty{etoolbox} package, except for the commands \cs{\deftog} and \cs{\requiretog}. There is no fear that the commands in this package will interfere with those from the \sty{etoolbox} package, since the control sequence names are different.
+
+\medskip
+\begin{krverbatim}
+\deftog{<toggle>}
+\end{krverbatim}
+This defines a new \cs{<toggle>} whether or not \cs{<toggle>} is already defined. If \cs{<toggle>} is already defined, a warning message is logged in the transcript file and the new definition is effected.
+
+\medskip
+\begin{krverbatim}
+\newtog{<toggle>}
+\end{krverbatim}
+This defines a new \cs{<toggle>} if \cs{<toggle>} is not already defined; otherwise the package issues a fatal error.
+
+\medskip
+\begin{krverbatim}
+\providetog{<toggle>}
+\end{krverbatim}
+This defines a new \cs{<toggle>} if \cs{<toggle>} is not already defined. If \cs{<toggle>} is already defined, the command does nothing.
+
+\medskip
+\begin{krverbatim}
+\requiretog{<toggle>}
+\end{krverbatim}
+
+\cs{\requiretog} takes arguments like \cs{\newtog} and behaves like \cs{\providetog} with the difference: if the toggle is already defined, the command \cs{\requiretog} calls \LaTeX's \cs{\CheckCommand} to make sure that the new and existing definitions are identical, whereas \cs{\providetog} assumes that if the toggle is already defined, the existing definition should persist. \cs{\requiretog} assures that a toggle will have the given definition, but \cs{\requiretog} also warns the user if there was a previous and different existing definition. For example, if the toggle \cs{<toga>} is currently \cs{<true>}, then since all new toggles start out as \cs{<false>}, a call \cx{\requiretog{toga}} will issue a warning in the log file that the new and old definitions of \cs{<toga>} don't agree and the new definition, therefore, can't go ahead.
+
+The \sty{keyreader} package also provides the command \cs{\requirecmd}, which has the same logic as \cs{\requiretog} but can be used for general \LaTeX{} commands, including those with optional arguments.
+
+\medskip
+\begin{krverbatim}
+\settog{<toggle>}{<true |krvert false>}
+\end{krverbatim}
+This command sets \cs{<toggle>} to \cs{<value>}, where \cs{<value>} may be either \cs{<true>} or \cs{<false>}. This statement will issue an error if \cs{<toggle>} wasn't previously defined.
+
+\medskip
+\begin{krverbatim}
+\togtrue{<toggle>}
+\end{krverbatim}
+This sets \cs{<toggle>} to \cs{<true>}. It will issue an error if \cs{<toggle>} wasn't previously defined.
+
+\medskip
+\begin{krverbatim}
+\togfalse{<toggle>}
+\end{krverbatim}
+This sets \cs{<toggle>} to \cs{<false>}. It will issue an error if \cs{<toggle>} wasn't previously defined.
+
+\medskip
+\begin{krverbatim}
+\iftog{<toggle>}{<true>}{<false>}
+\end{krverbatim}
+This yields the \cs{<true>} statement if the boolean \cs{<toggle>} is currently \cs{<true>}, and \cs{<false>} otherwise. It will issue an error if \cs{<toggle>} wasn't previously defined.
+
+\medskip
+\begin{krverbatim}
+\ifnottog{<toggle>}{<not true>}{<not false>}
+\end{krverbatim}
+This behaves like \cs{\iftog} but the logic of the test is reversed. It will issue an error if \cs{<toggle>} wasn't previously defined.
+
+\subsection{Toggle keys}
+
+The syntax for defining toggle keys is exactly like those for boolean keys in the \sty{xkeyval} package:
+\begin{krverbatim}
+\define@togkey[<pre>]{<fam>}[<mp>]{<key>}[<default>]{<func>}
+\define@togkey+[<pre>]{<fam>}[<mp>]{<key>}[<default>]%
+ {<func1>}{<func2>}
+\end{krverbatim}
+
+If the macro prefix \cs{<mp>} is not specified, these create a toggle of the form \cs{<pre>@<family>@<key>} using \cs{\newtog} (which initializes the switch to \cs{<false>}) and a key macro of the form \cs{\<pre>@<family>@<key>} which first checks the validity of the user input. If the value is valid, it uses it to set the boolean and then executes \cs{<func>}. If the user input wasn't valid, then the boolean will not be set and the package will generate a fatal error.
+
+If \cs{<mp>} is specified, then the key definition process will create a toggle of the form \cs{<mp><key>} and a key macro of the form \cs{\<pre>@<family>@<key>}. The value \cs{<default>} will be used by the key macro when the user sets the key without a value.
+
+If the \cs{+} version of the macro is used, the user can specify two key macros \cs{<func1>} and \cs{<func2>}.
+
+If user input is valid, the macro will set the toggle and executes \cs{<func1>}; otherwise, it will not set the boolean but will execute \cs{<func2>}.
+
+As an example, consider the following (adapted from the \sty{xkeyval} package to suit toggle keys):
+
+\begin{krverbatim}
+\define@togkey{fam}[my@]{frame}{%
+ \iftog{my@frame}{%
+ \PackageInfo{mypack}{Turning frames on}%
+ }{%
+ \PackageInfo{mypack}{Turning frames off}%
+ }%
+}
+
+\define@togkey+{fam}{shadow}{%
+ \iftog{KV@fam@shadow}{%
+ \PackageInfo{mypack}{Turning shadows on}%
+ }{%
+ \PackageInfo{mypack}{Turning shadows off}%
+ }%
+}{%
+ \PackageWarning{mypack}{Erroneous input `#1' ignored}%
+}
+\end{krverbatim}
+
+The first example creates the toggle \cs{<my@frame>} and defines the key macro
+\cs{\KV@fam@frame} to set the boolean (if the input is valid). The second key intimates
+the user of changed settings, or produces a warning when input was incorrect.
+
+It is also possible to define multiple toggle keys with a single command
+\begin{krverbatim}
+\define@togkeys[<pre>]{<fam>}[<mp>]{<keys>}[<default>]
+\end{krverbatim}
+This creates a toggle key for every entry in the comma-separated list \cs{<keys>}. As is the case with the commands \cs{\define@cmdkeys} and \cs{\define@boolkeys} from the \sty{xkeyval} package, the individual keys in this case can't have a custom function. See section~\ref{sec:multiplekeys} for how to define multiple keys with custom functions.
+
+As an example of defining multiple toggle keys, consider
+\begin{krverbatim}
+\define@togkeys{fam}[my@]{toga,togb,togc}
+\end{krverbatim}
+
+This is an abbreviation for
+\begin{krverbatim}
+\define@togkey{fam}[my@]{toga}{}
+\define@togkey{fam}[my@]{togb}{}
+\define@togkey{fam}[my@]{togc}{}
+\end{krverbatim}
+
+Now we can do
+\begin{krverbatim}
+\define@togkey{fam}[my@]{book}{%
+ \iftog{my@book}{\krsetkeys[KV]{fam}{togc=true}}{}%
+}
+
+\krsetkeys[KV]{fam}{book=true}
\end{krverbatim}
-The main user interface is the \krcmd{define@keylist} macro, whose syntax is
+Toggle keys can be set in the same way that other key types are set. \cs{\krsetkeys} is introduced by the \sty{keyreader} package as a drop-in replacement for the legacy \cs{\setkeys} of the \sty{xkeyval} package (see Section~\ref{sec:dirty-trick}). \cs{\setkeys} can still be used when the situation permits (see Section~\ref{sec:dirty-trick}).
+
+The status of toggles can be examined by doing
+\begin{krverbatim}
+\show\<KR@toggle@><mp><key>
+\end{krverbatim}
+when the \cs{<mp>} is present. When the user has specified no \cs{<mp>} in defining the key, he has to issue
\begin{krverbatim}
-\define@keylist{<key type/id>, <key>, <key value>,
+\show\<KR@toggle@><pre>@<family>@<key>.
+\end{krverbatim}
+
+\section{Defining multiple keys by one command}
+\label{sec:multiplekeys}
+
+The main user interface for defining multiple keys is the \cs{\define@keylist} macro, whose syntax is
+\begin{krverbatim}
+\define@keylist{<key type/id>, <key>, <key default value>,
<key macro/function>; <another set of key specifiers>; etc}
\end{krverbatim}
-There are four key types: 1 (ordinary key), 2 (command key), 3 (boolean key),
-4 (choice key). The key and its attributes are separated by commas; they constitute one \krsty{object}. The objects are separated by the \krsty{parser}, which is the semicolon in the above example.
+There are five key types: 1 (ordinary key), 2 (command key), 3 (boolean key),
+4 (toggle key), and 5 (choice key). The key and its attributes are separated by commas; they constitute one \cs{object}. The objects are separated by the \cs{<parser>}, which is the semicolon in the above example.
If the key list is available in a macro, say,
\begin{krverbatim}
-\def\keylist{<key type/id>, <key>, <key value>,
+\def\keylist{<key type/id>, <key>, <key default value>,
<key macro/function>; <another set of key specifiers>; etc},
\end{krverbatim}
-then the keys can be defined by the starred form of \krcmd{define@keylist}:
+then the keys can be defined by the starred form of \cs{\define@keylist}:
\begin{krverbatim}
\define@keylist*\keylist.
\end{krverbatim}
-\krcmd{define@keylist*} takes a macro as argument, while \krcmd{define@keylist} accepts a key list.
+\cx{\define@keylist*} takes a macro as argument, while \cs{\define@keylist} accepts a key list.
+
+\subsection{Choice key values}
-The \krcmd{ChoiceKeyValues} macro is needed for choice keys; it lists the alternate
+The \cs{\ChoiceKeyValues} macro is needed for choice keys; it lists the alternate
admissible values for a choice key and thus can't be empty when a choice key
is being defined. Its syntax is
\begin{krverbatim}
-\ChoiceKeyValues{<key>}{<admissible key values>}.
+\ChoiceKeyValues{<key>}{<comma-separated list of admissible
+ key values>}.
\end{krverbatim}
-To save tokens, the abbreviation \krcmd{CKVS} is provided for \krcmd{ChoiceKeyValues} and may be used in place of \krcmd{ChoiceKeyValues}.
-
-It has to be defined each time a choice key is being defined. For example, if we want to define two choice keys \krsty{align} and \krsty{election}, then before the call to \krcmd{define@keylist}, we have to set
+To further save tokens, the macro \cs{\ChoiceKeyValues} may be abbreviated by \cs{\CKVS}. It has to be defined each time a choice key is being defined. For example, if we want to define two choice keys \cs{align} and \cs{election}, then before the call to \cs{\define@keylist}, we have to set
\begin{krverbatim}
\CKVS{align}{center,right,left,justified}
\CKVS{election}{state,federal,congress,senate}.
\end{krverbatim}
-It doesn't matter which choice key first gets a \krcmd{CKVS}. The prevailing key family, obtainable from \krcmd{kr@keyfamily}, is used internally by \krcmd{ChoiceKeyValues} to build distinct alternate values lists for choice keys. Unless the key family changes, you can't set two \krcmd{ChoiceKeyValues} for the same choice key. This will be possible only if the package option \krsty{xchoicelist} (meaning ``allow overwriting of choice list'') has been set \krsty{true}, either through \krcmd{documentclass}, \krcmd{usepackage}, or \krcmd{krsetup}.
+It doesn't matter which choice key first gets a \cs{\CKVS}. The prevailing key family, obtainable from \cs{\KR@keyfamily}, is used internally by \cs{\ChoiceKeyValues} to build distinct alternate values lists for choice keys. \emph{Unless the key family changes, you can't set two \cs{\ChoiceKeyValues} for the same choice key. This will be possible only if the package option \cs{xchoicelist} \bparen meaning ``allow overwriting of choice list''\eparen has been set \cs{<true>}, either through \cs{\documentclass}, \cs{\usepackage}, or \cs{\krsetup}}. Thus any number of choice keys can appear in one \cs{\define@keylist} or \cx{\define@keylist*} statement if their lists of alternate/admissible values have been set by \cs{\CKVS}.
-As mentioned earlier, the key family (and other package options) can be changed via
+As mentioned earlier, the key family and other package options can be changed dynamically via
\begin{krverbatim}
-\krsetup{parser=;,macroprefix=mp@,keyprefix=KV,
- keyfamily=myfamily,xchoicelist=false}.
+\krsetup{parser=value,macroprefix=value,keyprefix=value,
+ keyfamily=value,xchoicelist=value}.
\end{krverbatim}
-Thus any number of choice keys can appear in one \krcmd{define@keylist} statement if their lists of alternate/admissible values have been set by \krcmd{CKVS}.
+In line with the philosophy of the \sty{xkeyval} package, all the choice keys to be defined using the \sty{keyreader} package require \cs{\ChoiceKeyValues}: choice keys, by definition, have pre-ordained or acceptable values.
-In line with the philosophy of the \krsty{xkeyval} package, all the choice keys to be defined using this package require \krcmd{ChoiceKeyValues}: choice keys by definition have pre-ordained or acceptable values.
+\subsection{Internals}
-\section{Examples}
+The internal equivalent of \cs{\ChoiceKeyValues} (the choice key list of alternative values) is the macro \cs{\<family@key@altlist>}. For example, for the \cs{align} key above, the internal of \cs{\CKVS} is \cs{\fam@align@altlist}, assuming the current family is \cs{fam}.
+
+For all keys in a family, the internal of the key macro/function is available in \cs{\<family@key@func>}, and the value submitted by the user when setting the key can be accessed via the macro \cs{\<family@key@value>}.
+
+\subsection{Examples}
\label{sec:examples}
-Suppose we wish to define a set of keys \krsty{\{color,angle,scale,align\}}. The keys \krsty{color}, \krsty{angle} and \krsty{scale} will de defined using command keys, while the key \krsty{align} will be defined by choice keys. Assume that the \krsty{align} key can only assume the values \krsty{\{center,right,left,justified\}}, where the first three values would further imply \krcmd{centering}, \krcmd{flushright}, and \krcmd{flushleft}, respectively. Moreover, we assume that the key \krsty{scale} will be associated with a macro called \krcmd{mydo}, where \krcmd{do} is assumed defined elsewhere. The keys \krsty{color} and \krsty{angle} aren't associated with macros. Then we can go:
+Suppose that the key family and other attributes have been set as
+\begin{krverbatim}
+\krsetup{parser=;,macroprefix=mp@,keyprefix=KV,
+ keyfamily=fam,xchoicelist=false}.
+\end{krverbatim}
+Further, suppose we wish to define a set of keys \cs{<color,angle,scale,align>}. The keys \cs{color}, \cs{angle} and \cs{scale} will de defined using command keys, while the key \cs{align} will be defined by choice keys. Assume that the \cs{align} key can only assume the values \cs{<center,right,left,justified>}, where the first three values would further imply \cs{\centering}, \cs{\flushright}, and \cs{\flushleft}, respectively. Moreover, we assume that the key \cs{scale} will be associated with a macro called \cs{\mydo}, where \cs{\do} is assumed defined elsewhere. The keys \cs{color} and \cs{angle} aren't associated with macros. Then we can go:
\begin{krverbatim}
\CKVS{align}{center,right,left,justified}
-
+\CKVS{weather}{sunny,cloudy,lightrain,heavyrain,snow,
+ sleet,windy,\someweather}
+ % |color(gray) We assume that \someweather is defined
+ % |color(gray) somewhere and holds an admissible value
+ % |color(gray) for the key ``weather'' at any level.|color(verbcolor)
\def\f@align{%
\ifcase\nr\relax
- \def\kr@align{\centering}%
+ \def\mp@align{\centering}%
\or
- \def\kr@align{\flushright}%
+ \def\mp@align{\flushright}%
\or
- \def\kr@align{\flushleft}%
+ \def\mp@align{\flushleft}%
\or
- \let\kr@align\relax
+ \let\mp@align\relax
\fi
}
\define@keylist{2,color,gray!25,;2,angle,45,;
- 2,scale,1,\def\mydo##1{\do ##1};4,align,center,\f@align;
- |color(red)\stopread|color(blue);3,mybool,true,}.
+ 2,scale,1,\def\mydo##1{\do ##1};5,align,center,\f@align;
+ |color(red)\stopread|color(verbcolor);3,mybool,true,;
+ 5,weather,sunny,\protected@edef\VWeather{\val}}.
\end{krverbatim}
-The \krcmd{nr} macro is a bin parameter defined by the keyreader package in accordance with the instructions in the \krsty{xkeyval} guide. It refreshes with the choice key. See the \krsty{xkeyval} guide for further details.
+The \cs{\nr} and \cs{\val} macros are bin parameters defined by the \sty{xkeyval} package. \cs{\val} contains the user input for the current key and \cs{\nr} contains the numeral corresponding to the user input in the \cs{\CKVS} list, starting from 0 (zero). For example, in the \cx{\CKVS{align}} list, the \cs{\nr} values are \cs{center}~(0), \cs{right}~(1), \cs{left}~(2), and \cs{justified}~(3). These parameters thus refresh with the choice key and its user-supplied value.
-Instead of defining the macro \krcmd{f@align} before hand, we can submit its replacement text directly to the macro \krcmd{define@keylist}, but, because \krcmd{f@align} contains a conditional, some care is needed in doing so (see section~\ref{sec:conditionals}). Once the key \krsty{align} has been defined, the macro \krcmd{f@align} can be reused---perhaps to define other keys---even before the key \krsty{align} is set. This is because it isn't \krcmd{f@align} that is used in defining the key \krsty{align} but its ``meaning'' (\ie, the meaning of \krcmd{f@align}). In this way, the user can economize on tokens. The same applies to all the macros that may be used in defining keys.
+Instead of defining the macro \cs{\f@align} before hand, we can submit its replacement text directly to the macro \cs{\define@keylist}, but, because \cs{\f@align} contains a conditional, some care is needed in doing so (see section~\ref{sec:conditionals}). Once the key \cs{align} has been defined, the macro \cs{\f@align} can be reused---perhaps to define other keys---even before the key \cs{align} is set. This is because it isn't \cs{\f@align} that is used in defining the key \cs{align} but its internal counterpart (\ie, a family-dependent internal of \cs{\f@align}, which is \cs{\fam@align@func}). In this way, the user can economize on tokens. The same applies to all the macros that may be used in defining keys.
-Note the \krcmd{stopread} command inserted above. Because of it, the key \krsty{mybool} will not be read and defined; the rest (\ie, \krsty{color}, \krsty{angle}, \krsty{scale} and \krsty{align}) will be read and defined. All the entries for \krsty{mybool} will instead be saved in the macro \krcmd{kr@remainder}.
+Note the \cs{\stopread} command inserted above. Because of it, the key \cs{mybool} will not be read and defined; the rest (\ie, \cs{color}, \cs{angle}, \cs{scale} and \cs{align}) will be read and defined. All the entries for \cs{mybool} and \cs{weather} will instead be saved in the macro \cs{\KR@remainder}, possibly for some other uses.
Hundreds of keys can be defined efficiently in this way, using very few tokens.
@@ -150,7 +376,7 @@ As another example, we consider the following page setup keys:
\begin{krverbatim}
\CKVS{align}{center,right,left,justified}
\CKVS{election}{state,federal,congress,senate}
-% |color(gray)need to be defined only once|normalcolor
+% |color(gray)\CKVS needs to be defined only once for each key in a family.|normalcolor
\define@keylist{%
3,boolvar,true,;1,paperheight,\paperheight,;
@@ -158,10 +384,12 @@ As another example, we consider the following page setup keys:
2,textheight,\textheight,\f@textheight;
2,textwidth,\textwidth,\f@textwidth;
1,evensidemargin,\evensidemargin,;
- 4,align,center,\f@align;
- 4,election,congress,;
+ 5,align,center,\f@align;
+ 5,election,congress,;
2,testdim,2cm,\long\def\f@testdim##1{A test dimension ##1
\par\bigskip}%
+ % |color(gray) Note the number of parameter characters
+ % |color(gray) in the definition of \f@testdim.
}
\end{krverbatim}
which have the following trivial key macros:
@@ -193,7 +421,7 @@ which have the following trivial key macros:
\end{krverbatim}
Again, once the keys have been defined, these macros can be reused.
-The same set of keys can be defined via the starred form of \krcmd{define@keylist}:
+The same set of keys can be defined via the starred form of \cs{\define@keylist}:
\begin{krverbatim}
\def\keylist{%
3,boolvar,true,;1,paperheight,\paperheight,;
@@ -201,41 +429,49 @@ The same set of keys can be defined via the starred form of \krcmd{define@keylis
2,textheight,\textheight,\f@textheight;
2,textwidth,\textwidth,\f@textwidth;
1,evensidemargin,\evensidemargin,;
- 4,align,center,\f@align;
- 4,election,congress,;
- 2,testdim,2cm,\long\def\f@testdim####1%
- {Do something with ####1}%
- % |color(gray) Note the number of parameter characters here.
+ 4,mytoggle,true,\let\settoggle\settog;
+ 5,align,center,\f@align;
+ 5,election,congress,;
+ 2,testdim,2cm,\long\def\f@testdim##1%
+ {Do something with ##1}%
}
\define@keylist*\keylist.
\end{krverbatim}
Since the keys have been defined, they can now be set. In the following, we set only two of the keys:
\begin{krverbatim}
-\setkeys[KV]{myfamily}{align=right,testdim=3cm}
+\setkeys[KV]{fam}{align=right,testdim=3cm}
\end{krverbatim}
-The macro \krcmd{mp@align} holds the value \krcmd{flushright}, while
+The macro \cs{\mp@align} holds the value \cs{\flushright}, while
\begin{krverbatim}
-\KV@myfamily@testdim
+\KV@fam@testdim
\end{krverbatim}
holds the macros:
\begin{krverbatim}
\def\mp@testdim{#1}
\long\def\f@testdim##1{A test dimension##1\par\bigskip},
\end{krverbatim}
-where \krsty{\#1} is the value submitted for the key \krsty{testdim}.
-Try \krcmd{show\string\mp@align}, \krcmd{show\string\KV@myfamily@testdim}, and \krcmd{show\string\f@testdim} to confirm the above assertions.
+where \cs{\#1} is the value submitted for the key \cs{testdim}.
+Try \cx{\show\mp@align}, \cx{\show\KV@fam@testdim}, and \cx{\show\f@testdim} to confirm the above assertions.
The rest of the defined keys can now be set as follows:
\begin{krverbatim}
-\setkeys[KV]{myfamily}{boolvar=true,paperheight,paperwidth,
+\setkeys[KV]{fam}{boolvar=true,paperheight,paperwidth,
textheight,textwidth=6cm}
\end{krverbatim}
-Try \krcmd{show\string\ifmp@boolvar} to confirm that \krsty{boolvar} is now \krsty{true}; it is originally set as \krsty{false}. The macro \krcmd{KV@myfamily@paperwidth} holds the function \krcmd{f@paperwidth}; \krcmd{mp@textheight} holds the value submitted to key \krsty{textheight} at any instance of \krcmd{setkeys}. By the above \krcmd{setkeys}, only the default values of \krsty{paperheight}, \krsty{paperwidth}, and \krsty{textheight} are presently available.
+Try \cx{\show\ifmp@boolvar} to confirm that \cs{boolvar} is now \cs{<true>}; it was originally set as \cs{<false>}. The macro \cs{\KV@fam@paperwidth} holds the function \cs{\f@paperwidth}; \cs{\mp@textheight} holds the value submitted to key \cs{textheight} at any instance of \cs{\setkeys}. By the above \cs{\setkeys}, only the default values of \cs{paperheight}, \cs{paperwidth}, and \cs{textheight} are presently available.
+
+Instead of using macros to pass key macros and functions, it is also possible to use token registers. An example is provided below:
+\begin{krverbatim}
+\toks0={\long\def\f@testdim#1{A test dimension #1\par\bigskip}}
+
+\define@keylist{3,boolvar,true,;2,testdim,2cm,\the\toks0}.
+\end{krverbatim}
+The advantage of using token registers is that the parameter characters need not be doubled in the token registers, unlike when using macros. The token register \cs{\toks0} can be reused as soon as the key \cs{testdim} is defined.
\subsection[Demonstrating an effect]%
- {Demonstrating the effect of limiting {\tt\textbackslash textwidth}}
+ {Demonstrating the effect of limiting \textbackslash textwidth}
After defining and setting the keys above, the following tokens can be used in a source file to demonstrate the effect of setting the page setup keys shown above:
\begin{krverbatim}
@@ -250,122 +486,137 @@ After defining and setting the keys above, the following tokens can be used in a
\lipsum[1]
\end{krverbatim}
-\section{Complementary boolean keys}
+\section{Input error}
-The syntax of complementary boolean keys is
+Both boolean and choice keys issue error messages if the input is not valid, \ie, not in the list of admissible values. The default input error is defined by \cs{\KR@inputerr} macro to be
\begin{krverbatim}
-\define@comp@boolkeys[<key-prefix>]{<family>}[<macro-prefix]
- {<primary boolean>}[<default value for primary boolean>]
- {<secondary boolean>}{<func for primary boolean>}
- {<func for secondary boolean>}.
+\KR@err{Erroneous value `#1' for key `#2'}{%
+ Please use the correct value for key `#2'.}.
\end{krverbatim}
+\cs{\KR@inputerr} can be redefined by the user. It takes two arguments (\ie, value and key).
-When the user doesn't supply the \krsty{key-prefix} and/or \krsty{macro-prefix}, the package will use \krsty{KV} and \krsty{mp@}, respectively. When one boolean (primary or secondary) is true, the other is
-automatically set false. Infinite loops, which are possible in back-linked key settings, are avoided in the \krsty{keyreader} package.
+\section{Conditionals in key macros}
+\label{sec:conditionals}
-As an example, we define below two complementary keys \krsty{draft} and \krsty{final} with different key macros:
-\begin{krverbatim}
-\define@comp@boolkeys[KV]{myfamily}[kr@]{draft}[true]{final}%
- {%
- \def\gobble##1{}%
- }{%
- \def\notgobble##1{##1}%
- }.
-\end{krverbatim}
-The key prefix (default \krsty{KV}), macro prefix (default \krsty{mp@}), and key macros (no default) can be empty:
-\begin{krverbatim}
-\define@comp@boolkeys{myfamily}{draft}[true]{final}{}{}.
-\end{krverbatim}
+The \TeX{} conditional primitives \cs{\if} and \cs{\fi} cannot appear in the key macro when \cs{\define@keylist} is being invoked. The reason can be traced to the discussion on page~211 of the \TeX Book and the loop used in the \sty{keyreader} package to define keys. There are three approaches to resolving this problem, and the user can choose anyone he/she prefers.
-The defined complementary keys \krsty{draft} and \krsty{final} can now be set as follows:
-\begin{krverbatim}
-\setkeys[KV]{myfamily}{draft=true}
+\subsection{Burying conditionals in macros or token registers}
-\setkeys[KV]{myfamily}{final=true}
-\end{krverbatim}
-The second statement above reverses the boolean \krsty{draft} to \krsty{false}, which had been set in the first statement to \krsty{true}. There is no meaning to the following:
+Key macros/functions involving conditional operations such as
\begin{krverbatim}
-\setkeys[KV]{myfamily}{draft=true,final=true}.
+\ifmp@bool \do \fi
\end{krverbatim}
+can be submitted to \cs{\define@keylist} via macros, as seen above. We give more examples below.
-As an exercise, in a document file, after defining and setting the above keys, one can issue the command \krcmd{krsetup\{draft=true\}} and do
+Suppose we want to submit the following:
\begin{krverbatim}
-\show\ifkr@draft \show\ifkr@final \show\gobble
-\show\KV@myfamily@draft.
+\define@keylist{3,bool,true,\ifmp@bool \do \fi}.
\end{krverbatim}
-These statements assume the macro prefix to be \krsty{kr@}. Next, we may set
+The presence of \cs{\if} and \cs{\fi} in the argument will trigger an error when \TeX{} is scanning or skipping tokens, and, secondly, because of the loop and conditional used by the \sty{keyreader} package in defining keys. Neither \cs{\protect} nor \cs{\noexpand} is helpful here. One solution is to first define
\begin{krverbatim}
-\krsetup{final=true}
+\def\f@bool{\ifmp@bool \do \fi}
\end{krverbatim}
-and do
+and then do
\begin{krverbatim}
-\show\ifkr@final \show\ifkr@draft \show\notgobble.
+\define@keylist{3,bool,true,\f@bool},
\end{krverbatim}
+which will execute \cs{\f@bool} when the key \cs{bool} is set. Once the key \cs{bool} has been defined by the above statement, the function \cs{\f@bool} may be redefined and reused many times, any time, even before the setting of the key \cs{bool}. It isn't the function \cs{\f@bool} that is used in defining the key \cs{bool}, but an internal of \cs{\f@bool}.
-\section{Input error}
-
-Both boolean and choice keys issue error messages if the input is not valid, \ie, not in the list of admissible values. The default input error is defined by \krcmd{kr@inputerr} macro to be
+As another example, we may do
\begin{krverbatim}
-<Erroneous value `#1' for key `#2'>.
+\def\f@abool{\ifmp@abool\def\do####1{%
+ \def####1########1{\expandafter\expandafter\expandafter\in@
+ \expandafter\expandafter\expandafter{\expandafter####1
+ \expandafter}\expandafter{########1}}}\fi}
+
+\define@keylist{3,abool,true,\f@abool}.
\end{krverbatim}
-\krcmd{kr@inputerr} can be redefined by the user. It takes two arguments (\ie, value and key).
+Token registers (including scratch token registers) can be used here economically instead of macros:
+\begin{krverbatim}
+\toks0{\ifmp@abool\def\do#1{%
+ \def#1##1{\expandafter\expandafter\expandafter\in@
+ \expandafter\expandafter\expandafter{\expandafter#1
+ \expandafter}\expandafter{##1}}}\fi}
-\section{Conditionals in key macros}
-\label{sec:conditionals}
+\toks1{\iftog{toggleone}{def\tempa#1{Use #1}}{}}
-The \TeX{} conditional primitives \krcmd{if} and \krcmd{fi} cannot appear in the key macro when \krcmd{define@keylist} is being invoked. The reason can be traced to the discussion on page~211 of the \TeX Book. Key macros/functions involving conditional operations such as
-\begin{krverbatim}
-\ifmp@boolone \do \fi
+\define@keylist{3,abool,true,\the\toks0;
+ 4,toggleone,true,\the\toks1}
+
+\setkeys[KV]{fam}{abool=true,toggleone=true}.
\end{krverbatim}
-can be submitted to \krcmd{define@keylist} via macros, as seen above. We give more examples below.
+You can see the significant reduction in the number of parameter characters when using token registers. The token registers \cs{\toks0} and \cs{\toks1} can be reused to define many other keys.
-Suppose we want to submit the following:
+\subsection{Using a ``dirty'' trick to submit the conditionals}
+\label{sec:dirty-trick}
+
+There are two downsides to the above approach of hiding conditionals in macros:
+\begin{enumerate}
+\item The macros have to be defined and, although they can be redefined and reused, they tend to defeat the initial aim of the package, which is to economize on tokens.
+\item If the conditionals involve macro definitions as in the above example, the parameter characters have to be doubled in each instance, except when using token registers.
+\end{enumerate}
+
+Suppose we want to define a boolean key \cs{mybool} with the following key macro:
\begin{krverbatim}
-\define@keylist{3,boolone,true,\ifmp@boolone \do \fi}.
+\ifmp@mybool\def\hold##1{\def##1####1{####1}}\fi,
\end{krverbatim}
-The presence of \krcmd{if...} and \krcmd{fi} in the argument will trigger an error when \TeX{} is scanning or skipping tokens (see the \TeX Book). Neither \krcmd{protect} nor \krcmd{noexpand} is helpful here. One solution is to first define
+where the macro prefix is \cs{mp@} and the key family has been defined previously. Then, instead of hiding the conditional in a macro, we can go
\begin{krverbatim}
-\def\f@boolone{\ifmp@boolone \do \fi}
+\define@keylist{3,mybool,true,
+ \fif{mp@mybool}\def\hold##1{\def##1####1{####1}}\ffi}.
\end{krverbatim}
-and then do
+Here we have used \cx{\fif{mp@mybool}} and \cs{\ffi} for \cs{\ifmp@mybool} and \cs{\fi}, respectively, to hide the latter two from \TeX's scanning and skipping mechanism. Please note that \cx{\fif{mp@mybool}} requires that the argument \cs{<mp@mybool>} be enclosed in braces. Something like \cs{\fifmp@mybool} will be interpreted by \TeX{} as undefined control sequence when the key \cs{mybool} is being set.
+
+Now, however, when setting the key \cs{mybool}, the user has to use \cs{\krsetkeys} instead of \sty{xkeyval}'s legacy \cs{\setkeys}. The command \cs{\krsetkeys} does understand that \cs{\fif} and \cs{\ffi} stand for \cs{\if} and \cs{\fi}, respectively, and have been used to ``deceive'' \TeX. \cs{\krsetkeys} has the same syntax as \cs{\setkeys}:
\begin{krverbatim}
-\define@keylist{3,boolone,true,\f@boolone},
+\krsetkeys*+[key prefix]{key family}{keys=values}.
\end{krverbatim}
-which will execute \krcmd{f@boolone} when the key \krsty{boolone} is set. Once the key \krsty{boolone} has been defined by the above statement, the function \krcmd{f@boolone} may be redefined and reused many times, any time, even before the setting of the key \krsty{boolone}. It isn't the function \krcmd{f@boolone} that is used in defining the key \krsty{boolone}, but the ``meaning'' of \krcmd{f@boolone}.
+\cs{\krsetkeys} can in general be used in place of \cs{\setkeys}, even in instances (\ie, for keys) where \cs{\fif} and \cs{\ffi} have not been used.
-As another example, we may do
+In the case of conditionals starting with \cs{\ifcase}, a \cs{\noexpand} before the \cs{\ifcase} solves the problem:
\begin{krverbatim}
-\def\f@bool{\ifmp@bool\def\do####1{%
- \def####1########1{\expandafter\expandafter\expandafter\in@
- \expandafter\expandafter\expandafter{\expandafter####1
- \expandafter}\expandafter{########1}}}\fi}
+\CKVS{focus}{center,left,right,justified}
-\define@keylist{3,bool,true,\f@bool}.
+\define@keylist{5,focus,center,|color(red)\noexpand|color(verbcolor)\ifcase\nr\relax
+ \def\mp@focus{\centering}\or\def\mp@focus{\flushright}
+ \or\def\mp@focus{\flushleft}\or\let\mp@focus\relax\fi
+}
\end{krverbatim}
-``Toggles,'' introduced in the \krsty{etoolbox} package, can also be used to circumvent the problem of matching \krcmd{if} and \krcmd{fi} in difficult circumstances, since toggles aren't \TeX\ primitives, but the \krsty{xkeyval} doesn't as yet have a mechanism for defining and setting toggle keys. However, this shouldn't be difficult to implement in the future.
+\subsection{Using toggles}
+
+Toggle switches, described in Section~\ref{sec:toggles}, can also be used to circumvent the problem of matching \cs{\if} and \cs{\fi} in difficult circumstances, since toggles aren't \TeX\ primitives. For example, the following works:
+\begin{krverbatim}
+\define@keylist{4,toggleone,true,
+ \iftog{toggleone}{\def\temp{This is defined by a toggle}}{}}.
+\end{krverbatim}
+And, as noted in Section~\ref{sec:toggles}, toggles are very economical.
\section{Disabling keys}
-The \krsty{keyreader} package has modified the definition of \krcmd{disable@keys} from the \krsty{xkeyval} package to allow for bespoke warnings and error messages. The new command is \krcmd{krdisable@keys}; the use syntax remains the same as that of \krcmd{disable@keys}:
+The \sty{keyreader} package has modified the definition of \cs{\disable@keys} from the \sty{xkeyval} package to allow for bespoke warnings and error messages, without engendering any conflict with the legacy \cs{\disable@keys}. The new command is \cs{\krdisable@keys}; the use syntax remains the same as that of \cs{\disable@keys}:
\begin{krverbatim}
\krdisable@keys[<key prefix>]{<key family>}{<comma %
separated list of keys to disable>}.
\end{krverbatim}
-Any attempt to subsequently set a disabled key will prompt the following error message. (The \krsty{xkeyval} package issues a warning in this case.) The error message can be modified by the user, but the ``names'' \krcmd{disabledkeyerr} and \krcmd{disabledkey} should be retained.
+Any attempt to subsequently set a disabled key will prompt the following error message. (The \sty{xkeyval} package issues a warning in this case.) The error message can be modified by the user, but the ``names'' \cs{\KR@disabledkey@err} and \cs{\KR@disabledkey} should be retained.
\begin{krverbatim}
-\def\disabledkeyerr{%
+\def\KR@disabledkey@err{%
\PackageError{keyreader}{%
- Key `\disabledkey' has been disabled.\MessageBreak
+ Key `\KR@disabledkey' has been disabled.}{%
You can't set or reset it at this late stage.\MessageBreak
You should have set it earlier in the\MessageBreak
\string\documentclass\space or \string\usepackage
- }{\@ehc}%
+ }%
}
\end{krverbatim}
-If the user attempts to disable an undefined key, the \krsty{xkeyval} package issues a fatal error; the \krsty{keyreader} package, on the other hand, issues a warning in the transcript .log file, since the situation isn't fatal to the outcome.
+If the user attempts to disable an undefined key, the \sty{xkeyval} package issues a fatal error; the \sty{keyreader} package, on the other hand, issues a warning in the transcript .log file, since the situation isn't fatal to the outcome.
+
+\section{Epilogue}
+
+The are many commands available in the package for general use, but they are not documented here.
\end{document}
diff --git a/Master/texmf-dist/tex/latex/keyreader/keyreader.sty b/Master/texmf-dist/tex/latex/keyreader/keyreader.sty
index 5b28021c5b2..da826d47d9b 100644
--- a/Master/texmf-dist/tex/latex/keyreader/keyreader.sty
+++ b/Master/texmf-dist/tex/latex/keyreader/keyreader.sty
@@ -1,6 +1,6 @@
-%+++++++++++++++++++++++++++++++++++++ LICENSE ++++++++++++++++++++++++++++++++++++++%
+%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% %
-% This is file 'keyreader.sty', version 0.2. %
+% This is file 'keyreader.sty', version 0.3. %
% %
% This package reads multiple keys to be defined by xkeyval.sty. %
% %
@@ -24,8 +24,8 @@
\catcode064 11% @
\catcode123 01% {
\catcode125 02% }
-\def\x{\endgroup
- \edef\kr@restorecodes{%
+\def\KR@tempa{\endgroup
+ \edef\KR@restorecodes{%
\catcode035 \the\catcode035% #
\catcode064 \the\catcode064% @
\catcode123 \the\catcode123% {
@@ -33,66 +33,156 @@
\catcode061 \the\catcode061% =
}%
}
-\x
+\KR@tempa
\@makeother{\=}%
\catcode035=06% #
\catcode064=11% @
\catcode123=01% {
\catcode125=02% }
-\def\kr@ensurecode#1#2{%
- \edef\kr@restorecodes{%
- \kr@restorecodes
+\def\KR@ensurecode#1#2{%
+ \edef\KR@restorecodes{%
+ \KR@restorecodes
\catcode#1=\the\catcode#1\relax
}%
\catcode#1=#2\relax
}
-\AtEndOfPackage{\kr@restorecodes}
-\kr@ensurecode{044}{12}% ,
-\kr@ensurecode{058}{12}% :
-\kr@ensurecode{059}{12}% ;
-\kr@ensurecode{038}{03}% &
+\AtEndOfPackage{\KR@restorecodes}
+\KR@ensurecode{044}{12}% ,
+\KR@ensurecode{058}{12}% :
+\KR@ensurecode{059}{12}% ;
\ProvidesPackage{keyreader}%
- [2010/01/13 v0.2 Read multiple keys for the xkeyval parser (AM)]
+ [2010/01/24 v0.3 Extensions for the xkeyval parser (AM)]
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\@ifpackageloaded{xkeyval}{}{\RequirePackage{xkeyval}[2008/08/13]}
-\protected\long\def\kr@warn#1{\PackageWarningNoLine{keyreader}{#1}}
-\protected\long\def\kr@err#1{\PackageError{keyreader}{#1}{\@ehc}}
-\protected\long\def\kr@afterfi#1\fi{\fi#1}
-\def\kr@CommandListParser#1{%
- \long\def\kr@define@keylist##1##2{%
- \mathchardef\kr@tempcntb=\z@
- ##1\kr@readlist##2#1&
- }%
- \long\def\kr@readlist##1#1##2&{%
- \kr@ifblank{##1}{}%
+\def\KR@nil{\noexpand\KR@nil}
+\protected\long\def\KR@info#1{\PackageInfo{keyreader}{#1\@gobble}}
+\protected\long\def\KR@warn#1{\PackageWarningNoLine{keyreader}{#1}}
+\protected\long\def\KR@err#1#2{\PackageError{keyreader}{#1}{#2}}
+\protected\long\def\KR@afterfi#1\fi{\fi#1}
+\protected\long\def\KR@afterelsefi#1\else#2\fi{\fi#1}
+\def\KR@commandlistparser#1{%
+ \long\def\KR@define@keylist##1##2{%
+ \mathchardef\KR@tempcntb=\z@
+ ##1\KR@readlist##2#1\KR@nil
+ }%
+ \long\def\KR@readlist##1#1##2\KR@nil{%
+ \KR@ifblank{##1}{}%
{%
- \edef\@i{\detokenize{##1}}%
- \edef\@ii{\detokenize{\stopread}}%
- \ifx\@i\@ii
- \mathchardef\kr@tempcntb=\@ne
- \stopread##2&
- \else
- \kr@define@key##1&
- \fi
+ \KR@ifstrequal{##1}{\stopread}{%
+ \mathchardef\KR@tempcntb=\@ne
+ \stopread##2\KR@nil
+ }{%
+ \KR@define@multiple@keys##1\KR@nil
+ }%
}%
- \ifnum\kr@tempcntb=\z@
- \kr@ifblank{##2}{}{\kr@readlist##2&}%
+ \ifnum\KR@tempcntb=\z@
+ \KR@ifblank{##2}{}{\KR@readlist##2\KR@nil}%
\fi
}%
}
-\define@cmdkey[KV]{keyreader}[kr@]{parser}[;]{%
- \if\kr@parser,\kr@afterfi\kr@err{Parser can't be comma}\fi
- \kr@CommandListParser{#1}%
+\def\KR@expandargs#1#2#3#4{%
+ \begingroup
+ \protected@edef\KR@tempa{\endgroup
+ \ifcase#1\relax
+ \noexpand#2{#3}%
+ \or
+ \unexpanded{#2#3}{#4}%
+ \or
+ \noexpand#2{#3}{#4}%
+ \or
+ {#2}{#3}{#4}%
+ \else
+ \KR@err{Erroneous expansion type '#1'}{\noexpand\@ehc}
+ \fi
+ }%
+ \KR@tempa
+}
+\long\def\KR@inputerr#1#2{%
+ \KR@err{Erroneous value '#1' for key '#2'}{%
+ Please use the correct value for key '#2'.}%
+}
+\protected\long\def\KR@ifblank#1{%
+ \KR@ifbl@nk#1\KR@nil\KR@nil\@secondoftwo\@firstoftwo:}
+\long\def\KR@ifbl@nk#1#2\KR@nil#3#4#5:{#4}
+\protected\def\KR@xifblank#1{\KR@expandargs{0}\KR@ifblank{#1}}
+\def\KR@findescape#1{%
+ \begingroup
+ \escapechar=92\relax
+ \edef\KR@tempa{\expandafter\@car\string#1\@nil}%
+ \ifx\KR@tempa\@backslashchar
+ \aftergroup\@secondoftwo
+ \else
+ \aftergroup\@firstoftwo
+ \fi
+ \endgroup
+}
+\protected\long\def\KR@ifstrequal#1#2{%
+ \begingroup
+ \KR@expandargs{1}\KV@@sp@def\KR@tempa{\detokenize{#1}}%
+ \KR@expandargs{1}\KV@@sp@def\KR@tempb{\detokenize{#2}}%
+ \ifx\KR@tempa\KR@tempb
+ \aftergroup\@firstoftwo
+ \else
+ \aftergroup\@secondoftwo
+ \fi
+ \endgroup
+}
+\protected\long\def\KR@xifstrequal#1#2{%
+ \KR@expandargs{2}\KR@ifstrequal{#1}{#2}%
+}
+\def\KR@listparser@err{%
+ \KR@err{List parser '\KR@parser' not allowed}%
+ {Use semicolon (preferable) or colon.}%
+}
+\define@cmdkey[KV]{keyreader}[KR@]{parser}[;]{%
+ \@onelevel@sanitize\KR@parser
+ \KR@xifblank{\KR@parser}{\KR@listparser@err}{}%
+ \KR@expandargs{1}\KV@@sp@def\KR@parser\KR@parser%
+ \def\KR@tempa{,}%
+ \ifx\KR@parser\KR@tempa\KR@listparser@err\fi
+ \KR@expandargs{0}\KR@commandlistparser\KR@parser%
+}
+\def\KR@keyprefix@err{%
+ \KR@err{Key prefix '\KR@keyprefix' is not allowed}%
+ {Use another prefix.}%
+}
+\define@cmdkey[KV]{keyreader}[KR@]{keyprefix}[KV]{%
+ \KR@xifblank{\KR@keyprefix}{\KR@keyprefix@err}{}%
+ \KR@expandargs{1}\KV@@sp@def\KR@keyprefix\KR@keyprefix%
+ \XKV@for@n{KR,mp,fam,XKV}\KR@tempa{%
+ \ifx\KR@keyprefix\KR@tempa\KR@keyprefix@err\fi
+ }%
+}
+\def\KR@keyfamily@err{%
+ \KR@err{Key family '\KR@keyfamily' is not allowed}%
+ {Use another family name.}%
}
-\define@cmdkey[KV]{keyreader}[kr@]{keyprefix}[KV]{}
-\define@cmdkey[KV]{keyreader}[kr@]{keyfamily}[fam]{}
-\define@cmdkey[KV]{keyreader}[kr@]{macroprefix}[mp@]{}
-\define@boolkey[KV]{keyreader}[kr@]{xchoicelist}[true]{}
-\DeclareOptionX*{\kr@warn{Unknown option '\CurrentOption' ignored}}
+\define@cmdkey[KV]{keyreader}[KR@]{keyfamily}[fam]{%
+ \KR@xifblank{\KR@keyfamily}{\KR@keyfamily@err}{}%
+ \KR@expandargs{1}\KV@@sp@def\KR@keyfamily\KR@keyfamily%
+ \XKV@for@n{KR,mp,keyreader,KV,XKV}\KR@tempa{%
+ \ifx\KR@keyfamily\KR@tempa\KR@keyfamily@err\fi
+ }%
+}
+\def\KR@macroprefix@err{%
+ \KR@err{Macro prefix '\KR@macroprefix' is not allowed}%
+ {Use another prefix.}%
+}
+\define@cmdkey[KV]{keyreader}[KR@]{macroprefix}[mp@]{%
+ \KR@xifblank{\KR@macroprefix}{\KR@macroprefix@err}{}%
+ \KR@expandargs{1}\KV@@sp@def\KR@macroprefix\KR@macroprefix%
+ \XKV@for@n{KR,keyreader,fam,KV,XKV}\KR@tempa{%
+ \ifx\KR@macroprefix\KR@tempa\KR@macroprefix@err\fi
+ }%
+}
+\define@boolkey+[KV]{keyreader}[KR@]{xchoicelist}[true]{}{%
+ \KR@inputerr{#1}{xchoicelist}%
+}
+\DeclareOptionX*{\KR@warn{Unknown option '\CurrentOption' ignored}}
\ExecuteOptionsX[KV]<keyreader>{parser,keyprefix,keyfamily,macroprefix}
\ProcessOptionsX*[KV]<keyreader>\relax
\newcommand\krsetup[1]{\setkeys[KV]{keyreader}{#1}}
-\def\kr@defcommand#1#2{%
+\def\KR@named@f#1#2{%
\ifcsname#2\endcsname
\expandafter\ifx\csname#2\endcsname\relax\else
\def\reserved@a{#2}%
@@ -102,10 +192,19 @@
\expandafter#1\csname#2\expandafter\endcsname
\fi
}
-\def\kr@namedef#1{\kr@defcommand\def{#1}}
-\def\kr@nameedef#1{\kr@defcommand\edef{#1}}
-\def\kr@nameuse#1{\ifcsname#1\endcsname\csname#1\expandafter\endcsname\fi}
-\def\kr@ifnameundef#1{%
+\def\KR@namedef#1{\KR@named@f\def{#1}}
+\def\KR@n@medef#1#2{\expandafter\def\csname#1\endcsname{#2}}
+\def\KR@nameedef#1{\KR@named@f\edef{#1}}
+\def\KR@n@meedef#1#2{\expandafter\edef\csname#1\endcsname{#2}}
+\def\KR@nameuse#1{\ifcsname#1\endcsname\csname#1\expandafter\endcsname\fi}
+\def\KR@ifnamedef#1{%
+ \ifcsname#1\endcsname
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+}
+\def\KR@ifnameundef#1{%
\ifcsname#1\endcsname
\expandafter\ifx\csname#1\endcsname\relax
\expandafter\expandafter\expandafter\@firstoftwo
@@ -116,116 +215,353 @@
\expandafter\@firstoftwo
\fi
}
-\long\def\kr@ifnextchar#1#2#3{% \new@ifnextchar
+\long\def\KR@ifnextchar#1#2#3{% \new@ifnextchar
\let\tmp@d=#1\def\tmp@a{#2}\def\tmp@b{#3}%
- \futurelet\@let@token\kr@ifnch
-}
-\long\def\kr@ifnch{\ifx\@let@token\tmp@d\let\tmp@b\tmp@a\fi\tmp@b}
-\long\def\kr@testopt#1#2{\kr@ifnextchar[{#1}{#1[{#2}]}}
-\long\def\kr@ifstar#1#2{\kr@ifnextchar*{\def\tmp@a*{#1}\tmp@a}{#2}}
-\long\def\kr@ifblank#1{\kr@ifbl@nk#1&&\@secondoftwo\@firstoftwo:}
-\long\def\kr@ifbl@nk#1#2&#3#4#5:{#4}
-\long\def\kr@expandonce#1{\unexpanded\expandafter{#1}}
-\long\def\kr@csexpandonce#1{\expandafter\kr@expandonce\csname#1\endcsname}
-\@ifdefinable\stopread{\long\def\stopread#1&{\long\def\kr@remainder{#1}}}
-\long\def\kr@inputerr#1#2{\kr@err{Erroneous value '#1' for key '#2'}}
-\mathchardef\kr@tempcnta=\z@\mathchardef\kr@tempcntb=\z@
-\mathchardef\kr@tempcntc=\z@
+ \futurelet\@let@token\KR@ifnch
+}
+\long\def\KR@ifnch{\ifx\@let@token\tmp@d\let\tmp@b\tmp@a\fi\tmp@b}
+\long\def\KR@testopt#1#2{\KR@ifnextchar[{#1}{#1[{#2}]}}
+\long\def\KR@ifstar#1#2{\KR@ifnextchar*{\def\tmp@a*{#1}\tmp@a}{#2}}
+\long\def\KR@expandonce#1{\unexpanded\expandafter{#1}}
+\long\def\KR@csexpandonce#1{\expandafter\KR@expandonce\csname#1\endcsname}
+\newcommand*\nameletcs[2]{\expandafter\let\csname#1\endcsname#2}
+\newcommand*\csletname[2]{\expandafter\let\expandafter#1\csname#2\endcsname}
+\newcommand*\nameletname[2]{%
+ \expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname
+}
+\def\define@comp@boolkeys{\KR@testopt{\KR@comp@opta}{KV}}
+\def\KR@comp@opta[#1]#2{\KR@testopt{\KR@define@comp@boolkeys[#1]{#2}}{mp@}}
+\def\KR@define@comp@boolkeys[#1]#2[#3]#4[#5]#6#7#8{%
+ \KR@namedef{comp@#2@#4}{\KR@nameuse{if#3#4}\KR@nameuse{#3#6false}\fi}%
+ \KR@namedef{comp@#2@#6}{\KR@nameuse{if#3#6}\KR@nameuse{#3#4false}\fi}%
+ \KR@namedef{func@#2@#4}{#7}%
+ \KR@namedef{func@#2@#6}{#8}%
+ \begingroup\protected@edef\KR@tempa{\endgroup
+ \unexpanded{\define@boolkey+[#1]{#2}[#3]{#4}[#5]{%
+ \KR@nameuse{comp@#2@#4}\KR@nameuse{func@#2@#4}}%
+ {\KR@inputerr{##1}{#4}}%
+ }%
+ \unexpanded{\define@boolkey+[#1]{#2}[#3]{#6}[#5]{%
+ \KR@nameuse{comp@#2@#6}\KR@nameuse{func@#2@#6}}%
+ {\KR@inputerr{##1}{#6}}%
+ }%
+ }%
+ \KR@tempa
+}
+\newcommand*\KR@star@or@none{}
+\newcommand*\KR@star@or@long[1]{%
+ \KR@ifstar {%
+ \let\l@ngrel@x\relax
+ \def\KR@star@or@none{*}#1%
+ }{%
+ \let\l@ngrel@x\long
+ \def\KR@star@or@none{}#1%
+ }%
+}
+\protected\long\def\requirecmd{\KR@star@or@long\KR@require@cmd}
+\newcommand\KR@require@cmd[1]{%
+ \ifdefined#1%
+ \KR@afterelsefi
+ \expandafter\CheckCommand\KR@star@or@none
+ \else
+ \KR@afterfi
+ \expandafter\newcommand\KR@star@or@none
+ \fi
+ {#1}%
+}
+\def\@check@eq#1#2{%
+ \unless\ifx#1#2%
+ \KR@warn{%
+ Previous definition of \string#1\MessageBreak
+ doesn't match your new definition.\MessageBreak
+ *** I haven't redefined \string#1\space ***
+ }%
+ \fi
+}
+\protected\def\KR@undeftoggle@err#1{%
+ \KR@err{Toggle '#1' undefined}%
+ {You need to first define '#1' before use.}%
+}
+\protected\def\deftog#1{%
+ \KR@ifnamedef{KR@toggle@#1}{%
+ \KR@warn{Toggle '#1' redefined\on@line}%
+ }{}%
+ \nameletcs{KR@toggle@#1}\@secondoftwo
+}
+\protected\def\newtog#1{%
+ \KR@ifnamedef{KR@toggle@#1}{%
+ \KR@err{Toggle '#1' already defined}%
+ {Please provide a new toggle or redefine '#1'.}%
+ }{%
+ \nameletcs{KR@toggle@#1}\@secondoftwo
+ }%
+}
+\protected\def\providetog#1{%
+ \KR@ifnamedef{KR@toggle@#1}{%
+ \KR@info{Toggle '#1' already defined.\MessageBreak
+ Not redefined\on@line}%
+ }{%
+ \nameletcs{KR@toggle@#1}\@secondoftwo
+ }%
+}
+\protected\def\requiretog#1{%
+ \expandafter\requirecmd\csname KR@toggle@#1\endcsname[2]{##2}%
+}
+\protected\def\settog#1#2{%
+ \KR@ifnamedef{KR@toggle@#1}{%
+ \KR@ifnamedef{KR@t@ggle#2}{%
+ \nameletname{KR@toggle@#1}{KR@t@ggle#2}%
+ }{%
+ \KR@err{%
+ Inadmissible value '#2' for toggle '#1'
+ }{%
+ Valid values for toggles are 'true' and 'false'.
+ }%
+ }%
+ }{%
+ \KR@undeftoggle@err{#1}%
+ }%
+}
+\protected\def\togtrue#1{%
+ \KR@ifnamedef{KR@toggle@#1}{%
+ \nameletcs{KR@toggle@#1}\KR@t@ggletrue
+ }{%
+ \KR@undeftoggle@err{#1}%
+ }%
+}
+\protected\def\togfalse#1{%
+ \KR@ifnamedef{KR@toggle@#1}{%
+ \nameletcs{KR@toggle@#1}\KR@t@gglefalse
+ }{%
+ \KR@undeftoggle@err{#1}%
+ }%
+}
+\global\let\KR@t@ggletrue\@firstoftwo
+\global\let\KR@t@gglefalse\@secondoftwo
+\protected\def\iftog#1{%
+ \KR@ifnamedef{KR@toggle@#1}{%
+ \csname KR@toggle@#1\endcsname
+ }{%
+ \KR@undeftoggle@err{#1}%
+ }%
+}
+\protected\def\ifnottog#1{%
+ \KR@ifnamedef{KR@toggle@#1}{%
+ \csname KR@toggle@#1\endcsname\@secondoftwo\@firstoftwo
+ }{%
+ \KR@undeftoggle@err{#1}\@gobbletwo
+ }%
+}
+\def\define@togkey{\XKV@t@stopta{\XKV@testoptd\KR@define@togkey{}}}
+\def\KR@define@togkey#1#2[#3]{%
+ \ifXKV@pl\KR@afterelsefi
+ \expandafter\KR@d@f@ne@togkey
+ \else\KR@afterfi
+ \expandafter\KR@d@fine@togkey
+ \fi
+ \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}%
+}
+\def\KR@d@fine@togkey#1#2#3#4#5{%
+ \KR@d@f@ne@t@gkey#1{#2}{#3}{#4}%
+ {{\settog{#3}{\XKV@resa}#5}}%
+}
+\def\KR@d@f@ne@togkey#1#2#3#4#5#6{%
+ \KR@d@f@ne@t@gkey#1{#2}{#3}{#4}%
+ {{\settog{#3}{\XKV@resa}#5}{#6}}%
+}
+\def\KR@d@f@ne@t@gkey#1#2#3#4#5{%
+ \newtog{#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\define@togkeys{\XKV@plfalse\XKV@testoptd\KR@define@togkeys{}}
+\def\KR@define@togkeys#1#2[#3]{%
+ \XKV@sp@deflist\KR@tempa{#2}%
+ \XKV@for@o\KR@tempa\KR@tempa{%
+ \expandafter\KR@d@fine@togkeys\expandafter{\KR@tempa}{#1}{#3}%
+ }%
+}
+\def\KR@d@fine@togkeys#1#2#3{%
+ \expandafter\KR@d@f@ne@t@gkey\csname\XKV@header#1\endcsname
+ {#1}{#2#1}{#3}{{\settog{#2#1}{\XKV@resa}}}%
+}
+\@ifdefinable\stopread{%
+ \long\def\stopread#1\KR@nil{%
+ {\toks@{#1}\long\xdef\KR@remainder{\the\toks@}}
+ }%
+}
+\mathchardef\KR@tempcnta=\z@\mathchardef\KR@tempcntb=\z@
+\mathchardef\KR@tempcntc=\z@
\protected\long\def\define@keylist{%
- \kr@ifstar{\kr@define@keylist\expandafter}{\kr@define@keylist\@firstofone}%
+ \KR@ifstar{\KR@define@keylist\expandafter}%
+ {\KR@define@keylist\@firstofone}%
}
-\def\ChoiceKeyValues#1#2{%
- \ifkr@xchoicelist
- \expandafter\edef\csname kr@altlist@\kr@keyfamily @#1\endcsname{#2}%
+\newcommand\ChoiceKeyValues[2]{%
+ \ifKR@xchoicelist
+ \KR@n@meedef{\KR@keyfamily @#1@altlist}{#2}%
\else
- \kr@ifnameundef{kr@altlist@\kr@keyfamily @#1}{%
- \kr@nameedef{kr@altlist@\kr@keyfamily @#1}{#2}%
+ \KR@ifnameundef{\KR@keyfamily @#1@altlist}{%
+ \KR@nameedef{\KR@keyfamily @#1@altlist}{#2}%
}{%
- \kr@err{You have attempted to set two \MessageBreak
- \string\ChoiceKeyValues\space for the same choice key,\MessageBreak
- in the same family}%
+ \KR@err{%
+ You have attempted to set two \MessageBreak
+ \string\ChoiceKeyValues\space for the choice\MessageBreak
+ key '#1' in the same family '\KR@keyfamily'
+ }{%
+ You can only do that if you set 'xchoicelist'=true.
+ }%
}%
\fi
}
\@ifdefinable\CKVS{\global\let\CKVS\ChoiceKeyValues}
-\def\kr@define@key#1,#2,#3,#4&{%
+\def\KR@define@multiple@keys#1,#2,#3,#4\KR@nil{%
+ \edef\KR@tempa{\string\if\KR@macroprefix#2}%
+ \@onelevel@sanitize\KR@tempa
+ \KR@expandargs{2}\in@{\KR@tempa}{\detokenize{#4}}%
+ \ifin@
+ \KR@afterfi
+ \KR@err{%
+ You can't use \string\if\space and \string\fi\space in key macro
+ }{%
+ Use \string\fif\space and \string\ffi\space instead.
+ }%
+ \fi
+ \KR@expandargs{2}\in@{\detokenize{\fif}}{\detokenize{#4}}%
+ \ifin@
+ \KR@afterelsefi
+ \KR@namedef{\KR@keyfamily @#2@func}{#4}%
+ \else
+ \KR@afterfi
+ \KR@nameedef{\KR@keyfamily @#2@func}{\KR@expandonce{#4}}%
+ \fi
\begingroup
- \protected@edef\x{\endgroup
+ \protected@edef\KR@tempa{\endgroup
\ifcase#1\relax
- \mathchardef\kr@tempcntc=\@ne
+ \mathchardef\KR@tempcntc=\@ne
\or
- \noexpand\define@key[\kr@keyprefix]{\kr@keyfamily}%
- {#2}[#3]{\kr@expandonce{#4}}%
+ \noexpand\define@key[\KR@keyprefix]{\KR@keyfamily}%
+ {#2}[#3]{%
+ \KR@namedef{\KR@keyfamily @#2@value}{\unexpanded{##1}}%
+ \noexpand\KR@nameuse{\KR@keyfamily @#2@func}%
+ }%
\or
- \noexpand\define@cmdkey[\kr@keyprefix]{\kr@keyfamily}%
- [\kr@macroprefix]{#2}[#3]{\kr@expandonce{#4}}%
+ \noexpand\define@cmdkey[\KR@keyprefix]{\KR@keyfamily}%
+ [\KR@macroprefix]{#2}[#3]{%
+ \KR@namedef{\KR@keyfamily @#2@value}{\unexpanded{##1}}%
+ \noexpand\KR@nameuse{\KR@keyfamily @#2@func}%
+ }%
\or
- \noexpand\define@boolkey+[\kr@keyprefix]{\kr@keyfamily}%
- [\kr@macroprefix]{#2}[#3]{\kr@expandonce{#4}}%
- {\unexpanded{\kr@inputerr{##1}{#2}}}%
+ \noexpand\define@boolkey+[\KR@keyprefix]{\KR@keyfamily}%
+ [\KR@macroprefix]{#2}[#3]{%
+ \KR@namedef{\KR@keyfamily @#2@value}{\unexpanded{##1}}%
+ \noexpand\KR@nameuse{\KR@keyfamily @#2@func}%
+ }{%
+ \unexpanded{\KR@inputerr{##1}{#2}}%
+ }%
\or
- \kr@ifnameundef{kr@altlist@\kr@keyfamily @#2}{\mathchardef\kr@tempcnta=\@ne}{}
- \noexpand\define@choicekey*+[\kr@keyprefix]{\kr@keyfamily}{#2}%
- [\unexpanded{\val\nr}]{\kr@nameuse{kr@altlist@\kr@keyfamily @#2}}[#3]%
- {\kr@expandonce{#4}}{\unexpanded{\kr@inputerr{##1}{#2}}}%
+ \noexpand\define@togkey+[\KR@keyprefix]{\KR@keyfamily}%
+ [\KR@macroprefix]{#2}[#3]{%
+ \KR@namedef{\KR@keyfamily @#2@value}{\unexpanded{##1}}%
+ \noexpand\KR@nameuse{\KR@keyfamily @#2@func}%
+ }{%
+ \unexpanded{\KR@inputerr{##1}{#2}}%
+ }%
+ \or
+ \KR@ifnameundef{\KR@keyfamily @#2@altlist}{%
+ \mathchardef\KR@tempcnta=\@ne}{}%
+ \noexpand\define@choicekey*+[\KR@keyprefix]{\KR@keyfamily}{#2}%
+ [\unexpanded{\val\nr}]{%
+ \KR@nameuse{\KR@keyfamily @#2@altlist}%
+ }[#3]{%
+ \KR@namedef{\KR@keyfamily @#2@value}{\unexpanded{##1}}%
+ \noexpand\KR@nameuse{\KR@keyfamily @#2@func}%
+ }{%
+ \unexpanded{\KR@inputerr{##1}{#2}}%
+ }%
\else
- \mathchardef\kr@tempcntc=\@ne
+ \mathchardef\KR@tempcntc=\@ne
\fi
- }\x
- \ifnum\kr@tempcnta=\@ne\kr@afterfi
- \kr@err{%
- Alternate key values list for '#2' is empty:
- \MessageBreak choicekey can't be defined.
- \MessageBreak You need to first define admissible
- \MessageBreak key values through '\string\ChoiceKeyValues'
- \MessageBreak for choice key '#2'
- }%
+ }%
+ \KR@tempa
+ \ifnum\KR@tempcnta=\@ne
+ \KR@afterfi
+ \KR@err{%
+ Choice key '#2' can't be defined.\MessageBreak
+ Alternate key values list for '#2' is empty
+ }{%
+ You need to first define admissible\MessageBreak
+ key values through '\string\ChoiceKeyValues'\MessageBreak
+ for choice key '#2'
+ }%
\fi
- \ifnum\kr@tempcntc=\@ne\kr@afterfi
- \kr@err{Unknown key type/identifier '#1'}%
+ \ifnum\KR@tempcntc=\@ne
+ \KR@afterfi
+ \KR@err{%
+ Unknown key type/identifier '#1'
+ }{%
+ You can only use key types 1 to 5.
+ }%
\fi
}
-\def\define@comp@boolkeys{\kr@testopt{\kr@comp@opta}{KV}}
-\def\kr@comp@opta[#1]#2{\kr@testopt{\kr@define@comp@boolkeys[#1]{#2}}{mp@}}
-\def\kr@define@comp@boolkeys[#1]#2[#3]#4[#5]#6#7#8{%
- \kr@namedef{comp@#2@#4}{\kr@nameuse{if#3#4}\kr@nameuse{#3#6false}\fi}%
- \kr@namedef{comp@#2@#6}{\kr@nameuse{if#3#6}\kr@nameuse{#3#4false}\fi}%
- \kr@namedef{func@#2@#4}{#7}%
- \kr@namedef{func@#2@#6}{#8}%
- \begingroup\protected@edef\x{\endgroup
- \unexpanded{\define@boolkey+[#1]{#2}[#3]{#4}[#5]{%
- \kr@nameuse{comp@#2@#4}\kr@nameuse{func@#2@#4}}%
- {\kr@inputerr{##1}{#4}}%
- }%
- \unexpanded{\define@boolkey+[#1]{#2}[#3]{#6}[#5]{%
- \kr@nameuse{comp@#2@#6}\kr@nameuse{func@#2@#6}}%
- {\kr@inputerr{##1}{#6}}%
+\def\krsetkeys{%
+ \def\fif##1{%
+ \KR@findescape{##1}{}{%
+ \KR@err{Bad argument '\string##1'}%
+ {Backslash in '\string##1' not allowed.}%
}%
- }\x
-}
-\def\disabledkeyerr{%
- \kr@err{Key '\disabledkey' has been disabled.\MessageBreak
- You can't set or reset it at this late stage.\MessageBreak
- You should have set it earlier in the\MessageBreak
- \string\documentclass\space or \string\usepackage}%
-}
-\def\krdisable@keys{\XKV@testoptb\kr@dis@ble@keys}
-\long\def\kr@dis@ble@keys#1{%
- \XKV@checksanitizeb{#1}\kr@tempa
- \XKV@for@o\kr@tempa\kr@tempa{%
- \XKV@ifundefined{\XKV@header\kr@tempa}{%
- \kr@warn{Key '\kr@tempa' undefined: can't be disabled}%
+ \csname if##1\endcsname
+ }%
+ \let\ffi\fi
+ \XKV@testopta{\XKV@testoptc\XKV@setkeys}%
+}
+\protected\def\KR@disabledkey@err{%
+ \KR@err{%
+ Key '\KR@disabledkey' has been disabled
+ }{%
+ You can't set or reset '\KR@disabledkey' at this\MessageBreak
+ late stage. You should have set it \MessageBreak
+ earlier in \string\documentclass\space or \string\usepackage
+ }%
+}
+\def\krdisable@keys{\XKV@testoptb\KR@dis@ble@keys}
+\long\def\KR@dis@ble@keys#1{%
+ \XKV@checksanitizeb{#1}\KR@tempa
+ \XKV@for@o\KR@tempa\KR@tempa{%
+ \XKV@ifundefined{\XKV@header\KR@tempa}{%
+ \KR@warn{Key '\KR@tempa' undefined: can't be disabled\on@line}%
}{%
- \global\let\disabledkey\kr@tempa
+ \global\let\KR@disabledkey\KR@tempa
}%
- \XKV@ifundefined{\XKV@header\kr@tempa @default}{%
- \edef\kr@tempc{\noexpand\XKV@define@key{\kr@tempa}}%
+ \XKV@ifundefined{\XKV@header\KR@tempa @default}{%
+ \edef\KR@tempb{\noexpand\XKV@define@key{\KR@tempa}}%
}{%
- \edef\kr@tempc{\noexpand\XKV@define@key{\kr@tempa}[]}%
+ \edef\KR@tempb{\noexpand\XKV@define@key{\KR@tempa}[]}%
}%
- \expandafter\kr@tempc\expandafter{\disabledkeyerr}%
+ \expandafter\KR@tempb\expandafter{\KR@disabledkey@err}%
}%
}
+\protected\def\KR@cs#1#2{%
+ \begingroup\toks@{#1}%
+ \edef\@i{\the\toks@}\@onelevel@sanitize\@i
+ \KR@expandargs{1}\KV@@sp@def\@i{\@i}%
+ \tt\textup{\textcolor{#2}{\KR@expandonce{\@i}}}%
+ \endgroup\xspace
+}
+\protected\def\KR@cx#1#2{%
+ \begingroup\toks@{#1}%
+ \edef\@i{\expandafter\expandafter\expandafter\zap@space%
+ \expandafter\detokenize\expandafter{\the\toks@} \@empty}%
+ \tt\textup{\textcolor{#2}{\KR@expandonce{\@i}}}%
+ \endgroup\xspace
+}
\endinput