summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/keyreader/keyreader.sty
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 /Master/texmf-dist/tex/latex/keyreader/keyreader.sty
parente828c375ba40d5ea05fd4cf79482c15d56c28789 (diff)
keyreader (12oct12)
git-svn-id: svn://tug.org/texlive/trunk@28020 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/keyreader/keyreader.sty')
-rw-r--r--Master/texmf-dist/tex/latex/keyreader/keyreader.sty669
1 files changed, 473 insertions, 196 deletions
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