diff options
author | Karl Berry <karl@freefriends.org> | 2010-01-13 00:08:31 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2010-01-13 00:08:31 +0000 |
commit | 1af5c8773983ef7a0aa17ab1c46e8ecc5d333bb7 (patch) | |
tree | c82a29a0d2e46757d149d5c2aff5bc96e8426413 /Master/texmf-dist | |
parent | 8ef4b34298b082adaed9714c182beb730e8aafeb (diff) |
new latex package keyreader 0.1 (11jan10)
git-svn-id: svn://tug.org/texlive/trunk@16692 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/doc/latex/keyreader/README | 39 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf | bin | 0 -> 107029 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex | 340 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/keyreader/keyreader.sty | 204 |
4 files changed, 583 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/keyreader/README b/Master/texmf-dist/doc/latex/keyreader/README new file mode 100644 index 00000000000..b5fdc5d981b --- /dev/null +++ b/Master/texmf-dist/doc/latex/keyreader/README @@ -0,0 +1,39 @@ +%++++++++++++++++++++++++++++++++++++ MOTIVATION ++++++++++++++++++++++++++++++++++++% +% % +% The elaborate and useful xkeyval package introduced \define@cmdkeys and % +% \define@boolkeys, which allow for the setting of 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 saves tokens, as hundreds of keys % +% can, in principle, be issued simultaneously by one command. % +% % +% Also, the xkeyval package doesn't have the notion of complementary keys, % +% which is useful 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. % +% % +% 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 work 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 http://www.latex-project.org/lppl.txt % +% and version 1.3 or later is part of all distributions of LaTeX version % +% 2005/12/01 or later. % +% % +% 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. % +% % +% 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 Binary files differnew file mode 100644 index 00000000000..1056b606804 --- /dev/null +++ b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf diff --git a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex new file mode 100644 index 00000000000..a11013decd3 --- /dev/null +++ b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex @@ -0,0 +1,340 @@ +\documentclass{article} +\usepackage[scaled=0.9]{helvet} +\usepackage{lipsum,parskip,xspace} +\usepackage{fancyvrb} +\usepackage{xcolor} +\usepackage{multicol} +\usepackage{hyperref} +\usepackage[parser=;,macroprefix=mp@,keyprefix=KV, + keyfamily=myfamily]{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} +\newcommand*\krcs[1]{\textcolor{xteal1}{\texttt{\string#1}}\xspace} +\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\krvlabel{\textcolor{green}{\fboxrule1pt\fcolorbox{red}{gray!45}{\hspace{1cm}}}} +\CustomVerbatimEnvironment{krverbatim}{Verbatim}{numbers=left, + label={\krvlabel},labelposition=topline,numberblanklines=false, firstnumber=last,frame=single,rulecolor=\color{xmagenta1},framerule=1pt, + framesep=7pt,formatcom=\color{blue},xrightmargin=0pc,commandchars=\|\(\), + commentchar=&} + +\begin{document} +\DefineShortVerb{\+} +\title{The \texttt{\color{blue}keyreader} Package\footnote{Version 0.1.}} +\author{Ahmed Musa\\\email{a.musa@rocketmail.com}} +\maketitle +\thispagestyle{empty} + +\leavevmode\textcolor{blue}{\rule[0ex]{\hsize}{2pt}} +\columnseprule0.5pt\premulticols2cm\relax +\begin{multicols}{2} + \small\tableofcontents\normalsize +\end{multicols} +\vspace*{-.5cm} +\leavevmode\textcolor{blue}{\rule[0ex]{\hsize}{2pt}} + +\section{Motivation} + +The elaborate and powerful \krsty{xkeyval} package introduced \krcmd{define@cmdkeys} and +\krcmd{define@boolkeys}, which permit the setting of 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. + +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. + +\section{Usage} + +The package can be loaded in style files by +\begin{krverbatim} +\RequirePackage[options]{keyreader} +\end{krverbatim} +and in document files via +\begin{krverbatim} +\usepackage[options]{keyreader} +\end{krverbatim} +where the options and their default values are +\begin{krverbatim} +parser=;, macroprefix=mp@, keyprefix=KV, keyfamily=myfamily. +\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: +\begin{krverbatim} +\krsetup{parser=;,macroprefix=mp@,keyprefix=KV, + keyfamily=myfamily}. +\end{krverbatim} + +The main user interface is the \krcmd{define@keylist} macro, whose syntax is +\begin{krverbatim} +\define@keylist{<key type/id>, <key>, <key 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. + +If the key list is available in a macro, say, +\begin{krverbatim} +\def\keylist{<key type/id>, <key>, <key value>, + <key macro/function>; <another set of key specifiers>; etc}, +\end{krverbatim} +then the keys can be defined by +\begin{krverbatim} +\cmddefine@keylist\keylist. +\end{krverbatim} +\krcmd{cmddefine@keylist} takes a macro as argument, while \krcmd{define@keylist} accepts a key list. + +The \krcmd{kr@altlist} 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 or set. It has to be defined or redefined each time a choice +key is being defined, if its contents (ie, those of \krcmd{kr@altlist}) change from +one choice key to the next one being defined. This, unfortunately, implies the restriction that no two choice keys can appear in one \krcmd{define@keylist} statement. This restriction can be easily lifted but at the cost of some complication and extra requirement for the package user. So far this hasn't been a severe limitation (to me, anyway). + +\section{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: +\begin{krverbatim} +\def\kr@altlist{center,right,left,justified} + +\def\f@align{% + \ifcase\kr@nr\relax + \def\kr@align{\centering}% + \or + \def\kr@align{\flushright}% + \or + \def\kr@align{\flushleft}% + \or + \let\kr@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,}. +\end{krverbatim} +The \krcmd{kr@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. + +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. + +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}. + +Hundreds of keys can be defined efficiently in this way, using very few tokens. + +As another example, we consider the following page setup keys: +\begin{krverbatim} +\def\kr@altlist{center,right,left,justified} % reused + +\define@keylist{% + 3,boolvar,true,;1,paperheight,\paperheight,; + 1,paperwidth,\paperwidth,\f@paperwidth; + 2,textheight,\textheight,\f@textheight; + 2,textwidth,\textwidth,\f@textwidth; + 1,evensidemargin,\evensidemargin,; + 4,align,center,\f@align; + 2,testdim,2cm,\long\def\f@testdim##1{A test dimension ##1 + \par\bigskip}% +} +\end{krverbatim} +which have the following trivial key macros: +\begin{krverbatim} +\def\f@textwidth{\AtBeginDocument{\wlog{`textwidth' % + is \mp@textwidth}}} + +\def\f@textheight{% + \ifx\@empty\mp@textheight + \wlog{`textheight' value empty}% + \else + \wlog{`textheight' value not empty}% + \fi +} + +\def\f@paperwidth{\wlog{`paperwidth' was defined as % + ordinary key.}} +\newcommand\f@align{% + \ifcase\kr@nr\relax + \def\mp@align{\centering}% + \or + \def\mp@align{\flushright}% + \or + \def\mp@align{\flushleft}% + \or + \let\mp@align\relax + \fi +} +\end{krverbatim} +Again, once the keys have been defined, these macros can be reused. + +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} +\end{krverbatim} + +The macro \krcmd{mp@align} holds the value \krcmd{flushright}, while +\begin{krverbatim} +\KV@myfamily@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. + +The rest of the defined keys can now be set as follows: +\begin{krverbatim} +\setkeys[KV]{myfamily}{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. + +\subsection[Demonstrating an effect]% + {Demonstrating the effect of limiting {\tt\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} +\begin{center} + \begin{minipage}{\mp@textwidth} + \lipsum[1] % from the lipsum package + \end{minipage} +\end{center} + +\lipsum[1] +\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 \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. + +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 defined complementary keys \krsty{draft} and \krsty{final} can now be set as follows: +\begin{krverbatim} +\setkeys[KV]{myfamily}{draft=true} + +\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: +\begin{krverbatim} +\setkeys[KV]{myfamily}{draft=true,final=true}. +\end{krverbatim} + +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 +\begin{krverbatim} +\show\ifkr@draft \show\ifkr@final \show\gobble +\show\KV@myfamily@draft. +\end{krverbatim} +These statements assume the macro prefix to be \krsty{kr@}. Next, we may set +\begin{krverbatim} +\krsetup{final=true} +\end{krverbatim} +and do +\begin{krverbatim} +\show\ifkr@final \show\ifkr@draft \show\notgobble. +\end{krverbatim} + +\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 +\begin{krverbatim} +<Erroneous value `#1' for key `#2'>. +\end{krverbatim} +\krcmd{kr@inputerr} can be redefined by the user. It takes two arguments (\ie, value and key). + + +\section{Conditionals in key macros} +\label{sec:conditionals} + +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 +\end{krverbatim} +can be submitted to \krcmd{define@keylist} via macros, as seen above. We give more examples below. + +Suppose we want to submit the following: +\begin{krverbatim} +\define@keylist{3,boolone,true,\ifmp@boolone \do \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 +\begin{krverbatim} +\def\f@boolone{\ifmp@boolone \do \fi} +\end{krverbatim} +and then do +\begin{krverbatim} +\define@keylist{3,boolone,true,\f@boolone}, +\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}. + +As another example, we may do +\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} + +\define@keylist{3,bool,true,\f@bool}. +\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. + +\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}: +\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. +\begin{krverbatim} +\def\disabledkeyerr{% + \PackageError{keyreader}{% + 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 + }{\@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. + +\end{document} + +%%% End of file keyreader-guide.tex %%%
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/keyreader/keyreader.sty b/Master/texmf-dist/tex/latex/keyreader/keyreader.sty new file mode 100644 index 00000000000..f240c803946 --- /dev/null +++ b/Master/texmf-dist/tex/latex/keyreader/keyreader.sty @@ -0,0 +1,204 @@ +%+++++++++++++++++++++++++++++++++++++ LICENSE ++++++++++++++++++++++++++++++++++++++% +% % +% This is file 'keyreader.sty', version 0.1. % +% % +% This package reads multiple keys to be defined by xkeyval.sty. % +% % +% This work 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 http://www.latex-project.org/lppl.txt % +% and version 1.3 or later is part of all distributions of LaTeX version % +% 2005/12/01 or later. % +% % +% 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. % +% % +% Copyright (c) 2010 Ahmed Musa (a.musa@rocketmail.com). % +% % +%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% + +\begingroup +\catcode064 11% @ +\catcode123 01% { +\catcode125 02% } +\def\x{\endgroup + \edef\kr@restorecodes{% + \catcode035 \the\catcode035% # + \catcode064 \the\catcode064% @ + \catcode123 \the\catcode123% { + \catcode125 \the\catcode125% } + \catcode061 \the\catcode061% = + }% +} +\x +\@makeother{\=}% +\catcode035=06% # +\catcode064=11% @ +\catcode123=01% { +\catcode125=02% } +\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}% & +\ProvidesPackage{keyreader}% + [2010/01/01 v0.1 Read multiple keys 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\define@keylist##1{% + \mathchardef\kr@cntb=\z@ + \kr@readlist##1#1& + }% + \long\def\cmddefine@keylist##1{% + \mathchardef\kr@cntb=\z@% + \expandafter\kr@readlist##1#1& + }% + \long\def\kr@readlist##1#1##2&{% + \kr@ifblank{##1}{}% + {% + \edef\@i{\detokenize{##1}}% + \edef\@ii{\detokenize{\stopread}}% + \ifx\@i\@ii + \mathchardef\kr@cntb=\@ne + \stopread##2& + \else + \kr@define@key##1& + \fi + }% + \ifnum\kr@cntb=\z@ + \kr@ifblank{##2}{}{\kr@readlist##2&}% + \fi + }% +} +\define@cmdkey[KV]{keyreader}[kr@]{parser}[;]{% + \if\kr@parser,\kr@afterfi\kr@err{Parser can't be comma}\fi + \kr@CommandListParser{#1}% +} +\define@cmdkey[KV]{keyreader}[kr@]{keyprefix}[KV]{} +\define@cmdkey[KV]{keyreader}[kr@]{keyfamily}[fam]{} +\define@cmdkey[KV]{keyreader}[kr@]{macroprefix}[mp@]{} +\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@namedef#1{% + \ifcsname#1\endcsname + \def\reserved@a{#1}% + \@notdefinable + \else + \expandafter\def\csname#1\expandafter\endcsname + \fi +} +\def\kr@nameuse#1{% + \ifcsname#1\endcsname\csname#1\expandafter\endcsname\fi +} +\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#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@cnta=\z@\mathchardef\kr@cntb=\z@\mathchardef\kr@cntc=\z@ +\let\kr@altlist\@empty +\def\kr@define@key#1,#2,#3,#4&{% + \begingroup + \protected@edef\x{\endgroup + \ifcase#1\relax + \mathchardef\kr@cntc=\@ne + \or + \noexpand\define@key[\kr@keyprefix]{\kr@keyfamily}% + {#2}[#3]{\kr@expandonce{#4}}% + \or + \noexpand\define@cmdkey[\kr@keyprefix]{\kr@keyfamily}% + [\kr@macroprefix]{#2}[#3]{\kr@expandonce{#4}}% + \or + \noexpand\define@boolkey+[\kr@keyprefix]{\kr@keyfamily}% + [\kr@macroprefix]{#2}[#3]{\kr@expandonce{#4}}% + {\unexpanded{\kr@inputerr{##1}{#2}}}% + \or + \ifx\kr@altlist\@empty + \mathchardef\kr@cnta=\@ne + \fi + \noexpand\define@choicekey*+[\kr@keyprefix]{\kr@keyfamily}{#2}% + [\unexpanded{\kr@val\kr@nr}]{\kr@altlist}[#3]% + {\kr@expandonce{#4}}{\unexpanded{\kr@inputerr{##1}{#2}}}% + \else + \mathchardef\kr@cntc=\@ne\relax + \fi + }\x + \ifnum\kr@cnta=\@ne\kr@afterfi + \kr@err{'\string\kr@altlist' is empty: choicekey can't be defined. + \MessageBreak You need to first define '\string\kr@altlist' + \MessageBreak as a nonempty set. It is the list of + \MessageBreak alternates values for your choicekey.}% + \fi + \ifnum\kr@cntc=\@ne\kr@afterfi + \kr@err{Unknown key type/identifier '#1'}% + \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}}% + }% + }\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}% + }{% + \global\let\disabledkey\kr@tempa + }% + \XKV@ifundefined{\XKV@header\kr@tempa @default}{% + \edef\kr@tempc{\noexpand\XKV@define@key{\kr@tempa}}% + }{% + \edef\kr@tempc{\noexpand\XKV@define@key{\kr@tempa}[]}% + }% + \expandafter\kr@tempc\expandafter{\disabledkeyerr}% + }% +} + +\endinput + +%%% End of file keyreader.sty %%%
\ No newline at end of file |