From c873315ca2aa88a1dbfb1e8114b2172d13f05e64 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 15 Jan 2010 00:18:54 +0000 Subject: keyreader 0.2 (14jan10) git-svn-id: svn://tug.org/texlive/trunk@16716 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/keyreader/README | 2 +- .../doc/latex/keyreader/keyreader-guide-0dot2.pdf | Bin 0 -> 116557 bytes .../doc/latex/keyreader/keyreader-guide-0dot2.tex | 381 +++++++++++++++++++++ .../doc/latex/keyreader/keyreader-guide.pdf | Bin 107029 -> 0 bytes .../doc/latex/keyreader/keyreader-guide.tex | 340 ------------------ 5 files changed, 382 insertions(+), 341 deletions(-) create mode 100644 Master/texmf-dist/doc/latex/keyreader/keyreader-guide-0dot2.pdf create mode 100644 Master/texmf-dist/doc/latex/keyreader/keyreader-guide-0dot2.tex delete mode 100644 Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf delete mode 100644 Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex (limited to 'Master/texmf-dist/doc/latex/keyreader') diff --git a/Master/texmf-dist/doc/latex/keyreader/README b/Master/texmf-dist/doc/latex/keyreader/README index b5fdc5d981b..f8b3c25df38 100644 --- a/Master/texmf-dist/doc/latex/keyreader/README +++ b/Master/texmf-dist/doc/latex/keyreader/README @@ -18,7 +18,7 @@ % % %+++++++++++++++++++++++++++++++++++++ LICENSE ++++++++++++++++++++++++++++++++++++++% % % -% This is file 'keyreader.sty', version 0.1. % +% This is file 'keyreader.sty', version 0.2. % % % % This package reads multiple keys to be defined by xkeyval.sty. % % % diff --git a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide-0dot2.pdf b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide-0dot2.pdf new file mode 100644 index 00000000000..d85c1c17a05 Binary files /dev/null and b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide-0dot2.pdf differ diff --git a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide-0dot2.tex b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide-0dot2.tex new file mode 100644 index 00000000000..2ac2ad0cc4f --- /dev/null +++ b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide-0dot2.tex @@ -0,0 +1,381 @@ +\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} +\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.2.}} +\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 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. + +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 and class 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, +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: +\begin{krverbatim} +\krsetup{parser=;, macroprefix=mp@, keyprefix=KV, + keyfamily=myfamily, xchoicelist=false}. +\end{krverbatim} + +The main user interface is the \krcmd{define@keylist} macro, whose syntax is +\begin{krverbatim} +\define@keylist{, , , + ; ; 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{, , , + ; ; etc}, +\end{krverbatim} +then the keys can be defined by the starred form of \krcmd{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. + +The \krcmd{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{}{}. +\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 +\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}. + +As mentioned earlier, the key family (and other package options) can be changed via +\begin{krverbatim} +\krsetup{parser=;,macroprefix=mp@,keyprefix=KV, + keyfamily=myfamily,xchoicelist=false}. +\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 \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. + +\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} +\CKVS{align}{center,right,left,justified} + +\def\f@align{% + \ifcase\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} +\CKVS{align}{center,right,left,justified} +\CKVS{election}{state,federal,congress,senate} +% |color(gray)need to be defined only once|normalcolor + +\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; + 4,election,congress,; + 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\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. + +The same set of keys can be defined via the starred form of \krcmd{define@keylist}: +\begin{krverbatim} +\def\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; + 4,election,congress,; + 2,testdim,2cm,\long\def\f@testdim####1% + {Do something with ####1}% + % |color(gray) Note the number of parameter characters here. +} +\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} +\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] + % |color(gray)From the |emph(lipsum) package. + % |color(gray)The |emph(blindtext) package can also be used. + \end{minipage} +\end{center} + +\lipsum[1] +\end{krverbatim} + +\section{Complementary boolean keys} + +The syntax of complementary boolean keys is +\begin{krverbatim} +\define@comp@boolkeys[]{}[}[] + {}{} + {}. +\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} +. +\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[]{}{}. +\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/doc/latex/keyreader/keyreader-guide.pdf b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf deleted file mode 100644 index 1056b606804..00000000000 Binary files a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf and /dev/null differ diff --git a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex deleted file mode 100644 index a11013decd3..00000000000 --- a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex +++ /dev/null @@ -1,340 +0,0 @@ -\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{, , , - ; ; 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{, , , - ; ; 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[]{}[}[] - {}{} - {}. -\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} -. -\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[]{}{}. -\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 -- cgit v1.2.3