summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-10-18 22:48:27 +0000
committerKarl Berry <karl@freefriends.org>2012-10-18 22:48:27 +0000
commitb0e15470dc26b571d82f3998008a0936f8e3a597 (patch)
tree65059d813205a97e4af7602ed6c3826db063e4c5
parente828c375ba40d5ea05fd4cf79482c15d56c28789 (diff)
keyreader (12oct12)
git-svn-id: svn://tug.org/texlive/trunk@28020 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/keyreader/README8
-rw-r--r--Master/texmf-dist/doc/latex/keyreader/keyreader-example1.tex68
-rw-r--r--Master/texmf-dist/doc/latex/keyreader/keyreader-guide.cfg (renamed from Master/texmf-dist/tex/latex/keyreader/keyreader-guide.cfg)6
-rw-r--r--Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdfbin250340 -> 232171 bytes
-rw-r--r--Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex93
-rw-r--r--Master/texmf-dist/tex/latex/keyreader/keyreader.sty669
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check7
-rwxr-xr-xMaster/tlpkg/libexec/ctan2tds34
8 files changed, 639 insertions, 246 deletions
diff --git a/Master/texmf-dist/doc/latex/keyreader/README b/Master/texmf-dist/doc/latex/keyreader/README
index fa3a3b270fd..25603641d83 100644
--- a/Master/texmf-dist/doc/latex/keyreader/README
+++ b/Master/texmf-dist/doc/latex/keyreader/README
@@ -6,7 +6,7 @@ Ahmed Musa
VERSION
-Version 0.4b, January 2012
+Version 0.5, October 2012
SUMMARY
@@ -16,7 +16,7 @@ Keys are automatically set/initialized as soon as they are defined.
It provides a compact and robust interface to the xkeyval package.
The xkeyval package's commands for setting keys are made more robust,
in the sense that outer braces in key values are preserved throughout
-parsing and unbalanced conditionals can be parsed as part of a key's
+parsing and unbalanced conditionals can be parsed as part of a key's
value. In the case of choice keys defined by the command
\krddefinekeys, each admissible value of the key can be associated
with a callback, unlike in the xkeyval package.
@@ -26,6 +26,10 @@ ltxkeys package because the xkeyval package, on which the keyreader
package is based, has been quite stable for some years (its inherent
shortcomings not withstanding).
+RELATED PACKAGES
+
+xkeyval, ltxkeys, skeyval
+
LICENSE
Copyright (c) 2010-2012 Ahmed Musa
diff --git a/Master/texmf-dist/doc/latex/keyreader/keyreader-example1.tex b/Master/texmf-dist/doc/latex/keyreader/keyreader-example1.tex
new file mode 100644
index 00000000000..bf8c56d5348
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/keyreader/keyreader-example1.tex
@@ -0,0 +1,68 @@
+\documentclass{article}
+\usepackage{keyreader}
+\usepackage{xcolor}
+\usepackage{graphicx}
+\makeatletter
+\newdimen\shadowsize
+\krddefinekeys*[KV]{ebox}[mp@]{%
+ bool/frame/true;
+ bool/shadow/true;
+ cmd/framecolor/black;
+ cmd/shadecolor/white;
+ cmd/shadowcolor/gray;
+ cmd/framesize/.4pt;
+ cmd/boxsize/.1\columnwidth;
+ cmd/shadowsize/1pt;
+ choice/align/center/
+ center.do=\let\mp@alignright\hfil\let\mp@alignleft\hfil,
+ right.do=\let\mp@alignright\hfill\let\mp@alignleft\relax,
+ left.do=\let\mp@alignright\relax\let\mp@alignleft\hfill,
+ justified.do=\let\mp@alignright\relax\let\mp@alignleft\relax
+ //\@@warning{Invalid value for 'align'};
+}
+\savevaluekeys[KV]{ebox}{frame,framecolor,framesize}
+\krdpresetkeys[KV]{ebox}{%
+ frame,framecolor=black,shadecolor=white,framesize=0.5pt,boxsize,align
+}
+\krdpostsetkeys[KV]{ebox}{%
+ shadow=\usevalue{frame},shadowcolor=\usevalue{framecolor}!40,
+ shadowsize=\usevalue{framesize}*4
+}
+\newcommand*\ebox[2][]{%
+ \krdsetkeys[KV]{ebox}{#1}%
+ \begingroup
+ \ifmp@frame
+ \fboxrule=\dimexpr\mp@framesize\relax
+ \else
+ \fboxrule=0pt
+ \fi
+ \ifmp@shadow
+ \shadowsize=\dimexpr\mp@shadowsize\relax
+ \else
+ \shadowsize=0pt
+ \fi
+ \setbox0=\hbox{%
+ \fcolorbox{\mp@framecolor}{\mp@shadecolor}{%
+ \hbox to\mp@boxsize{%
+ \mp@alignright #2\mp@alignleft
+ }%
+ }%
+ }%
+ \hskip\shadowsize
+ \color{\mp@shadowcolor}%
+ \rule[-\dp0]{\wd0}{\the\dimexpr\ht0+\dp0\relax}%
+ \llap{\raisebox{\shadowsize}{\box0\hskip\shadowsize}}%
+ \endgroup
+}
+\makeatother
+
+\begin{document}
+\parindent-60pt
+\scalebox{2}{%
+ \ebox[shadecolor=brown!70]{ebox1}%
+ \ebox[framecolor=magenta,boxsize=2cm,align=right]{ebox2}%
+ \ebox[shadow=false,framesize=1pt,framecolor=red,boxsize=1.5cm,align=left]{ebox3}%
+ \ebox[framesize=1pt,framecolor=green,shadowcolor=blue]{ebox4}%
+ \ebox[frame=false,shadow,shadowcolor=yellow,framesize=.5pt]{ebox5}%
+}
+\end{document}
diff --git a/Master/texmf-dist/tex/latex/keyreader/keyreader-guide.cfg b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.cfg
index 22fe64bc33e..af803ae50e3 100644
--- a/Master/texmf-dist/tex/latex/keyreader/keyreader-guide.cfg
+++ b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.cfg
@@ -1,5 +1,5 @@
\ProvidesFile{keyreader-guide.cfg}%
- [2012/01/14 v0.0.3 Configuration file for keyreader-guide (AM)]
+ [2012/10/10 v0.5 Configuration file for keyreader-guide (AM)]
\amltxoptions{%
geometryoptions = {left=3cm,right=3cm,top=2.5cm,%
@@ -20,6 +20,7 @@
speccolor = teal,
sectionheadcolor = blue
}
+
\fancypagenos[%
textalign = center,
show-on-page-one = false,
@@ -35,8 +36,7 @@
right-header = \ttcl{black}{\today}
]
-\newwatermark
-[page=1,fontfamily=phv,fontsize=11pt,fontseries=m,align=center,
+\newwatermark[page=1,fontfamily=phv,fontsize=11pt,fontseries=m,align=center,
coordunit=pc,width=.978\paperwidth,angle=0,scale=1,xpos=-.62,ypos=31.2]{%
\xwmcolorbox[framesep=5pt,framerule=2pt,fillcolor=white,
outerframecolor=Orange,innerframecolor=brown,textalign=justified,
diff --git a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.pdf
index 899cb1c32bc..2dd2392b7c4 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 6f8ce6b1319..23eaf5618f5 100644
--- a/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex
+++ b/Master/texmf-dist/doc/latex/keyreader/keyreader-guide.tex
@@ -29,7 +29,7 @@
\title{}
\titlenotes[t1,t2]{%
The package is available at \url{\titleurltext}.\sep
- This user manual corresponds to version~0.4b of the package.
+ This user manual corresponds to version~0.5 of the package.
}
\subtitle{}
\titleurl{http://mirror.ctan.org/macros/latex/contrib/keyreader/}
@@ -39,7 +39,8 @@
}
\def\abstractname{\textsf{Summary}}
\begin{abstract}
- The \pkg'{keyreader} provides robustness and some extensions to the \pkg'{xkeyval}. It preserves braces in key values throughout parsing and saves estate when defining keys. Also, the command \fx{\krdsetkeys} allows unbalanced conditionals to be parsed as values of keys. Furthermore, when the command \fx{\krddefinekeys} is used, keys are initialized as soon as they are defined, and, unlike in the \pkg'{xkeyval}, admissible alternate values of choice keys can have individual callbacks. The looping macros of the \pkg'{xkeyval} are redefined, to increase robustness. The command \fx{\define@key} of the \pkg'{xkeyval} has had two of its subordinate commands redefined, to offset a complaint about the grabbing of the key's callback when defining keys with \fx{\define@key}. This user manual assumes that the reader is familiar with some of the functions and user interfaces of the \pkg'{xkeyval}.
+ \small
+ The \pkg{keyreader} bundle is platform independent and provides robustness and some extensions to the \pkg'{xkeyval}. However, it is completely independent of the \pkg'{xkeyval}. It preserves braces in key values throughout parsing and saves estate when defining keys. Also, the command \fx{\krdsetkeys} allows unbalanced conditionals to be parsed as values of keys. Furthermore, when the command \fx{\krddefinekeys} is used, keys are initialized as soon as they are defined, and, unlike in the \pkg'{xkeyval}, admissible alternate values of choice keys can have individual callbacks. The looping macros of the \pkg'{xkeyval} are redefined, to increase robustness. The command \fx{\define@key} of the \pkg'{xkeyval} has had two of its subordinate commands redefined, to offset a complaint about the grabbing of the key's callback when defining keys with \fx{\define@key}. This user manual assumes that the reader is familiar with some of the functions and user interfaces of the \pkg'{xkeyval}. The \fx{\krdkeys} command ... Unlike the \pkg'{xkeyval}, the \pkg'{keyreader} can be loaded before \hx{\documentclass} and this feature doesn't affect its ability to later filter class options-list for options that have values.
\end{abstract}
\let\licensename\relax
@@ -72,9 +73,10 @@ The \pkg'{keyreader} has been used as a development platform for the \pkg'{ltxke
shortcomings not withstanding. Has the user ever tried to pass to \pkg'{xkeyval}'s \fx{\setkeys} an unbalanced conditional as the value of a key? He/she will quickly be hit by the error message \quoted{! Incomplete \hx{\ifx}; all text was ignored after line \ldots}, or something similar. This limitation has been removed by the \pkg'{keyreader}.
-\docsection(sec:user-commands)<user commands>{User commands}
+The packages in the \pkg{keyreader} bundle are ...
-\docsubsection(sec:definingkeys){Defining keys}
+
+\docsection(sec:definingkeys){Defining keys}
The syntax for defining keys is:
@@ -83,7 +85,18 @@ The syntax for defining keys is:
\finish{newmacro}
\fxim*{\krddefinekeys}
-The optional \ang{kprefix} and mandatory \ang{kfamily} have unambiguous connotations. The optional \ang{mprefix} is the macro prefix, in the parlance of the \pkg'{xkeyval}. The default values of \ang{kprefix} and \ang{mprefix} are \ffx'{KRD,krdmp@}, respectively.
+The optional \ang{kprefix} and mandatory \ang{kfamily} have unambiguous connotations. The optional \ang{mprefix} is the macro prefix, in the parlance of the \pkg'{xkeyval}. The default values of \ang{kprefix} and \ang{mprefix} are \ffx'{KV,krdmp}, respectively.
+
+\start'{macro}[Syntax of key keylist]
+\krddefinekeys[<pref>]{<fam>}[<mp>]{
+ ord/<key>/<dft>/<f1>;
+ cmd/<key>/<dft>/<f1>;
+ bool/<key>/<dft>/<f1>;
+ bool+/<key>/<dft>/<f1>/<f2>;
+ choice/<key>/<dft>/<nominations>/<f1>;
+ choice+/<key>/<dft>/<nominations>/<f1>/<f2>;
+}
+\finish{macro}
In the case of ordinary, command and boolean keys, \ang{keylist} has the syntax
@@ -126,7 +139,7 @@ The star (\redstar*) sign on \fx{\krddefinekeys} is an optional suffix. If it is
Choice keys defined by \fx{\krddefinekeys} are of the \stform of choice keys (see the \pkg'{xkeyval} guide). Hence they will always convert the user input into lowercase before matching it against the alternate/admissible list of values specified at key definition time. The matching, as done by \fx{\krdsetkeys}, is catcode-agnostic.
-\docsubsection(sec:settingkeys){Setting keys}
+\docsection(sec:settingkeys){Setting keys}
The command \fx{\krdsetkeys} is a more robust counterpart of the \pkg'{xkeyval}'s \fx{\setkeys}, in the sense that it preserves all outer braces in the values of keys and allows the parsing of key values with unbalanced conditionals. The new command \fx{\krdsetkeys} has the same syntax as the original \fx{\setkeys} of the \pkg'{xkeyval}, namely
@@ -139,10 +152,33 @@ As usual, the star (\redstar) and plus sign (\redplus) are optional suffixes. Th
The command \fx{\krdsetkeys} isn't exactly \pkg'{xkeyval}'s \fx{\setkeys}, since the former is more robust and avoids the selective sanitization of \keyval list that is done by \fx{\setkeys}. The macro \fx{\krdsetkeys} \quoted{normalizes} the \keyval or comma-separated key list. Therefore, users of the \pkg'{keyreader} should always call the command \fx{\krdsetkeys} instead of \fx{\setkeys}. Both have the same user interface. The \fx{\setkeys} command of the \pkg'{xkeyval}'s remains unchanged.
-The \pkg'{xkeyval}'s command \fxi{\setrmkeys}, which sets \quoted{remaining keys}, has also been modified to \fxi{\krdsetrmkeys}, while keeping \fx{\setrmkeys} unchanged. Users of the \pkg'{keyreader} should use \fx{\krdsetrmkeys} in place of \fx{\setrmkeys}.
+The \pkg'{xkeyval}'s command \fxi{\setrmkeys}, which sets \quoted{remaining keys}, has been replaced by \fxi{\krdsetrmkeys}, while keeping \fx{\setrmkeys} unchanged. Users of the \pkg'{keyreader} should use \fx{\krdsetrmkeys} in place of \fx{\setrmkeys}.
+
+\start*+{example}[\ifkrdnovalue]
+\krdordkey[KV]{fam}{keya}[default]{%
+ \ifkrdnovalue
+ \krd@err{No user value supplied for key `keya'}
+ {Key `KV/fam/keya' requires a user value.}%
+ \else
+ \edef\userinput{\unexpanded{#1}}%
+ \fi
+}
+\krdsetkeys[KV]{fam}{keya}
+\krdsetkeys[KV]{fam}{keya=value}
+\finish{example}
+
+
+\docsection(sec:disable-keys)<disabling keys>{Disabling keys}
+
+The command \fxim{\krddisablekeys} has the same use syntax as the \fxi{\disable@keys} command of the \pkg'{xkeyval}, but will issue an error (instead of a warning) when an attempt is made to set a disabled key.
+
+
+\docsection(sec:options-processing)<options processing>{Options processing}
+The commands \ffxi'{\krdDeclareOption, \krdExecuteOptions, \krdProcessOptions} are replacements for \ffxi'{\DeclareOptionX, \ExecuteOptionsX, \ProcessOptionsX} of the \pkg'{xkeyval}.
-\docsubsection(sec:examples)<examples>{Examples}
+
+\docsection(sec:examples)<examples>{Some examples}
\start*+{example}[\krddefinekeys, \krdsetkeys]
\krddefinekeys*[KV]{fam}[pnt@]{%
@@ -155,7 +191,7 @@ The \pkg'{xkeyval}'s command \fxi{\setrmkeys}, which sets \quoted{remaining keys
left.do=\def\vcp@align{flushleft},
right.do=\def\vcp@align{flushright},
justified.do=\def\vcp@align{relax}/
- \ifkrddef\else
+ \ifkrdindef\else
\def\xa##1{#1##1}
\fi;
ord/keye/{keye-default}/\def\y##1{#1##1}
@@ -163,9 +199,24 @@ The \pkg'{xkeyval}'s command \fxi{\setrmkeys}, which sets \quoted{remaining keys
\krdsetkeys[KV]{fam}[keyb]{keya={green},keyb=\@iden,keyc=false,keyd=left}
|com(Setting keys with values having unbalanced conditionals:)
\krdsetkeys[KV]{fam}{keye={\iffalse keye-value}}
+
+\let\warning\@latex@warning@no@line
+\krddefinekeys*[KV]{fam}[mp@]{%
+ ord/keya/default-a/\def\x##1{#1*##1};
+ bool/keyb/true/;
+ bool+/keyc/true//\@latexerr{Invalid value for keyc};
+ cmd/keyd/black;
+ choice+/keye/center/
+ center.do=\let\mp@alignright\hfil\let\mp@alignleft\hfil,
+ right.do=\let\mp@alignright\hfill\let\mp@alignleft\relax,
+ left.do=\let\mp@alignright\relax\let\mp@alignleft\hfill,
+ justified.do=\let\mp@alignright\relax\let\mp@alignleft\relax
+ //\warning{Invalid value for keye};
+}
+
\finish{example}
-The braces around \quoted{green}, the value of \fx{keya}, will be preserved throughout parsing. It should be remembered that keys are automatically set as soon as they are defined by \fx{\krddefinekeys}. The boolean \fx{\ifkrddef} is true when \fx{\krddefinekeys} is defining keys, and false otherwise. The essence of it is that since keys are set as soon as they are defined by \fx{\krddefinekeys}, some actions should not be executed at this time, until the keys are being set by the user.
+The braces around \quoted{green}, the value of \fx{keya}, will be preserved throughout parsing. It should be remembered that keys are automatically set as soon as they are defined by \fx{\krddefinekeys}. The boolean \fx{\ifkrdindef} is true when \fx{\krddefinekeys} is defining keys, and false otherwise. The essence of it is that since keys are set as soon as they are defined by \fx{\krddefinekeys}, some actions should not be executed at this time, until the keys are being set by the user.
Using the keys defined in the above example, let us make \qcomma and \qequal active and see how the \pkg'{keyreader} will deal with them.
@@ -221,10 +272,10 @@ The output of the following example is shown in \sref{fig:1}:
shadowsize=\usevalue{framesize}*4
}
\newcommand*\ebox[2][]{%
- \setkeys[KV]{ebox}{#1}%
- |com(What happens if we use the following, instead of the above \setkeys?)
+ \krdsetkeys[KV]{ebox}{#1}%
+ |com(What happens if we use the following, instead of the above \krdsetkeys?)
|com(Preset and postset keys wouldn't be set when `#1' is empty:)
- |com(\krdifblank{#1}{}{\setkeys[KV]{ebox}{#1}})
+ |com(\krdifblank{#1}{}{\krdsetkeys[KV]{ebox}{#1}})
\begingroup
\ifmp@frame
\fboxrule=\dimexpr\mp@framesize\relax
@@ -270,22 +321,14 @@ The output of the following example is shown in \sref{fig:1}:
\end{figure}
-\docsubsection(sec:disable-keys)<disabling keys>{Disabling keys}
-
-The command \fxim{\krddisablekeys} has the same use syntax as the \fxi{\disable@keys} command of the \pkg'{xkeyval}, but will issue an error (instead of a warning) when an attempt is made to set a disabled key.
-
-
-\docsubsection(sec:options-processing)<options processing>{Options processing}
-
-The commands \ffxi'{\krdDeclareOption, \krdExecuteOptions, \krdProcessOptions} are aliases for
-\ffxi'{\DeclareOptionX, \ExecuteOptionsX, \ProcessOptionsX} of the \pkg'{xkeyval}.
-
-
\docsection(sec:version-hist){Version history}
The following change history highlights significant changes that affect user utilities and interfaces; changes of technical nature are not documented in this section.
\begin{versionhist}
+ \begin{version}{0.5}{2012/10/10}
+ \item The \pkg'{keyreader} can now be loaded before \fx{\documentclass}.
+ \end{version}
\begin{version}{0.4b}{2012/01/14}
\item The command \fx{\krdsetkeys} can now parse key values with unbalanced conditionals.
\end{version}
@@ -293,7 +336,7 @@ The following change history highlights significant changes that affect user uti
\item The key list in \fx{\krddefinekeys} shouldn't have been normalized with respect to forward slash (/).
\end{version}
\begin{version}{0.4}{2011/12/20}
- \item Several of the former functions of the package have been transferred to the \pkg'{ltxkeys} with even more robustness. The package now provides mainly a compact and robust interface to the features of the \pkg'{xkeyval}.
+ \item Several of the former functions of the package have been transferred to the independent \pkg'{ltxkeys} with even more robustness. The package now provides mainly a compact and robust interface to the features of the \pkg'{xkeyval} for users of \pkg'{xkeyval}.
\end{version}
\begin{version}{0.3}{2011/03/26}
\item Bug fix.
diff --git a/Master/texmf-dist/tex/latex/keyreader/keyreader.sty b/Master/texmf-dist/tex/latex/keyreader/keyreader.sty
index 782d3db2354..e30f0dcaf02 100644
--- a/Master/texmf-dist/tex/latex/keyreader/keyreader.sty
+++ b/Master/texmf-dist/tex/latex/keyreader/keyreader.sty
@@ -1,6 +1,5 @@
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
-% %
-% This is file 'keyreader.sty', version 0.4b, January 2012. %
+% This is file 'keyreader.sty', version 0.5, October 2012. %
% %
% This package and accompanying files may be distributed and/or %
% modified under the conditions of the LaTeX Project Public License, %
@@ -17,14 +16,14 @@
% purpose. %
% %
% Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com). %
-% %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
\ProvidesPackage{keyreader}
- [2012/01/14 v0.4b Robust interfaces to xkeyval package (AM)]
+ [2012/10/10 v0.5 Robust interfaces to xkeyval package (AM)]
+\newdimen\krdz@
\ifcase
- \ifx\eTeXversion\@undefined\z@\else
- \ifnum\eTeXversion<\tw@\z@\else\@ne\fi\fi
+ \ifx\eTeXversion\@undefined\krdz@\else
+ \ifnum\eTeXversion<\tw@\krdz@\else\@ne\fi\fi
\PackageError{keyreader}
{eTeX not loaded or old version}
{This package requires eTeX version 2 or higher.}%
@@ -38,7 +37,7 @@
\catcode044 12% ,
\def\reserved@a{\endgroup
\def\do##1,{%
- \ifx##1\end\else
+ \ifx\end##1\else
\catcode##1\string=\the\catcode##1 %
\expandafter\do
\fi
@@ -53,7 +52,7 @@
\catcode061 12% =
\catcode044 12% ,
\def\do#1=#2,{%
- \ifx#1\end\else
+ \ifx\end#1\else
\edef\krd@restorecodes{%
\krd@restorecodes
\catcode#1=\the\catcode#1 %
@@ -64,34 +63,67 @@
}
\do 032=10,033=12,036=03,038=04,040=12,041=12,042=12,043=12,%
059=12,045=12,047=12,058=12,063=12,091=12,093=12,126=13,\end=,%
+
\AtEndOfPackage{%
\krdAfterEndPackage{%
\krd@restorecodes
- \let\krd@restorecodes\@undefined
+ \let\krd@restorecodes\relax
}%
}
-\RequirePackage{xkeyval}[2008/08/13]
+
+\ifx\XKeyValLoaded\endinput\else
+ \input xkeyval
+\fi
+\let\XKV@doxs\relax
+
+\let\krd@err\@latex@error
+\def\krd@ehd{%
+ There is a problem here. Investigate it before
+ \MessageBreak proceeding. Try typing <return>
+ to proceed.\MessageBreak If that doesn't work,
+ type X <return> to quit.
+}
\def\@space{ }
-\protected\def\krdnewlet#1{\@ifdefinable#1\relax\let#1}
+\protected\def\krdnewlet#1{\@ifdefinable{#1}\relax\let#1= }
\krdnewlet\krd@nil\relax
\def\krd@nnil{\krd@nil}
\def\krdswap#1#2{#2#1}
\def\krd@quark{\@gobble\krd@quark}
\newcount\krd@csvdepth
-\newif\ifkrdloopbreak
+\newif\ifkrd@foreach@break
\newif\ifkrd@st
-\newif\ifkrddef
-\krdnewlet\krdloopbreak\krdloopbreaktrue
+\newif\ifkrdindef
+\long\def\krdifblank#1{%
+ \ifcat$\detokenize\expandafter{\@gobble#1.}$%
+ \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
+}
+
\begingroup
-\catcode`\&=7
+\catcode`\&=8
+\gdef\krdifledbyspace#1{\krd@ifledbyspace&&#1& \trim@nil}
+\gdef\krd@ifledbyspace&#1& #2\trim@nil{%
+ \krdifblank{#2}\@secondoftwo\@firstoftwo
+}
\gdef\krdtrimspace#1{\krd@trimspace@a.#1& &}
\gdef\krd@trimspace@a#1 &{\krd@trimspace@b#1&}
\gdef\krd@trimspace@b#1&#2{%
- \krdexpandonce{\romannumeral-`\q\expandafter\noexpand\@gobble#1}%
+ \krdexpandonce{%
+ \romannumeral-`\q
+ \expandafter\krdifledbyspace\expandafter{\@gobble#1}%
+ {\expandafter\noexpand\@gobble#1}{\expandafter\@space\@gobble#1}%
+ }%
}
\endgroup
+
+\def\krdzapspace#1{\krd@zapspace#1 \zap@nil}
+\def\krd@zapspace#1 #2\zap@nil{%
+ \krdifblank{#2}{#1}{%
+ \krd@zapspace#1#2\zap@nil
+ }%
+}
+
\protected\def\krdAfterEndPackage{%
- \krdifcsndef{\@currname.\@currext-krd@endpkghook}{}{%
+ \krdifcsdef{\@currname.\@currext-krd@endpkghook}{}{%
\@namedef{\@currname.\@currext-krd@endpkghook}{}%
}%
\expandafter\g@addto@macro
@@ -119,7 +151,7 @@
\fi
}%
}
-\newcommand*\krdifcsndef[1]{%
+\newcommand*\krdifcsdef[1]{%
\krdifblank{#1}{%
\expandafter\@secondoftwo\@gobble
}{%
@@ -138,19 +170,15 @@
\ifx#1#2\krd@ifx@quark
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}
-\long\def\krdifblank#1{%
- \ifcat$\detokenize\expandafter{\@gobble#1.}$%
- \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
-}
\def\krdifbool#1{%
\krdifblank{#1}{%
- \@secondoftwo
+ \krd@err{No boolean}\krd@ehd
}{%
- \krdifcsndef{if#1}{%
+ \krdifcsdef{if#1}{%
\csname @\csname if#1\endcsname
first\else second\fi oftwo\endcsname
}{%
- \@latex@error{Undefined boolean '#1'}\@ehc
+ \krd@err{Undefined boolean '#1'}\krd@ehd
}%
}%
}
@@ -164,14 +192,15 @@
\expandafter\krd@ifswitch@aux\romannumeral-`\q#1\krd@nil{%
\if#1\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}{%
- \@latex@error{Invalid switch '#1'}\@ehc
+ \krd@err{Invalid switch '#1'}\krd@ehd
}%
}%
}
\krdifx\pdfstrcmp\@undefined{%
\RequirePackage{pdftexcmds}%
\krdifx\pdf@strcmp\@undefined{%
- \cpt@err{Neither '\string\pdfstrcmp' nor '\string\pdf@strcmp' exists}\@ehc
+ \krd@err{Neither '\string\pdfstrcmp' nor
+ '\string\pdf@strcmp' exists}\krd@ehd
}{%
\let\krd@pdfstrcmp\pdf@strcmp
}%
@@ -201,8 +230,13 @@
\def\krd@ifbraced@d#1\krd@nil#2{%
\krdifstrcmp{#1}{#2}\@secondoftwo\@firstoftwo
}
+
+\def\krdoxdetok#1{\detokenize\expandafter{#1}}
+\def\krdusearg#1#2{%
+ \expandafter\krdswap\expandafter{\expandafter{#2}}{#1}%
+}
\def\krdexpandonce#1{\unexpanded\expandafter{#1}}
-\def\krdnoexpandcsn#1{\krdexpandonce{\csname#1\endcsname}}
+\def\krdnoexpandcs#1{\krdexpandonce{\csname#1\endcsname}}
\protected\def\krdexpanded#1{%
\begingroup
\protected@edef\reserved@a{\endgroup#1}\reserved@a
@@ -215,6 +249,16 @@
\protected\def\krdexpandsecondonce#1#2{%
\krdexpanded{\unexpanded{#1}\krdexpandonce{#2}}%
}
+\protected\def\krdifescaped#1{%
+ \begingroup
+ \escapechar92\relax
+ \edef\x{\expandafter\@car\string#1x\@nil}%
+ \expandafter\endgroup
+ \csname @\ifx\x\@backslashchar first\else second\fi oftwo\endcsname
+}
+\def\krdifcond#1\fi{%
+ \csname @#1first\else second\fi oftwo\endcsname
+}
% Eg,
% \newcount\nr\nr=\tw@
% \def\do#1{%
@@ -224,6 +268,7 @@
% }
% \edef\x{\krdfor{\cmda,\cmdb}}
% \show\x -> \let\cmda\cmda@ii \let\cmdb\cmdb@ii
+%
\def\krdfor#1{\krd@for@a#1,\krd@nnil,\krd@nil}
\def\krd@for@a#1,#2\krd@nil{%
\krdifblank{#1}{%
@@ -234,14 +279,16 @@
}%
}
% We redefine xkeyval's loops to increase robustness.
-% We can't replace \@nil by \krd@nil here because xkeyval
-% uses \@nil in calling these macros:
+% We can't replace \@nil by \krd@nil here because xkeyval uses \@nil
+% to terminate the loops.
\protected\long\def\XKV@for@n#1#2#3{%
\edef#2{\unexpanded{#1}}%
\krdifx#2\@empty{}{%
\XKV@f@r#2{#3}#1,\@nil,%
}%
}
+\let\krdcommaloop\XKV@for@n
+\let\krdecommaloop\XKV@for@o
\protected\long\def\XKV@f@r#1#2#3,{%
\edef#1{\unexpanded{#3}}%
\krdifx#1\@nnil{}{#2\XKV@f@r#1{#2}}%
@@ -277,64 +324,75 @@
\edef#1{\unexpanded{#2}}%
\krdcsvnormalize#1%
}
-\def\krd@loopdo@stack{}
-\protected\def\krd@pushloopdo{%
- \global\advance\krd@csvdepth\@ne
- \def\reserved@a##1{\expandafter\@gobble\string##1@%
- \romannumeral\krd@csvdepth}%
- \def\do##1{\let\noexpand##1\krdnoexpandcsn{\reserved@a{##1}}}%
- \xdef\krd@loopdo@stack{%
- \krdfor{\krd@loopdo,\ifkrdloopbreak,\krd@final@loopact,%
- \krd@regular@loopact}%
- {\krdexpandonce\krd@loopdo@stack}%
- }%
- \def\do##1{\let\krdnoexpandcsn{\reserved@a{##1}}\noexpand##1}%
- \krdexpanded{%
- \krdfor{\krd@loopdo,\ifkrdloopbreak,\krd@final@loopact,%
- \krd@regular@loopact}%
- }%
+
+\protected\def\krd@pushmacros#1#2#3{%
+ \begingroup
+ \global\advance#2\@ne
+ \krdifdef#1{}{\def#1{}}%
+ \def\reserved@a##1{\expandafter\@gobble\string##1@\romannumeral#2}%
+ \def\do##1{\let\noexpand##1\krdnoexpandcs{\reserved@a{##1}}}%
+ \xdef#1{#3{\krdexpandonce#1}}%
+ \def\do##1{\let\krdnoexpandcs{\reserved@a{##1}}\noexpand##1}%
+ \krdexpanded{\endgroup#3}%
}
-\protected\def\krd@poploopdo{%
+\protected\def\krd@popmacros#1#2{%
\begingroup
- \def\reserved@a##1##{\endgroup##1\gdef\krd@loopdo@stack}%
- \expandafter\reserved@a\krd@loopdo@stack
- \global\advance\krd@csvdepth\m@ne
+ \def\reserved@a##1##{\endgroup##1\gdef#1}%
+ \expandafter\reserved@a#1%
+ \global\advance#2\m@ne
}
+
\protected\def\krd@testst#1{\@ifstar{\krd@sttrue#1}{\krd@stfalse#1}}
-% \krdlistloop[<parser>]{<list>}<\if...>\fi<ini-code><final-code><reg-code>
-% When the conditional <\if...> isn't true, the regular code <reg-code>
-% will be executed for every member of the list.
-% <final-code> will be executed when the conditional <\if...> is true.
-% <ini-code> may be used to first turn <\if...> off before commencing
-% the loop. \ifkrdloopbreak may be used as the conditional in <\if...>.
-% Both <ini-code> and <final-code> can be empty (ie, {}).
-% Use '#1' in <final-code> and <reg-code> to access the current element
-% of the list.
-\protected\def\krdlistloop{\krd@testst{\@testopt\krd@listloop,}}
-\protected\def\krd@listloop[#1]#2#3\fi#4#5#6{%
- \krd@pushloopdo
- \edef\krd@csvarg{\krdifbool{krd@st}\krdexpandonce\unexpanded{#2}}%
- \krdcsvnormalize[#1]\krd@csvarg
- \def\krd@final@loopact##1{#5}%
- \def\krd@regular@loopact##1{#6}%
+% \krdforeach[<parser>]
+% {<list>}<\if...>\fi{<ini-code>}{<final-code>}{<reg-code>}
+% \krdforeach*[<parser>]
+% {<listcmd>}<\if...>\fi{<ini-code>}{<final-code>}{<reg-code>}
+%
+% 1. When the conditional <\if...> isn't true, the regular code <reg-code>
+% will be executed for every member of the list.
+% 2. <final-code> will be executed when the conditional <\if...> is true.
+% <ini-code> may be used to first turn <\if...> off before commencing
+% the loop. \ifkrd@foreach@break may be used as the conditional in
+% <\if...>.
+% 3. Both <ini-code> and <final-code> can be empty (ie, {}).
+% 4. Use '#1' in <final-code> and <reg-code> to access the current element
+% of the list.
+%
+\protected\def\krdforeach{\krd@testst{\@testopt\krd@foreach,}}
+\protected\def\krd@foreach[#1]#2#3\fi#4#5#6{%
+ \krd@pushmacros\krd@foreach@stack\krd@csvdepth{%
+ \do\krd@foreach@do\do\krd@foreach@final\do\krd@foreach@regular
+ \do\stopforeach
+ }%
+ \edef\krd@foreach@item{\krdifbool{krd@st}\krdexpandonce\unexpanded{#2}}%
+ \krdcsvnormalize[#1]\krd@foreach@item
+ \def\krd@foreach@final##1{#5}%
+ \def\krd@foreach@regular##1{#6}%
+ \krd@foreach@breakfalse
+ \let\stopforeach\krd@foreach@breaktrue
% Initial code:
#4\relax
- \def\krd@loopdo##1#1##2\krd@nnil{%
- \edef\krd@csvarg{\krdexpandonce{\@gobble##1}}%
- \krdifx\krd@csvarg\krd@nnil{}{%
- #3\relax
- \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
- {%
- \expandafter\krd@final@loopact\expandafter{\krd@csvarg}\relax
+ \def\krd@foreach@do##1#1##2\krd@nnil{%
+ \edef\krd@foreach@item{\krdexpandonce{\@gobble##1}}%
+ \krdifx\krd@foreach@item\krd@nnil{%
+ \krd@foreach@breakfalse
+ }{%
+ \krdifcond#3\fi{%
+ \expandafter\krd@foreach@final\expandafter{\krd@foreach@item}\relax
}{%
- \expandafter\krd@regular@loopact\expandafter{\krd@csvarg}\relax
- \krd@loopdo.##2\krd@nnil
+ \expandafter\krd@foreach@regular\expandafter{\krd@foreach@item}\relax
+ \krdifbool{krd@foreach@break}{%
+ \krd@foreach@breakfalse
+ }{%
+ \krd@foreach@do.##2\krd@nnil
+ }%
}%
}%
}%
- \expandafter\krd@loopdo\expandafter.\krd@csvarg#1\krd@nil#1\krd@nnil
- \krd@poploopdo
+ \expandafter\krd@foreach@do\expandafter
+ .\krd@foreach@item#1\krd@nil#1\krd@nnil
+ \krd@popmacros\krd@foreach@stack\krd@csvdepth
}
\protected\def\krdaddtolist{\krd@testst{\@testopt{\krd@addtolist{e}},}}
\protected\def\krdgaddtolist{\krd@testst{\@testopt{\krd@addtolist{x}},}}
@@ -461,16 +519,85 @@
\def\krd@remleadparser#1##1\krd@nil{\noexpand##1}%
\def\krd@parserequalerr##1#1=##2\krd@nil{%
\krdifblank{##2}{}{%
- \@latex@error{There is '#1=' in your key-value list}\@ehc
+ \krd@err{There is '#1=' in your key-value list}\krd@ehd
}%
}%
}
\endgroup
\krd@setupnormalize{,}
+
+% Filter class options to remove '=' and option values. Do this
+% retroactively if this package was loaded before \documentclass.
+% The keyreader package can be loaded before \documentclass.
+\protected\def\XKV@filterclassoptions{%
+ \XKV@sgfalse
+ \ifx\@classoptionslist\@undefined\else
+ \ifx\@classoptionslist\relax\else
+ \ifx\@classoptionslist\@empty\else
+ \XKV@sgtrue
+ \fi
+ \fi
+ \fi
+ \ifXKV@sg
+ \let\XKV@filterclassoptions\relax
+ \let\XKV@origclassoptionslist\@classoptionslist
+ \let\XKV@classoptionslist\@classoptionslist
+ \def\@classoptionslist{}%
+ \XKV@for@o\XKV@classoptionslist\XKV@tempa{%
+ \@expandtwoargs\in@{=}{\krdoxdetok\XKV@tempa}%
+ \ifin@\else
+ \edef\@classoptionslist{%
+ \@classoptionslist\ifx\@classoptionslist\@empty\else,\fi
+ \unexpanded\expandafter{\XKV@tempa}%
+ }%
+ \fi
+ }%
+ \fi
+}
+\def\XKV@getdocumentclass{%
+ \let\XKV@documentclass\@undefined
+ \XKV@sgfalse
+ \ifdefined\@filelist
+ \ifx\@filelist\@gobble\else
+ \ifx\@filelist\relax\else
+ \ifx\@filelist\@empty\else
+ \XKV@sgtrue
+ \fi
+ \fi
+ \fi
+ \fi
+ \ifXKV@sg
+ \def\XKV@tempb{00}%
+ \XKV@whilist\@filelist\XKV@tempa\if\XKV@tempb\fi{%
+ \filename@parse\XKV@tempa
+ \ifx\filename@ext\@clsextension
+ \edef\XKV@tempa{\filename@area\filename@base.\filename@ext}%
+ \XKV@ifundefined{opt@\XKV@tempa}{}{%
+ \let\XKV@documentclass\XKV@tempa
+ \def\XKV@tempb{01}%
+ }%
+ \fi
+ }%
+ \fi
+}
+\XKV@getdocumentclass
+\ifdefined\XKV@documentclass
+ \XKV@filterclassoptions
+\else
+ \let\XKV@documentclass\@empty
+ \let\XKV@classoptionslist\@empty
+ \xdef\@popfilename{%
+ \unexpanded\expandafter{\@popfilename}%
+ \noexpand\XKV@filterclassoptions
+ }%
+\fi
+
% Redefine \XKV@define@key to heed a complaint about the grabbing
% of the callback:
\protected\def\XKV@define@key#1{%
- \@ifnextchar[{\XKV@d@fine@k@y{#1}}{%
+ \@ifnextchar[{%
+ \XKV@d@fine@k@y{#1}%
+ }{%
\begingroup
\toks1{\endgroup\@namedef{\XKV@header#1}####1}%
\def\reserved@a{\the\toks\expandafter1\expandafter{\the\toks0}}%
@@ -489,7 +616,7 @@
\begingroup\expandafter\endgroup\expandafter\XKV@tempa\expandafter
{\expandafter\edef\csname#1#2\endcsname{\unexpanded{##1}}#4}%
}
-% Allow macro prefix (mp@) for choice keys:
+% Allow macro prefix (default: mp@) for choice keys:
\protected\def\define@choicekey{%
\XKV@testopta{\XKV@testoptb
{\@testopt\XKV@define@choicekey{choice\XKV@header}}}%
@@ -509,7 +636,7 @@
\XKV@d@fine@ch@ic@key{#1}%
}
\def\XKV@d@fine@ch@ic@key#1{%
- \edef\reserved@a{\krdnoexpandcsn{\XKV@header#1}}%
+ \edef\reserved@a{\krdnoexpandcs{\XKV@header#1}}%
\krdifbool{XKV@pl}{%
\expandafter\XKV@d@f@ne@ch@ic@k@y\reserved@a
}{%
@@ -520,7 +647,7 @@
\def\XKV@d@f@ne@ch@ic@k@y#1#2#3{\XKV@d@f@n@@ch@ic@k@y#1{{#2}{#3}}}
\def\XKV@d@f@n@@ch@ic@k@y#1#2{%
\edef#1##1{%
- \edef\krdnoexpandcsn{\XKV@macropf}{\noexpand\unexpanded{##1}}%
+ \edef\krdnoexpandcs{\XKV@macropf}{\noexpand\unexpanded{##1}}%
\ifXKV@st\noexpand\XKV@sttrue\else\noexpand\XKV@stfalse\fi
\ifXKV@pl\noexpand\XKV@pltrue\else\noexpand\XKV@plfalse\fi
\noexpand\XKV@checkchoice[\the\XKV@tempa@toks]{##1}{\the\XKV@toks}%
@@ -551,7 +678,7 @@
\expandafter\XKV@g@tkeyname\XKV@tempa=\@nil\XKV@tempa
\XKV@addtolist@x\XKV@naa\XKV@tempa
}%
- \ifnum\XKV@depth=\z@\let\XKV@rm\@empty\fi
+ \ifnum\XKV@depth=\krdz@\let\XKV@rm\@empty\fi
\expandafter\XKV@usepresetkeys\expandafter{\krd@na}{preseth}%
\krdexpandsecond\krd@s@tkeys
{{\krdexpandonce\XKV@resb}{\krdexpandonce\krd@na}}%
@@ -593,7 +720,8 @@
\krdexpandargonce{\KV@@sp@def\XKV@tkey}\XKV@tkey
\krdifx\XKV@tkey\@empty{%
\krdifblank{#2}{}{%
- \XKV@err{No key specified for value '\the\XKV@toks'}%
+ \krd@err{No key specified for value
+ \MessageBreak '\the\XKV@toks'}\krd@ehd
}%
}{%
\@expandtwoargs\in@{,\XKV@tkey,}{,\XKV@na,}%
@@ -628,7 +756,8 @@
\krdifbool{XKV@st}{%
\XKV@addtolist@o\XKV@rm\CurrentOption
}{%
- \XKV@err{Key '\XKV@tkey' undefined in families '\XKV@fams'}%
+ \krd@err{Key '\XKV@tkey' is undefined in
+ families \MessageBreak '\XKV@fams'}\krd@ehd
}%
}%
}{%
@@ -642,7 +771,7 @@
}%
}
% When the key default value has doubled hash characters,
-% then xkeyval's definition of \XKV@default fails:
+% xkeyval's definition of \XKV@default fails:
\protected\def\XKV@default#1#2\@nil{%
\edef\XKV@tempa{\expandafter\@gobble\string#1}%
\edef\XKV@tempb{\XKV@header\XKV@tkey}%
@@ -654,7 +783,7 @@
}%
\csname\XKV@header\XKV@tkey @default\endcsname
\expandafter\endgroup\the\toks@
- \krdifcsndef{XKV@\XKV@header save}{%
+ \krdifcsdef{XKV@\XKV@header save}{%
\expandafter\XKV@testsavekey\csname XKV@\XKV@header
save\endcsname\XKV@tkey
}{}%
@@ -673,6 +802,32 @@
\XKV@srstate{}{@\romannumeral\XKV@depth}%
}%
}
+\protected\def\XKV@replacepointers#1{%
+ \let\XKV@tempa\@empty
+ \let\XKV@resa\@empty
+ \XKV@r@placepointers#1\usevalue\@nil
+}
+\def\XKV@r@placepointers#1\usevalue#2{%
+ \XKV@addtomacro@n\XKV@tempa{#1}%
+ \edef\XKV@tempb{\unexpanded{#2}}%
+ \ifx\XKV@tempb\@nnil\else\XKV@afterfi
+ \XKV@ifundefined{XKV@\XKV@header#2@value}{%
+ \krd@err{No value has been recorded for key
+ \MessageBreak '#2'; pointer not replaced}\krd@ehd
+ \XKV@r@placepointers
+ }{%
+ \@expandtwoargs\in@{,\detokenize{#2},}{,\krdoxdetok\XKV@resa,}%
+ \ifin@\XKV@afterelsefi
+ \krd@err{Possible back linking of pointers;
+ \MessageBreak pointer replacement terminated}\krd@ehd
+ \else\XKV@afterfi
+ \XKV@addtolist@x\XKV@resa{#2}%
+ \expandafter\expandafter\expandafter\XKV@r@placepointers
+ \csname XKV@\XKV@header#2@value\endcsname
+ \fi
+ }%
+ \fi
+}
\protected\def\krdsetrmkeys{\XKV@testopta{\XKV@testoptc\krd@setrmkeys}}
\protected\def\krd@setrmkeys[#1]{%
\krdexpandargonce{\krd@setkeys[#1]}\XKV@rm
@@ -686,30 +841,39 @@
\protected\def\krdpostsetkeys{\@testopt\krd@postsetkeys{KV}}
\protected\def\krd@postsetkeys[#1]#2#3{\presetkeys[#1]{#2}{}{#3}}
\protected\def\krd@disabledkey@err#1{%
- \@latex@error{Key '#1' has been disabled}
+ \krd@err{Key '#1' has been disabled}
{You can't set or reset key '#1' at this\MessageBreak
late stage. Perhaps you should have set it \MessageBreak
earlier in \string\documentclass\@space or \string\usepackage}%
}
\protected\def\krddisablekeys{\XKV@testoptb\krd@disablekeys}
\protected\def\krd@disablekeys#1{%
- \def\krd@tempa{#1}%
- \krdcsvnormalize\krd@tempa
- \XKV@for@o\krd@tempa\krd@tempa{%
- \krdifcsndef{\XKV@header\krd@tempa}{}{%
- \@latex@warning@no@line{Key '\krd@tempa' is undefined:
+ \def\XKV@tempa{#1}%
+ \krdcsvnormalize\XKV@tempa
+ \XKV@for@o\XKV@tempa\XKV@tempa{%
+ \krdifcsdef{\XKV@header\XKV@tempa}{}{%
+ \@latex@warning@no@line{Key '\XKV@tempa' is undefined:
couldn't be disabled}%
}%
- \krdifcsndef{\XKV@header\krd@tempa @default}{%
- \edef\krd@tempb{\noexpand\XKV@define@key{\krd@tempa}[]}%
+ \krdifcsdef{\XKV@header\XKV@tempa @default}{%
+ \edef\XKV@tempb{\noexpand\XKV@define@key{\XKV@tempa}[]}%
}{%
- \edef\krd@tempb{\noexpand\XKV@define@key{\krd@tempa}}%
+ \edef\XKV@tempb{\noexpand\XKV@define@key{\XKV@tempa}}%
}%
- \krdexpandarg{\expandafter\krd@tempb\expandafter}%
- {\krd@disabledkey@err{\krd@tempa}}%
+ \krdexpandarg{\expandafter\XKV@tempb\expandafter}%
+ {\krd@disabledkey@err{\XKV@tempa}}%
}%
}
\edef\krd@hashchar{\string#}
+
+% \krddefinekeys[<pref>]{<fam>}[<mp>]{
+% ord/<key>/<dft>/<f1>;
+% cmd/<key>/<dft>/<f1>;
+% bool/<key>/<dft>/<f1>;
+% bool+/<key>/<dft>/<f1>/<f2>;
+% choice/<key>/<dft>/<alt>/<f1>;
+% choice+/<key>/<dft>/<alt>/<f1>/<f2>;
+% }
\protected\def\krddefinekeys{%
\begingroup
\endlinechar\m@ne
@@ -720,146 +884,186 @@
}
\protected\def\krd@d@finekeys#1#2[#3]#4{%
\expandafter\endgroup
- \ifkrd@st
- \def\krd@keyst{00}%
- \else
- \def\krd@keyst{01}%
- \fi
- \krddeftrue
+ \edef\krd@keyst{0\ifkrd@st0\else1\fi}%
+ \krdindeftrue
\begingroup
- \edef\key@prefix{\krdtrimspace{#1}}%
- \edef\key@family{\krdtrimspace{#2}}%
- \edef\macro@prefix{\krdtrimspace{#3}}%
+ \edef\krd@prefix{\krdtrimspace{#1}}%
+ \edef\krd@family{\krdtrimspace{#2}}%
+ \edef\krd@macpref{\krdtrimspace{#3}}%
\toks@{}%
\def\krd@rej{^?^}%
- \def\key@vals{}%
- \def\krd@altlista{}%
- \def\krd@altlistb{}%
+ \def\krd@vals{}%
+ \def\krd@altlist@a{}%
+ \def\krd@altlist@b{}%
\def\krd@splita##1/##2/{\krd@splitb##1/##2/.}%
- \def\krd@splitb##1/##2/##3/##4/##5/##6\krd@nil{%
- \edef\key@type{\krdtrimspace{##1}}%
- \edef\key@name{\krdtrimspace{##2}}%
+ \def\krd@splitb##1/##2/##3/##4/##5/##6/##7/##8/##9\krd@nil{%
+ \edef\krd@type{\krdzapspace{##1}}%
+ \edef\krd@name{\krdtrimspace{##2}}%
+ \edef\krd@default{\krdusearg\krdtrimspace{\@gobble##3}}%
+ \edef\krd@itemfour{\krdtrimspace{##4}}%
+ \edef\krd@itemfive{\krdtrimspace{##5}}%
+ \edef\krd@itemsix{\krdtrimspace{##6}}%
\@expandtwoargs\in@{\krd@hashchar}{\detokenize{##2}}%
\ifin@
- \@latex@error{Bad key name '\detokenize{##2}'}\@ehc
+ \krd@err{Bad key name '\detokenize{##2}'}\krd@ehd
\fi
\if\krd@keyst
- \krdifcsndef{\key@prefix @\key@family @##2}{%
- \@latex@error{Key '##2' already exists in
- family '\key@family'}\@ehc
+ \krdifcsdef{\krd@prefix @\krd@family @##2}{%
+ \krd@err{Key '##2' already exists in
+ family '\krd@family'}\krd@ehd
}{}%
\fi
- \@expandtwoargs\in@{,\detokenize\expandafter{\key@type},}%
- {,\detokenize{ord,cmd,bool,choice},}%
+ \@expandtwoargs\in@
+ {,\krdoxdetok\krd@type,}
+ {,\detokenize{ord,cmd,bool,bool+,choice,choice+},}%
\ifin@\else
- \@latex@error{Unknown key type '\key@type'}\@ehc
+ \krd@err{Unknown key type '\krd@type'}\krd@ehd
\fi
- \edef\key@default{\expandafter\krdtrimspace\expandafter{\@gobble##3}}%
- \edef\krd@resa{\krdtrimspace{##4}}%
- \edef\krd@resb{\krdtrimspace{##5}}%
- \@expandtwoargs\in@{,\detokenize\expandafter{\key@default},}%
- {,\detokenize{true,false},}%
- \edef\key@vals{%
- \ifx\key@vals\@empty\else\krdexpandonce\key@vals,\fi
- \ifx\key@default\krd@rej\else
- \key@name=\ifin@ false\else\krdexpandonce\key@default\fi
+ \@expandtwoargs\in@
+ {,\krdoxdetok\krd@default,}{,\detokenize{true,false},}%
+ \edef\krd@vals{%
+ \ifx\krd@vals\@empty\else\krdexpandonce\krd@vals,\fi
+ \ifx\krd@default\krd@rej\else
+ \krd@name=\ifin@ false\else\krdexpandonce\krd@default\fi
\fi
}%
- \def\reserved@a####1{%
- \def\reserved@a########1####1########2########3\krd@nil{%
- \def\key@typenr{########2}%
- \ifx\key@typenr\krd@nnil
- \@latex@error{Invalid key type '####1'}\@ehc
- \fi
+ % ord{0}cmd{1}bool{2}bool+{3}choice{4}choice+{5}
+ \krdusearg\krd@gettypenr{\krd@type}%
+ \ifnum\krd@typenr>\thr@@
+ \def\reserved@a{%
+ \krd@err{Empty nominations for choice key \krd@name}\krd@ehd
}%
- \reserved@a ord{0}cmd{1}bool{2}choice{3}####1{\krd@nil}\krd@nil
- }%
- \expandafter\reserved@a\expandafter{\key@type}%
- \ifnum\key@typenr=\thr@@
- \edef\reserved@a{\unexpanded{##4}}%
- \krdifx\reserved@a\@empty{%
- \@latex@error{Empty alternate list for choice key \key@name}\@ehc
- }{%
- \krdifx\reserved@a\krd@rej{%
- \@latex@error{Empty alternate list for choice key \key@name}\@ehc
- }{%
+ \ifx\krd@itemfour\@empty
+ \reserved@a
+ \else
+ \ifx\krd@itemfour\krd@rej
+ \reserved@a
+ \else
\krd@getaltlist{##4}%
- }%
- }%
+ \fi
+ \fi
\fi
\krdexpanded{%
\toks@{\the\toks@
- \krdnoexpandcsn{define@\ifnum\key@typenr>\z@\key@type\fi key}%
- \ifnum\key@typenr=\thr@@*\fi
- \ifnum\key@typenr>\@ne+\fi
- [\key@prefix]{\key@family}%
- \ifnum\key@typenr>\z@[\macro@prefix]\fi
- {\key@name}%
- \ifnum\key@typenr=\thr@@
+ \krdnoexpandcs{define@\krd@typefordef key}%
+ \ifnum\krd@typenr>\thr@@*\fi
+ \if\krd@plustype+\fi
+ [\krd@prefix]{\krd@family}%
+ \ifnum\krd@typenr>\krdz@[\krd@macpref]\fi
+ {\krd@name}%
+ \ifnum\krd@typenr>\thr@@
[\unexpanded{\krduserinput\krdorder}]%
- {\krdexpandonce\krd@altlista}%
+ {\krdexpandonce\krd@altlist@a}%
\fi
- \krdifx\key@default\krd@rej{}{%
- [{\expandafter\krdifbraced\expandafter{\key@default}%
- {{{\krdexpandonce\key@default}}}{\krdexpandonce\key@default}}]%
- }%
- {%
- \ifnum\key@typenr=\thr@@
- \krdifx\krd@resb\krd@rej{}{\unexpanded{##5}}%
- \krd@executealt{########1}{\krdexpandonce\krd@altlistb}%
+ \ifx\krd@default\krd@rej\else\XKV@afterfi
+ [{\expandafter\krdifbraced\expandafter{\krd@default}%
+ {{{\krdexpandonce\krd@default}}}{\krdexpandonce\krd@default}}]%
+ \fi
+ {% callback1
+ \ifnum\krd@typenr>\thr@@
+ \ifx\krd@itemfive\krd@rej\else\krdexpandonce\krd@itemfive\fi
+ \krd@executealt{########1}{\krdexpandonce\krd@altlist@b}%
\else
- \krdifx\krd@resa\krd@rej{}{\unexpanded{##4}}%
+ \ifx\krd@itemfour\krd@rej\else\krdexpandonce\krd@itemfour\fi
\fi
}%
- \ifnum\key@typenr>\@ne{\noexpand\krd@keyvalerr}\fi
+ \if\krd@plustype
+ {%
+ \ifnum\krd@typenr>\thr@@
+ \ifx\krd@itemsix\krd@rej
+ \noexpand\krd@keyvalerr
+ \else
+ \krdexpandonce\krd@itemsix
+ \fi
+ \else
+ \ifx\krd@itemfive\krd@rej
+ \noexpand\krd@keyvalerr
+ \else
+ \krdexpandonce\krd@itemfive
+ \fi
+ \fi
+ }%
+ \fi
}%
}%
}%
- \edef\key@list{\unexpanded{#4}}%
- \krdlistloop*[;]\key@list\ifx\end\@undefined\fi{}{}{%
- \krd@splita##1/^?^/^?^/^?^/^?^/\krd@nil
+ \edef\krd@list{\unexpanded{#4}}%
+ % Don't normalize for slash, since double slash (meaning, eg,
+ % "no value") will be made one slash.
+ \krdforeach*[;]\krd@list\if01\fi{}{}{%
+ \krd@splita##1/^?^/^?^/^?^/^?^/^?^/^?^/^?^/\krd@nil
}%
\krdexpanded{\endgroup
\the\toks@
- \noexpand\krdsetkeys[\key@prefix]%
- {\key@family}{\krdexpandonce\key@vals}%
+ \noexpand\krdsetkeys[\krd@prefix]%
+ {\krd@family}{\krdexpandonce\krd@vals}%
+ }%
+ \krdindeffalse
+}
+\protected\def\krd@gettypenr#1{%
+ \def\reserved@a##1#1##2##3\krd@nil{%
+ \def\krd@typenr{##2}%
+ \ifx\krd@typenr\krd@nnil
+ \krd@err{Invalid key type '#1'}\krd@ehd
+ \else
+ \edef\krd@typefordef{%
+ % Using \numexpr will remove \relax, which is needed
+ % to stop \ifcase's search for number.
+ \ifcase\numexpr\krd@typenr\relax\or
+ cmd\or bool\or bool\or choice\or choice\fi
+ }%
+ \fi
}%
- \krddeffalse
+ \reserved@a ord{0}cmd{1}bool{2}bool+{3}choice{4}choice+{5}%
+ #1{\krd@nil}\krd@nil
+ \@expandtwoargs\in@{+\relax}{\krdoxdetok\krd@type\relax}%
+ \edef\krd@plustype{0\ifin@ 0\else 1\fi}%
}
\protected\def\krd@keyvalerr{%
\krd@getinnoval
- \@latex@error{Erroneous value '\krd@ival' for key or option
- \MessageBreak'\XKV@tkey'}{Invalid key value encountered.}%
+ \krd@err{Erroneous value '\krd@ival'
+ \MessageBreak for key or option '\XKV@tkey'}
+ {Invalid value for key '\XKV@tkey'.}%
}
\protected\def\krd@getaltlist#1{%
- \def\krd@g@taltlist##1.do=##2\krd@nil{%
- \edef\krd@tempa{\krdtrimspace{##1}}%
- \edef\krd@tempb{\detokenize\expandafter{\krd@tempa}{\krdtrimspace{##2}}}%
- \krdaddtolist*\krd@altlista\krd@tempa
- \krdaddtolist*\krd@altlistb\krd@tempb
- }%
- \krdlistloop[,]{#1}\ifx\end\@undefined\fi{}{}{%
- \@expandtwoargs\in@{\detokenize{.do=}}{\detokenize{##1}}%
- \krdifbool{in@}{%
- \krd@g@taltlist##1\krd@nil
- }{%
- \krd@g@taltlist##1.do=\krd@nil
+ \begingroup
+ \def\krd@g@taltlist##1.do=##2.do=##3\krd@nil{%
+ \edef\XKV@tempa{\krdtrimspace{##1}}%
+ \edef\XKV@tempb{\krdoxdetok\XKV@tempa{\krdtrimspace{##2}}}%
+ \def\@do####1####2{%
+ \edef####1{%
+ \krdexpandonce####1\ifx####1\@empty\else,\fi
+ \krdexpandonce####2%
+ }%
}%
+ \@do\krd@altlist@a\XKV@tempa
+ \@do\krd@altlist@b\XKV@tempb
+ }%
+ \def\do##1{%
+ \krd@g@taltlist##1.do=.do=\krd@nil
}%
+ \krdfor{#1}%
+ \global\let\krd@altlist@a\krd@altlist@a
+ \global\let\krd@altlist@b\krd@altlist@b
+ \endgroup
}
\protected\def\krd@executealt#1#2{%
\edef\reserved@a{\krdtrimspace{#1}}%
- \edef\reserved@a{\detokenize\expandafter{\reserved@a}}%
- \krdexpandsecond{\def\reserved@a##1}\reserved@a##2##3\krd@nil{%
- \edef\reserved@a{\unexpanded{##2}}%
- \krdifx\reserved@a\krd@nnil{%
- \@latex@error{No alternate list match for key '\XKV@tkey'}\@ehc
- }{%
- ##2%
+ \edef\reserved@a{\krdoxdetok\reserved@a}%
+ \def\reserved@b##1{%
+ \def\reserved@a####1##1####2####3\krd@nil{%
+ \edef\reserved@a{\unexpanded{####2}}%
+ \krdifx\reserved@a\krd@nnil{%
+ \krd@err{No choice match for key '\XKV@tkey'}\krd@ehd
+ }{%
+ ####2%
+ }%
}%
+ \reserved@a#2#1{\krd@nil}\krd@nil
}%
- \reserved@a#2#1{\krd@nil}\krd@nil
+ \krdusearg\reserved@b{\reserved@a}%
}
+\def\krd@lengthofival{20}
\protected\def\krd@getinnoval{%
\begingroup
\def\reserved@a##1=##2=##3\krd@nil{%
@@ -870,12 +1074,12 @@
\def\krd@ival{???}%
}{%
\def\krd@ival{}%
- \@tempcnta\z@
+ \@tempcnta\krdz@
\def\do##1{%
\def\reserved@a{##1}%
\krdifx\reserved@a\krd@nnil{}{%
\advance\@tempcnta\@ne
- \ifnum\@tempcnta<20\relax
+ \ifnum\@tempcnta<\krd@lengthofival\relax
\edef\krd@ival{\krd@ival##1}%
\expandafter\do
\else
@@ -890,11 +1094,84 @@
\def\noexpand\krd@ival{\krd@ival}%
}%
}
+\def\XKV@testopte#1{%
+ \XKV@ifstar{\XKV@sttrue\XKV@t@stopte#1}{\XKV@stfalse\XKV@t@stopte#1}%
+}
+\def\XKV@t@stopte#1{\@testopt{\XKV@t@st@pte#1}{KV}}
+\def\XKV@t@st@pte#1[#2]{%
+ \XKV@makepf{#2}%
+ \@ifnextchar<{\XKV@@t@st@pte#1}%
+ {\XKV@@t@st@pte#1<\@currname.\@currext>}%
+}
+\def\XKV@@t@st@pte#1<#2>{%
+ \XKV@sp@deflist\XKV@fams{#2}%
+ \@testopt#1{}%
+}
+\def\DeclareOptionX{%
+ \let\@fileswith@pti@ns\@badrequireerror
+ \XKV@ifstar\XKV@dox\XKV@d@x
+}
+\long\def\XKV@dox#1{\XKV@toks{#1}\edef\XKV@doxs{\the\XKV@toks}}
+\def\XKV@d@x{\@testopt\XKV@@d@x{KV}}
+\def\XKV@@d@x[#1]{%
+ \@ifnextchar<{\XKV@@@d@x[#1]}{\XKV@@@d@x[#1]<\@currname.\@currext>}%
+}
+\def\XKV@@@d@x[#1]<#2>#3{\@testopt{\define@key[#1]{#2}{#3}}{}}
+\def\ExecuteOptionsX{\XKV@stfalse\XKV@plfalse\XKV@t@stopte\XKV@setkeys}
+\def\ProcessOptionsX{\XKV@plfalse\XKV@testopte\XKV@pox}
+\def\XKV@pox[#1]{%
+ \let\XKV@tempa\@empty
+ \XKV@inpoxtrue
+ \let\@fileswith@pti@ns\@badrequireerror
+ \edef\XKV@testclass{\@currname.\@currext}%
+ \ifx\XKV@testclass\XKV@documentclass
+ \let\@unusedoptionlist\XKV@classoptionslist
+ \XKV@ifundefined{ver@xkvltxp.sty}{}{%
+ \@onelevel@sanitize\@unusedoptionlist
+ }%
+ \else
+ \ifXKV@st
+ \def\XKV@tempb##1,{%
+ \def\CurrentOption{##1}%
+ \ifx\CurrentOption\@nnil\else
+ \XKV@g@tkeyname##1=\@nil\CurrentOption
+ \XKV@key@if@ndefined{\CurrentOption}{}{%
+ \XKV@useoption{##1}%
+ \XKV@addtolist@n\XKV@tempa{##1}%
+ }%
+ \expandafter\XKV@tempb
+ \fi
+ }%
+ \expandafter\XKV@tempb\XKV@classoptionslist,\@nil,%
+ \fi
+ \fi
+ \expandafter\XKV@addtolist@o\expandafter
+ \XKV@tempa\csname opt@\@currname.\@currext\endcsname
+ \def\XKV@tempb{\XKV@setkeys[#1]}%
+ \expandafter\XKV@tempb\expandafter{\XKV@tempa}%
+ \let\XKV@doxs\relax
+ \let\XKV@rm\@empty
+ \XKV@inpoxfalse
+ \let\@fileswith@pti@ns\@@fileswith@pti@ns
+ \AtEndOfPackage{\let\@unprocessedoptions\relax}%
+}
+\def\XKV@useoption#1{%
+ \def\XKV@resa{#1}%
+ \XKV@ifundefined{ver@xkvltxp.sty}{}{%
+ \@onelevel@sanitize\XKV@resa
+ }%
+ \@expandtwoargs\@removeelement{\XKV@resa}%
+ {\@unusedoptionlist}\@unusedoptionlist
+}
\krdnewlet\krdDeclareOption\DeclareOptionX
\krdnewlet\krdExecuteOptions\ExecuteOptionsX
\krdnewlet\krdProcessOptions\ProcessOptionsX
+\krdDeclareOption[KV]<keyreader>{lengthofival}[20]{%
+ \edef\krd@lengthofival{\number#1}%
+}
\krdDeclareOption*{\PackageWarning{keyreader}{Unknown option
'\CurrentOption' ignored}}
+\krdExecuteOptions[KV]<keyreader>{lengthofival}
\krdProcessOptions[KV]<keyreader>\relax
\endinput
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index 25af5f4b68f..44358187eef 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -56,7 +56,8 @@ my @TLP_working = qw(
beebe begriff bengali bera berenisadf betababel beton
bez123 bezos bgreek bgteubner bguq bhcexam
bib-fr bibarts biber bibhtml
- biblatex biblatex-apa biblatex-bwl biblatex-chem biblatex-chicago
+ biblatex biblatex-apa biblatex-bwl
+ biblatex-caspervector biblatex-chem biblatex-chicago
biblatex-dw biblatex-fiwi biblatex-historian
biblatex-ieee biblatex-juradiss
biblatex-luh-ipw
@@ -159,7 +160,7 @@ my @TLP_working = qw(
euler eulervm euro euro-ce europecv eurosym
everyhook everypage
exam examdesign examplep exceltex excludeonly exercise exp-testopt
- expdlist export expressg extarrows exteps
+ expdlist export expressg exsheets extarrows exteps
extpfeil extract extsizes
facsimile facture faktor
fancybox fancyhdr fancyhdr-it fancynum fancypar
@@ -319,7 +320,7 @@ my @TLP_working = qw(
phaistos philex philokalia philosophersimprint
phonetic photo physics physymb piano picinpar pict2e
pictex pictex2 pictexsum piechartmp piff pigpen
- pinlabel pitex pittetd pkfix pkfix-helper placeins placeins-plain
+ pinlabel pitex pittetd pkfix pkfix-helper pkuthss placeins placeins-plain
plainpkg plari plantslabels plates play plipsum
plnfss plweb pmgraph pmx pnas2009
poemscol poetrytex polski poltawski
diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds
index 660656beda3..506a888c49e 100755
--- a/Master/tlpkg/libexec/ctan2tds
+++ b/Master/tlpkg/libexec/ctan2tds
@@ -491,6 +491,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`);
'kdgcoursetext', "die 'skipping, confused/nonfree license'",
'kelly', "die 'skipping, obsoleted by cbgreek?'",
'kerkis', "&MAKEflatten",
+ 'keyreader', "&MAKEmv_doctex",
'keys3', "die 'skipping, merged into expl3'",
'knitting', "&MAKEflatten",
'koi8', "die 'skipping, ca.1996, noinfo license'",
@@ -725,7 +726,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`);
'pigpen', "&MAKEflatten",
'pinlabel', "&MAKEnosymlinks",
'pitthesis', "die 'skipping, noinfo license",
- 'pkuthss', "&MAKEpkuthss",
+ 'pkuthss', "&MAKEmv_doctex",
'pl', "die 'skipping, not ready, cf. cc-pl, sorry",
'pl-qx', "&MAKEplqx",
'pmxchords', "die 'skipping, problematic musixtex scripts'",
@@ -873,7 +874,7 @@ chomp ($Build = `cd $Master/../Build/source && pwd`);
'sikumuna', "die 'skipping, lyx template'",
'simpsons', "die 'skipping, noinfo license'",
'skak', "&MAKEflatten",
- 'skeyval', "&MAKEpkuthss",
+ 'skeyval', "&MAKEmv_doctex",
'slashbox', "die 'skipping, noinfo license, c.1993'",
'slidenotes', "die 'skipping, nonfree'",
'smallcap', "die 'skipping, questionable license, 1996'",
@@ -3811,6 +3812,20 @@ sub MAKEmisc {
killfiles($standardclean);
}
+sub MAKEmv_doctex {
+ # move files in tex to runtime, and doc/* up a level.
+ &donormal ();
+ #
+ my $texdest = "$DEST/tex/$whichformat/$package";
+ &xmkdir ($texdest);
+ &SYSTEM ("$MV `find tex -type f` $texdest/");
+ &SYSTEM ("$RM -r tex"); # rm now-empty dir
+ &SYSTEM ("$MV doc/* .");
+ #
+ # remove newly empty directories.
+ &SYSTEM ("find -depth -type d -print | xargs rmdir 2>/dev/null");
+}
+
sub MAKEtamethebeast {
my $destdir = "$DEST/doc/bibtex/$package";
&SYSTEM("mkdir -p $destdir");
@@ -4988,21 +5003,6 @@ sub POSTpedigreeperl {
&SYSTEM ("$MV Pedigree/*.pm $scriptdir/Pedigree/");
}
-sub MAKEpkuthss {
- # move files in tex to runtime, and doc/* up a level.
- &donormal ();
- #
- my $texdest = "$DEST/tex/$whichformat/$package";
- &xmkdir ($texdest);
- &SYSTEM ("$MV `find tex -type f` $texdest/");
- &SYSTEM ("$RM -r tex"); # rm now-empty dir
- &SYSTEM ("$MV doc/* .");
- #
- # remove newly empty directories.
- &SYSTEM ("find -depth -type d -print | xargs rmdir 2>/dev/null");
-}
-
-
sub POSTpgf {
print "POST$package - mv generic,latex,... directories\n";
&SYSTEM ("cd $DEST && mkdir tex && mv context generic latex plain tex");