diff options
author | Karl Berry <karl@freefriends.org> | 2012-11-06 22:35:59 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-11-06 22:35:59 +0000 |
commit | 6cab410e49d491c2884a037e0a134eeb2c2acda9 (patch) | |
tree | 5b7b72852382a70ac7f27f43b913d1da8f66ed12 /Master/texmf-dist/tex/latex/skeyval | |
parent | 705b4d8f092a56d9ae900940d265fb6f55b3033d (diff) |
skeyval (6nov12)
git-svn-id: svn://tug.org/texlive/trunk@28197 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/skeyval')
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval-bc.sty | 18 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval-core.tex | 2771 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex | 687 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval-ltxcmds.tex | 69 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval-ltxpatch.sty | 48 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.sty | 50 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.tex | 41 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval-view.sty | 74 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/skeyval/skeyval.sty | 500 |
9 files changed, 2697 insertions, 1561 deletions
diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-bc.sty b/Master/texmf-dist/tex/latex/skeyval/skeyval-bc.sty index 1f65a1d0100..de53f5161e0 100644 --- a/Master/texmf-dist/tex/latex/skeyval/skeyval-bc.sty +++ b/Master/texmf-dist/tex/latex/skeyval/skeyval-bc.sty @@ -1,8 +1,17 @@ %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% % This is file 'skeyval-bc.sty', version 0.73 of skeyval package, % -% January 2011. This file is provided only for backward compatibility % -% (bc) of the package. Beginning from version 1.0, September 2012, the % -% package has changed radically. % +% January 2011. % +% NOTE % +% This file is provided only for backward compatibility (bc) of the % +% skeyval package. Beginning from version 1.0, September 2012, the % +% package has changed radically. Users of pre-version 1.0 of the package % +% can load it now by calling: % +% % +% \usepackage[compatibility]{skeyval} % +% \RequirePackage[compatibility]{skeyval} % +% or % +% \usepackage{skeyval-bc} % +% \RequirePackage{skeyval-bc} % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % @@ -1992,7 +2001,8 @@ } \SKV@def*\SKV@compoptb[#1]#2{\SKV@testopt{\SKV@compoptc[#1]{#2}}{mp@}} \SKV@def*\SKV@compoptc[#1]#2[#3]#4{% - \SKV@testopt{\SKV@co@pkey[#1]{#2}[#3]{#4}}{true}} + \SKV@testopt{\SKV@co@pkey[#1]{#2}[#3]{#4}}{true}% +} \SKV@def*\SKV@biboolkeys[#1]#2[#3]#4[#5]#6#7#8{% \@namedef{#1@#2@#4@func}{% #7\relax diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-core.tex b/Master/texmf-dist/tex/latex/skeyval/skeyval-core.tex index 13e0a2a37f2..83348e842a8 100644 --- a/Master/texmf-dist/tex/latex/skeyval/skeyval-core.tex +++ b/Master/texmf-dist/tex/latex/skeyval/skeyval-core.tex @@ -1,5 +1,5 @@ %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -% This is file 'skeyval-core.tex', version 1.1, 2012/10/15. % +% This is file 'skeyval-core.tex', version 1.1a, 2012/10/16. % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % @@ -29,9 +29,6 @@ \csname skeyval-core-loaded\endcsname \expandafter\let\csname skeyval-core-loaded\endcsname\endinput -% Remove ++++++++++++++++++++++++++++++++++++++++++ -\RequirePackage[notraceifs]{codetrace} - \begingroup \catcode035 06 % # \catcode064 11 % @ @@ -45,9 +42,17 @@ \expandafter\do \fi }% - \edef\skv@core@restorecodes{\do035,064,123,125,061,059,\do,}% + \edef\skv@core@restorecodes{\do35,64,123,125,61,59,13,\do,}% } \skv@prova + +\edef\skv@core@restorecodes{% + \unexpanded\expandafter{\skv@core@restorecodes}% + \endlinechar\the\endlinechar\relax + \catcode`\^^M=\the\catcode`\^^M\relax +} +\endlinechar13 % +\catcode013 05 % ^^M \catcode035 06 % # \catcode064 11 % @ \catcode123 01 % { @@ -57,7 +62,7 @@ \def\do#1=#2,{% \ifx\do#1\else \edef\skv@core@restorecodes{% - \skv@core@restorecodes + \unexpanded\expandafter{\skv@core@restorecodes}% \catcode#1=\the\catcode#1\relax }% \catcode#1=#2\relax @@ -65,27 +70,31 @@ \fi } \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,\do=,% + 059=12,045=12,047=12,058=12,063=12,091=12,093=12,126=13,13=5,\do=,% \newdimen\skvz@\skvz@=0pt\relax +\newcount\skvm@ne\skvm@ne=-1\relax \ifcase - \ifx\eTeXversion\@undefined\skvz@\else - \ifnum\eTeXversion<\tw@\skvz@\else\@ne\fi\fi - \errhelp{This package requires eTeX version 2 or higher.}% + \ifx\eTeXversion\@undefined0\else + \ifnum\eTeXversion<\tw@0\else1\fi\fi\relax + \errhelp{This package requires eTeX version 2 or higher.} \errmessage{skeyval package: eTeX not loaded or old version.} \expandafter\endinput \fi -\newif\ifskv@inlatex +%\chardef\skv@five=5\relax +%\chardef\skv@six=6\relax +\newif\ifskv@latex +\newif\ifskv@tempst \ifx\ProvidesFile\@undefined - \skv@inlatexfalse - \message{File 'skeyval-core.tex' 2012/10/15 v1.1: + \skv@latexfalse + \message{File 'skeyval-core.tex' 2012/10/16 v1.1a: Core of 'skeyval' key-value parser (AM)} \input skeyval-ltxcmds \else - \skv@inlatextrue + \skv@latextrue \ProvidesFile{skeyval-core.tex} - [2012/10/15 v1.1 Base file of skeyval package (AM)] + [2012/10/16 v1.1a Base file of skeyval package (AM)] \@addtofilelist{skeyval-core.tex} \long\def\@nodocument#1{% \@latex@error{'#1' appeared\on@line\space without @@ -216,7 +225,43 @@ {#1}{\unexpanded{#3}}% } -\long\def\skvgobbleldspaces{\skvifnextchar x{}{}} +% Expandable \@testopt: +% +% Eg, +% \def\macroa{\skvnewxtestopt\macrob{Mr.}} +% \def\macrob[#1]#2{#1 #2} +% \edef\testa{\expandafter\macroa\activespace{David Carlisle}} +% \edef\testb{\macroa[Mr.]{Heiko Oberdiek}} +% +\long\def\skvnewxtestopt#1#2#3{% + % #3 will be seen as a space only if that space is active. But + % \skvifstrcmpTF will detokenize that space before comparison. + \skvifstrcmpTF{ }{#3}{% + \skvnewxtestopt#1{#2}% + }{% + \skvifstrcmpTF{#3}{[}% + {#1[}{\skvifntypeTF{#3}{#1[#2]#3}{#1[#2]{#3}}}% + }% +} + +% Expandable \@ifnextchar: +% +% Eg, +% \def\temp{\skvxifnextchar*{\def\x{T}}{\def\x{F}}} +% \temp* (star seen) or \temp<some token> (star not seen) +% +% ** This can't be used to test the presence of explicit left brace. +% +\long\def\skvxifnextchar#1#2#3#4{% + % #4 will be seen as a space only if that space is active. But + % \skvifstrcmpTF will detokenize that space before comparison. + \skvifstrcmpTF{ }{#4}{% + \skvxifnextchar#1{#2}{#3}% + }{% + \skvifstrcmpTF{#4}{#1}{#2}{\skvifntypeTF{#4}{#3#4}{#3{#4}}}% + }% +} + \long\def\skvgobbleleadingspaces{\skvsimpleifnextchar x{}{}} \long\protected\def\skvstarorlong#1{% \skvifstar{\let\l@ngrel@x\relax#1}{\let\l@ngrel@x\long#1}% @@ -272,6 +317,8 @@ \skvnewlet\skv@nil\relax \skvnewlet\skvrelax\relax \skvnewdef*\skv@relaxtoks{\relax} +\skvnewdef*\skv@truetoks{true} +\skvnewdef*\skv@falsetoks{false} \skvnewdef*\skv@nnil{\skv@nil} \skvnewdef\skv@car#1#2\car@nil{#1} \skvnewdef\skv@car@detok#1#2\car@nil{\detokenize{#1}} @@ -285,6 +332,7 @@ \skvnewdef*\skv@quark{\@gobble\skv@quark} \skvnewlet\skvrom\romannumeral \skvnewdef*\skv@rej{^skv^} +\skvnewdef*\skv@dotna{.na} \skvnewdef\skvafterfi#1\fi{\fi#1} \skvnewdef\skvafterfifi@inneriscond#1\fi#2\fi{\fi#1\fi} \skvnewdef\skvafterfifi#1\fi#2\fi{\fi\fi#1} @@ -303,22 +351,22 @@ \in@@#2{\in@@}#1\in@@ } \skvrobustdef*\skvcsnewif#1{% - \skvifstrcmp{#1}{x}{% + \skvifstrcmpTF{#1}{x}{% \skv@err{Redefining primitve '\@backslashchar ifx'?}\@ehd }{% \csname newif\expandafter\endcsname\csname if#1\endcsname }% } \skvnewdef*\skv@zapornot#1{% - \ifnum#1=\skvz@ - \expandafter\@iden - \else + \if#1% \expandafter\skvzapspaces + \else + \expandafter\@iden \fi } \skvnewdef\skvzapspaces#1{\skv@zapspaces.#1 \zap@nil} \skvnewdef\skv@zapspaces#1 #2\zap@nil{% - \skvifblank{#2}{% + \skvifblankTF{#2}{% \@gobble#1% }{% \skv@zapspaces#1#2\zap@nil @@ -331,26 +379,26 @@ \newcommand\skvifleadspace[3]{% \romannumeral\csname - @\skvifnull{#1}{second}{\iffalse{\fi\skv@ifleadspace.#1 x}}% + @\skvifnullTF{#1}{second}{\iffalse{\fi\skv@ifleadspace.#1 x}}% oftwo\endcsname{0 #2}{0 #3}% } \skvnewdef\skv@ifleadspace#1 {% - \expandafter\skvifnull\expandafter{\@gobble#1}{first}{second}% + \expandafter\skvifnullTF\expandafter{\@gobble#1}{first}{second}% \expandafter\@gobble\expandafter{\iffalse}\fi } -% \skvifldspace{ }{}{} gives <true> as desired. +% \skvifldspaceTF{ }{}{} gives <true> as desired. \begingroup \lccode`\&=0 \catcode`\&=7 \lccode`\!=0 \catcode`\!=8 \lowercase{\endgroup - \skvnewdef\skvifldspace#1{\skv@ifldspace!#1! &} - \skvnewdef\skv@ifldspace#1! #2&{\skvifnotblank{#2}} + \skvnewdef\skvifldspaceTF#1{\skv@ifldspace!#1! &} + \skvnewdef\skv@ifldspace#1! #2&{\skvifblankFT{#2}} \skvnewdef\skvtrimspace#1{\skv@trimspace@a.#1& &} \skvnewdef\skv@trimspace@a#1 &{\skv@trimspace@b#1&} \skvnewdef\skv@trimspace@b#1{% \unexpanded\expandafter{% \romannumeral0% - \expandafter\skvifldspace\expandafter{\@gobble#1}{% + \expandafter\skvifldspaceTF\expandafter{\@gobble#1}{% \@gobble#1% }{% \expandafter\@space\@gobble#1% @@ -364,7 +412,7 @@ \edef#1{\expandafter\skvtrimspace\expandafter{#1}}% } \skvnewdef*\skvcsuse#1{% - \ifcsname#1\endcsname + \skvifcsname#1\then \csname#1\expandafter\endcsname \fi } @@ -375,12 +423,17 @@ \skvnewdef\skvaftercsname#1#2{% \expandafter\skvswap\expandafter{\csname#2\endcsname}{#1}% } -\skvnewdef*\skvifdef#1{% - \skvifblank{#1}\@secondoftwo{% - \skvifx#1\@undefined{% +\skvnewlet\skvaftercs\skvaftercsname +\skvnewdef*\skvifdef#1\then{\if0\skvifdefTF{#1}{0}{1}} +\skvnewdef*\skvifundef#1\then{\if0\skvifdefTF{#1}{1}{0}} +% \skvifcsname x\then\def\x{T}\else\def\x{F}\fi +\skvnewdef*\skvifcsname#1\then{\if0\skvifcsdefTF{#1}{0}{1}} +\skvnewdef*\skvifdefTF#1{% + \skvifblankTF{#1}\@secondoftwo{% + \skvifxTF#1\@undefined{% \@secondoftwo }{% - \ifx#1\relax + \ifx\relax#1% \expandafter\@secondoftwo \else \expandafter\@firstoftwo @@ -388,9 +441,9 @@ }% }% } -\skvnewdef*\skvifundef#1{\skvifdef{#1}\@secondoftwo\@firstoftwo} -\skvnewdef*\skvifcsdef#1{% - \skvifblank{#1}{% +\skvnewdef*\skvifdefFT#1{\skvifdefTF{#1}\@secondoftwo\@firstoftwo} +\skvnewdef*\skvifcsdefTF#1{% + \skvifblankTF{#1}{% \expandafter\@secondoftwo\@gobble }{% \ifcsname#1\endcsname @@ -407,24 +460,25 @@ \fi }% } -\skvnewdef*\skvifcsundef#1{\skvifcsdef{#1}\@secondoftwo\@firstoftwo} +\skvnewdef*\skvifcsdefFT#1{\skvifcsdefTF{#1}\@secondoftwo\@firstoftwo} \def\skv@ifx@#1#2\skv@ifx@nil{\expandafter#1} -\skvnewdef*\skvifx#1#2{% +\def\skv@ifx@@#1#2\skv@ifx@nil{#1} +\skvnewdef*\skvifxTF#1#2{% \csname @\expandafter\expandafter\expandafter - \ifx\skv@ifx@#1\batchmode\skv@ifx@nil\skv@car#2\noboundary\car@nil + \ifx\skv@ifx@#1\batchmode\skv@ifx@nil\skv@ifx@@#2\noboundary\skv@ifx@nil first\else second\fi oftwo\endcsname } -\skvnewdef*\skvnotifx#1#2{\skvifx{#1}{#2}\@secondoftwo\@firstoftwo} +\skvnewdef*\skvifxFT#1#2{\skvifxTF{#1}{#2}\@secondoftwo\@firstoftwo} \skvnewdef*\skv@ghost{\@gobble\skv@ghost} -\skvnewdef\skvifempty#1{% +\skvnewdef\skvifemptyTF#1{% \ifx#1\@empty\skv@ghost \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi } -\skvnewdef\skvifcsempty#1{\expandafter\skvifempty\csname#1\endcsname} -\skvnewdef\skvifdefempty#1{% - \skvifblank{#1}\@secondoftwo{% - \skvifntype{#1}{% - \skvifdef{#1}{\skvifx#1\@empty}{\@secondoftwo}% +\skvnewdef\skvifcsemptyTF#1{\expandafter\skvifemptyTF\csname#1\endcsname} +\skvnewdef\skvifdefemptyTF#1{% + \skvifblankTF{#1}\@secondoftwo{% + \skvifntypeTF{#1}{% + \skvifdefTF{#1}{\skvifxTF#1\@empty}{\@secondoftwo}% }{% \@secondoftwo }% @@ -436,22 +490,21 @@ % Keep lccode, in case the test occurs in a table: \lccode`\&=0 \catcode`\&=8 \lowercase{\endgroup - \skvnewdef\skvifnull#1{% + \skvnewdef\skvifnullTF#1{% \csname @\ifcat&\detokenize{#1}&first\else second\fi oftwo\endcsname } \skvnewdef\skviflacus#1\then{\ifcat&\detokenize{#1}&} } -\skvnewdef\skvifblank#1{% - \expandafter\skvifnull\expandafter{\@gobble#1.}% +\skvnewdef\skvifblankTF#1{% + \expandafter\skvifnullTF\expandafter{\@gobble#1.}% } -\skvnewdef\skvifnotblank#1{\skvifblank{#1}\@secondoftwo\@firstoftwo} -\skvnewdef\iflacuna#1\then{\if\relax\detokenize{#1}\relax} +\skvnewdef\skvifblankFT#1{\skvifblankTF{#1}\@secondoftwo\@firstoftwo} -\skvnewdef*\skvifbool#1{% - \skvifblank{#1}{% +\skvnewdef*\skvifboolTF#1{% + \skvifblankTF{#1}{% \@secondoftwo }{% - \skvifcsdef{if#1}{% + \skvifcsdefTF{if#1}{% \csname @\csname if#1\endcsname first\else second\fi oftwo\endcsname }{% @@ -459,35 +512,33 @@ }% }% } -\skvnewdef*\skvifnotbool#1{\skvifbool{#1}\@secondoftwo\@firstoftwo} -\skvnewdef*\skvifbooltrue#1\then{\csname if#1\endcsname} -\skvnewdef*\skvifboolfalse#1\then{\csname if#1\endcsname\else} -\skvnewdef*\skvifdefbool#1{% +\skvnewdef*\skvifboolFT#1{\skvifboolTF{#1}\@secondoftwo\@firstoftwo} +% \skvifbool sw1\then <true> \else <false> \fi +\skvnewdef*\skvifbool#1\then{\if0\skvifboolTF{#1}01} +\skvnewdef*\skvifdefboolTF#1{% \csname @\csname if#1\endcsname first\else second\fi oftwo\endcsname } -% \skvlogicalif<bool>"<true>"<false>" -\skvnewdef*\skvlogicalif#1"#2"#3"{% - \skvifbool{#1}{#2}{#3}\skvgobbleleadingspaces -} -% \skvifboolval{<toks>}{<true>}{<false>} -\skvrobustdef*\skvifboolval#1{% - \skvxifin{,\expandafter\skvtrimspace\expandafter +\skvnewdef*\skvifdefboolFT#1{\skvifdefboolTF{#1}\@secondoftwo\@firstoftwo} +% \skvifboolvalTF{<toks>}{<true>}{<false>} +\skvrobustdef*\skvifboolvalTF#1{% + \skvxifinTF{,\expandafter\skvtrimspace\expandafter {\detokenize{#1}},}{,\detokenize{true,false},}% } +\skvrobustdef*\skvxifboolvalTF#1{% + \begingroup + \edef\skv@prova{#1}% + \skvdespacecontent\skv@prova + \skvexpandtwoargs{\endgroup\skvifinTF} + {,\skvoxdetok\skv@prova,}{,\detokenize{true,false},}% +} % Generate error if <toks> is not a valid boolean value, otherwise % execute #2: -% \skvifvalidboolval{<toks>}{<true>} -\skvrobustdef*\skvifvalidboolval#1#2{% - \skvxifin{,\expandafter\skvtrimspace\expandafter +% \skvifboolvalT{<toks>}{<true>} +\skvrobustdef*\skvifboolvalT#1#2{% + \skvxifinTF{,\expandafter\skvtrimspace\expandafter {\detokenize{#1}},}{,\detokenize{true,false},}% {#2}{\skv@badboolerr{#1}}% } -\skvrobustdef*\skvxifboolval#1{% - \begingroup - \edef\skv@prova{#1}% - \skvexpandtwoargs{\endgroup\skvifin} - {,\skvoxdetok\skv@prova,}{,\detokenize{true,false},}% -} % Convert bool value (true or false) to switch value (00 or 01): \skvrobustdef*\skvbooltoswitch#1#2{% \begingroup @@ -505,74 +556,116 @@ \skv@err{Invalid boolean value '#1'; expected 'true' or 'false'}\@ehd } -% All switch functions of skeyval pacakge operate on a command -% and not on csname. -\skvnewdef*\skvnewswitch#1{% - \skvifcsdef{skv@sw@#1}{% +% Switches and toggles have separate namespaces. +\skvrobustdef*\skvnewswitch#1{% + \skvifcsdefTF{skv@switch@#1}{% \skv@err{Switch '\detokenize{#1}' already exists}\@ehd }{% - \skvcsdef{skv@sw@#1}{01}% + \skvcsdef{skv@switch@#1}{01}% }% } -\skvnewdef*\skvifswitch#1{% +\skvnewdef*\skvifswitchTF#1{% \if - \skvifcsdef{skv@sw@#1}{% - \csname skv@sw@#1\endcsname - \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + \skvifcsdefTF{skv@switch@#1}{% + \csname skv@switch@#1\endcsname }{% 01% }% + \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi +} +\skvnewdef*\skvifdefswitchTF#1{% + \if\csname skv@switch@#1\endcsname + \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi } -\skvnewdef*\skvswitchtrue#1{% - \skvifcsdef{skv@sw@#1}{% - \skvcsdef{skv@sw@#1}{00}% +\skvrobustdef*\skvswitchtrue#1{% + \skvifcsdefTF{skv@switch@#1}{% + \skvcsdef{skv@switch@#1}{00}% }{% \skv@err{No switch '\detokenize{#1}'}\@ehd }% } -\skvnewdef*\skvswitchfalse#1{% - \skvifcsdef{skv@sw@#1}{% - \skvcsdef{skv@sw@#1}{01}% +\skvrobustdef*\skvswitchfalse#1{% + \skvifcsdefTF{skv@switch@#1}{% + \skvcsdef{skv@switch@#1}{01}% }{% \skv@err{No switch '\detokenize{#1}'}\@ehd }% } - -\begingroup -\def\x#1{\endgroup - \skvnewdef*\skvnegatesw##1{% - 0\ifcase##11#1\or\expandafter1\else\expandafter0\fi +\skvrobustdef*\skvnewtog#1{% + \skvifcsdefTF{skv@toggle@#1}{% + \skv@err{Switch '\detokenize{#1}' already exists}\@ehd + }{% + \skvcslet{skv@toggle@#1}\@secondoftwo }% - \skvnewdef*\skvifbothswtrue##1##2{% - 0\ifcase##1##2#1\expandafter0\else\expandafter1\fi +} +\skvrobustdef*\skvdeftog#1{\skvcslet{skv@toggle@#1}\@secondoftwo} +\skvnewdef*\skviftogTF#1{% + \skvifcsdefTF{skv@toggle@#1}{% + \csname skv@toggle@#1\endcsname + }{% + \@secondoftwo + }% +} +\skvnewdef*\skviftogFT#1{\skviftogTF{#1}\@secondoftwo\@firstoftwo} +\skvnewdef*\skvifdeftogTF#1{\csname skv@toggle@#1\endcsname} +\skvrobustdef*\skvsettogtrue#1{% + \skvifcsdefTF{skv@toggle@#1}{% + \skvcslet{skv@toggle@#1}\@firstoftwo + }{% + \skv@err{No toggle '\detokenize{#1}'}\@ehd }% - \skvnewdef*\skvifoneswtrue##1##2{% - 0\ifnum##1##2<101#1\expandafter0\else\expandafter1\fi +} +\skvrobustdef*\skvsettogfalse#1{% + \skvifcsdefTF{skv@toggle@#1}{% + \skvcslet{skv@toggle@#1}\@secondoftwo + }{% + \skv@err{No toggle '\detokenize{#1}'}\@ehd }% } -\x{ } -\skvnewdef\skvifcond#1\fi{% +% plasw=plain switch (ie, 00 or 01). +\skvnewdef*\skvifplaswTF#1{% + \if#1\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi +} +\skvnewdef*\skvifplaswFT#1{% + \if#1\expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi +} +% \def\swa{01} \def\swb{01} +% \if\skvnegateplasw\swa...\else...\fi +% \if\skvifbothplaswtrue\swa\swb...\else...\fi +% \if\skvifoneplaswtrue\swa\swb...\else...\fi +\skvnewdef*\skvnegateplasw#1{0\skvifplaswTF{#1}10}% +\skvnewdef*\skvifbothplaswtrue#1#2{% + 0\ifcase#1#2 \expandafter0\else\expandafter1\fi +} +\skvnewdef*\skvifoneplaswtrue#1#2{% + 0\ifnum#1#2<101 \expandafter0\else\expandafter1\fi +} + +\skvnewdef\skvifcondTF#1\fi{% \csname @#1first\else second\fi oftwo\endcsname } -\skvnewdef\skvifnotcond#1\fi{\skvifcond{#1}\fi\@secondoftwo\@firstoftwo} -% Maybe #1 isn't expandable: -\skvnewdef\skvifcondition#1\fi{% +\skvnewdef\skvifcondFT#1\fi{\skvifcondTF{#1}\fi\@secondoftwo\@firstoftwo} +% In case #1 isn't expandable. This is the difference between +% \skvifcondTF and \skvifconditionTF. +\skvnewdef\skvifconditionTF#1\fi{% #1\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } -\skvnewdef*\skvifnum#1#{\skvifcond\ifnum#1\fi} +\skvnewdef*\skvifnumTF#1#{\skvifcondTF\ifnum#1\fi} +\skvnewdef*\skvifdim#1#{\skvifcondTF\ifdim#1\fi} +\skvnewdef*\skvifnumFT#1#{\skvifnumTF#1{\@secondoftwo}{\@firstoftwo}} \skvnewdef\skvalloftwo#1#2{#1#2} % If '#1' is a single, non-space and non-braced token: -\skvnewdef\skvifntype#1{% +\skvnewdef\skvifntypeTF#1{% \csname @\if0\skv@strcmp {\skvexpandonce{\skvalloftwo#1{}{}}}{\unexpanded{#1{}}}% first\else second\fi oftwo\endcsname } -\skvnewdef\skvxifntype{\skvexpandarg\skvifntype} +\skvnewdef\skvxifntypeTF{\skvexpandarg\skvifntypeTF} \skvrobustdef*\skvundef#1{\let#1\@undefined} \skvrobustdef*\skvgundef#1{\global\let#1\@undefined} \skvrobustdef*\skvcsundef#1{\skvcslet{#1}\@undefined} @@ -583,38 +676,45 @@ \skvrobustdef*\skvemptifycmds#1{% \skvcommaparse{#1}\skv@prova{\expandafter\def\skv@prova{}}% } -\skvifdef\pdfstrcmp{% +\skvrobustdef*\skvemptify#1{\def\do##1{\def##1{}}#1} +\skvrobustdef*\skvdumpgarbage{% + \let\gdl\skvgundef + \let\dl\skvundef + \skv@garbagelist + \def\skv@garbagelist{}% +} +% \skvgarbageitems{\dl<cmd1>\gdl<cmd2>...} +\skvrobustdef*\skvgarbageitems{\skvappto\skv@garbagelist} +\skvifdefTF\pdfstrcmp{% \let\skv@strcmp\pdfstrcmp }{% \RequirePackage{pdftexcmds}% - \skvifdef\pdf@strcmp{% + \skvifdefTF\pdf@strcmp{% \let\skv@strcmp\pdf@strcmp }{% \skv@err{Neither '\string\pdfstrcmp' nor '\string\pdf@strcmp' exists}\@ehd }% } -\skvnewdef\skvifstrcmp#1#2{% +\skvnewdef\skvifstrcmpTF#1#2{% \csname @\ifnum\skv@strcmp{\detokenize{#1}}% {\detokenize{#2}}=0first\else second\fi oftwo\endcsname } -\skvnewdef\skvifstreq#1\with#2\then{% +\skvnewdef*\skvifstrcmpFT#1#2{\skvifstrcmpTF{#1}{#2}\@secondoftwo\@firstoftwo} +\skvnewdef\skvifstreq#1#2\then{% \ifnum\skv@strcmp{\detokenize{#1}}{\detokenize{#2}}=\skvz@ } -% \ifskvstreq may be used in, eg, \newforeach, where every user-given -% conditional must start with \if...: -\skvnewlet\ifskvstreq\skvifstreq -\skvnewdef\skvoifstrcmp#1#2{% +\skvnewdef\skvoifstrcmpTF#1#2{% \csname @\ifnum\skv@strcmp{\skvexpandonce{#1}}% {\skvexpandonce{#2}}=0first\else second\fi oftwo\endcsname } -\skvnewdef\skvxifstrcmp#1#2{% +\skvnewdef\skvxifstrcmpTF#1#2{% \csname @\ifnum\skv@strcmp{#1}{#2}=0first\else second\fi oftwo\endcsname } \skvrobustdef\skvcslet#1#2{\expandafter\let\csname#1\endcsname#2} \skvrobustdef\skvnewcslet#1{% - \skvifcsdef{#1}{% + \skvifcsdefTF{#1}{% \skv@err{Command '\skvnoexpandcs{#1}' already defined}\@ehd }{% \skvcslet{#1}% @@ -625,7 +725,7 @@ \let\expandafter#1\csname#2\endcsname } \skvrobustdef\skvnewletcs#1{% - \skvifdef{#1}{% + \skvifdefTF{#1}{% \skv@err{Command '\string#1' already defined}\@ehd }{% \skvletcs#1% @@ -637,7 +737,7 @@ \endcsname\csname#2\endcsname } \skvrobustdef\skvnewcsletcs#1{% - \skvifcsdef{#1}{% + \skvifcsdefTF{#1}{% \skv@err{Command '\skvnoexpandcs{#1}' already defined}\@ehd }{% \skvcsletcs{#1}% @@ -694,8 +794,8 @@ \skvrobustdef*\skvsetnumber#1{% \begingroup - \def#1{\edef#1{\endgroup\def\noexpand#1{\the\count@}}#1}% - \afterassignment#1\count@ + \def\x{\edef\x{\endgroup\def\noexpand#1{\the\count@}}\x}% + \afterassignment\x\count@ } \skvnewlet\skvsetno\skvsetnumber \skvrobustdef*\skvadvanceno{\skv@advanceno\relax} @@ -705,21 +805,21 @@ \begingroup \count@#3\relax \endgroup - \skvifdef#2{% + \skvifdefTF#2{% #1\edef#2{\the\numexpr#2+#3\relax}% }{% \skv@err{Number '\string#2' is not defined}\@ehd }% } \skvrobustdef*\skvpushnumber#1{% - \skvifdef#1{% + \skvifdefTF#1{% \edef#1{\the\numexpr#1+1\relax}% }{% \def#1{0}% }% } \skvrobustdef*\skvpopnumber#1{% - \skvifdef#1{% + \skvifdefTF#1{% \edef#1{\the\numexpr#1+1\relax}% }{% \skv@err{Number '\string#1' is not defined}\@ehd @@ -736,11 +836,11 @@ % Removing spurious spaces before checking for brace. -% If we were to use \skvtrimspace for \skvifbraced, then the need +% If we were to use \skvtrimspace for \skvifbracedTF, then the need % for double \romannumeral will cause problems of premature expansion. \begingroup \lccode`\&=0 \catcode`\&=7 -\skvnewgdef\skvifbraced#1{% +\skvnewgdef\skvifbracedTF#1{% \expandafter\skv@ifbraced@a\expandafter{% \romannumeral-`\q\skv@ifbraced@b.#1& &% }% @@ -748,15 +848,15 @@ \skvnewgdef\skv@ifbraced@a#1{\skv@ifbraced@d#1\brace@nil{#1}} \skvnewgdef\skv@ifbraced@b#1 &{\skv@ifbraced@c#1&} \skvnewgdef\skv@ifbraced@c#1{% - \expandafter\skvifldspace\expandafter{\@gobble#1}% + \expandafter\skvifldspaceTF\expandafter{\@gobble#1}% {\@gobble#1}{\expandafter\@space\@gobble#1}% } \skvnewgdef\skv@ifbraced@d#1\brace@nil#2{% - \skvifstrcmp{#1}{#2}\@secondoftwo\@firstoftwo + \skvifstrcmpTF{#1}{#2}\@secondoftwo\@firstoftwo } \endgroup -\skvnewdef\skvifnotbraced#1{\skvifbraced{#1}\@secondoftwo\@firstoftwo} +\skvnewdef\skvifbracedFT#1{\skvifbracedTF{#1}\@secondoftwo\@firstoftwo} % \skvstripouterbraces{<nr>}<cmd> \skvrobustdef*\skvstripouterbraces#1#2{% @@ -766,7 +866,7 @@ } \skvrobustdef*\skv@stripouterbraces#1\strip@nil#2#3{% \advance\@tempcnta\@ne - \skvifnum\@tempcnta=#3{% + \skvifnumTF\@tempcnta=#3{% \edef#2{\unexpanded{#1}}% \skvaftergroupdef#2\endgroup }{% @@ -774,19 +874,19 @@ }% } -\skvrobustdef*\skvifescaped#1{% +\skvrobustdef*\skvifescapedTF#1{% \begingroup\escapechar92\relax \edef\x{\expandafter\skv@car\string#1x\car@nil}% \expandafter\endgroup \csname @\ifx\x\@backslashchar first\else second\fi oftwo\endcsname } -\skvnewdef\skvifnotescaped#1{\skvifescaped{#1}\@secondoftwo\@firstoftwo} +\skvnewdef\skvifnotescaped#1{\skvifescapedTF{#1}\@secondoftwo\@firstoftwo} \skvnewdef*\skvremovescape#1{\expandafter\@gobble\string#1} \skvnewdef*\skvgobblescape#1{% - \skvifblank{#1}{}{% - \skvifnum\escapechar>255{\string#1}{% - \skvifnum\escapechar<0{\string#1}{% - \skvifnum\escapechar=32{% + \skvifblankTF{#1}{}{% + \skvifnumTF\escapechar>255{\string#1}{% + \skvifnumTF\escapechar<0{\string#1}{% + \skvifnumTF\escapechar=32{% \expandafter\@gobblespace\string#1% }{% \skvremovescape{#1}% @@ -828,15 +928,15 @@ \expandafter\skvswap\expandafter{\expandafter{#2}}{#1}% } \skvnewlet\skvexpbracenext\skvexpandbracenext -\skvrobustdef*\skvifin#1#2{% +\skvrobustdef*\skvifinTF#1#2{% \skv@in@{#1}{#2}% \csname @\ifin@ first\else second\fi oftwo\endcsname } -\skvrobustdef*\skvifnotin#1#2{\skvifin{#1}{#2}\@secondoftwo\@firstoftwo} -\skvrobustdef*\skvxifin#1#2{\skvexpandtwoargs\skvifin{#1}{#2}} -\skvrobustdef*\skvxifnotin#1#2{\skvxifin{#1}{#2}\@secondoftwo\@firstoftwo} -\skvrobustdef*\skvifindetok#1#2#3{% - \skvexpandtwoargs\skvifin{#1\skvoxdetok{#2}#1}{#1\skvoxdetok{#3}#1}% +\skvrobustdef*\skvifinFT#1#2{\skvifinTF{#1}{#2}\@secondoftwo\@firstoftwo} +\skvrobustdef*\skvxifinTF#1#2{\skvexpandtwoargs\skvifinTF{#1}{#2}} +\skvrobustdef*\skvxifinFT#1#2{\skvxifinTF{#1}{#2}\@secondoftwo\@firstoftwo} +\skvrobustdef*\skvifindetokTF#1#2#3{% + \skvexpandtwoargs\skvifinTF{#1\skvoxdetok{#2}#1}{#1\skvoxdetok{#3}#1}% } \skvnewdef\skviffound#1\in#2\then{\skv@in@{#1}{#2}\ifin@} \skvnewdef\skvxiffound#1\in#2\then{\skvexpandtwoargs\skv@in@{#1}{#2}\ifin@} @@ -849,6 +949,7 @@ }% \skv@tempa#1==\skv@kvsplit } +\skvrobustdef*\skv@kvosplit#1{\skvexpbracenext\skv@kvsplit{#1}} % \skv@slsplit{<slashlist>}{<parametered.callback>} \skvrobustdef*\skv@slsplit#1#2{% \begingroup @@ -857,6 +958,8 @@ }% \skv@tempa#1/^skv^/^skv^/^skv^/^skv^/^skv^/^skv^/^skv^/\skv@slsplit } +\skvnewlet\skv@slashsplit\skv@slsplit +\skvrobustdef*\skv@slosplit#1{\skvexpbracenext\skv@slsplit{#1}} \skvrobustdef*\skv@rescan#1{% \begingroup @@ -869,15 +972,15 @@ \expandafter\reserved@a\scantokens\expandafter{#1}% } -\skvnewdef*\skvifdigitpresent#1{% - \skvifcond\if0\skvifblank{#1}{1}{\skv@ifdigitpresent#1\skv@nnil}\fi +\skvnewdef*\skvifdigitpresentTF#1{% + \skvifcondTF\if0\skvifblankTF{#1}{1}{\skv@ifdigitpresent#1\skv@nnil}\fi } \skvnewdef*\skv@ifdigitpresent#1{% - \skvifx#1\skv@nnil{% + \skvifxTF#1\skv@nnil{% 1% }{% - \skvifnum`#1>47{% - \skvifnum`#1<58{% + \skvifnumTF`#1>47{% + \skvifnumTF`#1<58{% 0\skv@removetonnil }{% \skv@ifdigitpresent @@ -888,13 +991,13 @@ }% } -\skvnewdef*\skvifalldigit#1{% - \skvifcond\if0\skvifblank{#1}{1}{\skv@ifalldigit#1\skv@nnil}\fi +\skvnewdef*\skvifalldigitTF#1{% + \skvifcondTF\if0\skvifblankTF{#1}{1}{\skv@ifalldigit#1\skv@nnil}\fi } \skvnewdef*\skv@ifalldigit#1{% - \skvifx#1\skv@nnil{0}{% - \skvifnum`#1>47{% - \skvifnum`#1<58{% + \skvifxTF#1\skv@nnil{0}{% + \skvifnumTF`#1>47{% + \skvifnumTF`#1<58{% \skv@ifalldigit }{% 1\skv@removetonnil @@ -905,15 +1008,15 @@ }% } -\skvnewdef*\skvifalphapresent#1{% - \skvifcond\if0\skvifblank{#1}{1}{\skv@ifalphapresent#1\skv@nnil}\fi +\skvnewdef*\skvifalphapresentTF#1{% + \skvifcondTF\if0\skvifblankTF{#1}{1}{\skv@ifalphapresent#1\skv@nnil}\fi } \skvnewdef*\skv@ifalphapresent#1{% - \skvifx#1\skv@nnil{% + \skvifxTF#1\skv@nnil{% 1% }{% - \skvifnum`#1>96{% - \skvifnum`#1<123{% + \skvifnumTF`#1>96{% + \skvifnumTF`#1<123{% 0\skv@removetonnil }{% \skv@ifalphapresent @@ -923,15 +1026,15 @@ }% }% } -\skvnewdef*\skvifAlphapresent#1{% - \skvifcond\if0\skvifblank{#1}{1}{\skv@ifAlphapresent#1\skv@nnil}\fi +\skvnewdef*\skvifAlphapresentTF#1{% + \skvifcondTF\if0\skvifblankTF{#1}{1}{\skv@ifAlphapresent#1\skv@nnil}\fi } \skvnewdef*\skv@ifAlphapresent#1{% - \skvifx#1\skv@nnil{% + \skvifxTF#1\skv@nnil{% 1% }{% - \skvifnum`#1>64{% - \skvifnum`#1<91{% + \skvifnumTF`#1>64{% + \skvifnumTF`#1<91{% 0\skv@removetonnil }{% \skv@ifAlphapresent @@ -941,12 +1044,12 @@ }% }% } -\skvnewdef*\skvifprimitive#1{% +\skvnewdef*\skvifprimitiveTF#1{% \expandafter\skv@ifprimitive\meaning#1\relax } \skvnewdef*\skv@ifprimitive#1#2\relax{% - \skvifcond\if#1\@backslashchar\fi{% - \skvifdigitpresent{#2}\@secondoftwo\@firstoftwo + \skvifcondTF\if#1\@backslashchar\fi{% + \skvifdigitpresentTF{#2}\@secondoftwo\@firstoftwo }{% \@secondoftwo }% @@ -959,13 +1062,13 @@ \def\x##1{\skvnoexpandcs{skv@\skvremovescape#1test@##1}}% \edef\x{\endgroup \def\noexpand#2####1{% - \unexpanded{\skvifx#1{##1}\@secondoftwo}{% - \unexpanded{\skvifprimitive{##1}\@secondoftwo}% + \unexpanded{\skvifxTF#1{##1}\@secondoftwo}{% + \unexpanded{\skvifprimitiveTF{##1}\@secondoftwo}% {\noexpand\expandafter\x{a}\noexpand\meaning####1:&}% }% }% \def\x{a}####1:####2&{\x{b}####1\string#1&}% - \def\x{b}####1\string#1####2&{\noexpand\skvifblank{####1}}% + \def\x{b}####1\string#1####2&{\noexpand\skvifblankTF{####1}}% }\x } \endgroup @@ -983,15 +1086,16 @@ } % If all the tokens are digits or arithmetic: -\skvnewdef*\skvifallarithmetic#1{% +\skvnewdef*\skvifallarithmeticTF#1{% \begingroup \skv@swatrue \skvifdimensionable{#1}{}{% \ifskv@isinteger\else \def\do##1##2{% \ifx\do##1\else - \skvifin{##1}{0123456789.+-*/()}{}{% - \skvifin{,##1##2,}{,em,ex,in,pt,pc,cm,mm,dd,cc,nd,nc,bp,sp,}{}{% + \skvifinTF{##1}{0123456789.+-*/()}{}{% + \skvifinTF{,##1##2,} + {,em,ex,in,pt,pc,cm,mm,dd,cc,nd,nc,bp,sp,}{}{% \skv@swafalse \def\do####1\skvrelax{}% }% @@ -1032,7 +1136,7 @@ \skvnewregister\bool\ifskv@isinteger -% In case the argument of \skvifinteger containes \numexpr: +% In case the argument of \skvifintegerTF containes \numexpr: \skvnewlet\skv@catch@nil\relax % #1: Essence, #2: Test token \skvrobustdef*\skvensureinteger#1#2{% @@ -1050,34 +1154,34 @@ \skvrobustdef*\skv@catchremainder#1\skv@catch@nil{% \endgroup\def\skv@elt{#1}% } -\skvrobustdef*\skvifinteger#1{% +\skvrobustdef*\skvifintegerTF#1{% \begingroup % Don't try '\numexpr0+#1' here: \afterassignment\skv@catchremainder \@tempcnta\numexpr0#1\relax\skv@catch@nil - \skvifx\skv@elt\@empty{% + \skvifxTF\skv@elt\@empty{% \@firstoftwo }{% - \skvifx\skv@elt\skv@relaxtoks\@firstoftwo\@secondoftwo + \skvifxTF\skv@elt\skv@relaxtoks\@firstoftwo\@secondoftwo }% } -\skvrobustdef\skvoifinteger{\skvexpbracenext\skvifinteger} +\skvrobustdef\skvoifinteger{\skvexpbracenext\skvifintegerTF} \skvrobustdef\skvifdimensionable#1{% \def\skv@dimunit{}% % Does 'pt' mean 0pt or 1pt? Make it an invalid input: - \lowercase{\skvifindetok{,}{#1}}\skv@validunit{% + \lowercase{\skvifindetokTF{,}{#1}}\skv@validunit{% \@latexerr{Illegal step '#1': no number found with it}\@ehd }{}% \skv@isintegerfalse - \skvifinteger{#1}{% + \skvifintegerTF{#1}{% \skv@isintegertrue\@secondoftwo }{% \expandafter\skv@ifdimensionable\skv@elt\skv@catch@nil }% } \skvrobustdef\skv@ifdimensionable#1#2\skv@catch@nil{% - \skvifx\relax#1{% - \skvifblank{#2}{% + \skvifxTF\relax#1{% + \skvifblankTF{#2}{% \skv@isintegertrue\@secondoftwo }{% \expandafter\skv@findunit\skv@elt\skv@catch@nil @@ -1098,7 +1202,7 @@ \expandafter\@secondoftwo \fi }% - \skvifstrcmp{.}{#1}{% + \skvifstrcmpTF{.}{#1}{% % In this case, #1 must have come with a trailing \relax. % Remove it and re-start the test: \def\skv@prova##1##2\relax\skv@catch@nil{% @@ -1107,13 +1211,13 @@ \skv@prova#2#3\skv@catch@nil }{% % Check for a valid unit. May be a \dimendef'd token. - \skvifin{,#1,}{,\hsize,\vsize,}{% + \skvifinTF{,#1,}{,\hsize,\vsize,}{% \skv@provb }{% \skvifdimen{#1}{% \skv@provb }{% - \lowercase{\skvifindetok{,}{#1#2}}\skv@validunit{% + \lowercase{\skvifindetokTF{,}{#1#2}}\skv@validunit{% \def\skv@dimunit{#1#2}% % Check if #3 has only one (leading) \relax: \def\skv@prova##1##2##3\skv@catch@nil{% @@ -1167,66 +1271,66 @@ \skv@dimexpr@true\skv@dimexpr@false } \skvrobustdef*\skv@dimexpr@end@end{% - \skvifnum\@tempcnta<\skvz@ + \skvifnumTF\@tempcnta<\skvz@ {\endgroup\@secondoftwo}{\endgroup\@firstoftwo}% } \skvrobustdef*\skv@dimexpr@true{\advance\@tempcnta\skvz@} \skvrobustdef*\skv@dimexpr@false{\advance\@tempcnta\m@ne} \skvrobustdef*\skv@dimexpr@bgroup#1(#2\skv@catch@nil{% \skv@dimexpr@egroup#1)\skv@catch@nil - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \skv@dimexpr@beg \skv@dimexpr@bgroup#2\skv@catch@nil }% } \skvrobustdef*\skv@dimexpr@egroup#1)#2\skv@catch@nil{% \skv@dimexpr@plus#1+\skv@catch@nil - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \skv@dimexpr@end \skv@dimexpr@egroup#2\skv@catch@nil }% } \skvrobustdef*\skv@dimexpr@plus#1+#2\skv@catch@nil{% \skv@dimexpr@minus#1-\skv@catch@nil - \skvifblank{#2}{}{\skv@dimexpr@plus#2\skv@catch@nil}% + \skvifblankTF{#2}{}{\skv@dimexpr@plus#2\skv@catch@nil}% } \skvrobustdef*\skv@dimexpr@minus#1-#2\skv@catch@nil{% - \skvifblank{#1}{}{% - \skvifin{*}{#1}{% - \skvifin{/}{#1}{% + \skvifblankTF{#1}{}{% + \skvifinTF{*}{#1}{% + \skvifinTF{/}{#1}{% \skv@err{I can't parse this: both star (*) and slash \MessageBreak (/) are in '#1'}\@ehd }{% - \skvifblank{#1}{}{\skv@dimexpr@times#1*\skv@catch@nil}% + \skvifblankTF{#1}{}{\skv@dimexpr@times#1*\skv@catch@nil}% }% }{% - \skvifblank{#1}{}{\skv@dimexpr@divide#1/\skv@catch@nil}% + \skvifblankTF{#1}{}{\skv@dimexpr@divide#1/\skv@catch@nil}% }% }% - \skvifblank{#2}{}{\skv@dimexpr@minus#2\skv@catch@nil}% + \skvifblankTF{#2}{}{\skv@dimexpr@minus#2\skv@catch@nil}% } % Because of, eg, 2pt*3/2, the test for * is more subtle: \skvrobustdef*\skv@dimexpr@times#1*#2\skv@catch@nil{% - \skvifblank{#1}{}{% + \skvifblankTF{#1}{}{% \skvifdimensionable{#1}\skv@dimexpr@true\skv@dimexpr@false }% - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \def\skv@prova##1*##2\skv@catch@nil{##1}% \skvexpbracenext\skv@dimexpr@integer{\skv@prova#2\skv@catch@nil}% }% } \skvrobustdef*\skv@dimexpr@divide#1/#2\skv@catch@nil{% - \skvifblank{#1}{}{% + \skvifblankTF{#1}{}{% \skvifdimensionable{#1}\skv@dimexpr@true\skv@dimexpr@false }% - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \def\skv@prova##1/##2\skv@catch@nil{##1}% \skvexpbracenext\skv@dimexpr@integer{\skv@prova#2\skv@catch@nil}% }% } \skvrobustdef*\skv@dimexpr@integer#1{% - \skvifblank{#1}{}{% - \skvifinteger{#1}\skv@dimexpr@true\skv@dimexpr@false + \skvifblankTF{#1}{}{% + \skvifintegerTF{#1}\skv@dimexpr@true\skv@dimexpr@false }% } @@ -1235,7 +1339,7 @@ \begingroup % The following \relax will not be cat-12, so it won't appear in #2: \def\skv@trim@a{% - \skvxifin{\detokenize{#1}\relax}{\skvoxdetok{#2}\relax}{% + \skvxifinTF{\detokenize{#1}\relax}{\skvoxdetok{#2}\relax}{% \def\skv@trim@b####1#1\normal@nil{% \edef#2{\unexpanded{####1}}% \skv@trim@a @@ -1263,7 +1367,7 @@ {\romannumeral-`\q\skv@tsvnormalize.#1 \normal@nil}% } \skvnewdef*\skv@tsvnormalize#1 #2\normal@nil{% - \skvifblank{#2} + \skvifblankTF{#2} {\expandafter\expandafter\expandafter\space \expandafter\noexpand\@gobble#1} {\skv@tsvnormalize#1#2\normal@nil}% @@ -1337,8 +1441,8 @@ \skv@activeparser#1##1#1~\normal@nil}% }% \def\skv@activeparser##1~##2\normal@nil{% - \skvifblank{##2}{% - \skvifswitch{inkv}{% + \skvifblankTF{##2}{% + \skvifdefswitchTF{inkv}{% \skv@activeequal##1!\normal@nil }{% \skv@spaceparser##1 #1\normal@nil @@ -1348,7 +1452,7 @@ }% }% \def\skv@activeequal##1!##2\normal@nil{% - \skvifblank{##2}{% + \skvifblankTF{##2}{% \skv@spaceparser##1 #1\normal@nil }{% \skv@activeequal##1=##2\normal@nil @@ -1356,15 +1460,15 @@ }% }% \def\skv@spaceparser##1 #1##2\normal@nil{% - \skvifblank{##2}{% + \skvifblankTF{##2}{% \skv@parserspace##1#1 \normal@nil }{% \skv@spaceparser##1#1##2\normal@nil }% }% \def\skv@parserspace##1#1 ##2\normal@nil{% - \skvifblank{##2}{% - \skvifswitch{inkv}{% + \skvifblankTF{##2}{% + \skvifdefswitchTF{inkv}{% \skv@spaceequal##1 =\normal@nil }{% \skv@doubleparser##1#1#1\normal@nil @@ -1374,25 +1478,25 @@ }% }% \def\skv@spaceequal##1 =##2\normal@nil{% - \skvifblank{##2}{% + \skvifblankTF{##2}{% \skv@equalspace##1= \normal@nil }{% \skv@spaceequal##1=##2\normal@nil }% }% \def\skv@equalspace##1= ##2\normal@nil{% - \skvifblank{##2}{% + \skvifblankTF{##2}{% \skv@doubleparser##1#1#1\normal@nil }{% \skv@equalspace##1=##2\normal@nil }% }% \def\skv@doubleparser##1#1#1##2\normal@nil{% - \skvifblank{##2}{% - \skvifswitch{inkv}{% + \skvifblankTF{##2}{% + \skvifdefswitchTF{inkv}{% \skv@doubleequal##1==\normal@nil }{% - \skvifblank{##1}{}{% + \skvifblankTF{##1}{}{% \skv@remleadparser##1\normal@nil }% }% @@ -1401,8 +1505,8 @@ }% }% \def\skv@doubleequal##1==##2\normal@nil{% - \skvifblank{##2}{% - \skvifblank{##1}{}{% + \skvifblankTF{##2}{% + \skvifblankTF{##1}{}{% \skv@remleadparser##1\normal@nil }% }{% @@ -1413,7 +1517,7 @@ \expandafter\space\noexpand##1% }% \def\skv@parserequalerr##1#1=##2\normal@nil{% - \skvifblank{##2}{}{% + \skvifblankTF{##2}{}{% \skv@err{There is '#1=' in your key-value list}\@ehd }% }% @@ -1431,19 +1535,19 @@ \skv@activeslash#1~\normal@nil}% }% \skvnewdef\skv@activeslash#1~#2\normal@nil{% - \skvifblank{#2} + \skvifblankTF{#2} {\skv@spaceslash#1 /\normal@nil} {\skv@activeslash#1/#2\normal@nil}% }% } \skvnewdef\skv@spaceslash#1 /#2\normal@nil{% - \skvifblank{#2} + \skvifblankTF{#2} {\skv@slashspace#1/ \normal@nil} {\skv@spaceslash#1/#2\normal@nil}% } \skvnewdef\skv@slashspace#1/ #2\normal@nil{% - \skvifblank{#2} - {\skvifblank{#1}{}{\expandafter\space\noexpand#1}} + \skvifblankTF{#2} + {\skvifblankTF{#1}{}{\expandafter\space\noexpand#1}} {\skv@slashspace#1/#2\normal@nil}% } @@ -1468,17 +1572,17 @@ \skv@mac@spaceparser##1 #1\normal@nil}% }% \long\def\skv@mac@spaceparser##1 #1##2\normal@nil{% - \skvifblank{##2} + \skvifblankTF{##2} {\skv@mac@parserspace##1#1 \normal@nil} {\skv@mac@spaceparser##1#1##2\normal@nil}% }% \long\def\skv@mac@parserspace##1#1 ##2\normal@nil{% - \skvifblank{##2} + \skvifblankTF{##2} {\skv@mac@doubleparser##1#1#1\normal@nil} {\skv@mac@parserspace##1#1##2\normal@nil}% }% \long\def\skv@mac@doubleparser##1#1#1##2\normal@nil{% - \skvifblank{##2}{ ##1} + \skvifblankTF{##2}{ ##1} {\skv@mac@doubleparser##1#1##2\normal@nil}% }% } @@ -1488,7 +1592,7 @@ \begingroup \def\skv@prova##1{\skvremovescape{##1}@skv@\romannumeral#3}% \def\do##1{\let\noexpand##1\skvnoexpandcs{\skv@prova{##1}}}% - \skvifcsdef{\skvremovescape{#1}@skv@stack}{}{% + \skvifcsdefTF{\skvremovescape{#1}@skv@stack}{}{% \skvcsdef{\skvremovescape{#1}@skv@stack}{}% }% \skvcsxdef{\skvremovescape{#1}@skv@stack}{% @@ -1501,7 +1605,7 @@ \skvrobustdef*\skvpopfunctions#1#2{% \begingroup \edef\skv@elt{\skvnoexpandcs{\skvremovescape{#1}@skv@stack}}% - \expandafter\skvifdef\skv@elt{% + \expandafter\skvifdefTF\skv@elt{% \expandafter\ifx\skv@elt\@empty \skv@err{Stack of '\noexpand#1' is empty}\@ehd \fi @@ -1528,7 +1632,7 @@ \def\skv@loop{% \advance\@tempcnta\@ne % Don't use \ifnum here, because #2 may contain booleans. - \skvifnum\@tempcnta<\numexpr#3+1\relax{% + \skvifnumTF\@tempcnta<\numexpr#3+1\relax{% \edef#1{\skvexpandonce#1.\romannumeral\@tempcnta.{#2}}% \skv@loop }{}% @@ -1572,7 +1676,7 @@ \skvcsvnormalize\skv@prova \def\do##1,{% \ifx\do##1\else - \skvifcsdef{if#1##1}{% + \skvifcsdefTF{if#1##1}{% \skv@err{Boolean '\skvnoexpandcs{if#1##1}' already exists}\@ehd }{% \toks@\expandafter{\the\expandafter\toks@ @@ -1588,12 +1692,12 @@ % Some checks are done in that section. \skvnewbools[skv@]{% - inset,st,cl,pl,kf,inpox,prepo,tracingkeys,swa,swb,% + inset,st,cl,pl,kf,inpox,prepo,tracingkeys,swa,swb,verbose,% intry,insa,success,inoptionsec,inopt,handlerswa,handlerswb% } -\skvnewbools{indirkeys} -\skvnewbools[skv]{indef,novalue,valuebraced} +%\skvnewbools{indirkeys} +\skvnewbools[skv]{indef,indirkeys,novalue,valuebraced} \skvnewbools[dirkeys@]{saveunknownkeys} \skvrobustdef*\skvnewcounts{\skv@testopt\skv@newcounts{}} @@ -1604,7 +1708,7 @@ \skvcsvnormalize\skv@prova \def\do##1,{% \ifx\do##1\else - \skvifcsdef{#1##1}{% + \skvifcsdefTF{#1##1}{% \skv@err{Counter '\skvnoexpandcs{#1##1}' already exists}\@ehd }{% \toks@\expandafter{\the\expandafter\toks@ @@ -1626,7 +1730,7 @@ \skvcsvnormalize\skv@prova \def\do##1,{% \ifx\do##1\else - \skvifcsdef{#1##1}{% + \skvifcsdefTF{#1##1}{% \skv@err{Number '\skvnoexpandcs{#1##1}' already exists}\@ehd }{% \toks@\expandafter{\the\expandafter\toks@ @@ -1655,16 +1759,16 @@ % 3. Package and class options can't be passed via quick keys. % 4. When defining keys, the syntax of <list> is: % -% {<key1,key2,etc>}/{<default>}/{<callback>}/{<choice list>}/{<arg>} +% {<keya-1,...,keya-n>}/{<default>}/{<callback>}/{<choice list>}/{<arg>} % ;...; -% {<key-n>}/{<default>}/{<callback>}/{<choice list>}/{<arg>} +% {<keyb-1,...,keyb-n>}/{<default>}/{<callback>}/{<choice list>}/{<arg>} % % Here, keys key1 and key2 will have the same default value, callback, % choice list and argument pattern. % -% 5. The special key '.exec' will simply execute the code <default>, -% without defining anything. -% 6. Use .na to indicate a missing item that isn't blank. +% 5. The special keys '.exec' and '.exec code' will simply execute the +% code <default>, without defining anything. +% 6. Use .na to indicate a missing item that isn't blank or empty. % % Example: % \quickkeys.define{fam}[mp@]{% @@ -1673,36 +1777,73 @@ % keyc,keyd/aaa+bbb/\def\x##1{#1*##1*#2}/.na/#1+#2; % } % -\skvnewdef*\skv@ifrejorempty#1{% - \skvifstrcmp{#1}{^skv^}{% +\skvnewdef*\skv@ifstrrejorempty#1{% + \skvifstrcmpTF{#1}{^skv^}{% \@firstoftwo }{% - \skvifblank{#1}{% + \skvifblankTF{#1}{% \@firstoftwo }{% \@secondoftwo }% }% } -\skvnewdef*\skv@ifrejorna#1{% - \skvifstrcmp{#1}{^skv^}{% +\skvnewdef*\skv@ifstrrejordotna#1{% + \skvifstrcmpTF{#1}{^skv^}{% \@firstoftwo }{% - \skvifstrcmp{#1}{.na}{% + \skvifstrcmpTF{#1}{.na}{% \@firstoftwo }{% \@secondoftwo }% }% } -\skvnewdef*\skv@ifrejornaorempty#1{% - \skvifstrcmp{#1}{^skv^}{% +\skvnewdef*\skv@ifstrnut#1{% + \skvifstrcmpTF{#1}{^skv^}{% \@firstoftwo }{% - \skvifstrcmp{#1}{.na}{% + \skvifstrcmpTF{#1}{.na}{% \@firstoftwo }{% - \skvifblank{#1}{% + \skvifblankTF{#1}{% + \@firstoftwo + }{% + \@secondoftwo + }% + }% + }% +} +\skvnewdef*\skv@ifcmdrejorempty#1{% + \skvifxTF#1\skv@rej{% + \@firstoftwo + }{% + \skvifemptyTF#1{% + \@firstoftwo + }{% + \@secondoftwo + }% + }% +} +\skvnewdef*\skv@ifcmdrejordotna#1{% + \skvifxTF#1\skv@rej{% + \@firstoftwo + }{% + \skvifxTF#1\skv@dotna{% + \@firstoftwo + }{% + \@secondoftwo + }% + }% +} +\skvnewdef*\skv@ifcmdnut#1{% + \skvifxTF#1\skv@rej{% + \@firstoftwo + }{% + \skvifxTF#1\skv@dotna{% + \@firstoftwo + }{% + \skvifemptyTF#1{% \@firstoftwo }{% \@secondoftwo @@ -1713,11 +1854,11 @@ \skvrobustdef*\quickkeys#1#{% \edef\skv@tempa{\skvtrimspace{#1}}% - \skvxifstrcmp{\skvexpandonce\skv@tempa}{.define}{% + \skvxifstrcmpTF{\skvexpandonce\skv@tempa}{.define}{% \begingroup\endlinechar\m@ne \skv@defquickkeys }{% - \skvxifstrcmp{\skvexpandonce\skv@tempa}{.set}{% + \skvxifstrcmpTF{\skvexpandonce\skv@tempa}{.set}{% \skv@setquickkeys }{% \skv@err{Unknown task for \string\quickkeys}\@ehd @@ -1729,26 +1870,26 @@ \endgroup \edef\skv@tempa{\skvkeepdoubleslashnormalize{#3}}% \def\skv@defquickkeys@b##1/##2/##3/##4/##5/##6/##7/##8/##9\skv@nil{% - \skvifin{,##1,}{,.exec,.exec code,}{% + \skvifinTF{,##1,}{,.exec,.exec code,}{% ##2\relax }{% % Loop over key list, if there are more than one key: \skvparselist{,}{##1}\skv@tempa{% % If ##2 is empty, the default will be empty: - \skv@ifrejorna{##2}{}{% + \skv@ifstrrejordotna{##2}{}{% \skvcsedef{#1/\skv@tempa/qkeys.def}{\unexpanded{##2}}% }% \skvcsedef{#1/\skv@tempa/qkeys.cbk}{% % ##3 may be empty: - \skv@ifrejorna{##3}{}{\unexpanded{##3}}% + \skv@ifstrrejordotna{##3}{}{\unexpanded{##3}}% }% - \skv@ifrejornaorempty{##4}{}{% + \skv@ifstrnut{##4}{}{% \skvcsedef{#1/\skv@tempa/qkeys.chc}{\unexpanded{##4}}% }% - \skv@ifrejornaorempty{##5}{}{% + \skv@ifstrnut{##5}{}{% \skvcsedef{#1/\skv@tempa/qkeys.arg}{\unexpanded{##5}}% }% - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \skvcsedef{#1/\skv@tempa/qkeys.hp}{\unexpanded{#2}}% }% }% @@ -1772,11 +1913,11 @@ \edef\skv@tempa{\unexpanded{#3}}% \skvkvnormalize\skv@tempa \def\skv@setqkeys##1##2{% - \skvifcsdef{#1/##1/qkeys.cbk}{}{% + \skvifcsdefTF{#1/##1/qkeys.cbk}{}{% \skv@err{Key '#1/##1' is not defined}\@ehd }% - \skvifstrcmp{##2}\skv@novalue{% - \skvifcsdef{#1/##1/qkeys.def}{% + \skvifstrcmpTF{##2}\skv@novalue{% + \skvifcsdefTF{#1/##1/qkeys.def}{% \skvcsletcs{#1/##1/qkeys.val}{#1/##1/qkeys.def}% }{% \skv@err{No user value and no default @@ -1785,20 +1926,20 @@ }{% \skvcsedef{#1/##1/qkeys.val}{\unexpanded{##2}}% }% - \skvifcsdef{#1/##1/qkeys.chc}{% + \skvifcsdefTF{#1/##1/qkeys.chc}{% \skvletcs\reserved@a{#1/##1/qkeys.chc}% \edef\reserved@b{\skvexpandcsonce{#1/##1/qkeys.val}}% - \skvxifin{,\skvoxdetok\reserved@b,}{,\skvoxdetok\reserved@a,}{}{% + \skvxifinTF{,\skvoxdetok\reserved@b,}{,\skvoxdetok\reserved@a,}{}{% \skv@err{Value '\detokenize{##2}' for key '##1' \MessageBreak is not in prescribed list \MessageBreak '\skvoxdetok\reserved@a'}\@ehd }% }{}% - \skvifcsdef{#1/##1/qkeys.hp}{% + \skvifcsdefTF{#1/##1/qkeys.hp}{% \skvletcs\reserved@a{#1/##1/qkeys.hp}% \skvcsletcs{\reserved@a##1}{#1/##1/qkeys.val}% }{}% - \skvifcsdef{#1/##1/qkeys.arg}{% + \skvifcsdefTF{#1/##1/qkeys.arg}{% \skvletcs\reserved@a{#1/##1/qkeys.arg}% }{% \let\reserved@a\skv@simplearg @@ -1811,7 +1952,7 @@ \reserved@a\csname#1/##1/qkeys.val\endcsname\quickkeyseov }% \def\skv@setquickkeys@c##1=##2=##3\skv@nil{% - \skvxifin{,\detokenize{##1},}{,\skvoxdetok\skv@qkeysna,}{}{% + \skvxifinTF{,\detokenize{##1},}{,\skvoxdetok\skv@qkeysna,}{}{% \skv@setqkeys{##1}{##2}% }% }% @@ -1841,7 +1982,7 @@ % % Example: % -% \skvifcase\skvifstrcmp{c} +% \skvifcase\skvifstrcmpTF{c} % {a}{do a} % {b}{do b} % {c}{do c} @@ -1861,16 +2002,16 @@ % % Example: % -% \skvifexpr{% -% not ( expr { \skvifdef\xa } and expr { \skvifempty\xa } ) -% or ( expr { \skvifbool{@tempswa} } or expr { \skvifx\xa\xb } ) +% \skvifexprTF{% +% not ( expr { \skvifdefTF\xa } and expr { \skvifemptyTF\xa } ) +% or ( expr { \skvifboolTF{@tempswa} } or expr { \skvifxTF\xa\xb } ) % }{% % \def\x{T} % }{% % \def\x{F} % } \skvnewnumbers[skv@]{exprcnt} -\skvrobustdef*\skvifexpr#1{% +\skvrobustdef*\skvifexprTF#1{% \begingroup \def\skv@expr@neg{01}% \skvsetno\skv@exprcnt\skvz@ @@ -1901,45 +2042,45 @@ } \skvrobustdef\skv@expr@bgroup#1(#2\skv@expr@nil{% \skv@expr@egroup#1)\skv@expr@nil - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \skv@expr@beg \skv@expr@bgroup#2\skv@expr@nil }% } \skvrobustdef\skv@expr@egroup#1)#2\skv@expr@nil{% \skv@expr@and#1and\skv@expr@nil - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \skv@expr@end \skv@expr@egroup#2\skv@expr@nil }% } \skvrobustdef\skv@expr@and#1and#2\skv@expr@nil{% \skv@expr@or#1or\skv@expr@nil - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \skv@exprcnt\ifnum\skv@exprcnt<\skvz@\m@ne\else\skvz@\fi \skv@expr@and#2\skv@expr@nil }% } \skvrobustdef\skv@expr@or#1or#2\skv@expr@nil{% \skv@expr@not#1not\skv@expr@nil - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \skv@exprcnt\ifnum\skv@exprcnt<\skvz@\skvz@\else\@ne\fi \skv@expr@or#2\skv@expr@nil }% } \skvrobustdef\skv@expr@not#1not#2\skv@expr@nil{% \skv@expr@do#1expr\skv@expr@nil - \skvifblank{#2}{}{% + \skvifblankTF{#2}{}{% \def\skv@expr@neg{00}% \skv@expr@not#2\skv@expr@nil }% } \skvrobustdef\skv@expr@do#1expr#2\skv@expr@nil{% - \skvifblank{#1}{}{% - \skv@err{Invalid \noexpand\skvifexpr test expression} + \skvifblankTF{#1}{}{% + \skv@err{Invalid \noexpand\skvifexprTF test expression} {The handicapped test part is: '\detokenize{#1}'}% }% - \skvifblank{#2}{}{\skv@expr@do@a#2\skv@expr@nil}% + \skvifblankTF{#2}{}{\skv@expr@do@a#2\skv@expr@nil}% } \skvrobustdef\skv@expr@do@a#1#2\skv@expr@nil{% \ignorespaces#1\skv@expr@true\skv@expr@false @@ -1947,7 +2088,7 @@ } \skvnewdef\skvwhileexpr#1\do#2{% - \skvifcond{#1}\fi{#2\skvwhileexpr{#1}\do{#2}}{}% + \skvifcondTF{#1}\fi{#2\skvwhileexpr{#1}\do{#2}}{}% } \skvbuildmacrostack\skv@keystate{% @@ -1958,25 +2099,31 @@ \do\ifskv@inpox\do\ifskv@prepo }\skv@stackdepthlimit -\skvbuildmacrostack\dirkeys@state{% +\skvbuildmacrostack\skv@dirkeys@state{% \do\dirkeys@prefixlist\do\dirkeys@familylist\do\dirkeys@holderprefixtoks \do\dirkeys@unknownkeysmacro\do\ifdirkeys@saveunknownkeys - \do\ifindirkeys + \do\ifskvindirkeys\do\ifskvdfk@initialize\do\ifskvdfk@saveinitialvalues }\skv@stackdepthlimit -\skvrobustdef*\skvappendtomacro{\skv@testst{\skv@appendtomacro{app}{e}}} -\skvrobustdef*\skvgappendtomacro{\skv@testst{\skv@appendtomacro{app}{x}}} -\skvrobustdef*\skvprependtomacro{\skv@testst{\skv@appendtomacro{pre}{e}}} -\skvrobustdef*\skvgprependtomacro{\skv@testst{\skv@appendtomacro{pre}{x}}} +\skvrobustdef\skvappto#1#2{% + \edef#1{\skvexpandonce{#1}\unexpanded{#2}}% +} +\skvrobustdef\skvgappto#1#2{% + \xdef#1{\skvexpandonce{#1}\unexpanded{#2}}% +} +\skvrobustdef\skvappendtomacro{\skv@testst{\skv@appendtomacro{app}{e}}} +\skvrobustdef\skvgappendtomacro{\skv@testst{\skv@appendtomacro{app}{x}}} +\skvrobustdef\skvprependtomacro{\skv@testst{\skv@appendtomacro{pre}{e}}} +\skvrobustdef\skvgprependtomacro{\skv@testst{\skv@appendtomacro{pre}{x}}} \skvrobustdef\skv@appendtomacro#1#2#3#4{% - \skvifescaped{#3}{% + \skvifescapedTF{#3}{% \@nameuse{#2def}#3{% - \skvifstrcmp{#1}{app}{% - \skvifdef#3{\skvexpandonce#3}{}% - \skvifdefbool{skv@tempst}\skvexpandonce\unexpanded{#4}% + \skvifstrcmpTF{#1}{app}{% + \skvifdefTF#3{\skvexpandonce#3}{}% + \skvifdefboolTF{skv@tempst}\skvexpandonce\unexpanded{#4}% }{% - \skvifdefbool{skv@tempst}\skvexpandonce\unexpanded{#4}% - \skvifdef#3{\skvexpandonce#3}{}% + \skvifdefboolTF{skv@tempst}\skvexpandonce\unexpanded{#4}% + \skvifdefTF#3{\skvexpandonce#3}{}% }% }% }{% @@ -1987,7 +2134,7 @@ % \skvaddlist{<parser>}{<listitem>} % This is usually called under \edef. \skvnewdef*\skvaddlist#1#2{% - \skvifempty#2{}{\skvexpandonce#2\unexpanded{#1}}% + \skvifemptyTF#2{}{\skvexpandonce#2\unexpanded{#1}}% } % \skvxaddtolist{<parser>}{<listcmd>}{<newitem>} \skvrobustdef\skvxaddtolist#1#2#3{% @@ -1998,18 +2145,18 @@ \skvrobustdef*\skvgaddtolist{\skv@teststopt{\skv@addtolist{\global}},} \skvrobustdef\skv@addtolist#1[#2]#3#4{% #1\edef#3{% - \skvifdef#3{% - \skvifempty#3{}{\skvexpandonce#3#2}% + \skvifdefTF#3{% + \skvifemptyTF#3{}{\skvexpandonce#3#2}% }{}% - \skvifdefbool{skv@tempst}\skvexpandonce\unexpanded{#4}% + \skvifdefboolTF{skv@tempst}\skvexpandonce\unexpanded{#4}% }% } % \skv@declarefilter{<filter.type>} \skvrobustdef*\skv@declarefilter#1{% \edef\skv@filter##1##2{% - \skvifblank{#1}{\let##2=##1}{% - \skvifx#1\relax{\let##2=##1}{% - \skvifstrcmp{#1}\nofilter{\let##2=##1}{% + \skvifblankTF{#1}{\let##2=##1}{% + \skvifxTF#1\relax{\let##2=##1}{% + \skvifstrcmpTF{#1}\nofilter{\let##2=##1}{% \unexpanded{#1}{##1}{##2}% }% }% @@ -2025,7 +2172,7 @@ \skvrobustdef*\skv@filtermergelist#1#2#3{% \begingroup \skv@declarefilter{#3}% - \skvifdef#1{\skvkvnormalize#1}{\def#1{}}% + \skvifdefTF#1{\skvkvnormalize#1}{\def#1{}}% \edef\skv@merga{\unexpanded{#2}}% \skvkvnormalize\skv@merga \skvcommaloop*\skv@merga\skv@merga{% @@ -2054,11 +2201,11 @@ \skvrobustdef*\skvmergelist{\skv@testcl\skv@mergelist} \skvrobustdef*\skv@mergelist#1#2{% \begingroup - \skvifdef#1{\skvkvnormalize#1}{\def#1{}}% + \skvifdefTF#1{\skvkvnormalize#1}{\def#1{}}% \edef\skv@tempa{\unexpanded{#2}}% \skvkvnormalize\skv@tempa \skvcommaloop*\skv@tempa\skv@tempa{% - \skvxifin{,\skvoxdetok\skv@tempa,}{,\skvoxdetok#1,}{}{% + \skvxifinTF{,\skvoxdetok\skv@tempa,}{,\skvoxdetok#1,}{}{% \edef#1{\skvaddlist,#1\skvexpandonce\skv@tempa}% }% }% @@ -2072,12 +2219,14 @@ % than \skvfilterremoveelements. % \if@tempswa can be used to test if, at the end, anything was % removed from #1. -\skvrobustdef*\skvfilterremoveelements{\skv@testcl\skv@filterremoveelements} +\skvrobustdef*\skvfilterremoveelements{% + \skv@testcl\skv@filterremoveelements +} \skvrobustdef*\skv@filterremoveelements#1#2#3{% \begingroup \let\skv@origlist#1% \skv@declarefilter{#3}% - \skvifdef#1{\skvkvnormalize#1}{\def#1{}}% + \skvifdefTF#1{\skvkvnormalize#1}{\def#1{}}% \skvcommaparse{#2}\skv@rema\skv@rema{% \skv@filter\skv@rema\skv@remb \let\skv@remc#1\let#1\@empty @@ -2107,12 +2256,12 @@ \skvrobustdef\skv@removeelements#1#2{% \begingroup \let\skv@origlist#1% - \skvifdef#1{}{\def#1{}}% + \skvifdefTF#1{}{\def#1{}}% \edef\skv@rema{\unexpanded{#2}}% \skvcsvnormalize\skv@rema \let\skv@remb#1\let#1\@empty \skvcommaparse*\skv@remb\skv@tempa{% - \skvxifin{,\skvoxdetok\skv@tempa,}{,\skvoxdetok\skv@rema,}{}{% + \skvxifinTF{,\skvoxdetok\skv@tempa,}{,\skvoxdetok\skv@rema,}{}{% \edef#1{\skvaddlist,#1\skvexpandonce\skv@tempa}% }% }% @@ -2138,11 +2287,13 @@ % Example: % \def\cmd{a = 1 , b = 2 , c = 3} % \skvfilterreplaceelements\cmd{{a = 1}{x = 1},{c = 3}{z=3}}\skv@getkeyname -\skvrobustdef*\skvfilterreplaceelements{\skv@testcl\skv@filterreplaceelements} +\skvrobustdef*\skvfilterreplaceelements{% + \skv@testcl\skv@filterreplaceelements +} \skvrobustdef*\skv@filterreplaceelements#1#2#3{% \begingroup \skv@declarefilter{#3}% - \skvifdef#1{\skvkvnormalize#1}{\def#1{}}% + \skvifdefTF#1{\skvkvnormalize#1}{\def#1{}}% \def\do##1##2\skv@nil{% \ifx#3\skv@getkeyname \def\@do####1=####2=####3\skv@nil####4{% @@ -2189,24 +2340,30 @@ \skv@prefix\ifx\skvcurrentfamily\@empty\else\skvcurrentfamily/\fi }% } +\skvrobustdef*\skvdefaultprefix#1{\edef\skv@defaultpref{#1}} +\skvdefaultprefix{KV} \skvrobustdef*\skv@testopta#1{% \skvifstar {\skv@sttrue\skv@t@stopta{#1}}{\skv@stfalse\skv@t@stopta{#1}}% } \skvrobustdef*\skv@t@stopta#1{\skvifplus{\skv@pltrue#1}{\skv@plfalse#1}} -\skvrobustdef*\skv@testoptb#1{\skv@testopt{\skv@t@stoptb{#1}}{KV}} +\skvrobustdef*\skv@testoptb#1{% + \skv@testopt{\skv@t@stoptb{#1}}\skv@defaultpref +} \skvrobustdef*\skv@t@stoptb#1[#2]#3{% \skv@makeprefix{#2}\skv@makeheader{#3}#1% } -\skvrobustdef*\skv@testoptc#1{\skv@testopt{\skv@t@stoptc{#1}}{KV}} +\skvrobustdef*\skv@testoptc#1{% + \skv@testopt{\skv@t@stoptc{#1}}\skv@defaultpref +} \skvrobustdef*\skv@t@stoptc#1[#2]#3{% - \skvxifin{,}{\detokenize{#2}}{% + \skvxifinTF{,}{\detokenize{#2}}{% \skv@err{Only one prefix is allowed here, \MessageBreak but you gave '#2'}\@ehd }{% \skv@makeprefix{#2}% \edef\skv@fams{#3}% - \skvxifin{,}{\detokenize{#3}}{% + \skvxifinTF{,}{\detokenize{#3}}{% \skvcsvnormalize\skv@fams }{% \skvdespacecontent\skv@fams @@ -2214,6 +2371,7 @@ \skv@testopt#1{}% }% } +% \skv@testoptd{<cmd>}{<pre-mp>} \skvrobustdef*\skv@testoptd#1#2{% \skv@testoptb{% \edef\skv@provb{#2\skv@header}% @@ -2221,6 +2379,7 @@ \expandafter\skv@prova\expandafter{\skv@provb}% }% } +% \skv@t@stoptd{<cmd>}[<mp>]{<key>} \skvrobustdef*\skv@t@stoptd#1[#2]#3{% \skvifnextchar[{\skv@sttrue#1{#2}{#3}}{\skv@stfalse#1{#2}{#3}[]}% } @@ -2252,15 +2411,15 @@ } \skvrobustdef*\skv@definedefault#1#2{% \ifskv@inoptionsec\else - \skvxifin{,\skvcurrentprefix,}{,skv,SKV,}{% - \skvxifin{,\skvcurrentfamily,}{,skeyval,}{% + \skvxifinTF{,\skvcurrentprefix,}{,skv,SKV,}{% + \skvxifinTF{,\skvcurrentfamily,}{,skeyval,}{% \skv@err{Prefix/family '\skvcurrentprefix/\skvcurrentfamily' are reserved}\@ehd }{}% }{}% \fi \ifskv@tracingkeys - \skvxifin{,#1,}{,\skv@badkeynames,}{% + \skvxifinTF{,#1,}{,\skv@badkeynames,}{% \skv@err{Key name '#1' not allowed}\@ehd }{}% \fi @@ -2285,18 +2444,18 @@ % create 'needini' lists of families. \skvrobustdef*\skv@recordkey#1#2{% \begingroup - \skvifcsundef{\skv@header.@needini}{% + \skvifcsdefFT{\skv@header.@needini}{% \endgroup\skv@swafalse }{% \skv@swatrue - \skvxifin{,#1,}{,\skvexpandcsonce{\skv@header.@needini},}{% + \skvxifinTF{,#1,}{,\skvexpandcsonce{\skv@header.@needini},}{% \edef\skv@tempa{\skvtrimspace{#2}}% \edef\skv@tempa{% - #1=\skvoifstrcmp{\skv@tempa}{true}{false}{\skvexpandonce\skv@tempa}% + #1=\skvoifstrcmpTF{\skv@tempa}{true}{false}{\skvexpandonce\skv@tempa}% }% \skvletcs\skv@tempb{\skv@header.@inikv}% - \skvifdef\skv@tempb{% - \skvxifin{,\skvoxdetok\skv@tempa,}{,\skvoxdetok\skv@tempb,}{}{% + \skvifdefTF\skv@tempb{% + \skvxifinTF{,\skvoxdetok\skv@tempa,}{,\skvoxdetok\skv@tempb,}{}{% \skvcsedef{\skv@header.@inikv}{% \skvaddlist,\skv@tempb\skvexpandonce\skv@tempa }% @@ -2326,7 +2485,7 @@ \skvrobustdef*\skv@strippointers#1#2{% \begingroup \edef#2{% - \skvifstrcmp{#1}{\skvcurrentkey} + \skvifstrcmpTF{#1}{\skvcurrentkey} {\skvcurrentkey}{\skvtrimspace{#1}}% }% \def\skv@prova{\expandafter\skv@findpointer\expandafter}% @@ -2336,48 +2495,41 @@ % after each call to \skv@findpointer, we want to use the latest % meaning of #2. \def\do{}% + \def\skv@add##1{% + \edef\do{\skvexpandonce\do\unexpanded{##1}}% + }% \skv@prova{#2}{.need value}#2{% - \def\do{\skvcsdef{\skv@header#2.@ndv}{00}}% + \skv@add{\skvcsdef{\skv@header#2.@ndv}{00}}% }{% - \skv@prova{#2}{.require value}#2{% - \def\do{\skvcsdef{\skv@header#2.@ndv}{00}}% + \skv@prova{#2}{.forbid value}#2{% + \skv@add{\skvcsdef{\skv@header#2.@fbv}{00}}% }{% - \skv@prova{#2}{.value required}#2{% - \def\do{\skvcsdef{\skv@header#2.@ndv}{00}}% + \skv@prova{#2}{.expanded}#2{% + \edef#2{#2}% }{% - \skv@prova{#2}{.forbid value}#2{% - \def\do{\skvcsdef{\skv@header#2.@fbv}{00}}% + \skv@prova{#2}{.expand once}#2{% + \edef#2{\skvexpandtwice{#2}}% }{% - \skv@prova{#2}{.value forbidden}#2{% - \def\do{\skvcsdef{\skv@header#2.@fbv}{00}}% - }{% - \skv@prova{#2}{.expanded}#2{% - \edef#2{#2}% - }{% - \skv@prova{#2}{.expand once}#2{% - \edef#2{\skvexpandtwice{#2}}% - }{% - \skv@prova{#2}{.expand twice}#2{% - \edef#2{\skvexpandthrice{#2}}% - }{}% - }% - }% - }% + \skv@prova{#2}{.expand twice}#2{% + \edef#2{\skvexpandthrice{#2}}% + }{}% }% }% }% }% - \skvexpanded{\endgroup - \skvcmdexit{#2}\do - }% + \skvexpanded{\endgroup\skvcmdexit#2\do}% } \skvrobustdef*\skv@findpointer#1#2#3{% \begingroup \def\skv@prova##1#2##2##3\pointer@nil{% \endgroup - \skvifstrcmp{##2}{\skv@nil}{% + \skvifstrcmpTF{##2}{\skv@nil}{% \@secondoftwo }{% + \skviflacus##1\then\else + \skv@err{Nothing should come before the + \MessageBreak pointer '#2' on key '##2'}\@ehd + \fi \edef#3{\skvtrimspace{##2}}% \@firstoftwo }% @@ -2404,7 +2556,7 @@ \ifx#2\@empty \edef#2{\unexpanded{#1}}% \else - \skvifstreq{#2}\with{\skvcurrentkey}\then + \skvifstreq{#2}{\skvcurrentkey}\then \in@true % The number of arguments of the pseudo key is determined by the % number of closed parentheses: @@ -2443,7 +2595,7 @@ \begingroup \let\skvcurrentvalue\@empty \let\skv@tempa\@empty - \skvifbraced{#1}{% + \skvifbracedTF{#1}{% \skv@r@placepointers{#1}.use value\skv@nil }{% \skv@r@placepointers#1.use value\skv@nil @@ -2459,20 +2611,20 @@ % \skvrobustdef*\skv@r@placepointers#1.use value#2{% \edef\skv@prova{\unexpanded{#2}}% - \skvifx\skv@prova\skv@nnil{% + \skvifxTF\skv@prova\skv@nnil{% \edef\skvcurrentvalue{\unexpanded{#1}}% }{% - \skvifcsundef{\skv@header#2.@value}{% + \skvifcsdefFT{\skv@header#2.@value}{% \skv@err{No value recorded for key '#2'; ignored}\@ehd \skv@r@placepointers }{% - \skvxifin{,\detokenize{#2},}{,\skvoxdetok\skv@tempa,}{% + \skvxifinTF{,\detokenize{#2},}{,\skvoxdetok\skv@tempa,}{% \skv@err{Back linking of pointers; \MessageBreak pointer replacement canceled}\@ehd }{% \edef\skv@tempa{\skvaddlist,\skv@tempa\unexpanded{#2}}% \edef\skv@prova{\skvexpandcsonce{\skv@header#2.@value}}% - \skvexpandbracenext\skvifbraced\skv@prova{% + \skvexpandbracenext\skvifbracedTF\skv@prova{% \skvexpandbracenext{\skv@r@placepointers#1}\skv@prova }{% \skvexpandnext{\skv@r@placepointers#1}\skv@prova @@ -2508,7 +2660,7 @@ % % which will be used at setkeys to define and execute the key's callback. % -\skvrobustdef*\skvassignargs{\skv@testopt\skv@assignargs{KV}} +\skvrobustdef*\skvassignargs{\skv@testopt\skv@assignargs\skv@defaultpref} \skvrobustdef*\skv@assignargs[#1]#2{% \begingroup \skv@testopt{\skv@assignargs@a{#1}{#2}}{^skv^}% @@ -2516,7 +2668,7 @@ \skvrobustdef*\skv@assignargs@a#1#2[#3]#4#5{% \edef\skv@tempc{\skvtrimspace{#5}}% \def\skv@tempd{}% - \skvifstrcmp{#3}{^skv^}{% + \skvifstrcmpTF{#3}{^skv^}{% \def\skvexpander{x0}% }{% \skv@checkexpander{#3}% @@ -2539,7 +2691,7 @@ \skvexpanded{\endgroup\skv@tempd}% } \skvrobustdef*\skv@checkexpander#1{% - \skvxifin{,\expandafter\skvtrimspace\expandafter + \skvxifinTF{,\expandafter\skvtrimspace\expandafter {\detokenize\expandafter{#1}},}{,\detokenize{x0,x1,x2,xx},}{}{% \skv@err{Illegal expansion type '#1'}\@ehd }% @@ -2555,7 +2707,7 @@ \skvexpanded{\skv@testopt{\skv@ordkey@a{\skvcurrentkey}}{^skv^}}% } \skvrobustdef*\skv@ordkey@a#1[#2]#3{% - \skvifstrcmp{#2}{^skv^}{}{\skv@definedefault{#1}{#2}}% + \skvifstrcmpTF{#2}{^skv^}{}{\skv@definedefault{#1}{#2}}% \skvcsedef{\skv@header#1.@cbk}{\unexpanded{#3}}% } \skvrobustdef*\skvordkeys{\skv@testoptb\skv@ordkeys} @@ -2579,7 +2731,7 @@ \skvexpanded{\skv@testopt{\skv@voidkey@a{\skvcurrentkey}}{^skv^}}% } \skvrobustdef*\skv@voidkey@a#1[#2]#3{% - \skvifstrcmp{#2}{^skv^}{}{\skv@definedefault{#1}{#2}}% + \skvifstrcmpTF{#2}{^skv^}{}{\skv@definedefault{#1}{#2}}% % Simply inserting '#3' in the next definition will not work because % of the possible parameter characters in #3: \edef\skv@tempa##1##2{% @@ -2625,7 +2777,7 @@ \skvexpanded{\skv@testopt{\skv@pntkey@a{\skvcurrentkey}}{^skv^}}% } \skvrobustdef*\skv@pntkey@a#1[#2]#3{% - \skvifstrcmp{#2}{^skv^}{}{\skv@definedefault{#1}{#2}}% + \skvifstrcmpTF{#2}{^skv^}{}{\skv@definedefault{#1}{#2}}% \skvcsedef{\skv@header#1.@cbk}{\unexpanded{#3}}% } @@ -2634,38 +2786,37 @@ % \skvcmdkey[<pref>]{<fam>}[<mp>]{<key>}[<defa>]{<callback>} % \skvrobustdef*\skvcmdkey{% - \def\skv@zapnr{0}% + \def\skv@zapsw{01}% \skv@testoptd\skv@cmdkey{cmd}% } - % \skvzcmdkey will internally zap the spaces in the key's name, but the % key user will not notice that: he can still use the key's name with % spaces in it. The key's author could then use the zapped name internally % in his code. \skvrobustdef*\skvzcmdkey{% - \def\skv@zapnr{1}% + \def\skv@zapsw{00}% \skv@testoptd\skv@cmdkey{cmd}% } % When the key's value has doubled hash characters, xkeyval's definition % of \skv@cmdkey fails: \skvrobustdef*\skv@cmdkey#1#2[#3]#4{% \skv@strippointers{#2}\skvcurrentkey - \skvifdefbool{skv@st}{\skv@definedefault\skvcurrentkey{#3}}{}% + \skvifdefboolTF{skv@st}{\skv@definedefault\skvcurrentkey{#3}}{}% % This is to allow the key name to be expanded before possibly zapping % spaces in key name: \edef\skv@prova{#1\skvcurrentkey}% \edef\skv@prova{\expandafter\skv@zapornot\expandafter - {\expandafter\skv@zapnr\expandafter}\expandafter{\skv@prova}}% + {\expandafter\skv@zapsw\expandafter}\expandafter{\skv@prova}}% \skvcslet{\skv@header\skvcurrentkey.@hp}\skv@prova \skvcsedef{\skv@header\skvcurrentkey.@cbk}{\unexpanded{#4}}% } % \skvcmdkeys[<pref>]{<fam>}[<mp>]{<keys>}[<defa>]{<callback>} \skvrobustdef*\skvcmdkeys{% - \def\skv@zapnr{0}% + \def\skv@zapsw{01}% \skv@testoptd\skv@cmdkeys{cmd}% } \skvrobustdef*\skvzcmdkeys{% - \def\skv@zapnr{1}% + \def\skv@zapsw{00}% \skv@testoptd\skv@cmdkeys{cmd}% } \skvrobustdef*\skv@cmdkeys#1#2[#3]#4{% @@ -2676,63 +2827,202 @@ %% Choice keys: % +% The skeyval package allows holder-macro prefixes {<mp>} for choice keys. +% % \skvchoicekey[<pref>]{<fam>}[<mp>]{<key>}[<bins>]{<choices>} -% [<defa>]{<callback>} +% [<default>]{<callback>} +% \skvchoicekey+[<pref>]{<fam>}[<mp>]{<key>}[<bins>]{<choices>} +% [<default>]{<callback>}{<fallback>} +% \skvchoicekey*[<pref>]{<fam>}[<mp>]{<key>}[<bins>]{<choices>} +% [<default>]{<callback>} +% \skvchoicekey*+[<pref>]{<fam>}[<mp>]{<key>}[<bins>]{<choices>} +% [<default>]{<callback>}{<fallback>} % -% The skeyval package allows holder-macro prefixes for choice keys. +% \skvchoicekeys[KV]{fam}[mp@]{key1,key2}[\val\nr]{% +% center.do=\def\vala{#1}, +% right.do=\def\valb{#1}, +% left.do=\def\valc{#1} +% }[center]{\def\x##1{#1*##1}} +% +% \skv@preparenominations{00.or.01}{<altlist>} +\skvrobustdef*\skv@preparenominations#1#2{% + \begingroup + \def\skv@altlista{}% + \def\skv@altlistb{}% + \def\skv@provc##1.do=##2.do=##3\skv@choice@nil{% + \if#1\lowercase{\fi + \edef\skv@prova{\skvtrimspace{##1}}% + \if#1}\fi + \skvstripouterbraces{2}\skv@prova + \edef\skv@altlista{% + \skvxonce\skv@altlista\ifx\skv@altlista\@empty\else,\fi + \skvxonce\skv@prova + }% + \edef\reserved@a{% + \skvnoexpandcs{\skvoxdetok\skv@prova @skvch}% + {\skvtrimspace{##2}}% + }% + \edef\skv@altlistb{\skvxonce\skv@altlistb\skvxonce\reserved@a}% + }% + \skvcommaparse{#2}\skv@prova{% + \expandafter\skv@provc\skv@prova.do=.do=\skv@choice@nil + }% + \ifx\skv@altlista\@empty + \skv@err{No nominations (state pattern) for choice key}\@ehd + \def\skv@altlistb{}% + \fi + \skvexpanded{\endgroup + \skvcmdexit\skv@altlista\skvcmdexit\skv@altlistb + }% +} +% \skv@executechoice{00.or.01}{<currentvalue>}{<altlist>} +\skvrobustdef*\skv@executechoice#1#2#3{% + \begingroup + \if#1\lowercase{\fi + \edef\skv@prova{\skvtrimspace{#2}}% + \if#1}\fi + \skvstripouterbraces{2}\skv@prova + \edef\do{% + \expandafter\noexpand\csname\detokenize + \expandafter{\skv@prova}@skvch\endcsname + }% + % Hide #3 in a macro to avoid confusing any parameter + % characters in #3 with the parameters of \skv@prova: + \edef\skv@provb{\unexpanded{#3}}% + \edef\skv@prova{\def\noexpand\skv@prova####1\skvxonce\do####2####3}% + \skv@prova\skv@choice@nil{% + \toks@{##2}% + \edef\skv@prova{\unexpanded{##2}}% + \ifx\skv@prova\skv@nnil + \skv@err{No state pattern match found for key + \MessageBreak '\skvcurrentkey'}\@ehd + \toks@{}% + \fi + }% + \expandafter\expandafter\expandafter\skv@prova\expandafter + \skv@provb\do{\skv@nil}\skv@choice@nil + \expandafter\endgroup\the\toks@ +} \skvrobustdef*\skvchoicekey{% \skv@testopta{\skv@testoptb {\skv@testopt\skv@choicekey@a{choice\skv@header}}}% } +\skvnewlet\skvchoicekeys\skvchoicekey \skvrobustdef*\skv@choicekey@a[#1]#2{% - \skv@strippointers{#2}\skvcurrentkey - \skvcsedef{\skv@header\skvcurrentkey.@hp}{% - \skvtrimspace{#1}\skvcurrentkey + \skvxifinTF{\skv@hashchar}{\detokenize{#2}}{% + \skv@err{Hash character '\skv@hashchar' not allowed + \MessageBreak in key name}\@ehd + }{% + \edef\skv@currlist{\unexpanded{#2}}% + \edef\skv@hp{\skvtrimspace{#1}}% + \skv@testopt\skv@choicekey@b{}% }% - \skv@testopt\skv@choicekey@b{}% } \skvrobustdef*\skv@choicekey@b[#1]#2{% - \def\skv@bins{#1}% - \edef\skv@tempa{\unexpanded{#2}}% - \skvcsvnormalize\skv@tempa - \skv@toksa\expandafter{\skv@tempa}% + \edef\skv@bins{\unexpanded{#1}}% + % Check the syntax of bins. This also helps catch wrong use syntax + % of \skvchoicekeys: it's easy to get the syntax of \skvchoicekeys + % wrong. The default value may have been put in place of bins. + \ifx\skv@bins\@empty\else + \skvtfor\skv@prova:=#1\do{% + \skvexpbracenext\skvifescapedTF\skv@prova{}{% + \skv@err{Token '\skvoxdetok\skv@prova' of bin of + \MessageBreak choice key isn't escaped}\@ehd + }% + }% + \fi + \skvifblankTF{#2}{% + \skv@err{No nominations (state pattern) for + \MessageBreak choice keys '\skv@currlist'}\@ehd + }{% + \skvifboolTF{skv@st}{% + \skv@preparenominations{00}{#2}% + }{% + \skv@preparenominations{01}{#2}% + }% + }% \skvifnextchar[\skv@choicekey@c{\skv@choicekey@c[^skv^]}% } \skvrobustdef*\skv@choicekey@c[#1]{% - \skvifstrcmp{#1}{^skv^}{}{\skv@definedefault\skvcurrentkey{#1}}% - \skvifdefbool{skv@pl}\skv@choicekey@e\skv@choicekey@d + \edef\skv@default{\skvtrimspace{#1}}% + % Choice can't have braced values, since that will make matching + % to state pattern difficult: + \skvstripouterbraces{2}\skv@default + \skvifdefboolTF{skv@pl}\skv@choicekey@e\skv@choicekey@d +} +\skvrobustdef*\skv@choicekey@d#1{% + \skvexpanded{% + \noexpand\skv@choicekey@f{{% + \noexpand\skv@executechoice\ifskv@st{00}\else{01}\fi + {####1}{\skvxonce\skv@altlistb}% + \unexpanded{#1}% + }}% + }% +} +\skvrobustdef*\skv@choicekey@e#1#2{% + \skvexpanded{% + \noexpand\skv@choicekey@f{{% + \noexpand\skv@executechoice\ifskv@st{00}\else{01}\fi + {####1}{\skvxonce\skv@altlistb}% + \unexpanded{#1}% + }{\unexpanded{#2}}}% + }% } -\skvrobustdef*\skv@choicekey@d#1{\skv@choicekey@f{{#1}}} -\skvrobustdef*\skv@choicekey@e#1#2{\skv@choicekey@f{{#1}{#2}}} \skvrobustdef*\skv@choicekey@f#1{% - \edef\skv@tempa##1##2{% + \edef\skv@prova##1##2{% \ifskv@st\noexpand\skv@sttrue\else\noexpand\skv@stfalse\fi \ifskv@pl\noexpand\skv@pltrue\else\noexpand\skv@plfalse\fi - \skv@checkchoice[\skvexpandonce\skv@bins]{##1}{\the\skv@toksa}##2% + \noexpand\skv@checkchoice + \ifx\skv@bins\@empty\else[\skvxonce\skv@bins]\fi + {##1}{\skvxonce\skv@altlista}##2% }% - \skv@toksa\expandafter{\skv@tempa{##1}{#1}}% - \skvcsedef{\skv@header\skvcurrentkey.@cbk}{\the\skv@toksa}% + \skv@toksa\expandafter{\skv@prova{##1}{#1}}% + % Why separate \skv@choicekey@g? It is needed by skeyval-view.sty: + \skv@choicekey@g +} +\skvrobustdef*\skv@choicekey@g{% + \skvcommaparse*\skv@currlist\skv@prova{% + \skvexpbracenext\skv@strippointers\skv@prova\skvcurrentkey + \ifx\skv@default\skv@rej\else + \skvexpanded{% + \noexpand\skv@definedefault + {\skvxonce\skvcurrentkey}{\skvxonce\skv@default}% + }% + \fi + \skvcsedef{\skv@header\skvcurrentkey.@hp}{\skv@hp\skvcurrentkey}% + \skvcsedef{\skv@header\skvcurrentkey.@cbk}{\the\skv@toksa}% + }% +} + +\skvrobustdef*\skv@togkey@settog#1#2#3{% + \edef\skv@prova{\skv@zapornot{#1}{#2}}% + \csname skvsettog#3\expandafter\endcsname\expandafter{\skv@prova}% } %% Boolean keys: % % \skvboolkey[<pref>]{<fam>}[<mp>]{<key>}[<defa>]{<callback>} +% \skvboolkey+[<pref>]{<fam>}[<mp>]{<keys>}[<defa>]{<callback>}{<fallback>} % % Boolean keys create a store to receive the key's value and also create % a boolean internally. +% \skvrobustdef*\skvboolkey{% - \def\skv@zapnr{0}% + \def\skv@typetogkey{01}% + \def\skv@zapsw{01}% \skv@t@stopta{\skv@testoptd\skv@boolkey{}}% } -% \skvzcmdkey will internally zap the spaces in the key's name and in +% \skvzboolkey will internally zap the spaces in the key's name and in % the boolean that it creates internally, but the key user will not % notice that: he will still be able to submit the original key's name % with spaces in it. The key's author could then use the zapped key % name and boolean in his code (internally). \skvrobustdef*\skvzboolkey{% - \def\skv@zapnr{1}% + \def\skv@typetogkey{01}% + \def\skv@zapsw{00}% \skv@t@stopta{\skv@testoptd\skv@boolkey{}}% } +% \skv@boolkeys{<mp>}{<key>}[<default>] \skvrobustdef*\skv@boolkey#1#2[#3]{% \skv@strippointers{#2}\skvcurrentkey \skvexpanded{% @@ -2740,21 +3030,38 @@ {\skvcurrentkey}{#1\skvcurrentkey}% }{#3}% } +% \skv@boolkey@a{<key>}{<mp.key>}{<default>}{<callback>} \skvrobustdef*\skv@boolkey@a#1#2#3#4{% \def\skv@tempa{\skv@boolkey@c{#1}{#2}{#3}}% - \expandafter\skv@tempa\expandafter{\expandafter{\expandafter - \csname\expandafter\skv@zapornot\expandafter{\skv@zapnr}{#2}% - \skv@value\endcsname#4}}% + \skvifplaswTF\skv@typetogkey{% + \expandafter\skv@tempa\expandafter{\expandafter{\expandafter + \skv@togkey@settog\expandafter{\skv@zapsw}{#2}\skv@value#4}}% + }{% + \expandafter\skv@tempa\expandafter{\expandafter{\expandafter + \csname\expandafter\skv@zapornot\expandafter{\skv@zapsw}{#2}% + \skv@value\endcsname#4}}% + }% } +% \skv@boolkey@b{<key>}{<mp.key>}{<default>}{<callback>}{<fallback>} \skvrobustdef*\skv@boolkey@b#1#2#3#4#5{% \def\skv@tempa{\skv@boolkey@c{#1}{#2}{#3}}% - \expandafter\skv@tempa\expandafter{\expandafter{\expandafter - \csname\expandafter\skv@zapornot\expandafter{\skv@zapnr}{#2}% - \skv@value\endcsname#4}{#5}}% + \skvifplaswTF\skv@typetogkey{% + \expandafter\skv@tempa\expandafter{\expandafter{\expandafter + \skv@togkey@settog\expandafter{\skv@zapsw}{#2}\skv@value#4}{#5}}% + }{% + \expandafter\skv@tempa\expandafter{\expandafter{\expandafter + \csname\expandafter\skv@zapornot\expandafter{\skv@zapsw}{#2}% + \skv@value\endcsname#4}{#5}}% + }% } +% \skv@boolkey@c{<key>}{<mp.key>}{<default>}{{<callback>}{<fallback>}} \skvrobustdef*\skv@boolkey@c#1#2#3#4{% - \skvcsnewif{\skv@zapornot{\skv@zapnr}{#2}}% - \skvifdefbool{skv@st}{\skv@definedefault{#1}{#3}}{}% + \if\skv@typetogkey + \skvdeftog{\skv@zapornot{\skv@zapsw}{#2}}% + \else + \skvcsnewif{\skv@zapornot{\skv@zapsw}{#2}}% + \fi + \skvifdefboolTF{skv@st}{\skv@definedefault{#1}{#3}}{}% \edef\skv@tempa##1##2{% \noexpand\skv@sttrue \ifskv@pl\noexpand\skv@pltrue\else\noexpand\skv@plfalse\fi @@ -2763,25 +3070,33 @@ \skv@toksa\expandafter{\skv@tempa{##1}{#4}}% \skvcsedef{\skv@header#1.@cbk}{\the\skv@toksa}% } +% % \skvboolkeys[<pref>]{<fam>}[<mp>]{<keys>}[<defa>]{<callback>} +% \skvboolkeys+[<pref>]{<fam>}[<mp>]{<keys>}[<defa>]{<callback>}{<fallback>} +% \skvrobustdef*\skvboolkeys{% - \def\skv@zapnr{0}% + \def\skv@typetogkey{01}% + \def\skv@zapsw{01}% \skv@t@stopta{\skv@testoptd\skv@boolkeys{}}% } \skvrobustdef*\skvzboolkeys{% - \def\skv@zapnr{1}% + \def\skv@typetogkey{01}% + \def\skv@zapsw{00}% \skv@t@stopta{\skv@testoptd\skv@boolkeys{}}% } +% \skv@boolkeys{<mp>}{<keys>}[<default>] \skvrobustdef*\skv@boolkeys#1#2[#3]{% - \skvifdefbool{skv@pl}\skv@boolkeys@b\skv@boolkeys@a{#2}{#1}{#3}% + \skvifdefboolTF{skv@pl}\skv@boolkeys@b\skv@boolkeys@a{#2}{#1}{#3}% } +% \skv@boolkeys@a{<keys>}{<mp>}{<default>}{<callback>} \skvrobustdef*\skv@boolkeys@a#1#2#3#4{\skv@boolkeys@c{#1}{#2}{#3}{#4}{^skv^}} +% \skv@boolkeys@b{<keys>}{<mp>}{<default>}{<callback>}{<fallback>} \skvrobustdef*\skv@boolkeys@b#1#2#3#4#5{\skv@boolkeys@c{#1}{#2}{#3}{#4}{#5}} \skvrobustdef*\skv@boolkeys@c#1#2#3#4#5{% \skvcommaparse{#1}\skv@tempa{% \skvexpbracenext\skv@strippointers\skv@tempa\skvcurrentkey \skvexpanded{% - \skvifstrcmp{#5}{^skv^}{% + \skvifstrcmpTF{#5}{^skv^}{% \skv@boolkey@a{\skvcurrentkey}% {#2\skvcurrentkey}\unexpanded{{#3}{#4}}% }{% @@ -2791,6 +3106,170 @@ }% }% } +% +% \skvbiboolkeys[<pref>]{<fam>}[<mp>]{<key1,key2>}[<defa>] +% {<callback.for.key1>}{<callback.for.key2>} +% \skvbiboolkeys+[<pref>]{<fam>}[<mp>]{<key1,key2>}[<defa>] +% {<callback.for.key1>}{<callback.for.key2>}{<fallback>} +% +% Example: +% +% \skvbiboolkeys+[KV]{fam}[mp@]{.need value{keya},keyb}[true]{% +% \ifmp@keya\def\xa##1{##1}\fi +% }{% +% \ifmp@keyb\def\xb##1{##1}\fi +% }{% +% \skv@warn{Value '#1' is invalid}% +% } +% +\skvrobustdef*\skvbiboolkeys{% + \def\skv@typetogkey{01}% + \def\skv@zapsw{01}% + \skv@t@stopta{\skv@testoptd\skv@biboolkeys{}}% +} +\skvrobustdef*\skvzbiboolkeys{% + \def\skv@typetogkey{01}% + \def\skv@zapsw{00}% + \skv@t@stopta{\skv@testoptd\skv@biboolkeys{}}% +} +\skvrobustdef*\skv@biboolkeys#1#2[#3]{% + \begingroup + \edef\skv@currlist{\unexpanded{#2}}% + \skvcsvnormalize\skv@currlist + \@tempcnta\skvz@ + \skvcommaloop*\skv@currlist\skv@tempa{% + \advance\@tempcnta\@ne + \ifnum\@tempcnta>\tw@ + \skvbreakloop + \fi + }% + \ifnum\@tempcnta=\tw@\else + \skv@err{Number of bi-keys isn't 2: + \MessageBreak ||\skv@currlist||}\@ehd + \fi + \skvexpanded{% + \ifskv@pl\skv@biboolkeys@b\else\skv@biboolkeys@a\fi + {\skv@currlist}% + }{#1}{#3}% +} +% \skv@bilboolkeys@a{<key1,key2>}{<mp>}{<default>} +% {<callback1>}{<callback2>} +\skvrobustdef*\skv@biboolkeys@a#1#2#3#4#5{% + \skv@biboolkeys@c{#1}{#2}{#3}{#4}{#5}{^skv^}% +} +% \skv@bilboolkeys@a{<key1,key2>}{<mp>}{<default>} +% {<callback1>}{<callback2>}{<fallback>} +\skvrobustdef*\skv@biboolkeys@b#1#2#3#4#5#6{% + \skv@biboolkeys@c{#1}{#2}{#3}{#4}{#5}{#6}% +} +\skvrobustdef*\skv@biboolkeys@c#1#2#3#4#5#6{% + % Don't group the following: pointers will be lost outide the group. + % 'bicallerid' is used to indicate that the master key is the one + % that has instantiated the callback of the slave. This avoids + % infinite re-entrance of \skvsetkeys. + \edef\skv@default{\unexpanded{#3}}% + \edef\skv@tempc{\unexpanded{#4}}% + \edef\skv@tempd{\unexpanded{#5}}% + \edef\skv@tempe{\unexpanded{#6}}% + \toks@{}\def\skv@provd{}% + \let\\\noexpand + \def\@do##1##2{% + \skvifcsname\skv@header##1.@##2\then + \edef\skv@provd{% + \skv@provd + \skvcsdef{\skv@header##1.@##2}{% + \csname\skv@header##1.@##2\endcsname + }% + }% + \fi + }% + \def\skv@provc##1##2##3##4{% + \skvsettogtrue{\skv@header bicallerid/##3}% + \skvxonce\@elt + \\\skvifxTF\\\skvcurrentvalue\\\skv@truetoks{% + \\\skviftogTF{\skv@header bicallerid/##4}{}{% + \skvsetkeys[##1]{##2}{##4=false}% + }% + }{% + \\\skviftogTF{\skv@header bicallerid/##4}{}{% + \skvsetkeys[##1]{##2}{##4=true}% + }% + }% + \skvsettogfalse{\skv@header bicallerid/##3}% + }% + % \skv@provb{<KV>}{<fam>}{<primary.key>}{<secondary.key>} + \def\skv@provb##1##2##3##4{% + \@do{##3}{ndv}\@do{##3}{fbv}% + \skvexpanded{% + \toks@{\the\toks@ + \skvdeftog{\skv@header bicallerid/##3}% + \skvifstrcmpTF{#6}{^skv^}{% + \skv@boolkey@a + {##3}{#2##3}{\skvxonce\skv@default}{% + \skv@provc{##1}{##2}{##3}{##4}% + }% + }{% + \skv@boolkey@b + {##3}{#2##3}{\skvxonce\skv@default}{% + \skv@provc{##1}{##2}{##3}{##4}% + }{\skvxonce\skv@tempe}% + }% + }% + }% + }% + \def\skv@prova##1,##2\skv@nil{% + \skv@strippointers{##1}\skv@tempa + \skv@strippointers{##2}\skv@tempb + \skvexpanded{% + \let\\\@elt\\\skv@tempc + \\\skv@provb{\skvcurrentprefix}{\skvcurrentfamily}% + {\skv@tempa}{\skv@tempb}% + \let\\\@elt\\\skv@tempd + \\\skv@provb{\skvcurrentprefix}{\skvcurrentfamily}% + {\skv@tempb}{\skv@tempa}% + }% + }% + \skv@prova#1\skv@nil + \skvexpanded{\endgroup + \skv@provd\the\toks@ + }% +} + +%% Toggle keys: +% +% \skvtogkey[<pref>]{<fam>}[<mp>]{<key>}[<defa>]{<callback>} +% \skvtogkey+[<pref>]{<fam>}[<mp>]{<key>}[<defa>]{<callback>}{<fallback>} +% +\skvrobustdef*\skvtogkey{% + \def\skv@typetogkey{00}% + \def\skv@zapsw{01}% + \skv@t@stopta{\skv@testoptd\skv@boolkey{}}% +} +\skvrobustdef*\skvztogkey{% + \def\skv@typetogkey{00}% + \def\skv@zapsw{00}% + \skv@t@stopta{\skv@testoptd\skv@boolkey{}}% +} +\skvrobustdef*\skvtogkeys{% + \def\skv@typetogkey{00}% + \def\skv@zapsw{01}% + \skv@t@stopta{\skv@testoptd\skv@boolkeys{}}% +} +\skvrobustdef*\skvztogkeys{% + \def\skv@typetogkey{00}% + \def\skv@zapsw{00}% + \skv@t@stopta{\skv@testoptd\skv@boolkeys{}}% +} +\skvrobustdef*\skvbitogkeys{% + \def\skv@typetogkey{00}% + \def\skv@zapsw{01}% + \skv@t@stopta{\skv@testoptd\skv@biboolkeys{}}% +} +\skvrobustdef*\skvzbitogkeys{% + \def\skv@typetogkey{00}% + \def\skv@zapsw{00}% + \skv@t@stopta{\skv@testoptd\skv@biboolkeys{}}% +} % Style keys % @@ -2841,7 +3320,7 @@ \skvcommaparse{#1}\skv@prova{% \skvexpbracenext\skv@strippointers\skv@prova\skvcurrentkey \skvexpanded{% - \skvifstrcmp{#3}{^skv^}{}{% + \skvifstrcmpTF{#3}{^skv^}{}{% \skv@definedefault{\skvcurrentkey}{\unexpanded{#3}}% }% \skv@appendstyles@b{\skvcurrentkey}\unexpanded{{#2}{#4}}% @@ -2851,12 +3330,12 @@ % \skv@appendstyles@b{<parent.key>}{<styles>}{<parent.key.callback>} \skvrobustdef*\skv@appendstyles@b#1#2#3{% \def\skv@stylelist{}% - \skvkvparse{#2}\skv@provb{% - \def\skv@prova##1=##2=##3\skv@nil{% - \skvxifstrcmp{#1}{##1}{% + \skvkvparse{#2}\skv@prova{% + \ksv@kvosplit\skv@prova{% + \skvxifstrcmpTF{#1}{##1}{% \skv@err{Linking key '##1' to itself}\@ehd }{% - \skvifcsdef{\skv@header##1.@cbk}{}{% + \skvifcsdefTF{\skv@header##1.@cbk}{}{% \skv@err{Style key '##1' is undefined}\@ehd }% }% @@ -2865,10 +3344,9 @@ \skvexpandonce\skvexpanderpointer{\unexpanded{##2}}% }% }% - \expandafter\skv@prova\skv@provb==\skv@nil }% \edef\elt{% - \skvifcsdef{\skv@header#1.@cbk} + \skvifcsdefTF{\skv@header#1.@cbk} {\skvxpandcsonce{\skv@header#1.@cbk}}{}% }% \edef\skv@elt{% @@ -2876,7 +3354,7 @@ {\skvcurrentfamily}{\skvexpandonce\skv@stylelist}}% }% \skvcsedef{\skv@header#1.@cbk}{% - \skvxifstrcmp{\skv@type}{prep}{% + \skvxifstrcmpTF{\skv@type}{prep}{% \skvexpandonce\skv@elt\unexpanded{#3}\skvexpandonce\elt }{% \skvexpandonce\elt\unexpanded{#3}\skvexpandonce\skv@elt @@ -2933,7 +3411,7 @@ } \skvrobustdef*\skv@checkchoice@a#1#2\skv@nil#3#4{% \def\skv@tempa{#2}% - \skvifx\skv@tempa\@empty{% + \skvifxTF\skv@tempa\@empty{% \skv@checkchoice@b#1{#3}{#4}% }{% \skv@checkchoice@c#1#2{#3}{#4}% @@ -2946,7 +3424,7 @@ \else \def\skv@tempa{\endgroup\def#1{#2}}% \fi - \skvifin{,#2,}{,#3,}{% + \skvifinTF{,#2,}{,#3,}{% \ifskv@pl \skvappendtomacro\skv@tempa{\@firstoftwo}% \else @@ -2997,13 +3475,13 @@ \skvrobustdef*\skv@checkchoice@d#1\skv@nil,{\@firstoftwo} \skvrobustdef*\skv@checkchoice@e#1\skv@nil,{\@firstofone} -% \skvifkeydef[<prefs>]{<fams>}{key}{<true>}{<false>} +% \skvifkeydefTF[<prefs>]{<fams>}{key}{<true>}{<false>} % 1. The search will stop as soon as the key is found in one combination % of prefixes/families. % 2. The prefix and header created here may be needed in #5 and #6. Hence % we put entry prefix and header on stack before commencing the search. -\skvrobustdef*\skvifkeydef{\skv@testopt{\skv@ifkeyundef0}{KV}} -\skvrobustdef*\skvifkeyundef{\skv@testopt{\skv@ifkeyundef1}{KV}} +\skvrobustdef*\skvifkeydefTF{\skv@testopt{\skv@ifkeyundef0}\skv@defaultpref} +\skvrobustdef*\skvifkeydefFT{\skv@testopt{\skv@ifkeyundef1}\skv@defaultpref} \skvrobustdef*\skv@ifkeyundef#1[#2]#3#4#5#6{% \skvpushstate\skv@keystate\skv@keydepth \edef\skv@prefs{#2}% @@ -3019,7 +3497,7 @@ \ifskv@kf\skvbreakloop\fi }% \skvexpanded{% - \skvifbool{skv@kf}{% + \skvifboolTF{skv@kf}{% \if0#1% \noexpand\@firstoftwo \else @@ -3039,19 +3517,21 @@ \skvrobustdef*\skv@ifk@yundef{% \skvcommaparse*\skv@fams\skv@prova{% \skv@makeheader\skv@prova - \skvifcsundef{\skv@header\skvcurrentkey.@cbk}{}{% + \skvifcsdefFT{\skv@header\skvcurrentkey.@cbk}{}{% \skv@kftrue\skvbreakloop }% }% } -% \skvifkeyinfamilies[<prefs>]{<fams>}{key}{<true>}{<false>} +% \skvifkeyinfamiliesTF[<prefs>]{<fams>}{key}{<true>}{<false>} +% % The search will be done on all combinations of prefixes/families. The % callback <true> or <false> will be executed for all the combinations. -\skvrobustdef*\skvifkeyinfamilies{% - \skv@testopt{\skv@ifkeyinfamilies0}{KV}% +% +\skvrobustdef*\skvifkeyinfamiliesTF{% + \skv@testopt{\skv@ifkeyinfamilies0}\skv@defaultpref } -\skvrobustdef*\skvifkeynotinfamilies{% - \skv@testopt{\skv@ifkeyinfamilies1}{KV}% +\skvrobustdef*\skvifkeyinfamiliesFT{% + \skv@testopt{\skv@ifkeyinfamilies1}\skv@defaultpref } \skvrobustdef*\skv@ifkeyinfamilies#1[#2]#3#4#5#6{% \skvpushstate\skv@keystate\skv@keydepth @@ -3067,7 +3547,7 @@ \skvcommaparse*\skv@fams\skv@prova{% \skv@makeheader\skv@prova \skvexpanded{% - \skvifcsdef{\skv@header\skvcurrentkey.@cbk}{% + \skvifcsdefTF{\skv@header\skvcurrentkey.@cbk}{% \if0#1% \noexpand\@firstoftwo \else @@ -3084,18 +3564,18 @@ }% \skvpopstate\skv@keystate\skv@keydepth } -% \skvifkeyinfamily{<prefix>/<family>}{<key>} -\skvnewdef*\skvifkeyinfamily#1#2{% - \skvifcsdef{\skvtrimspace{#1}/\skvtrimspace{#2}.@cbk}% +% \skvifkeyinfamilyTF{<prefix>/<family>}{<key>} +\skvnewdef*\skvifkeyinfamilyTF#1#2{% + \skvifcsdefTF{\skvtrimspace{#1}/\skvtrimspace{#2}.@cbk}% } -% \skvifkeyincurrentfamily{<key>} -\skvnewdef*\skvifkeyincurrentfamily#1{% - \skvifcsdef{\skvcurrentpath/\skvtrimspace{#1}.@cbk}% +% \skvifkeyincurrentfamilyTF{<key>} +\skvnewdef*\skvifkeyincurrentfamilyTF#1{% + \skvifcsdefTF{\skvcurrentpath/\skvtrimspace{#1}.@cbk}% } -% \skvifonekeyinfamily{<prefix>/<family>}{<keys>} +% \skvifonekeyinfamilyTF{<prefix>/<family>}{<keys>} % Given a list of keys, test if at least one of them is defined. -% Example: \edef\x{\skvifonekeyinfamily{KV/fam}{keya,keyb,keyc}{T}{F}}. -\skvnewdef*\skvifonekeyinfamily#1#2{% +% Example: \edef\x{\skvifonekeyinfamilyTF{KV/fam}{keya,keyb,keyc}{T}{F}}. +\skvnewdef*\skvifonekeyinfamilyTF#1#2{% \ifnum\numexpr0\skv@ifonekeydef{#1}#2,\@nnil,>\skvz@ \expandafter\@firstoftwo \else @@ -3106,7 +3586,7 @@ \ifx\@nnil#2% \expandafter\@gobble \else - \skvifcsndef{\skvtrimspace{#1}/\skvtrimspace{#2}.@cbk}{+1}{+0}% + \skvifcsdefTF{\skvtrimspace{#1}/\skvtrimspace{#2}.@cbk}{+1}{+0}% \expandafter\skv@ifonekeydef \fi {#1}% @@ -3137,24 +3617,25 @@ % \skvkeyslet[<pref>]{<family>}{<list>} % <list> -> <new keyname>=<old keyname> \skvrobustdef*\skvkeyslet{\skv@testoptb\skv@keyslet} +\skvnewlet\skvkeyinheritance\skvkeyslet \skvnewlet\skvkeylet\skvkeyslet \skvrobustdef*\skv@keyslet#1{% \skvletcs\skv@inikv{\skv@header.@inikv}% - \skvifundef\skv@inikv{}{% + \skvifdefFT\skv@inikv{}{% \expandafter\skv@getkeynames\expandafter{\skv@inikv}\skv@inikeys }% \def\skv@k@yslet##1=##2=##3\skv@nil{% - \skvifcsundef{\skv@header##2.@cbk}{% + \skvifcsdefFT{\skv@header##2.@cbk}{% \skv@err{Key '\skvcurrentpath/##2' is undefined}\@ehd }{% - \skvifcsdef{\skv@header##1.@cbk}{% + \skvifcsdefTF{\skv@header##1.@cbk}{% \skv@err{Key '\skvcurrentpath/##1' is already defined}\@ehd }{}% }% \skvcommaloop{cbk,ndv,fbv}\skv@prova{% \skvcsletcs{\skv@header##1.@\skv@prova}{\skv@header##2.@\skv@prova}% }% - \skvifcsdef{\skv@header##2.@defa}{% + \skvifcsdefTF{\skv@header##2.@defa}{% \edef\skvcurrentkey{##2}% \skv@getdefault\skvcurrentprefix\skvcurrentfamily\skvcurrentkey \skvcurrentvalue @@ -3165,8 +3646,8 @@ }{% \skv@swafalse }% - \skvifundef\skv@inikv{}{% - \skvxifnotin{,\detokenize{##2},}{,\skvoxdetok\skv@inikeys,}{}{% + \skvifdefFT\skv@inikv{}{% + \skvxifinFT{,\detokenize{##2},}{,\skvoxdetok\skv@inikeys,}{}{% \skvcsedef{\skv@header.@inikv}{% \expandafter\skvaddlist\expandafter ,\csname\skv@header.@inikv\endcsname @@ -3176,8 +3657,8 @@ }% \skvcommaloop{ignoredkeys,needini}\skv@prova{% \skvletcs\skv@tempa{\skv@header.@\skv@prova}% - \skvifundef\skv@tempa{}{% - \skvxifnotin{,\detokenize{##2},}{,\skvoxdetok\skv@tempa,}{}{% + \skvifdefFT\skv@tempa{}{% + \skvxifinFT{,\detokenize{##2},}{,\skvoxdetok\skv@tempa,}{}{% \skvcsedef{\skv@header.@\skv@prova}{\skvaddlist,\skv@tempa##1}% }% }% @@ -3194,14 +3675,14 @@ \skv@warn{Key '\skvcurrentpath/#1' has been disabled \MessageBreak You can't set or reset key '#1' at this \MessageBreak late stage. Perhaps you should have set it - \MessageBreak earlier \ifskv@inlatex in \noexpand\documentclass or + \MessageBreak earlier \ifskv@latex in \noexpand\documentclass or \string\usepackage\fi}% } \skvrobustdef*\skv@disabledkeyerror#1{% \skv@err{Key '\skvcurrentpath/#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 \ifskv@inlatex in \noexpand\documentclass or + \MessageBreak earlier \ifskv@latex in \noexpand\documentclass or \string\usepackage\fi}% } \skvrobustdef*\skvdisabledkeysmessagetype#1{% @@ -3229,11 +3710,11 @@ \skvrobustdef*\skvdisablekeys{\skv@testoptb\skv@disablekeys} \skvrobustdef*\skv@disablekeys#1{% \skvcommaparse{#1}\skv@tempa{% - \skvifcsdef{\skv@header\skv@tempa.@cbk}{}{% + \skvifcsdefTF{\skv@header\skv@tempa.@cbk}{}{% \skv@err{Key '\skv@tempa' is undefined: \MessageBreak couldn't be disabled}\@ehd }% - \skvifcsdef{\skv@header\skv@tempa.@defa}{% + \skvifcsdefTF{\skv@header\skv@tempa.@defa}{% \edef\skv@tempb{\noexpand\skv@ordkey{\skv@tempa}[]}% }{% \edef\skv@tempb{\noexpand\skv@ordkey{\skv@tempa}}% @@ -3249,22 +3730,22 @@ % % \skvpresetkeys[<pref>]{<fam>}{<keys>} % \skvgpresetkeys[<pref>]{<fam>}{<keys>} -\skvrobustdef*\skvpresetkeys{\skv@testopt\skv@presetkeys{KV}} +\skvrobustdef*\skvpresetkeys{\skv@testopt\skv@presetkeys\skv@defaultpref} \skvrobustdef*\skv@presetkeys[#1]#2#3{\skvpreposetkeys[#1]{#2}{#3}{}} -\skvrobustdef*\skvgpresetkeys{\skv@testopt\skv@gpresetkeys{KV}} +\skvrobustdef*\skvgpresetkeys{\skv@testopt\skv@gpresetkeys\skv@defaultpref} \skvrobustdef*\skv@gpresetkeys[#1]#2#3{\skvgpreposetkeys[#1]{#2}{#3}{}} -\skvrobustdef*\skvpostsetkeys{\skv@testopt\skv@postsetkeys{KV}} +\skvrobustdef*\skvpostsetkeys{\skv@testopt\skv@postsetkeys\skv@defaultpref} \skvrobustdef*\skv@postsetkeys[#1]#2#3{\skvpreposetkeys[#1]{#2}{}{#3}} -\skvrobustdef*\skvgpostsetkeys{\skv@testopt\skv@gpostsetkeys{KV}} +\skvrobustdef*\skvgpostsetkeys{\skv@testopt\skv@gpostsetkeys\skv@defaultpref} \skvrobustdef*\skv@gpostsetkeys[#1]#2#3{\skvgpreposetkeys[#1]{#2}{}{#3}} \skvrobustdef*\skvpreposetkeys{\skv@clfalse\skv@testoptb\skv@preposetkeys} \skvrobustdef*\skvgpreposetkeys{\skv@cltrue\skv@testoptb\skv@preposetkeys} \skvrobustdef*\skv@preposetkeys#1#2{% - \skvifblank{#1}{}{\skv@pr@posetkeys{#1}{preset}}% - \skvifblank{#2}{}{\skv@pr@posetkeys{#2}{postset}}% + \skvifblankTF{#1}{}{\skv@pr@posetkeys{#1}{preset}}% + \skvifblankTF{#2}{}{\skv@pr@posetkeys{#2}{postset}}% } \skvrobustdef*\skv@pr@posetkeys#1#2{% - \skvifcsundef{\skv@header.@#2}{% + \skvifcsdefFT{\skv@header.@#2}{% \skvnormalize{csv}{,}{#1}\skv@tempa \ifskv@cl\expandafter\global\fi \expandafter\def\csname\skv@header.@#2\expandafter @@ -3284,7 +3765,7 @@ \skv@cltrue\skv@testoptb\skv@removepresetkeys } \skvrobustdef*\skv@removepresetkeys#1{% - \skvifcsdef{\skv@header.@preset}{% + \skvifcsdefTF{\skv@header.@preset}{% \expandafter\skv@filterremoveelements\csname\skv@header .@preset\endcsname{#1}\skv@getkeyname }{% @@ -3300,7 +3781,7 @@ \skv@cltrue\skv@testoptb\skv@undefpresetkeys } \skvrobustdef*\skv@undefpresetkeys{% - \skvifcsundef{\skv@header.@preset}{% + \skvifcsdefFT{\skv@header.@preset}{% \skv@err{No preset keys defined for '\skvcurrentprefix/\skvcurrentfamily'}\@ehd }{% @@ -3318,7 +3799,7 @@ \skv@cltrue\skv@testoptb\skv@removepostsetkeys } \skvrobustdef*\skv@removepostsetkeys#1{% - \skvifcsdef{\skv@header.@postset}{% + \skvifcsdefTF{\skv@header.@postset}{% \expandafter\skv@filterremoveelements\csname\skv@header .@postset\endcsname{#1}\skv@getkeyname }{% @@ -3334,7 +3815,7 @@ \skv@cltrue\skv@testoptb\skv@undefpostsetkeys } \skvrobustdef*\skv@undefpostsetkeys{% - \skvifcsundef{\skv@header.@postset}{% + \skvifcsdefFT{\skv@header.@postset}{% \skv@err{No postset keys defined for '\skvcurrentprefix/\skvcurrentfamily'}\@ehd }{% @@ -3356,7 +3837,7 @@ \skv@r@movepreposetkeys{#2}{postset}% } \skvrobustdef*\skv@r@movepreposetkeys#1#2{% - \skvifcsdef{\skv@header.@#2}{% + \skvifcsdefTF{\skv@header.@#2}{% \expandafter\skv@filterremoveelements\csname\skv@header .@#2\endcsname{#1}\skv@getkeyname }{% @@ -3372,7 +3853,7 @@ \skv@cltrue\skv@testoptb\skv@undefpreposetkeys } \skvrobustdef*\skv@undefpreposetkeys{% - \skvifcsundef{\skv@header.@preset}{% + \skvifcsdefFT{\skv@header.@preset}{% \skv@err{No preset keys defined for '\skvcurrentprefix/\skvcurrentfamily'}\@ehd }{% @@ -3453,7 +3934,7 @@ \skv@cltrue\skv@testoptb\skv@saveinitialvaluekeys } \skvrobustdef*\skv@saveinitialvaluekeys#1{% - \skvifcsundef{\skv@header.@needini}{% + \skvifcsdefFT{\skv@header.@needini}{% \edef\skv@tempa{\unexpanded{#1}}% \skvcsvnormalize\skv@tempa \ifskv@cl\expandafter\global\fi @@ -3472,7 +3953,7 @@ \skv@cltrue\skv@testoptb\skv@removesaveinitialvaluekeys } \skvrobustdef*\skv@removesaveinitialvaluekeys#1{% - \skvifcsundef{\skv@header.@needini}{% + \skvifcsdefFT{\skv@header.@needini}{% \skv@err{No save-initial keys defined for '\skvcurrentprefix/\skvcurrentfamily'}\@ehd }{% @@ -3489,7 +3970,7 @@ \skv@cltrue\skv@testoptb\skv@undefsaveinitialvaluekeys } \skvrobustdef*\skv@undefsaveinitialvaluekeys{% - \skvifcsundef{\skv@header.@needini}{% + \skvifcsdefFT{\skv@header.@needini}{% \skv@err{No save-initial keys defined for '\skvcurrentprefix/\skvcurrentfamily'}\@ehd }{% @@ -3502,7 +3983,7 @@ \skvrobustdef*\skvignorekeys{\skv@clfalse\skv@testoptb\skv@ignorekeys} \skvrobustdef*\skvgignorekeys{\skv@cltrue\skv@testoptb\skv@ignorekeys} \skvrobustdef*\skv@ignorekeys#1{% - \skvifcsdef{\skv@header.@ignoredkeys}{% + \skvifcsdefTF{\skv@header.@ignoredkeys}{% \expandafter\skv@filtermergelist\csname \skv@header.@ignoredkeys\endcsname{#1}\skv@getkeyname }{% @@ -3521,7 +4002,7 @@ \skv@cltrue\skv@testoptb\skv@removeignorekeys } \skvrobustdef*\skv@removeignorekeys#1{% - \skvifcsundef{\skv@header.@ignoredkeys}{% + \skvifcsdefFT{\skv@header.@ignoredkeys}{% \skv@err{No ignore keys defined for '\skvcurrentprefix/\skvcurrentfamily'}\@ehd }{% @@ -3538,7 +4019,7 @@ \skv@cltrue\skv@testoptb\skv@undefignorekeys } \skvrobustdef*\skv@undefignorekeys{% - \skvifcsundef{\skv@header.@ignoredkeys}{% + \skvifcsdefFT{\skv@header.@ignoredkeys}{% \skv@err{No ignore keys defined for '\skvcurrentprefix/\skvcurrentfamily'}\@ehd }{% @@ -3568,9 +4049,9 @@ \skvnewlet\skvapendtocallback\skvappendkeycode \skvrobustdef*\skv@prependkeycode#1#2#3{% \edef\skvcurrentkey{\skvtrimspace{#2}}% - \skvifcsdef{\skv@header\skvcurrentkey.@cbk}{% + \skvifcsdefTF{\skv@header\skvcurrentkey.@cbk}{% \skvcsedef{\skv@header\skvcurrentkey.@cbk}{% - \skvifstrcmp{#1}{prep}{% + \skvifstrcmpTF{#1}{prep}{% \skvtrimspace{#3}% \skvexpandcsonce{\skv@header\skvcurrentkey.@cbk}% }{% @@ -3608,7 +4089,7 @@ \skvrobustdef*\skvgetrmkeys{\skv@clfalse\skv@testoptb\skv@getrmkeys} \skvrobustdef*\skvggetrmkeys{\skv@cltrue\skv@testoptb\skv@getrmkeys} \skvrobustdef*\skv@getrmkeys#1{% - \skvifcsdef{\skv@header.@rmkeys}{% + \skvifcsdefTF{\skv@header.@rmkeys}{% \skvletcs#1{\skv@header.@rmkeys}% \ifskv@cl\global\let#1=#1\fi }{% @@ -3641,7 +4122,7 @@ \skv@prepotrue \skvecommaloop*\skv@fams\skvcurrentfamily{% \skv@makeheader\skvcurrentfamily - \skvifcsundef{\skv@header.@#2}{}{% + \skvifcsdefFT{\skv@header.@#2}{}{% \skv@toksa\expandafter\expandafter\expandafter {\csname\skv@header.@#2\endcsname}% \skvexpandtwoargs\skv@setkeys@b{\the\skv@toksa}% @@ -3670,12 +4151,12 @@ \fi % \skv@na can't be anywhere else, not in \skv@setkeys@a. \edef\skv@na{\unexpanded{#2}}% - \skvifempty\skv@na{}{\skvcsvnormalize\skv@na}% + \skvifemptyTF\skv@na{}{\skvcsvnormalize\skv@na}% \edef\skv@tempa{\unexpanded{#1}}% - \skvifempty\skv@tempa{}{\skvkvnormalize\skv@tempa}% + \skvifemptyTF\skv@tempa{}{\skvkvnormalize\skv@tempa}% \def\skv@setkeys@c##1={% - \skvxifin{(}{\detokenize{##1}}{% - \skvxifin{)}{\detokenize{##1}}{% + \skvxifinTF{(}{\detokenize{##1}}{% + \skvxifinTF{)}{\detokenize{##1}}{% \def\skv@ispntkey{00}% \skv@extr@ctpntkey{##1}\skvcurrentkey\skvcurrentvalue \ifx\skvcurrentvalue\@empty @@ -3693,7 +4174,7 @@ \skv@g@tkeyname##1=\skv@nil\skvcurrentkey }% \def\skv@prova####1=####2\skv@nil{% - \skvifcond\if\skv@ispntkey\fi{}{% + \skvifcondTF\if\skv@ispntkey\fi{}{% \edef\skvcurrentvalue{\skvexpandonce{\@gobble####1}}% \ifx\skvcurrentvalue\skv@novaluetoks \skvnovaluetrue @@ -3701,7 +4182,7 @@ \else \skvnovaluefalse \fi - \skvexpbracenext\skvifbraced\skvcurrentvalue{% + \skvexpbracenext\skvifbracedTF\skvcurrentvalue{% \skvvaluebracedtrue }{% % Strip and use pointers from key value: @@ -3738,24 +4219,24 @@ \skvrobustdef*\skv@setkeys@d{% \skv@cnta\@ne \skvletcs\skv@tempa{\skv@header.@ignoredkeys}% - \skvifdef\skv@tempa{% - \skvxifin{,\skvcurrentkey,}{,\skv@tempa,}{% + \skvifdefTF\skv@tempa{% + \skvxifinTF{,\skvcurrentkey,}{,\skv@tempa,}{% \skv@cnta\skvz@ }{% - \skvxifin{,\skvcurrentkey,}{,\skv@na,}{\skv@cnta\skvz@}{}% + \skvxifinTF{,\skvcurrentkey,}{,\skv@na,}{\skv@cnta\skvz@}{}% }% }{% - \skvxifin{,\skvcurrentkey,}{,\skv@na,}{\skv@cnta\skvz@}{}% + \skvxifinTF{,\skvcurrentkey,}{,\skv@na,}{\skv@cnta\skvz@}{}% }% - \skvifnum\skv@cnta=\skvz@{}{% + \skvifnumTF\skv@cnta=\skvz@{}{% \skv@kffalse - \skvifdefbool{skv@prepo}{% + \skvifdefboolTF{skv@prepo}{% \skv@setkeys@e }{% - \skvifdefbool{skv@intry}{% + \skvifdefboolTF{skv@intry}{% \skv@setkeys@e }{% - \skvifdefbool{skv@pl}{% + \skvifdefboolTF{skv@pl}{% \skvecommaloop*\skv@fams\skvcurrentfamily{% \skv@makeheader\skvcurrentfamily \skv@setkeys@e @@ -3776,15 +4257,15 @@ }% }% }% - \skvifdefbool{skv@kf}{% - \ifskv@inpox\skvafterfifi@inneriscond - \ifx\skv@testclass\skv@documentclass\skvafterfi + \skvifdefboolTF{skv@kf}{% + \skvifdefboolTF{skv@inpox}{% + \ifx\skv@userclassorpackage\skv@documentclass\skvafterfi \expandafter\skv@useoption\expandafter{\CurrentOption}% \fi - \fi + }{}% }{% - \skvifdefbool{skv@inpox}{% - \skvifcsdef{\skv@header.@famhandler}{% + \skvifdefboolTF{skv@inpox}{% + \skvifcsdefTF{\skv@header.@famhandler}{% \begingroup \let\elt\skvexpandonce \skvexpanded{\endgroup @@ -3793,21 +4274,21 @@ {\elt\skvcurrentkey}{\elt\skvcurrentvalue}% }% }{% - \skvifcsdef{skv@dox@\@currname @\@currext}{% + \skvifcsdefTF{skv@dox@\@currname @\@currext}{% \skvcsuse{skv@dox@\@currname @\@currext}% }{% - \ifx\@currext\@clsextension\else + \ifx\@currext\@clsextension\else\skvafterfi \let\CurrentOption\skvcurrentkey\@unknownoptionerror \fi }% }% }{% - \skvifdefbool{skv@intry}{% + \skvifdefboolTF{skv@intry}{% % Continue in remaining families. When all the families have % been searched and the key isn't found, toggle 'intry' false % and raise error. }{% - \skvifdefbool{skv@st}{% + \skvifdefboolTF{skv@st}{% \ifskv@pl % In this case we've already saved any rm keys. \relax @@ -3815,7 +4296,7 @@ \expandafter\skv@setkeys@f \fi }{% - \skvifcsdef{\skv@header.@famhandler}{% + \skvifcsdefTF{\skv@header.@famhandler}{% \begingroup \let\elt\skvexpandonce \skvexpanded{\endgroup @@ -3834,21 +4315,21 @@ }% } \skvrobustdef*\skv@setkeys@e{% - \skvifcsundef{\skv@header\skvcurrentkey.@cbk}{% + \skvifcsdefFT{\skv@header\skvcurrentkey.@cbk}{% \ifskv@intry\skv@successfalse\fi }{% \skv@kftrue \ifskv@intry\skv@successtrue\fi \ifskvnovalue - \skvifcsdef{\skv@header\skvcurrentkey.@ndv}{% + \skvifcsdefTF{\skv@header\skvcurrentkey.@ndv}{% \skv@err{Key '\skvcurrenttriple' requires - \MessageBreak a user value}\@ehd + \MessageBreak a user value}{Key value needed.}% }{% - \skvifcsdef{\skv@header\skvcurrentkey.@defa}{% + \skvifcsdefTF{\skv@header\skvcurrentkey.@defa}{% \skv@getdefault\skvcurrentprefix\skvcurrentfamily\skvcurrentkey \skvcurrentvalue % Check if the default value is braced: - \skvexpbracenext\skvifnotbraced\skvcurrentvalue{}{% + \skvexpbracenext\skvifbracedFT\skvcurrentvalue{}{% \skvvaluebracedtrue }% }{% @@ -3858,17 +4339,17 @@ }% }% \else - \skvifcsdef{\skv@header\skvcurrentkey.@fbv}{% + \skvifcsdefTF{\skv@header\skvcurrentkey.@fbv}{% \skv@err{Key '\skvcurrenttriple' doesn't - \MessageBreak accept a user value}\@ehd + \MessageBreak accept a user value}{Key value forbidden.}% }{}% \fi - \skvifempty\skvcurrentvalue{}{% + \skvifemptyTF\skvcurrentvalue{}{% \expandafter\skv@replacepointers\expandafter{\skvcurrentvalue}% }% % Use argument type to possibly expand the argument: \def\do##1##2##3{% - \skvifcsdef{\skv@header\skvcurrentkey.@##1arg}{% + \skvifcsdefTF{\skv@header\skvcurrentkey.@##1arg}{% {\noexpand##2}% {\skvexpandcsonce{\skv@header\skvcurrentkey.@##1arg}}% }{% @@ -3879,7 +4360,7 @@ \edef\skv@prova{% % This ordering is important: \do{xx}{\@firstofone}{% - \do{x2}{\expandcstwice}{% + \do{x2}{\skvexpandtwice}{% \do{x1}{\skvexpandonce}{% \do{x0}{\unexpanded}{% \do{}{\unexpanded}{{\noexpand\unexpanded}{####1}}% @@ -3902,7 +4383,7 @@ }% \expandafter\skv@provb\skv@prova\skv@arg@nil \skvcslet{\skv@header\skvcurrentkey.@value}\skvcurrentvalue - \skvifcsdef{\skv@header\skvcurrentkey.@hp}{% + \skvifcsdefTF{\skv@header\skvcurrentkey.@hp}{% \skvexpanded{\skvcslet{\skvexpandcsonce {\skv@header\skvcurrentkey.@hp}}}\skvcurrentvalue }{}% @@ -3946,7 +4427,7 @@ \skvcommaloop*\skv@fams\skv@tempa{% \skv@makeheader\skv@tempa \skvletcs\skv@prova{\skv@header.@rmkeys}% - \skvifdef\skv@prova{% + \skvifdefTF\skv@prova{% \skvexpandbracenext{\skv@setkeys@a[#1]}\skv@prova }{}% }% @@ -3988,14 +4469,14 @@ \skvcommaloop*\skv@fams\skv@tempa{% \skv@makeheader\skv@tempa \skvletcs\skv@tempa{\skv@header.@inikv}% - \skvifundef\skv@tempa{% + \skvifdefFT\skv@tempa{% \skv@err{No 'save initial value' keys defined in family \MessageBreak'\skvcurrentprefix/\skvcurrentfamily'}\@ehd }{% % '\skv@header.@poxkeys' is the list of keys that have been % instantiated as current pacakge options. \skvletcs\skv@tempc{\skv@header.@poxkeys}% - \skvifundef\skv@tempc{% + \skvifdefFT\skv@tempc{% \edef\skv@tempe{% \skvexpandonce\skv@tempe \skvsetkeys[\skvcurrentprefix]{\skvcurrentfamily}% @@ -4006,7 +4487,7 @@ \def\skv@tempd{}% \skvcommaloop*\skv@tempa\skv@tempa{% \expandafter\skv@g@tkeyname\skv@tempa=\skv@nil\skv@tempb - \skvxifin{,\skvoxdetok\skv@tempb,}{,\skvoxdetok\skv@tempc,}{}{% + \skvxifinTF{,\skvoxdetok\skv@tempb,}{,\skvoxdetok\skv@tempc,}{}{% \edef\skv@tempd{% \skvexpandonce\skv@tempd\ifx\skv@tempd\@empty\else,\fi \skvexpandonce\skv@tempa @@ -4028,7 +4509,7 @@ % % \skvdefinekeys*+[<pref>]{<fams>}[<hp>]{<list>} % * -> define only new keys. -% + -> define across the given families. +% + -> define in all the given families. % % The only difference between \skvedefinekeys and \skvdefinekeys is the % value of \endlinechar. @@ -4036,15 +4517,21 @@ % Examples: % % \skvdefinekeys*+[KVA]{fam1,fam2}[thp@]{% -% .ords/{keya,keyb}/{default-a}, -% .cmds/{keyc,keyd}/, +% .initialize after define=true, +% .save initial values, +% .prepend to every key name=X@, +% .ord/{keya,keyb}/{default-a}, +% .cmd/{keyc,keyd}/, % .zcmd/key e/\def\cmde##1{##1}/ % \edef\y{\detokenize\expandafter{\thp@keye}}\def\x##1{#1*key e*##1}, -% .choice/keyf/center/{center.do=\def\x##1{#1*##1},left,right}, -% .zbool/show center/true/\edef\cmd{\ifthp@showcenter Yes\else No\fi}, -% .args/{key1,key2}/{#1/#2}, +% .choice/keyf/center/{center.do=\def\x##1{#1*##1},left,right}/ +% \def\f##1{#1*##1}/\@@warning{Invalid value for keyf}, +% .zbool/show center/true/\edef\cmd{\ifthp@showcenter Yes\else No\fi}/ +% \@@warning{Invalid value for show center}, +% .arg/{key1,key2}/{#1/#2}, % .arg/key3/{#1+#2}, % .exec/\def\x##1{##1}, +% .exec code=\def\y##1{##1}, % } % \skvshowcs{KVA/fam1/keyb.@defa} % \def\keybval{xx} @@ -4056,33 +4543,83 @@ % since the key names contain dot (.). Zapping the spaces in the % key name will not lead to a boolean of the \ifhp@key: \skvordkey[SKV]{definekeys}{.initialize}[true]{% - \skvifvalidboolval{#1}{% + \skvifboolvalT{#1}{% \csname skvdfk@initialize#1\endcsname }% } % Save default values as a kv list in macro <header>.@needini: \skvordkey[SKV]{definekeys}{.save initial values}[true]{% - \skvifvalidboolval{#1}{% + \skvifboolvalT{#1}{% \csname skvdfk@saveinitialvalues#1\endcsname }% } -%\skvsetkeys[SKV]{definekeys}{.initialize=false,.save initial values=false} +\skvrobustdef*\skvdfkinitialize{\skvdfk@initializetrue} +\skvrobustdef*\skvdfksaveinitialvalues{\skvdfk@saveinitialvaluestrue} +\skvrobustdef*\skvsetupdefinekeys#1{% + \skvsetkeys[SKV]{definekeys}{#1}% +} +\skvsetupdefinekeys{.initialize=false,.save initial values=false} + +\skvrobustdef*\skvdfkkeytypelet#1{% + \skvkvparse{#1}\skv@prova{% + \skvexpbracenext\skv@kvsplit\skv@prova{% + \skvifcsdefTF{skvdfk@typealias@##1}{% + \skv@err{Key type alias '##1' already defined}\@ehd + }{% + \skvifstrcmpTF{##2}{^skv^}{% + \skv@err{Key type alias '##1' has no master}\@ehd + }{% + \skvcsdef{skvdfk@typealias@##1}{##2}% + }% + }% + }% + }% +} +\skvdfkkeytypelet{% + .singleton=.choice, + .exec code=.exec, + .arg=.argx0,.args=.argx0, + .arg expanded once=.argx1, + .arg expanded twice=.argx2, + .arg expanded=.argxx, + .initialize keys after define=.initialize, + .initialize after define=.initialize, + .initialize keys=.initialize, + .save initial values=.saveini, + .save initial values of keys=.saveini, + .prepend to key name=.preptokey, + .prepend to every key name=.preptokey, + .append to key name=.apptokey, + .append to every key name=.apptokey, + .prepend to callback=.preptocode, + .prepend to every callback=.preptocode, + .append to callback=.apptocode, + .append to every callback=.apptocode, + .exec after define=.afterdef, + .after define=.afterdef, +} \skvnewdef*\skv@keyparser{,} -\skvnewdef*\skvdfk@afterdefinekeys{} -\skvrobustdef*\AfterDefineKeys{\skvgappendtomacro\skvdfk@afterdefinekeys} +\skvnewdef*\skvdfk@afterdefine@hook{} +\skvrobustdef*\skvafterdefinekeys{% + \skvgappendtomacro\skvdfk@afterdefine@hook +} \skvrobustdef*\skvdfk@testopta#1{% \skvifstar{% - \skv@sttrue\skvifplus + \skv@sttrue + \skvifplus {\skv@pltrue\skvdfk@testoptb#1}{\skv@plfalse\skvdfk@testoptb#1}% }{% - \skv@stfalse\skvifplus + \skv@stfalse + \skvifplus {\skv@pltrue\skvdfk@testoptb#1}{\skv@plfalse\skvdfk@testoptb#1}% }% } -\skvrobustdef*\skvdfk@testoptb#1{\skv@testopt{\skvdfk@t@stoptb{#1}}{KV}} +\skvrobustdef*\skvdfk@testoptb#1{% + \skv@testopt{\skvdfk@t@stoptb{#1}}\skv@defaultpref +} \skvrobustdef*\skvdfk@t@stoptb#1[#2]#3{% - \skvxifin{,}{\detokenize{#2}}{% + \skvxifinTF{,}{\detokenize{#2}}{% \skv@err{Only one prefix is allowed when calling \MessageBreak \noexpand\skvdefinekeys or similar commands, \MessageBreak but you gave '#2'}\@ehd @@ -4092,7 +4629,7 @@ % macro \skvdefinekeys. \edef\skv@checkkeyexist{\ifskv@st00\else01\fi}% \edef\skvdfk@pref{#2}% - \skvxifin{,}{\detokenize{#3}}{% + \skvxifinTF{,}{\detokenize{#3}}{% \edef\skvdfk@fams{#3}% \skvcsvnormalize\skvdfk@fams }{% @@ -4102,264 +4639,338 @@ \skv@testopt#1{userhp@}% }% } -\skvnewnumbers{skvdfk@depth} -\skvrobustdef*\skv@pushdefinekeys{% - \skvpushfunctions\skvdefinekeys{% - \do\skvdfk@pref\do\skvdfk@fams\do\skvdfk@currlist\do\skv@accumulated - \do\skv@acc@mulated\do\skv@igkeys\do\skvdfk@keys\do\skvdfk@keyvals - \do\skv@itemfour\do\skv@itemfive\do\skv@checkkeyexist\do\skv@hp - \do\skv@type\do\skv@typenr\do\skv@default\do\skv@isarg - \do\ifskvdfk@initialize\do\ifskvdfk@saveinitialvalues\do\ifskv@st - \do\ifskv@pl\do\skvcurrentprefix\do\skvcurrentfamily\do\skvcurrentkey - }\skvdfk@depth -} +% \skvedefinekeys has no stack, since everything is done in a local group. +% It is \skvmakekeys that has a stack. \skvrobustdef*\skvedefinekeys{% - \skv@pushdefinekeys \begingroup \endlinechar\m@ne - \skvdfk@testopta\skv@definekeys + \skvdfk@testopta\skv@definekeys@a } \skvrobustdef*\skvdefinekeys{% - \skv@pushdefinekeys \begingroup - \skvdfk@testopta\skv@definekeys + \skvdfk@testopta\skv@definekeys@a } -\skvrobustdef*\skv@definekeys[#1]#2{% - \skvexpanded{\endgroup - \skvcmdexitloop{\skv@checkkeyexist\skvdfk@pref\skvdfk@fams}% - \skvboolexit\ifskv@pl - }% +\skvrobustdef*\skv@definekeys@a[#1]#2{% \skvindeftrue + \def\skv@validtypes{% + .ord,.cmd,.zcmd,.bool,.zbool,.tog,.ztog,.choice,.choice*,% + .exec,.afterdef,.initialize,.saveini,.argx0,.argx1,.argx2,.argxx,% + .preptokey,.apptokey,.preptocode,.apptocode% + }% + \def\iftypeis##1\then{% + \ifnum\skv@strcmp{\skvoxdetok\skv@type}{\detokenize{##1}}=\skvz@ + }% + \def\skv@prependtoeverykeyname{}% + \def\skv@appendtoeverykeyname{}% + \def\skv@prependtoeverycallback{}% + \def\skv@appendtoeverycallback{}% \edef\skv@hp{#1}% \skvdespacecontent\skv@hp - \def\skv@accumulated{}% + \def\skv@accumulateonfams{}% \skv@makeprefix\skvdfk@pref \edef\skvdfk@currlist{\skvkeepdoubleslashnormalize{#2}}% - \def\skv@d@finekeys##1{% + \def\skv@definekeys@b##1{% \skv@makeheader{##1}% - \def\skv@acc@mulated{}% + \def\skv@accumulateonkeys{}% \def\skvdfk@keys{}% \def\skvdfk@keyvals{}% - \expandafter\skv@d@f@nekeys\expandafter{\skvdfk@currlist}% + \skvexpbracenext\skv@definekeys@c\skvdfk@currlist }% % If the plus variant is not specified, just take and use the first % family. - \skvifdefbool{skv@pl}{% + \skvifdefboolTF{skv@pl}{% \skvcommaloop*\skvdfk@fams\skv@tempa{% - \expandafter\skv@d@finekeys\expandafter{\skv@tempa}% + \skvexpbracenext\skv@definekeys@b\skv@tempa }% }{% \def\skv@prova##1,##2\skv@nil{% - \skv@d@finekeys{##1}% + \skv@definekeys@b{##1}% }% \expandafter\skv@prova\skvdfk@fams,\skv@nil }% - \skv@accumulated - \skvpopfunctions\skvdefinekeys\skvdfk@depth + \edef\skv@accumulateonfams{% + \skvxonce\skv@accumulateonfams + \skvxonce\skvdfk@afterdefine@hook\relax + }% + \expandafter\endgroup\skv@accumulateonfams \skvindeffalse - \skvdfk@afterdefinekeys\relax - \def\skvdfk@afterdefinekeys{}% + % 1. No need to reinitialize \skvdfk@afterdefine@hook here. Any changes + % done within the exited group haven't survived outside the group. + % 2. Don't call \skvdfk@initializefalse and \skvdfk@saveinitialvaluesfalse + % here while in \directkeys: this is reentered for each path. + \ifskvindirkeys\else + \skvdfk@initializefalse\skvdfk@saveinitialvaluesfalse + \fi } -\skvrobustdef*\skv@d@f@nekeys#1{% +\skvrobustdef*\skv@definekeys@c#1{% \edef\skv@igkeys{% - \skvifcsdef{\skv@header.@ignoredkeys}{% + \skvifcsname\skv@header.@ignoredkeys\then \skvexpandcsonce{\skv@header.@ignoredkeys}% - }{}% + \fi }% \def\skv@splita##1/##2/{\skv@splitb##1/##2/.}% \def\skv@splitb##1/##2/##3/##4/##5/##6/##7/##8/##9\skv@split@nil{% - \let\skv@gobble\relax - \edef\skv@type{\unexpanded{##1}}% - % Take the default early: it is needed in splitting multiple keys of - % the same type. In this case, the default value will not change - % until the splitting is completed. - \edef\skv@default{\skvexpandonce{\@gobble##3}}% - \def\skv@isarg{01}% - \def\skv@prova####1{% - \def\skv@prova########1####1########2########3\skv@nil{% - \def\skv@typenr{########2}% - \ifx\skv@typenr\skv@nnil - \skv@err{Invalid key type '####1'}\@ehd - \else - \ifnum\skv@typenr>6\relax - \ifnum\skv@typenr<11\relax - \def\skv@isarg{00}% - \fi - \fi - \fi - }% - \skv@prova .ord{0}.cmd{1}.zcmd{2}.bool{3}.zbool{4}.choice{5}% - .exec{6}.arg{7}.arg expanded{8}.arg expanded once{9}% - .arg expanded twice{10}.ords{11}.cmds{12}.zcmds{13}.bools{14}% - .zbools{15}.choices{16}.args{17}####1{\skv@nil}\skv@nil - }% - \expandafter\skv@prova\expandafter{\skv@type}% - \skvxifin{,\skv@typenr,}{,11,12,13,14,15,16,17,}{% - % Accumulate multiple keys of the same type: - \def\skv@prova####1s{\def\skv@type{####1}}% - \expandafter\skv@prova\skv@type - \skvcommaparse{##2}\skv@tempa{% - \skvexpanded{% - \noexpand\skv@splita - \skv@type/\skv@tempa/\skvexpandonce\skv@default/% - \unexpanded{##4/##5/##6/##7/##8/##9}\noexpand\skv@split@nil - }% - }% - % Skip the rest of \skv@splitb: - \let\skv@gobble\skv@gobbletoend + \skvxifinTF{\skv@hashchar}{\detokenize{##2}}{% + \skv@err{Key name(s) '\detokenize{##2}' contain hash character}\@ehd }{% - \skvifnum\skv@typenr=6{% - ##2% - \let\skv@gobble\skv@gobbletoend - }{% - % There may be multiple keys in ##2. So keep findpointers here, - % where multiple keys would have been split into separate units. - % For example, we can't check for ignored keys without first - % stripping the pointers: - \skv@strippointers{##2}\skvcurrentkey - \skvxifin{,\skvoxdetok\skvcurrentkey,}{,\skvoxdetok\skv@igkeys,}{% - \let\skv@gobble\skv@gobbletoend - }{% - \if\skv@isarg - \skvdfk@definearg\skv@type\skvcurrentkey\skv@default - \let\skv@gobble\skv@gobbletoend - \else - \let\skv@gobble\relax - \fi + % In case we have, eg, .exec=\def\x{?} instead of .exec/\def\x{?}: + \skvxifinTF{=}{\detokenize{##1}}{% + \skv@kvsplit{##1}{% + \edef\skv@type{\skvtrimspace{####1}}% + \edef\skv@itemtwo{\skvtrimspace{####2}}% }% + }{% + \edef\skv@type{\unexpanded{##1}}% + \edef\skv@itemtwo{\unexpanded{##2}}% }% }% - \skv@gobble + \skvifcsname skvdfk@typealias@\skv@type\then + \edef\skv@type{\skvcsuse{skvdfk@typealias@\skv@type}}% + \fi + \edef\skv@default{\skvexpandonce{\@gobble##3}}% + % To avoid mixing parameter characters in \skv@prova: + \edef\skv@rest{\unexpanded{{##4}/{##5}/{##6}/{##7}/{##8}/{##9}}}% + \skvexpbracenext\skv@definekeys@d\skv@type + }% + \def\skv@splitc##1/##2/##3/##4/##5/##6/##7/##8/##9\skv@split@nil{% \edef\skv@itemfour{\unexpanded{##4}}% \edef\skv@itemfive{\unexpanded{##5}}% - \skvxifin{\skv@hashchar}{\detokenize{##2}}{% - \skv@err{Key name '\detokenize{##2}' contains hash character}\@ehc - }{}% - \if\skv@checkkeyexist - \skvifcsdef{\skv@header\skvcurrentkey.@cbk}{% - \skv@err{Key '\skvcurrenttriple' already exists}\@ehd - }{}% - \fi - \ifnum\skv@typenr=5\relax - \edef\skv@prova{% - 0\ifx\skv@itemfour\@empty 1\else\ifx\skv@itemfour\skv@rej 1\fi\fi - }% - \ifcase\skv@prova\relax - \def\skv@altlista{}\def\skv@altlistb{}% - % \skv@itemfour is need here to hide unbalanced conditionals in ##4: - \expandafter\skv@getaltlist\expandafter{\skv@itemfour}% - \else - \skv@err{Empty alternate list for choice key '\skvcurrentkey'}\@ehd + \edef\skv@itemsix{\unexpanded{##6}}% + \skvifplaswTF\skv@isarg{% + \skvdfk@definearg{##1}{##2}{##3}% + }{% + \if\skv@checkkeyexist + \skvifcsname\skv@header##2.@cbk\then + \skv@err{Key '\skvcurrenttriple' already exists}\@ehd + \fi \fi - \fi - \edef\skvdfk@keys{\skvaddlist,\skvdfk@keys\skvcurrentkey}% - \skvxifboolval{\skvexpandonce\skv@default}\in@true\in@false - \edef\skvdfk@keyvals{% - \skvaddlist,\skvdfk@keyvals - % If a key has no default, then it can't be initialized. An empty - % default value should be indicated with a slash, eg, keya below: - % .cmd/keya/, .bool/keyb/true. - \expandafter\skv@ifrejorna\expandafter{\skv@default}{}{% - \skvcurrentkey=\skvifdefbool{in@}{false}{\skvxonce\skv@default}% - }% - }% - \edef\skv@acc@mulated{% - \skvexpandonce\skv@acc@mulated - \skvnoexpandcs{skv\expandafter\@gobble\skv@type key}% - \ifnum\skv@typenr=5*\fi - \ifnum\skv@typenr>2\ifnum\skv@typenr<6+\fi\fi - [\skvcurrentprefix]{\skvcurrentfamily}% - % ##2 should be inserted below instead of \skvcurrentkey, because - % \skvcurrentkey has had any possible pointer stripped: - \ifnum\skv@typenr>0\ifnum\skv@typenr<6[\skv@hp]\fi\fi - {##2}% - \ifnum\skv@typenr=5% no \relax here. - [\unexpanded{\skvuserinput\skvorder}]{\skvexpandonce\skv@altlista}% + \if\skv@ischoice + \skv@ifcmdnut\skv@itemfour{% + \skv@err{Empty nominations (state pattern) for + \MessageBreak choice key '##2'}\@ehd + }{}% \fi - % default: - \expandafter\skv@ifrejorna\expandafter{\skv@default}{}{% - [{\skvexpandonce\skv@default}]% + \edef\skvdfk@keys{\skvaddlist,\skvdfk@keys##2}% + \skvxifboolvalTF{\skvexpandonce\skv@default}\in@true\in@false + \edef\skvdfk@keyvals{% + \skvaddlist,\skvdfk@keyvals + \skv@ifcmdrejordotna\skv@default{}{% + ##2=\skvifdefboolTF{in@}{false}{\skvexpandonce\skv@default}% + }% }% - {% - % Key callback. If choice key, then the callback is item 5, - % otherwise it's item 4: - \skvifnum\skv@typenr=5{% - \skvifx\skv@itemfive\skv@rej{}{\skvexpandonce\skv@itemfive}% - \skv@executealt{########1}{\skvexpandonce\skv@altlistb}% - }{% - \skvifx\skv@itemfour\skv@rej{}{\skvexpandonce\skv@itemfour}% + \if\skv@isboolorchoice + \if\skv@ischoice + \let\skv@altact\skv@itemsix + \else + % bool or tog: + \let\skv@altact\skv@itemfive + \fi + \skv@ifcmdnut\skv@altact{\let\skv@altact\skvkeyvalueerror}{}% + \fi + \iftypeis.choice*\then + \def\skv@prova####1*{\def\skv@typeb{####1}}% + \expandafter\skv@prova\skv@type + \else + \let\skv@typeb\skv@type + \fi + % Remove leading dot (.): + \edef\skv@typeb{\expandafter\@gobble\skv@typeb}% + \edef\skv@accumulateonkeys{% + \skvexpandonce\skv@accumulateonkeys + \skvnoexpandcs{skv\skv@typeb key}% + \iftypeis.choice*\then*\fi + \if\skv@isboolorchoice+\fi + [\skvcurrentprefix]{\skvcurrentfamily}% + \if\skv@needhp[\skv@hp]\fi + {##2}% + \if\skv@ischoice + [\unexpanded{\skvuserinput\skvorder}]{\skvxonce\skv@itemfour}% + \fi + % default: + \skv@ifcmdrejordotna\skv@default{}{[{\skvxonce\skv@default}]}% + {% Key callback: + \skvxonce\skv@prependtoeverycallback + % If choice key, then the callback is item 5, otherwise + % it's item 4: + \if\skv@ischoice + \skv@ifcmdnut\skv@itemfive{}{\skvxonce\skv@itemfive}% + \else + \skv@ifcmdnut\skv@itemfour{}{\skvxonce\skv@itemfour}% + \fi + \skvxonce\skv@appendtoeverycallback }% + % Second branch of callback for '+' variants, now used for all + % boolean and choice keys: + \if\skv@isboolorchoice{\skvexpandonce\skv@altact}\fi }% - % Second branch of callback for '+' variants, now used for all - % boolean and choice keys: - \ifnum\skv@typenr>2\ifnum\skv@typenr<6{\skvkeyvalueerror}\fi\fi }% - \skv@gobble@nil }% \skvexpanded{\skvparselist{\skv@keyparser}}{#1}\skv@prova{% \expandafter\skv@splita\skv@prova /^skv^/^skv^/^skv^/^skv^/^skv^/^skv^/^skv^/^skv^\skv@split@nil }% - % 1. \skv@accumulated is a two-layer stack: there're loops on families - % and keys. + % 1. \skv@accumulateonfams is a two-layer stack: there're loops on + % families and keys. % 2. To save initial values of keys, the key names should be % entered by \skvsaveinitialvaluekeys in 'needini' list. This is % the case even when the boolean '.initialize' is true. See below. % 3. The boolean '.save initial values' is the one that will invoke % \skvsaveinitialvaluekeys below. - \edef\skv@accumulated{% - \skvexpandonce\skv@accumulated % looping on families - \skvifdefbool{skvdfk@saveinitialvalues}{% - \noexpand\skvsaveinitialvaluekeys[\skvcurrentprefix]% - {\skvcurrentfamily}{\skvexpandonce\skvdfk@keys}% - }{}% - \skvexpandonce\skv@acc@mulated % looping on keys - \skvifdefbool{skvdfk@initialize}{% - \noexpand\skvsetkeys[\skvcurrentprefix]% - {\skvcurrentfamily}{\skvexpandonce\skvdfk@keyvals}% - }{}% + \def\@elt{% + [\skvcurrentprefix]{\skvcurrentfamily}{\skvxonce\skvdfk@keyvals}% + }% + \edef\skv@accumulateonfams{% + \skvexpandonce\skv@accumulateonfams + \ifskvdfk@saveinitialvalues + \noexpand\skvsaveinitialvaluekeys\@elt + \fi + \skvexpandonce\skv@accumulateonkeys + \ifskvdfk@initialize + \noexpand\skvsetkeys\@elt + \fi + }% +} +\skvrobustdef*\skv@definekeys@d#1{% + \skvxifinFT{,#1,}{,\skv@validtypes,}{% + \skv@err{Invalid key type '#1' in \string\skvdefinekeys}\@ehd + }{% + \@tempswatrue + \iftypeis.exec\then + \@tempswafalse + \edef\skv@accumulateonkeys{% + \skvexpandonce\skv@accumulateonkeys\skvexpandonce\skv@itemtwo + }% + \else + \iftypeis.initialize\then + \@tempswafalse + \skv@ifcmdnut\skv@itemtwo{% + \edef\skv@itemtwo{true}% + }{% + \skvexpbracenext\skvifboolvalT\skv@itemtwo\relax + }% + \csname skvdfk@initialize\skv@itemtwo\endcsname + \edef\skv@accumulateonfams{% + \skvexpandonce\skv@accumulateonfams + \noexpand\csname skvdfk@initialize\skv@itemtwo\endcsname + }% + \else + \iftypeis.saveini\then + \@tempswafalse + \skv@ifcmdnut\skv@itemtwo{% + \edef\skv@itemtwo{true}% + }{% + \skvexpbracenext\skvifboolvalT\skv@itemtwo\relax + }% + \csname skvdfk@saveinitialvalues\skv@itemtwo\endcsname + \edef\skv@accumulateonfams{% + \skvexpandonce\skv@accumulateonfams + \noexpand\csname skvdfk@saveinitialvalues\skv@itemtwo + \endcsname + }% + \else + \iftypeis.preptokey\then + \@tempswafalse + \let\skv@prependtoeverykeyname\skv@itemtwo + \else + \iftypeis.apptokey\then + \@tempswafalse + \let\skv@appendtoeverykeyname\skv@itemtwo + \else + \iftypeis.preptocode\then + \@tempswafalse + \let\skv@prependtoeverycallback\skv@itemtwo + \else + \iftypeis.apptocode\then + \@tempswafalse + \let\skv@appendtoeverycallback\skv@itemtwo + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \skvifdefboolTF{@tempswa}{% + % Leave these tests here, so that they aren't repeated for each + % key in the next loop: + \def\do##1{\def##1{01}}% + \do\skv@isboolorchoice\do\skv@ischoice\do\skv@needhp\do\skv@isarg + \skvifinTF{,#1,}{,.choice,.choice*,}{% + \skvstripouterbraces{2}\skv@default + \def\skv@ischoice{00}% + \def\skv@isboolorchoice{00}% + \def\skv@needhp{00}% + }{% + \skvifinTF{,#1,}{,.bool,.zbool,.tog,.ztog,}{% + \def\skv@isboolorchoice{00}% + \def\skv@needhp{00}% + }{% + \skvifinTF{,#1,}{,.cmd,.zcmd,}{% + \def\skv@needhp{00}% + }{% + \skvifinTF{,#1,}{,.argx0,.argx1,.argx2,.argxx,}{% + \def\skv@isarg{00}% + }{}% + }% + }% + }% + \skvcommaprocess*\skv@itemtwo\skv@tempa{% + \skvexpbracenext\skv@strippointers\skv@tempa\skvcurrentkey + \edef\skvcurrentkey{% + \skv@prependtoeverykeyname\skvcurrentkey + \skv@appendtoeverykeyname + }% + \let\do\skvoxdetok + \skvxifinTF{,\do\skvcurrentkey,}{,\do\skv@igkeys,}{}{% + \edef\do{% + \noexpand\skv@splitc#1/\skvcurrentkey/% + {\skvexpandonce\skv@default}/\skvexpandonce\skv@rest + }% + \do\skv@split@nil + }% + }% + }{% + \skvifinFT{,#1,} + {,.preptokey,.apptokey,.preptocode,.apptocode,}{}{% + \let\skv@tempa\skv@itemtwo + \skvexpbracenext\skv@strippointers\skv@itemtwo\skv@itemtwo + \ifx\skv@tempa\skv@itemtwo\else + \skv@err{The token ||\skvoxdetok\skv@itemtwo|| + \MessageBreak shouldn't contain pointers for the + given key type or requested action}\@ehd + \fi + }% + }% }% } % % Assigning arguments within \skvdefinekeys: % -% Eg, .args/{key1,key2}/{#1/#2} +% Eg, .arg/{key1,key2}/{#1/#2} % \skvrobustdef*\skvdfk@definearg#1#2#3{% \begingroup - \toks@\expandafter{#3}% \def\skv@prova.arg##1\skv@nil{% - \if\relax\detokenize{##1}\relax - \def\skv@prova{x0}% - \else - \edef\skv@provb{\skvtrimspace{##1}}% - \def\skv@prova####1{% - \def\skv@prova########1####1########2########3\skv@nil{% - \def\skv@prova{########2}% - \ifx\skv@prova\skv@nnil - \def\skv@prova{x0}% - \fi - }% - \skv@prova - expanded{xx}expand once{x1}expand twice{x2}####1{\skv@nil}\skv@nil - }% - \expandafter\skv@prova\expandafter{\skv@provb}% - \fi + \edef\skv@prova{\skvtrimspace{##1}}% + }% + \skv@prova#1\skv@nil + \edef\skv@accumulateonkeys{% + \skvexpandonce\skv@accumulateonkeys + \skvcsedef{\skv@header#2.@\skv@prova arg}{% + \noexpand\unexpanded{\unexpanded{#3}}% + }% }% - \expandafter\skv@prova#1\skv@nil - \skvcsedef{\skv@header#2.@\skv@prova arg}{\the\toks@}% - \expandafter\skvaftergroupdef - \csname\skv@header#2.@\skv@prova arg\endcsname\endgroup + \skvaftergroupdef\skv@accumulateonkeys\endgroup } %+++++++++++++++++++++++ Keys for \skvmakekeys +++++++++++++++++++++++% % Example: % \skvmakekeys[ -% prefix=KVA, families={fam1,fam2}, hp=thp@, all new, -% define in all families, initialize=true, endlinechar=-1 +% .prefix=KVA, .families={fam1,fam2}, .hp=thp@, .all new, +% .define in all families, .initialize=true, .endlinechar=-1 % ]{% -% .ords/{keya,keyb}/{default-a}, -% .cmds/{keyc,keyd}/, +% .ord/{keya,keyb}/{default-a}, +% .cmd/{keyc,keyd}/, % .zcmd/key e/\def\cmde##1{##1}/ % \edef\y{\detokenize\expandafter{\thp@keye}}\def\x##1{#1*key e*##1}, % .choice/keyf/center/{center.do=\def\x##1{#1*##1},left,right}, @@ -4370,34 +4981,35 @@ % \skvsetkeys[KVA]{fam1}{keyb=.expand once{\keybval}} \skvedefinekeys*[SKV]{makekeys}[skvmk@]{% - .ords/{.new,.all new,.all are new}/true/ - \edef\skvmk@allnew{\skvifstrcmp{#1}{true}{00}{01}} + .ord/{.new,.all new,.all are new}/true/ + \edef\skvmk@allnew{0\skvifstrcmpTF{#1}{true}{0}{1}} , - .ords/{.initialize,.initialize after define}/true/ - \skvifvalidboolval{#1}{% + .ord/{.initialize,.initialize after define,.initialize keys after define} + /true/ + \skvifboolvalT{#1}{% \csname skvdfk@initialize#1\endcsname }% , - .ord/.save initial values/true/ - \skvifvalidboolval{#1}{% + .ord/.save initial values,.save initial values of keys/true/ + \skvifboolvalT{#1}{% \csname skvdfk@saveinitialvalues#1\endcsname }% , - .ords/{.endlinechar,.endline character}/13/ + .ord/{.endlinechar,.endline character}/13/ \def\skvmk@endlinechar{#1}, - .ords/{.define in all families,.in all families}/true/ - \edef\skvmk@inallfams{\skvifstrcmp{#1}{true}{00}{01}} + .ord/{.define in all families,.in all families}/true/ + \edef\skvmk@inallfams{0\skvifstrcmpTF{#1}{true}{0}{1}} , - .ord/.prefix/KV/ + .ord/.prefix/\skv@defaultpref/ \skviflacus#1\then - \def\skvmk@pref{KV}% + \let\skvmk@pref\skv@defaultpref \else \edef\skvmk@pref{#1}% \skvstripouterbraces{2}\skvmk@pref \fi , - .ords/{.holder prefix,.hp}/userhp@/\edef\skvmk@hp{#1}, - .ords/{.family,.families}/^skv^/ + .ord/{.holder prefix,.hp}/userhp@/\edef\skvmk@hp{#1}, + .ord/{.family,.families}/\@nil/ \skviflacus#1\then \skv@err{Key family is empty\on@line}\@ehd \else @@ -4406,6 +5018,7 @@ \fi , } + % Default settings for keys of \skvmakekeys. Presetting keys will be % inefficient here, since many of the keys have complements. It will be % necessary to include all the complements in the preset list, but doing @@ -4423,19 +5036,17 @@ \do\ifskvdfk@saveinitialvalues }\skv@makekeysdepth \skvsetkeys[SKV]{makekeys}{#1}% - \ifx\skvmk@fams\skv@rej + \ifx\skvmk@fams\@nnil \skv@err{No family specified for \string\skvmakekeys}\@ehd \fi - % Push the stack of \skvdefinekeys: - \skv@pushdefinekeys % The following \begingroup is ended in \skv@definekeys: \begingroup \skvexpanded{% \endlinechar=\skvmk@endlinechar\relax - \skvdfk@testopta\skv@definekeys + \skvdfk@testopta\skv@definekeys@a \if\skvmk@allnew*\fi\if\skvmk@inallfams+\fi [\skvmk@pref]{\skvmk@fams}% - [\ifx\skvmk@hp\@empty skvhp@\else\skvmk@hp\fi]% + [\ifx\skvmk@hp\@empty userhp@\else\skvmk@hp\fi]% }% {#2}% \skvpopfunctions\skvmakekeys\skv@makekeysdepth @@ -4444,52 +5055,19 @@ \skvrobustdef*\skvkeyvalueerror{% \skv@getinnoval\CurrentOption \skv@err{Erroneous value '\skv@ival' for key or option - \MessageBreak'\skvcurrentkey'} - {Invalid key value encountered.}% -} -\skvrobustdef*\skv@getaltlist#1{% - \begingroup - \def\skv@g@taltlist##1.do=##2.do=##3\skv@nil{% - \edef\skv@prova{\skvtrimspace{##1}}% - \edef\skv@provb{\skvoxdetok\skv@prova{\skvtrimspace{##2}}}% - \skvaddtolist*\skv@altlista\skv@prova - \skvaddtolist*\skv@altlistb\skv@provb - }% - \skvcommaparse{#1}\skv@prova{% - \expandafter\skv@g@taltlist\skv@prova.do=.do=\skv@nil - }% - \skvexpanded{\endgroup - \skvcmdexitloop{\skv@altlista\skv@altlistb}% - }% -} -\skvrobustdef*\skv@executealt#1#2{% - \edef\skv@prova{\skvtrimspace{#1}}% - \edef\skv@prova{\skvoxdetok\skv@prova}% - \def\skv@provb##1{% - \def\skv@provb####1##1####2####3\skv@nil{% - \edef\skv@prova{\unexpanded{####2}}% - \skvifx\skv@prova\skv@nnil{% - \skv@err{No alternate list match for key '\skvcurrentkey'}\@ehd - }{% - ####2% - }% - }% - }% - \expandafter\skv@provb\expandafter{\skv@prova}% - \skvexpandsecond{\skv@provb#2}\skv@prova{\skv@nil}\skv@nil + \MessageBreak'\skvcurrentkey'}{Invalid key value encountered.}% } \skvrobustdef*\skv@getinnoval#1{% \begingroup - \def\skv@prova##1=##2=##3\skv@nil{% + \skv@kvosplit{#1}{% \edef\skv@provb{\detokenize{##2}}% - \skvifx\skv@provb\@empty{% + \skvifxTF\skv@provb\@empty{% \def\skv@ival{???}% }{% \skv@getbasetoks{30}\skv@provb\skv@ival }% }% - \expandafter\skv@prova#1==\skv@nil \skvaftergroupdef\skv@ival\endgroup } % \skv@getbasetoks{<nr>}{<toks.cmd>}{<result.cmd>} @@ -4499,7 +5077,7 @@ \def#3{}\@tempcnta\skvz@ \def\do##1{% \def\skv@prova{##1}% - \skvifx\skv@prova\skv@nnil{}{% + \skvifxTF\skv@prova\skv@nnil{}{% \advance\@tempcnta\@ne \ifnum\@tempcnta<#1\relax \edef#3{#3\ifx\next\@sptoken\@space\fi##1}% @@ -4527,7 +5105,9 @@ % } % \skvsetkeys[KV]{fam}{unknownkey=val} % -\skvrobustdef*\skvunknownkeyhandler{\skv@testopt\skv@unknownkeyhandler{KV}} +\skvrobustdef*\skvunknownkeyhandler{% + \skv@testopt\skv@unknownkeyhandler\skv@defaultpref +} % For each prefix and family, this will define the functions % \<prefix>/<family>/.@famhandler of 4 parameters (prefix, family, % key name, current value). @@ -4547,27 +5127,26 @@ % .prefix=KVA,.families={fam1,fam2},.set in all families, % .save rm keys % ]{% -% key1,key2 +% key1=value1, key2=value2 % } - \skvmakekeys[ .prefix=SKV,.family=usekeys,.hp=skvuk@,.endlinechar=-1 ]{% - .ords/{.save rm,.save rm keys,.save unknown keys}/true/ - \edef\skvuk@saverm{\skvifstrcmp{#1}{true}{00}{01}} + .ord/{.save rm,.save rm keys,.save unknown keys}/true/ + \edef\skvuk@saverm{\skvifstrcmpTF{#1}{true}{00}{01}} , - .ords/{.set in all families,.in all families}/true/ - \edef\skvuk@inallfams{\skvifstrcmp{#1}{true}{00}{01}} + .ord/{.set in all families,.in all families}/true/ + \edef\skvuk@inallfams{\skvifstrcmpTF{#1}{true}{00}{01}} , - .ord/.prefix/KV/ + .ord/.prefix/\skv@defaultpref/ \skviflacus#1\then - \def\skvuk@pref{KV}% + \let\skvuk@pref\skv@defaultpref \else \edef\skvuk@pref{#1}% \skvstripouterbraces{2}\skvuk@pref \fi , - .ords/{.family,.families}/^skv^/ + .ord/{.family,.families}/\@nil/ \skviflacus#1\then \skv@err{Key family is empty\on@line}\@ehd \else @@ -4575,10 +5154,22 @@ \skvstripouterbraces{2}\skvuk@fams \fi , + .ord/{.path,paths}/\@nil/ + \skvifblankTF{#1}{% + \skv@err{Key family is empty\on@line}\@ehd + }{% + \edef\skvuk@paths{#1}% + \skvstripouterbraces{2}\skvuk@paths + \skvexpbracenext\skv@slashsplit\skvuk@paths{% + \skvsetkeys[SKV]{usekeys}{.prefix=##1,.family=##2}% + }% + }% + , } + % Default settings for keys of \skvusekeys: \skvsetkeys[SKV]{usekeys}{% - .prefix,.family=^skv^,.set in all families=false,.save rm=false + .prefix,.family=^skv^,.set in all families=false,.save rm=false% } \skvrobustdef*\skvusekeys{\skv@testopt\skv@usekeys{}} @@ -4587,7 +5178,7 @@ \do\skvuk@fams\do\skvuk@pref\do\skvuk@inallfams\do\skvuk@saverm }\skv@usekeysdepth \skvsetkeys[SKV]{usekeys}{#1}% - \ifx\skvuk@fams\skv@rej + \ifx\skvuk@fams\@nnil \skv@err{No family specified for \string\skvusekeys}\@ehd \fi \skvexpanded{% @@ -4600,34 +5191,41 @@ %++++++++++ Utilities for handlers of the macro \directkeys +++++++++++% \skvnewlet\handlereov\relax -\skvrobustdef*\directkeys{\skv@testst\dirkeys@parse} +% Undefine \dirkeys@handler@, in case a handler function is called +% without the handler name. Handler functions usually require +% 'dirkeys@handler@<handler.name>'. +\skvcsundef{dirkeys@handler@} + +\skvrobustdef*\directkeys{\skv@testst\skv@dirkeys@parse@a} \skvnewlet\dirkeys\directkeys -\skvrobustdef*\dirkeys@parse{% +\skvrobustdef*\skv@dirkeys@parse@a{% \begingroup \ifskv@tempst\endlinechar\m@ne\fi - \dirkeys@parse@a + \skv@dirkeys@parse@b } -\skvrobustdef*\dirkeys@parse@a#1{% +\skvrobustdef*\skv@dirkeys@parse@b#1{% \endgroup - \skvpushstate\dirkeys@state\dirkeys@depth - \indirkeystrue + \skvpushstate\skv@dirkeys@state\dirkeys@depth + \skvindirkeystrue % Note 1: Initialise all lists to empty. This note is referred to % somewhere: don't delete its number. \def\dirkeys@prefixlist{}% \def\dirkeys@familylist{}% \def\dirkeys@holderprefixtoks{}% \dirkeys@saveunknownkeysfalse + \skvdfk@initializefalse + \skvdfk@saveinitialvaluesfalse \edef\skv@tempa{\unexpanded{#1}}% \skvstripouterbraces{2}\skv@tempa \skvkvnormalize\skv@tempa - \def\dirkeys@do##1=##2=##3\dirkeys@nil{% + \def\skv@dirkeys@split##1=##2=##3\dirkeys@nil{% \edef\skv@tempa{\unexpanded{##2}}% \skvstripouterbraces{2}\skv@tempa \skvdespacecontent\skv@tempa % Get the first token, to test if it's \dirkeys. If it is, then % we have a nested \dirkeys: - \expandafter\skvifx\skv@car##1x\car@nil\dirkeys{% - \skvifempty\skv@tempa{% + \expandafter\skvifxTF\skv@car##1x\car@nil\dirkeys{% + \skvifemptyTF\skv@tempa{% ##1\relax }{% \skv@err{Something wrong with use of \string\dirkeys: @@ -4635,20 +5233,20 @@ }% }{% \skv@ensurehandlerdot{##1}% - \skvifcsdef{dirkeys@handler@##1}{% + \skvifcsdefTF{dirkeys@handler@##1}{% \csname dirkeys@handler@##1\expandafter\endcsname \skv@tempa\handlereov }{% \skv@err{Unknown handler '\detokenize{##1}'\MessageBreak - in command \string\dirkeys; or no '=' sign}\@ehd + in command \string\dirkeys, or no '=' sign}\@ehd }% }% }% - \skvexpanded{\skvparselist*{\skv@keyparser}}\skv@tempa\skv@tempa{% - \expandafter\dirkeys@do\skv@tempa==\dirkeys@nil + \skvexpanded{\skvdolist*{\skv@keyparser}}\skv@tempa\skv@tempa{% + \expandafter\skv@dirkeys@split\skv@tempa==\dirkeys@nil }% - \indirkeysfalse - \skvpopstate\dirkeys@state\dirkeys@depth + \skvindirkeysfalse + \skvpopstate\skv@dirkeys@state\dirkeys@depth } \skvrobustdef*\dirkeys@setdefaultroot{% \ifx\dirkeys@familylist\@empty @@ -4659,7 +5257,7 @@ \fi \fi \ifx\dirkeys@prefixlist\@empty - \def\dirkeys@prefixlist{KV}% + \let\dirkeys@prefixlist\skv@defaultpref \fi \ifx\dirkeys@holderprefixtoks\@empty \def\dirkeys@holderprefixtoks{user@}% @@ -4692,8 +5290,7 @@ \begingroup % #1 may contain parameter characters that may be confused with % ##1 and ##2 below. Hence we put it in the macro \skv@tempb. - % Ignored keys are always defined. This saves resources and has - % so far been harmless. + % Note: Ignored keys are omitted by \skvdefinekeys. \edef\skv@tempb{\unexpanded{#1}}% \def\skv@tempa{}% \def\do##1##2{% @@ -4718,9 +5315,9 @@ #2\ifdirkeys@saveunknownkeys*\else\ifskv@handlerswa*\fi\fi [##1]{##2}[\skvcsuse{##1/##2/.@ignoredkeys}]% % #1 may contain unbalanced conditionals; hence the need for - % \skvifdefbool here. When setting 'rm keys', then no + % \skvifdefboolTF here. When setting 'rm keys', then no % key list is needed here. - \skvifdefbool{skv@handlerswb}{}{{\skvexpandonce\skv@tempb}}% + \skvifdefboolTF{skv@handlerswb}{}{{\skvexpandonce\skv@tempb}}% }% }% \dirkeys@getcurrentroots\do @@ -4736,9 +5333,9 @@ \def\do##1##2{% \def\skv@tempb{}% \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% - \skvifdef\skv@igkeys{}{\def\skv@igkeys{}}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% \skvcommaparse{#1}\skv@tempa{% - \skvxifin{,\skvoxdetok\skv@tempa,}{,\skvoxdetok\skv@igkeys,}{}{% + \skvxifinTF{,\skvoxdetok\skv@tempa,}{,\skvoxdetok\skv@igkeys,}{}{% \edef\skv@tempb{% \skvexpandonce\skv@tempb\ifx\skv@tempb\@empty\else,\fi \skvexpandonce\skv@tempa @@ -4747,7 +5344,7 @@ }% \edef\skv@tempd{% \skvexpandonce\skv@tempd - \skvifempty\skv@tempb{}{% + \skvifemptyTF\skv@tempb{}{% \noexpand#2[##1]{##2}{\skvexpandonce\skv@tempb}% }% }% @@ -4805,16 +5402,46 @@ \skv@prova#1#2\skv@novalue#2\skv@nil } +% Pushing and popping prefix, family or holder prefix. +% +\skvnewnumbers[dirkeys@meta]{prefixdepth,familydepth,hpdepth} +\skvrobustdef*\dirkeys@pushmeta#1{% + \skvifcase\skvifstrcmpTF{#1}% + {prefix}{\def\@elt{prefixlist}}% + {family}{\def\@elt{familylist}}% + {hp}{\def\@elt{holderprefixtoks}}% + \elsedo + \skv@err{Unknown meta type '#1'}\@ehd + \endif + \skvaftercs\skvgadvanceno{dirkeys@meta#1depth}\@ne + \edef\skv@elt{\skvrom\csname dirkeys@meta#1depth\endcsname}% + \skvcsletcs{dirkeys@\@elt @meta@\skv@elt}{dirkeys@\@elt}% +} +\skvrobustdef*\dirkeys@popmeta#1{% + \skvifcase\skvifstrcmpTF{#1}% + {prefix}{\def\@elt{prefixlist}}% + {family}{\def\@elt{familylist}}% + {hp}{\def\@elt{holderprefixtoks}}% + \elsedo + \skv@err{Unknown meta type '#1'}\@ehd + \endif + \edef\skv@elt{\skvrom\csname dirkeys@meta#1depth\endcsname}% + \skvcsletcs{dirkeys@\@elt}{dirkeys@\@elt @meta@\skv@elt}% + \skvaftercs\skvgadvanceno{dirkeys@meta#1depth}\m@ne +} + % Assigning admissible values to keys. The handlers here are: % -% .choice, .choice expanded, .choice expanded once, .choice expanded twice. +% .state pattern, .state pattern expanded, .state pattern expanded once, +% .state pattern expanded twice. % % \dirkeys@savechoice{<list>}{<expander.type>} % % 1. <list> has the form % -% <key1>/{<ch1>.do={<act1>},...,<ch-n>.do={<act-n>}},..., -% <key-n>/{<ch1>.do={<act1>},...,<ch-n>.do={<act-n>}} +% {<key1,...,keyn>}/{<ch1>.do={<act1>},...,<ch-n>.do={<act-n>}} +% ,..., +% <keyx-n>/{<ch1>.do={<act1>},...,<ch-n>.do={<act-n>}} % % 2. If it didn't exist, the main key (eg, the above <key1>) will be % defined with an empty default value and an empty callback. @@ -4835,30 +5462,32 @@ \skvkvnormalize\skvcurrentsub \def\skv@doonroot##1##2{% \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% - \skvifdef\skv@igkeys{}{\def\skv@igkeys{}}% - \skvxifin{,\skvcurrentmaintoks,}{,\skv@igkeys,}{}{% - \skvifcsdef{##1/##2/\skvcurrentmaintoks.@cbk}{}{% - \edef\skv@tempd{% - \skvexpandonce\skv@tempd - \skvordkey[##1]{##2}{\skvcurrentmaintoks}[]{}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% + \skvcommaparse*\skvcurrentmaintoks\skv@tempb{% + \skvxifinTF{,\skv@tempb,}{,\skv@igkeys,}{}{% + \skvifcsdefTF{##1/##2/\skv@tempb.@cbk}{}{% + \edef\skv@tempd{% + \skvexpandonce\skv@tempd + \skvordkey[##1]{##2}{\skv@tempb}[]{}% + }% }% - }% - \def\skv@choicelist{}% - \skvcommaloop*\skvcurrentsub\skv@tempa{% - \def\skv@prova####1.do=####2.do=####3\skv@nil{% - \edef\skv@choicelist{% - \skvexpandonce\skv@choicelist - {\skvtrimspace{####1}}{\skvtrimspace{####2}}% + \def\skv@choicelist{}% + \skvcommaloop*\skvcurrentsub\skv@tempa{% + \def\skv@prova####1.do=####2.do=####3\skv@nil{% + \edef\skv@choicelist{% + \skvexpandonce\skv@choicelist + {\skvtrimspace{####1}}{\skvtrimspace{####2}}% + }% }% + \expandafter\skv@prova\skv@tempa.do=.do=\skv@nil }% - \expandafter\skv@prova\skv@tempa.do=.do=\skv@nil }% - }% - \edef\skv@tempd{% - \skvexpandonce\skv@tempd - \skvappendkeycode[##1]{##2}{\skvcurrentmaintoks}% - {\dirkeys@executechoice{#2}{########1}% - {\skvexpandonce\skv@choicelist}}% + \edef\skv@tempd{% + \skvexpandonce\skv@tempd + \skvappendkeycode[##1]{##2}{\skv@tempb}% + {\dirkeys@executechoice{#2}{########1}% + {\skvexpandonce\skv@choicelist}}% + }% }% }% \skv@rootlist @@ -4870,10 +5499,10 @@ \skvdespacecontent\skv@prova \def\do##1##2##3\skv@nil{% \edef\skv@provb{\unexpanded{##1}}% - \skvifx\skv@provb\skv@prova{% + \skvifxTF\skv@provb\skv@prova{% ##2% }{% - \skvifblank{##3}{% + \skvifblankTF{##3}{% \skv@err{No choice match found for key '\skvcurrentkey'}\@ehd }{% \do##3\skv@nil @@ -4933,36 +5562,35 @@ \skvkvnormalize\skvcurrentsub \def\skv@doonroot##1##2{% \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% - \skvifdef\skv@igkeys{}{\def\skv@igkeys{}}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% \skvcommaloop*\skvcurrentmaintoks\skv@maintoks{% - \skvxifin{,\skv@maintoks,}{,\skv@igkeys,}{}{% - \skvifcsdef{##1/##2/\skv@maintoks.@cbk}{}{% + \skvxifinTF{,\skv@maintoks,}{,\skv@igkeys,}{}{% + \skvifcsdefTF{##1/##2/\skv@maintoks.@cbk}{}{% % Link keys should always be set with a value. If they were % undefined before being designated as a link key, then % clearly they should have no default. \edef\skv@tempd{% \skvexpandonce\skv@tempd - \skvordkey[##1]{##2}{.value required{\skv@maintoks}}{}% + \skvordkey[##1]{##2}{.need value{\skv@maintoks}}{}% }% }% \def\skv@stylelist{}% \skvcommaloop*\skvcurrentsub\skv@tempa{% - \def\skv@prova####1=####2=####3\skv@nil{% - \skvxifstrcmp{\skv@maintoks}{####1}{% + \skv@kvosplit\skv@tempa{% + \skvxifstrcmpTF{\skv@maintoks}{####1}{% \skv@err{Linking key '####1' to itself}\@ehd }{% - \skvifcsdef{##1/##2/####1.@cbk}{}{% + \skvifcsdefTF{##1/##2/####1.@cbk}{}{% \skv@err{Style key '####1' is undefined}\@ehd }% }% - \skvxifin{,####1,}{,\skv@igkeys,}{}{% + \skvxifinTF{,####1,}{,\skv@igkeys,}{}{% \edef\skv@stylelist{% \skvaddlist,\skv@stylelist\unexpanded{####1}=% \skvexpandonce\skvexpander{\unexpanded{####2}}% }% }% }% - \expandafter\skv@prova\skv@tempa==\skv@nil }% }% \edef\skv@tempd{% @@ -4970,7 +5598,7 @@ % The styles contain value expanders \@firstofone, \unexpanded, etc. % They will be expanded by the next \skvexpanded when the main key % is set. - \skvifstrcmp{#2}{app}\skvappendkeycode\skvprependkeycode + \skvifstrcmpTF{#2}{app}\skvappendkeycode\skvprependkeycode [##1]{##2}{\skv@maintoks}% {\skvexpanded{\skvsetkeys[##1]{##2}% {\skvexpandonce\skv@stylelist}}}% @@ -5044,12 +5672,12 @@ \skvkvnormalize\skv@tempd \def\skv@doonroot##1##2{% \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% - \skvifdef\skv@igkeys{}{\def\skv@igkeys{}}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% \skvcommaloop*\skv@tempd\skv@tempa{% - \def\skv@prova####1=####2=####3\skv@nil{% - \skvxifin{,####1,}{,\skv@igkeys,}{}{% - \skvifcsdef{##1/##2/####1.@cbk}{% - \skvifblank{####2}{}{% + \skv@kvosplit\skv@tempa{% + \skvxifinTF{,####1,}{,\skv@igkeys,}{}{% + \skvifcsdefTF{##1/##2/####1.@cbk}{% + \skvifblankTF{####2}{}{% \edef\skv@tempe{% \skvexpandonce\skv@tempe\unexpanded{% \skvcsedef{##1/##2/####1.@#2arg}{\unexpanded{####2}}% @@ -5061,7 +5689,6 @@ }% }% }% - \expandafter\skv@prova\skv@tempa==\skv@nil }% }% \dirkeys@getcurrentroots\skv@doonroot @@ -5075,7 +5702,7 @@ \def\skv@defaultlist{}% \skvcommaparse{#3}\skvcurrentkey{% \skvletcs\skv@prova{#1/#2/\skvcurrentkey.@defa}% - \skvifdef\skv@prova{% + \skvifdefTF\skv@prova{% \skv@getdefault{#1}{#2}\skvcurrentkey\skvcurrentvalue \edef\skv@defaultlist{% \skvaddlist,\skv@defaultlist @@ -5095,13 +5722,13 @@ \begingroup \def\skv@tempa{}\def\skv@tempb{}% \def\do##1##2{% - \skvxifin{,##1,}{,\skv@tempa,}{}{% + \skvxifinTF{,##1,}{,\skv@tempa,}{}{% \edef\skv@tempa{% \skvexpandonce\skv@tempa \ifx\skv@tempa\@empty\else,\fi##1% }% }% - \skvxifin{,##2,}{,\skv@tempb,}{}{% + \skvxifinTF{,##2,}{,\skv@tempb,}{}{% \edef\skv@tempb{% \skvexpandonce\skv@tempb \ifx\skv@tempb\@empty\else,\fi##2% @@ -5117,7 +5744,7 @@ %%++++++++++++++++++++++++++ Try setting keys +++++++++++++++++++++++%% % % \skvtrysetkeys[<options>]{<keyvals>} -% .try set keys={<options>}{<keyvals>} +% .try set keys={<options>} % % Try to set a given key-value list on the paths given by the independent % options '.prefix/.prefixes' and '.family/.families' of \skvtrysetkeys. If @@ -5182,43 +5809,95 @@ % paths KV1/fam1, KV1/fam2, KV2/fam1, KV2/fam2, and you set '.try=2' or % '.upper goal=2', then only 2 paths will be traversed; not the desired 4. +\skvrobustdef*\dirkeys@trysetkeys#1{% + \begingroup + \@tempcnta\skvz@ + \def\skv@tempc{}% + \def\skv@tempd{}% + \def\skv@tempa##1={% + \begingroup + \let\bgroup\relax + \@ifnextchar\skv@orig@bgroup{% + \endgroup\@tempswatrue\skv@tempb##1=% + }{% + \endgroup\@tempswafalse\skv@tempb##1=% + }% + }% + \def\skv@tempb##1=##2=##3\skv@nil{% + \skvxifinTF{,##1,}{,.key values,.kv,.kv list,}{% + \advance\@tempcnta\@ne + \skvifnumTF\@tempcnta>\@ne{% + \skv@err{Multiple entries for key '.key values' or '.kv'}\@ehd + }{% + \edef\skv@tempd{\skvifstrcmpTF{##2}{^skv^}{}{\unexpanded{##2}}}% + }% + }{% + \edef\skv@tempc{% + \skvexpandonce\skv@tempc\ifx\skv@tempc\@empty\else,\fi + ##1% + \skvifstrcmpTF{##2}{^skv^}{}{% + =\if@tempswa{\fi\unexpanded{##2}\if@tempswa}\fi + }% + }% + }% + }% + \skvkvparse{#1}\skv@prova{% + \expandafter\skv@tempa\skv@prova=^skv^=\skv@nil + }% + \ifx\skv@tempd\@empty + \skv@err{No key-value pairs for handler '.try set keys'}\@ehd + \fi + \skvexpanded{\endgroup + \noexpand\skv@trysetkeys[\skvexpandonce\skv@tempc]% + {\skvexpandonce\skv@tempd}% + }% +} \skvedefinekeys[SKV]{skvtryset}[skvtry@]{% - .ords/{.try,.max attempt,.max attempts,.total}/12/ - \edef\skvtry@maxattempts{\number#1}% + .ord/{.try,.max attempt,.max attempts,.total}/12/ + \def\skvtry@maxattempts{#1}% + \skvstripouterbraces{2}\skvtry@maxattempts + \edef\skvtry@maxattempts{\number\skvtry@maxattempts}% \skvensureinteger{.max attempt}\skvtry@maxattempts - \ifnum#1<\@ne + \ifnum\skvtry@maxattempts<\@ne \skv@err{The max. number of attempts ('try') \MessageBreak can't be less than 1}\@ehd \fi , - .ords/{.upper goal,.max success,.max hits}/1/ - \edef\skvtry@maxsuccess{\number#1}% + .ord/{.upper goal,.max success,.max hits}/1/ + \def\skvtry@maxsuccess{#1}% + \skvstripouterbraces{2}\skvtry@maxsuccess + \edef\skvtry@maxsuccess{\number\skvtry@maxsuccess}% \skvensureinteger{upper goal}\skvtry@maxsuccess - \ifnum#1<\@ne + \ifnum\skvtry@maxsuccess<\@ne \skv@err{The max. number of successful attempts \MessageBreak ('upper goal') can't be less than 1}\@ehd \fi , - .ords/{.min success,.lower goal,.goal}/1/ - \edef\skvtry@minsuccess{\number#1}% + .ord/{.min success,.lower goal,.goal}/1/ + \def\skvtry@minsuccess{#1}% + \skvstripouterbraces{2}\skvtry@minsuccess + \edef\skvtry@minsuccess{\number\skvtry@minsuccess}% \skvensureinteger{lower goal}\skvtry@minsuccess - \ifnum#1<\@ne + \ifnum\skvtry@minsuccess<\@ne \skv@err{The min. number of successful attempts \MessageBreak ('lower goal') can't be less than 1}\@ehd \fi , - .ords/{.prefix,.prefixes,.add prefix,.add prefixes}/KV/ + .ord/{.prefix,.prefixes,.add prefix,.add prefixes}/\skv@defaultpref/ \edef\skvtry@prefs{#1} \skvstripouterbraces{2}\skvtry@prefs - \edef\skvtry@prefs{\skvifempty\skvtry@prefs{KV}{\skvtry@prefs}}% + \edef\skvtry@prefs{% + \skvifemptyTF\skvtry@prefs\skv@defaultpref\skvtry@prefs + }% \ifskv@insa \skvexpbracenext{\skvmergelist\skvtry@prefs}\dirkeys@prefixlist \fi \skvcsvnormalize\skvtry@prefs , - .ords/{.family,.families,.add family,.add families}/^skv^/ + .ord/{.family,.families,.add family,.add families}/\@nil/ \edef\skvtry@fams{#1} - \ifx\skvtry@fams\skv@rej\else + \skvstripouterbraces{2}\skvtry@fams + \ifx\skvtry@fams\@nnil\else \skvstripouterbraces{2}\skvtry@fams \ifskv@insa \skvexpbracenext{\skvmergelist\skvtry@fams}\dirkeys@familylist @@ -5226,26 +5905,30 @@ \skvcsvnormalize\skvtry@fams \fi , - .ords/{.path,.paths,.add path,.add paths,.root,.roots}/^skv^/ + .ord/{.path,.paths,.add path,.add paths,.root,.roots}/\@nil/ \edef\skv@tempa{\skvtrimspace{#1}} \skvstripouterbraces{2}\skv@tempa - \ifcase0\ifx\skv@tempa\skv@rej1\else + \ifcase0\ifx\skv@tempa\@nnil1\else \ifx\skv@tempa\@empty1\fi\fi\relax\skvafterfi - \skvexpbracenext\skvtry@fixpaths\skv@tempa + \skvexpbracenext\skvtry@processpaths\skv@tempa \fi , - .ords/{.ignore keys,.filter keys}// + .ord/{.ignore keys,.filter keys}// \def\skvtry@igkeys{#1} \skvstripouterbraces{2}\skvtry@igkeys , - .ords/{.save known keys,.save success}/true/ - \edef\skvtry@savesuccess{0\skvifstrcmp{#1}{true}01} + .ord/{.save known keys,.save success}/true/ + \def\skvtry@savesuccess{#1} + \skvstripouterbraces{2}\skvtry@savesuccess + \edef\skvtry@savesuccess{0\ifx\skvtry@savesuccess\skv@truetoks0\else1\fi} , - .ords/{.save known keys in,.success list,.success list macro}/ - \skvsuccesslist/\def\skvtry@successlistmacro{#1} + .ord/{.save known keys in,.success list,.success list macro}/ + \skvsuccesslist/ + \def\skvtry@successlistmacro{#1} + \skvstripouterbraces{2}\skvtry@successlistmacro , } -\skvrobustdef*\skvtry@fixpaths#1{% +\skvrobustdef*\skvtry@processpaths#1{% \def\skvtry@prefs{}% \def\skvtry@fams{}% \def\skv@tempc##1/##2/##3\skv@nil{% @@ -5278,44 +5961,44 @@ \skvrobustdef*\skvtrysetkeys{\skv@testopt\skv@trysetkeys{}} \skvrobustdef*\skv@trysetkeys[#1]#2{% \skvpushfunctions\skvtrysetkeys{% - % Don't include \skvsuccesslist here! \do\skvtry@fams\do\skvtry@prefs\do\skvtry@maxattempts \do\skvtry@minsuccess\do\skvtry@maxsuccess\do\skvtry@igkeys \do\skvtry@successlistmacro\do\skvtry@savesuccess + \do\CurrentOption\do\skv@tempsuccesslist + \do\skvcurrentkey\do\skvcurrentpath + \do\skvcurrentprefix\do\skvcurrentfamily }\skv@trysetkeysdepth \skvsetkeys[SKV]{skvtryset}{#1}% \ifx\skvtry@fams\skv@rej \skv@err{No families in which to 'try' to set keys}\@ehd \fi \skv@getkeynames{#2}\skv@naa - \ifnum\skv@trysetkeysdepth=\@ne - \expandafter\def\skvtry@successlistmacro{}% - \def\skv@tempsuccesslist{}% - \fi + \expandafter\def\skvtry@successlistmacro{}% + \def\skv@tempsuccesslist{}% \skv@intrytrue \skvcommaparse{#2}\CurrentOption{% \expandafter\skv@g@tkeyname\CurrentOption=\skv@nil\skvcurrentkey - \skvxifin{,\skvcurrentkey,}{,\skvtry@igkeys,}{}{% + \skvxifinTF{,\skvcurrentkey,}{,\skvtry@igkeys,}{}{% + \skvpushfunctions\skv@trysetkeys@istate{% + \do\CurrentOption\do\skvcurrentkey\do\skvcurrentpath + \do\skvcurrentprefix\do\skvcurrentfamily + \do\skv@attempts\do\skv@hits\do\skv@breakprefloop + \do\ifskv@success + }\skv@trysetkeysdepth@b \skv@successfalse - % Don't use \chardef here; it won't printed in the error message + % Don't use \chardef here; it won't print in the error message % if it wasn't incremented: \def\skv@attempts{0}% \def\skv@hits{0}% \def\skv@breakprefloop{01}% \skvcommaloop*\skvtry@prefs\skvcurrentprefix{% \skvcommaloop*\skvtry@fams\skvcurrentfamily{% - \skvpushfunctions\skv@trysetkeys@istate{% - \do\CurrentOption\do\skvcurrentkey\do\skvcurrentprefix - \do\skvcurrentfamily\do\skv@attempts\do\skv@hits - \do\skv@breakprefloop\do\ifskv@success - }\skv@trysetkeysdepth@b \skvexpanded{% % Don't use \skv@setkeys@a here: \skv@fams, etc. % will be mixed up. \skvsetkeys[\skvcurrentprefix]{\skvcurrentfamily}% {\skvexpandonce\CurrentOption}% }% - \skvpopfunctions\skv@trysetkeys@istate\skv@trysetkeysdepth@b \edef\skv@attempts{\the\numexpr\skv@attempts+1}% \ifskv@success \edef\skv@hits{\the\numexpr\skv@hits+1}% @@ -5346,6 +6029,7 @@ \noexpand\skvtrysetkeys\fi. \MessageBreak Actual hits were '\skv@hits'}\@ehd \fi + \skvpopfunctions\skv@trysetkeys@istate\skv@trysetkeysdepth@b }% }% \expandafter\let\skvtry@successlistmacro\skv@tempsuccesslist @@ -5361,7 +6045,10 @@ %%+++++++++++++++++++++++++ 'search also' set keys +++++++++++++++++++%% % % \skvsasetkeys[<options>]{<keyvals>} -% .sa set keys={<options>}{<keyvals>} +% .sa set keys={<options>} +% +% When using '.sa set keys', the key '.key values' must be part of +% <options>. % % 1. The only difference between \skvsasetkeys and \skvtrysetkeys is that, % when in \directkeys, the values of the options <prefix/prefixes> and @@ -5373,11 +6060,11 @@ % 2. All the options of \skvtrysetkeys apply to \skvsasetkeys. \skvnewlet\skvsasetkeys\skvtrysetkeys -\skvrobustdef*\dirkeys@dosasetkeys#1{% +\skvrobustdef*\dirkeys@sasetkeys#1{% \skv@insatrue - \skvifundef\dirkeys@familylist{\def\dirkeys@familylist{}}{}% - \skvifundef\dirkeys@prefixlist{\def\dirkeys@prefixlist{}}{}% - \skv@trysetkeys[#1]% + \skvifdefTF\dirkeys@familylist{}{\def\dirkeys@familylist{}}% + \skvifdefTF\dirkeys@prefixlist{}{\def\dirkeys@prefixlist{}}% + \dirkeys@trysetkeys{#1}% } % \dirkeys@addorremoveroots{<list>}{<operator>} @@ -5386,21 +6073,38 @@ \skvcsvnormalize[/]\skv@prova \def\skv@tempa{}\def\skv@tempb{}% \skvcommaparse*\skv@prova\skv@prova{% - \def\skv@provb##1/##2/##3\skv@nil{% - \skvxifin{,##1,}{,\skv@tempa,}{}{% - \edef\skv@tempa{\skv@tempa\ifx\skv@tempa\@empty\else,\fi##1}% + \skv@trimslashes\skv@prova + \skvexpbracenext\skv@slsplit\skv@prova{% + \skvifstrcmpTF{##2}{^skv^}{% + \let\skv@prova\skv@defaultpref + \def\skv@provb{##1}% + }{% + \def\skv@prova{##1}\def\skv@provb{##2}% + }% + \skvxifinTF{,\skv@prova,}{,\skv@tempa,}{}{% + \edef\skv@tempa{\skv@tempa\ifx\skv@tempa\@empty\else,\fi\skv@prova}% }% - \skvxifin{,##2,}{,\skv@tempb,}{}{% - \edef\skv@tempb{\skv@tempb\ifx\skv@tempb\@empty\else,\fi##2}% + \skvxifinTF{,\skv@provb,}{,\skv@tempb,}{}{% + \edef\skv@tempb{\skv@tempb\ifx\skv@tempb\@empty\else,\fi\skv@provb}% }% }% - \expandafter\skv@provb\skv@prova//\skv@nil }% \skv@clfalse \skvexpbracenext{#2\dirkeys@prefixlist}\skv@tempa \skvexpbracenext{#2\dirkeys@familylist}\skv@tempb } - +\skvrobustdef*\skv@trimslashes#1{% + \begingroup + \skvxifinFT{\skvrelax/}{\skvrelax#1}{}{% + \def\do/##1\skv@nil{\def#1{##1}}% + \expandafter\do#1\skv@nil + }% + \skvxifinFT{/\skvrelax}{#1\skvrelax}{}{% + \def\do##1/\skv@nil{\def#1{##1}}% + \expandafter\do#1\skv@nil + }% + \skvaftergroupdef#1\endgroup +} % \dirkeys@addtocodeorvalue{app/pre}{cbk/value}{<list>} \skvrobustdef*\dirkeys@addtocodeorvalue#1#2#3{% @@ -5411,16 +6115,16 @@ % ##1=prefix, ##2=family \def\do##1##2{% \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% - \skvifdef\skv@igkeys{}{\def\skv@igkeys{}}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% \skvkvparse*\skv@tempa\skv@tempa{% \expandafter\skv@kvsplit\expandafter{\skv@tempa}{% - \skvxifin{,\detokenize{####1},}{,\skvoxdetok\skv@igkeys,}{}{% + \skvxifinTF{,\detokenize{####1},}{,\skvoxdetok\skv@igkeys,}{}{% \skvletcs\skv@prova{##1/##2/####1.@#2}% - \skvifundef\skv@prova{% + \skvifdefFT\skv@prova{% \skv@err{Key '####1' isn't in family '##1/##2'}\@ehd }{% \skvcsedef{##1/##2/####1.@#2}{% - \skvifstrcmp{#1}{pre}{% + \skvifstrcmpTF{#1}{pre}{% \skvtrimspace{####2}\skvexpandonce\skv@prova }{% \skvexpandonce\skv@prova\skvtrimspace{####2}% @@ -5449,11 +6153,11 @@ % ##1=prefix, ##2=family \def\do##1##2{% \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% - \skvifdef\skv@igkeys{}{\def\skv@igkeys{}}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% \skvkvparse*\skv@tempa\skv@tempa{% \expandafter\skv@kvsplit\expandafter{\skv@tempa}{% - \skvxifin{,\detokenize{####1},}{,\skvoxdetok\skv@igkeys,}{}{% - \skvifcsdef{##1/##2/####1.@cbk}{% + \skvxifinTF{,\detokenize{####1},}{,\skvoxdetok\skv@igkeys,}{}{% + \skvifcsdefTF{##1/##2/####1.@cbk}{% \skvcsedef{##1/##2/####1.@defa}{% \skvnoexpandcs{##1/##2/####1}{\skvtrimspace{####2}}% }% @@ -5482,11 +6186,11 @@ % ##1=prefix, ##2=family \def\do##1##2{% \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% - \skvifdef\skv@igkeys{}{\def\skv@igkeys{}}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% \skvkvparse*\skv@tempa\skv@tempa{% \expandafter\skv@kvsplit\expandafter{\skv@tempa}{% - \skvxifin{,\detokenize{####1},}{,\skvoxdetok\skv@igkeys,}{}{% - \skvifcsdef{##1/##2/####1.@cbk}{% + \skvxifinTF{,\detokenize{####1},}{,\skvoxdetok\skv@igkeys,}{}{% + \skvifcsdefTF{##1/##2/####1.@cbk}{% \skvcsedef{##1/##2/####1.@value}{\skvtrimspace{####2}}% \edef\skv@tempb{% \skvexpandonce\skv@tempb @@ -5503,19 +6207,19 @@ \skvexpanded{\endgroup\skv@tempb}% } -% \dirkeys@inherit{value/cbk/defa}{<list>} +% \dirkeys@inherit{value.or.cbk.or.defa}{<list>} \skvrobustdef*\dirkeys@inherit#1#2{% % Hid the list from the parameters of \do: \edef\skv@tempa{\unexpanded{#2}}% % ##1=prefix, ##2=family \def\do##1##2{% \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% - \skvifdef\skv@igkeys{}{\def\skv@igkeys{}}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% \skvkvparse*\skv@tempa\skv@tempa{% \expandafter\skv@slsplit\expandafter{\skv@tempa}{% - \skvxifin{,\detokenize{####1},}{,\skvoxdetok\skv@igkeys,}{}{% - \ifcase\skvifcsdef{##1/##2/####1.@cbk}{0}{1}% - \skvifcsdef{##1/##2/####2.@cbk}{0}{1}\relax + \skvxifinTF{,\detokenize{####1},}{,\skvoxdetok\skv@igkeys,}{}{% + \ifcase\skvifcsdefTF{##1/##2/####1.@cbk}{0}{1}% + \skvifcsdefTF{##1/##2/####2.@cbk}{0}{1}\relax \skvcsletcs{##1/##2/####1.@#1}{##1/##2/####2.@#1}% \else \skv@err{Key '####1' or '####2' isn't in family '##1/##2'}\@ehd @@ -5527,17 +6231,21 @@ \dirkeys@getcurrentroots\do } -% \dirkeys@setbooleanhandler{<handler>}{<boolean>}{<bool value>} +% \dirkeys@setbooleanhandler{<handler>}{<boolean>}{<bool.value>} \skvrobustdef*\dirkeys@setbooleanhandler#1#2#3{% - \skvifblank{#3}{% - \csname#2true\endcsname - }{% - \skvifboolval{#3}{% - \csname#2#3\endcsname + \skvifcsdefTF{if#2}{% + \skvifblankTF{#3}{% + \csname#2true\endcsname }{% - \skv@err{Invalid value '\detokenize{#3}' for handler '#1': - \MessageBreak its expects either 'true' or 'false'}\@ehd + \skvifboolvalTF{#3}{% + \csname#2#3\endcsname + }{% + \skv@err{Invalid value '\detokenize{#3}' for handler '#1': + \MessageBreak its expects either 'true' or 'false'}\@ehd + }% }% + }{% + \skv@err{No boolean '\detokenize{#2}'}\@ehd }% } @@ -5546,68 +6254,89 @@ \skv@err{A dot (.) must lead handler name '#1'}\@ehd \fi } -\skvrobustdef*\skv@handlerloop#1{% +\skvrobustdef*\dirkeys@handlerloop#1{% \edef\skv@tempa{\unexpanded{#1}}% \skvstripouterbraces{2}\skv@tempa \skvkvparse*\skv@tempa } -% \dirkeys@defhandlers{<marker>}{<list>} -% <marker> indicates if we're in <new> or <define> handler. +% \dirkeys@defhandlers{<flag>}{<list>} +% <flag> indicates if we're in <new> (01) or <define> (00) handler. \skvrobustdef*\dirkeys@defhandlers#1#2{% - \def\do##1=##2=##3\handler@nil{% - \skv@ensurehandlerdot{##1}% - \if0#1% - \skvcsdef{dirkeys@handler@##1}####1{##2}% - \else - \skvifcsdef{dirkeys@handler@##1}{% - \skv@err{Handler '##1' arealdy exists}\@ehd + \dirkeys@handlerloop{#2}\skv@tempa{% + \skv@kvosplit\skv@tempa{% + \skv@ensurehandlerdot{##1}% + \skvifplaswTF{#1}{% + \skvcsdef{dirkeys@handler@##1}####1{##2}% }{% - \skvcsdef{dirkeys@handler@##1}####1\handlereov{##2}% + \skvifcsdefTF{dirkeys@handler@##1}{% + \skv@err{Handler '##1' arealdy exists}\@ehd + }{% + \skvcsdef{dirkeys@handler@##1}####1\handlereov{##2}% + }% }% - \fi - }% - \skv@handlerloop{#2}\skv@tempa{% - \expandafter\do\skv@tempa==\handler@nil + }% }% } % Define handlers of more than one argument. This is slightly more % expensive than '.new handlers': -% \dirkeys@defnarghandlers{<marker>}{<list>} -% <marker> indicates if we're in <new> or <define> handler. +% \dirkeys@defnarghandlers{<flag>}{<list>} +% <flag> indicates if we're in <new> (01) or <define> (00) handler. \skvrobustdef*\dirkeys@defnarghandlers#1#2{% - \def\do##1=##2=##3\handler@nil{% - \skv@ensurehandlerdot{##1}% - \def\skv@tempa####1####2\handler@nil{% - % ####2 must be hidden in a macro for later use in defining the - % handler: - \edef\skv@prova{\unexpanded{####2}}% - \edef\skv@tempa{\skvgenerateparameters{1}{####1}\handlereov}% - \def\skv@provb{% - \edef\skv@tempb{\protected\def\skvnoexpandcs{dirkeys@handler@##1}}% - \expandafter\expandafter\expandafter\skv@tempb\expandafter - \skv@tempa\expandafter{\skv@prova}% - }% - \if0#1% - \skv@provb - \else - \skvifcsdef{dirkeys@handler@##1}{% - \skv@err{Handler '##1' arealdy exists}\@ehd - }{% + \dirkeys@handlerloop{#2}\skv@tempa{% + \skv@kvosplit\skv@tempa{% + \skv@ensurehandlerdot{##1}% + \def\skv@tempa####1####2\handler@nil{% + % ####2 must be hidden in a macro for later use in defining the + % handler: + \edef\skv@prova{\unexpanded{####2}}% + \edef\skv@tempa{\skvgenerateparameters{1}{####1}\handlereov}% + \def\skv@provb{% + \edef\skv@tempb{\protected\def\skvnoexpandcs{dirkeys@handler@##1}}% + \expandafter\expandafter\expandafter\skv@tempb\expandafter + \skv@tempa\expandafter{\skv@prova}% + }% + \skvifplaswTF{#1}{% \skv@provb + }{% + \skvifcsdefTF{dirkeys@handler@##1}{% + \skv@err{Handler '##1' arealdy exists}\@ehd + }{% + \skv@provb + }% }% - \fi + }% + \skv@tempa##2\handler@nil }% - \skv@tempa##2\handler@nil }% - \skv@handlerloop{#2}\skv@tempa{% - \expandafter\do\skv@tempa==\handler@nil +} + +% \dirkeys@handlerlet{<flag>}{<kvlist>} +% <flag> is either 00 (for define) or 01 (for new handler). +\skvrobustdef*\dirkeys@handlerlet#1#2{% + \dirkeys@handlerloop{#2}\skv@tempa{% + \skv@kvosplit\skv@tempa{% + \skvifcsdefFT{dirkeys@handler@##2}{% + \skv@err{Handler '##2' doesn't exist}\@ehd + }{% + \skvifblankTF{##1}{% + \skv@err{No child handler}\@ehd + }{% + \skvifplaswTF{#1}{}{% + \skvifcsdefFT{dirkeys@handler@##1}{}{% + \skv@err{Handler '##1' arealdy exists}\@ehd + }% + }% + \skvcsletcs{dirkeys@handler@##1}{dirkeys@handler@##2}% + }% + }% + }% }% } \skvrobustdef*\skvusehandler#1#2{% \skv@ensurehandlerdot{#1}% - \skvifcsdef{dirkeys@handler@#1}{% + \skvifcsdefTF{dirkeys@handler@#1}{% \csname dirkeys@handler@#1\endcsname#2\handlereov }{% \skv@err{Handler '#1' is undefined}\@ehd @@ -5624,19 +6353,18 @@ % 2. It defines definable handlers of one or more arguments. See also % '.define handlers' later on (within the next call of \dirkeys). \skvrobustcsdef*{dirkeys@handler@.new handlers}#1\handlereov{% - \dirkeys@defhandlers{1}{#1}% + \dirkeys@defhandlers{01}{#1}% } -% In case one gives no value to a handler: -\skvundef\dirkeys@ + \dirkeys*{% .new handlers={% .exec code=#1, - .define handlers=\dirkeys@defhandlers{0}{#1}, - .define narg handlers=\dirkeys@defnarghandlers{0}{#1}, - .new narg handlers=\dirkeys@defnarghandlers{1}{#1}, + .define handlers=\dirkeys@defhandlers{00}{#1}, + .define narg handlers=\dirkeys@defnarghandlers{00}{#1}, + .new narg handlers=\dirkeys@defnarghandlers{01}{#1}, .kill handlers={% - \skv@handlerloop{#1}\skv@tempa{% - \skvifcsdef{dirkeys@handler@\skv@tempa}{% + \dirkeys@handlerloop{#1}\skv@tempa{% + \skvifcsdefTF{dirkeys@handler@\skv@tempa}{% \skvcsundef{dirkeys@handler@\skv@tempa}% }{% \skv@err{Handler '\skv@tempa' is undefined}\@ehd @@ -5644,30 +6372,15 @@ }% }, .use handler=\skvusehandler{#1}, - .handler let={% - \def\do##1=##2=##3\handler@nil{% - \skvifcsdef{dirkeys@handler@##1}{% - \skv@err{Handler '##1' arealdy exists}\@ehd - }{% - \skvifcsundef{dirkeys@handler@##2}{% - \skv@err{Handler '##2' doesn't exist}\@ehd - }{% - \skvifblank{##1}{% - \skv@err{No child handler}\@ehd - }{% - \skvcsletcs{dirkeys@handler@##1}{dirkeys@handler@##2}% - }% - }% - }% - }% - \skv@handlerloop{#1}\skv@tempa{% - \expandafter\do\skv@tempa==\handler@nil - }% - }, + .handler let*=\dirkeys@handlerlet{00}{#1}, + .handler let=\dirkeys@handlerlet{01}{#1}, .prefixes={% \def\dirkeys@prefixlist{}% \skvusehandler{.add prefixes}{#1}% }, + .default prefix={% + \skvdefaultprefix{#1} + }, .add prefixes={% \skv@clfalse\skv@mergelist\dirkeys@prefixlist{#1}% }, @@ -5715,8 +6428,8 @@ .pop prefixes=\dirkeys@popmeta{prefix}, .push families=\dirkeys@pushmeta{family}, .pop families=\dirkeys@popmeta{family}, - .push roots=\dirkeys@pushmeta{root}, - .pop roots=\dirkeys@popmeta{root}, + .push paths=\dirkeys@pushmeta{prefix}\dirkeys@pushmeta{family}, + .pop paths=\dirkeys@popmeta{prefix}\dirkeys@popmeta{family}, .push holder prefix=\dirkeys@pushmeta{hp}, .pop holder prefix=\dirkeys@popmeta{hp}, .save unknown keys={% @@ -5724,8 +6437,8 @@ {.save unknown keys}{dirkeys@saveunknownkeys}{#1}% }, .save unknown keys in={% - \skvifblank{#1}{}{% - \skvifescaped{#1}{% + \skvifblankTF{#1}{}{% + \skvifescapedTF{#1}{% \dirkeys@saveunknownkeystrue \def\dirkeys@unknownkeysmacro{#1}% }{% @@ -5753,7 +6466,7 @@ \dirkeys@dosetkeys{#1}\skvsetkeys }, .set rmkeys={% - \skvifblank{#1}{% + \skvifblankTF{#1}{% \skv@handlerswafalse\skv@handlerswbtrue \dirkeys@dosetkeys{}\skvsetrmkeys }{% @@ -5764,7 +6477,7 @@ }% }, .set rmkeys*={% - \skvifblank{#1}{% + \skvifblankTF{#1}{% \skv@handlerswatrue\skv@handlerswbtrue \dirkeys@dosetkeys{}\skvsetrmkeys }{% @@ -5823,10 +6536,10 @@ % key must first be set before choices are executed. % <key1>/{<ch1>.do={<act1>},...,<ch-n>.do={<act-n>}},..., % <key-n>/{<ch1>.do={<act1>},...,<ch-n>.do={<act-n>}} - .choice=\dirkeys@savechoice{#1}{x0}, - .choice expand once=\dirkeys@savechoice{#1}{x1}, - .choice expand twice=\dirkeys@savechoice{#1}{x2}, - .choice expanded=\dirkeys@savechoice{#1}{xx}, + .state pattern=\dirkeys@savechoice{#1}{x0}, + .state pattern expand once=\dirkeys@savechoice{#1}{x1}, + .state pattern expand twice=\dirkeys@savechoice{#1}{x2}, + .state pattern expanded=\dirkeys@savechoice{#1}{xx}, % {<key-i>,...,<key-j>}/{<stylelist-ij>},..., % {<key-n>,...,<key-m>}/{<stylelist-nm>}: .append style=\dirkeys@savestyle{#1}{app}{x0}, @@ -5898,7 +6611,7 @@ .no such key={4}{% % All the parameters would have been despaced when this handler % is called. #1=prefix, #2=family, #3=key, #4=value. - \skvifcsdef{#1@#2@handler}{% + \skvifcsdefTF{#1@#2@handler}{% \csname#1@#2@handler\endcsname{#1}{#2}{#3}{#4} }{% \skv@err{Key '#3' is not in family '#1/#2'}\@ehd @@ -5918,8 +6631,8 @@ }, % .get value={<pref>}{<fam>}{<key>}<cmd> .get value={4}{% - \skvifcsdef{#1/#2/#3.@value}{% - \skvifescaped{#4}{% + \skvifcsdefTF{#1/#2/#3.@value}{% + \skvifescapedTF{#4}{% \skvletcs#4{#1/#2/#3.@value}% }{% \skv@err{Token '\detokenize{#4}' isn't escaped}\@ehd @@ -5931,16 +6644,13 @@ }, % '.try set keys' doesn't use the active prefixes and families within % \dirkeys. The prefix, families and other options are to be supplied - % in the argument #1. - % .try set keys={<options>}{<kvlist>} - .try set keys={2}{% - \skv@trysetkeys[{#1}]{#2} - }, + % in the argument #1. The key .key values (or .kv) is used to + % supply the key-value pairs. + % .try set keys={<options>} + .try set keys={1}{\dirkeys@trysetkeys{#1}}, % 'search also' set keys. - % .sa set keys={<options>}{<kvlist>} - .sa set keys={2}{% - \dirkeys@dosasetkeys{#1}{#2} - }, + % .sa set keys={<options>} + .sa set keys={1}{\dirkeys@sasetkeys{#1}}, % .set boolean handler={<handler>}{<boolean>}{<value>} .set boolean handler={3}{% \dirkeys@setbooleanhandler{#1}{#2}{#3} @@ -5966,6 +6676,10 @@ .ignore path=.ignore roots, .ignore paths=.ignore roots, .restore root=.restore roots, .restore path=.restore roots, .restore paths=.restore roots, + .push prefix=.push prefixes, .pop prefix=.pop prefixes, + .push family=.push families, .pop family=.pop families, + .push path=.push paths, .pop path=.pop paths, + .push hp=.push holder prefix, .pop hp=.pop holder prefix, .ignore key=.ignore keys, .restore key=.restore keys, .define key=.define keys, .new key=.new keys, .initialize after define=.initialize keys after define, @@ -5982,7 +6696,11 @@ .try set=.try set keys, .sa set=.sa set keys, .search also set keys=.sa set keys, .use defaults=.set with defaults, - .echoice=.choice expanded, + .restrict values=.state pattern, + .nominations=.state pattern, + .singleton=.state pattern, + .estate pattern=.state pattern expanded, + .esingleton=.state pattern expanded, .style=.append style, .styles=.append style, .estyle=.append style expanded, @@ -6012,11 +6730,11 @@ }, } -% \skvpatchcmd[<prefix>]{<cmd>}{<search>}{<replace>}{<succeed>}{<fail>} +% \skvpatchcmd[<prefix>]{<cmd>}{<search>}{<replace>}{<success>}{<fail>} \skvrobustdef*\skvpatchcmd{% \begingroup \@makeother{\#}\endlinechar\m@ne - \skv@testopt\skv@patchcmd{########1}% + \skv@testopt\skv@patchcmd{####1}% } \skvrobustdef*\skv@patchcmd[#1]#2#3#4{% \ifskv@tracingkeys @@ -6025,7 +6743,7 @@ \skv@p@tchcmd{#1}{#2}{#3}{#4}% } \skvrobustdef*\skv@p@tchcmd#1#2#3#4{% - \skvifpatchable{#2}{#3}{#4}{% + \skvifpatchableTF{#2}{#3}{#4}{% \skv@patchdebug{++}{Command is patchable}% \skv@patchdebug{==}{Patching has begun}% \begingroup @@ -6046,20 +6764,20 @@ }% } \skvrobustdef*\skv@patchdebug#1#2{% - \ifskv@tracingkeys\typeout{[debug] #1 #2}\fi + \ifskv@tracingkeys\typeout{[debug] #1 #2.}\fi } -\skvrobustdef*\skvifpatchable#1#2#3{% +\skvrobustdef*\skvifpatchableTF#1#2#3{% \endgroup - \skvifundef{#1}{% + \skvifdefFT{#1}{% \skv@patchdebug{--}{Command not defined}% \@secondoftwo }{% \skv@patchdebug{++}{Command is defined}% - \skvifmacro{#1}{% + \skvifmacroTF{#1}{% \skv@patchdebug{++}{Command is a macro}% - \skvifscannable{#1}{% + \skvifscannableTF{#1}{% \skv@patchdebug{++}{Macro can be retokenized safely after patching}% - \skvifpattern{#2}{#1}{% + \skvifpatternTF{#2}{#1}{% \skv@patchdebug{++}{Requested search pattern found}% \@firstoftwo }{% @@ -6096,7 +6814,7 @@ \catcode`\noexpand\}=\the\catcode`\}\relax }% } -\skvrobustdef*\skvifscannable#1{% +\skvrobustdef*\skvifscannableTF#1{% % Fails if the content of #1 is already detokenized. \begingroup \edef\skv@tempa##1{% @@ -6115,7 +6833,7 @@ \expandafter\@secondoftwo \fi } -\skvrobustdef\skvifpattern#1#2{% +\skvrobustdef\skvifpatternTF#1#2{% \begingroup \edef\skv@tempa##1{\def##1####1\detokenize{#1}####2\skvrelax}% \skv@tempa\skv@tempa{% @@ -6128,21 +6846,28 @@ \edef\skv@tempb##1{##1\detokenize{#1}\skvrelax}% \skv@tempb{\expandafter\skv@tempa\meaning#2}% } -\skvrobustdef*\skvifmacro#1{% - \begingroup - \edef\skv@tempa##1{\def##1####1\detokenize{macro}:####2\skvrelax}% - \skv@tempa\skv@tempa{% - \expandafter\endgroup\ifx\@nnil##2\@nnil - \expandafter\@secondoftwo - \else - \expandafter\@firstoftwo - \fi +\skvrobustdef*\skvifmacroTF#1{% + \skvifntypeTF{#1}{% + \begingroup + \edef\skv@tempa##1{\def##1####1\detokenize{macro}:####2\skvrelax}% + \skv@tempa\skv@tempa{% + \expandafter\endgroup\ifx\@nnil##2\@nnil + \expandafter\@secondoftwo + \else + \expandafter\@firstoftwo + \fi + }% + \edef\skv@tempb##1{##1\detokenize{macro}:\skvrelax}% + \skv@tempb{\expandafter\skv@tempa\meaning#1}% + }{% + \@secondoftwo }% - \edef\skv@tempb##1{##1\detokenize{macro}:\skvrelax}% - \skv@tempb{\expandafter\skv@tempa\meaning#1}% } -%\skvxzapspaces{\detokenize{\begin{\document}}}\skv@begindoc@string -\edef\skv@begindoc@string{\string\begin\string{\string\document\string}} + +\skvrobustdef*\skvifmacroFT#1{\skvifmacroTF{#1}\@secondoftwo\@firstoftwo} + +%\skvxzapspaces{\detokenize{\begin{\document}}}\skv@begindoctoks +\edef\skv@begindoctoks{\string\begin\string{\string\document\string}} \skv@core@restorecodes \endinput diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex b/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex index b02ed4f91ed..309a5649c93 100644 --- a/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex +++ b/Master/texmf-dist/tex/latex/skeyval/skeyval-for.tex @@ -1,5 +1,5 @@ %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -% This is file 'skeyval-for', version 1.1, October 2012. % +% This is file 'skeyval-for', version 1.1a, 2012/10/16. % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % @@ -26,25 +26,48 @@ % Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com). % %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% +\begingroup% +\let\e\endlinechar\edef\p{\the\e}\e13\edef\n{\the\catcode\e}% +\xdef\skv@for@restorecatcodes{% + \let\noexpand\skv@for@restorecatcodes\relax% + \endlinechar=\p\relax\catcode\number\e=\n\relax% + \catcode\string`\noexpand`\string=\the\catcode\string``\relax% + \catcode\string`\noexpand=\string=\the\catcode\string`=\relax% +}% +\endgroup% +\endlinechar\string=13\relax% +\catcode13\string=5\relax% +\catcode\string``\string=12\relax +\catcode\string`=\string=12\relax +\def\skvgobble#1{} +\def\do#1{\catcode`\expandafter\skvgobble\string#1=\the\catcode`#1\relax} +\edef\skv@for@restorecatcodes{% + \unexpanded\expandafter{\skv@for@restorecatcodes}% + \do\ \do\%\do\@\do\(\do\)\do\[\do\]\do\|\do\:\do\;\do\,\do\.% + \do\>\do\<\do\!\do\*\do\+\do\-\do\^\do\_\do\&\do\$\do\~\do\'% + \do\"\do\ +} +\catcode`\ =10\relax +\catcode`\@=11 \catcode`\(=12 \catcode`\)=12 \catcode`\[=12 +\catcode`\]=12 \catcode`\|=12 \catcode`\:=12 \catcode`\;=12 +\catcode`\,=12 \catcode`\*=12 \catcode`\+=12 \catcode`\-=12 +\catcode`\<=12 \catcode`\>=12 \catcode`\!=12 \catcode`\.=12 +\catcode`\^=07 \catcode`\_=08 \catcode`\&=04 \catcode`\$=03 +\catcode`\~=13 \catcode`\%=14 \catcode`\'=12 \catcode`\"=12 + \csname skeyval-for-loaded\endcsname \expandafter\let\csname skeyval-for-loaded\endcsname\endinput -\edef\skv@for@restorecatcodes{% - \catcode`\noexpand\@\the\catcode`\@\relax - \let\noexpand\skv@for@restorecatcodes\relax -} -\catcode`\@=11\relax - \ifx\ProvidesFile\@undefined - \message{File 'skeyval-for.tex' 2012/10/15 v1.1 + \message{File 'skeyval-for.tex' 2012/10/16 v1.1a Loops for skeyval package (AM)} \else \ProvidesFile{skeyval-for.tex} - [2012/10/15 v1.1 Loops for skeyval package (AM)] + [2012/10/16 v1.1a Loops for skeyval package (AM)] \@addtofilelist{skeyval-for.tex} \fi -\skvrobustdef*\skv@nostackerr{\skv@err{You've called empty stack}\@ehd} +\skvrobustdef*\skv@nostackerr{\skv@err{You've called an empty stack}\@ehd} % \skvsavestate<base-fn>{<fn-list>}<counter> \skvrobustdef*\skvsavestate#1#2#3{% \skvgadvanceno#3\@ne @@ -52,7 +75,7 @@ \let\s\string\escapechar\m@ne \def\skv@prova##1{\s##1@skv@\romannumeral#3}% \def\do##1{\let\noexpand##1\skvnoexpandcs{\skv@prova{##1}}}% - \skvifcsdef{\s#1@skv@stack}{}{\skvcsdef{\s#1@skv@stack}{\nostack}}% + \skvifcsdefTF{\s#1@skv@stack}{}{\skvcsdef{\s#1@skv@stack}{\nostack}}% \skvcsxdef{\s#1@skv@stack}{#2{\skvexpandcsonce{\s#1@skv@stack}}}% \def\do##1{\let\skvnoexpandcs{\skv@prova{##1}}\noexpand##1}% \edef\reserved@a{\endgroup#2}\reserved@a @@ -71,25 +94,27 @@ \skvgadvanceno#2\m@ne } -\skvnewregisters\bool{\ifskvbreakloop\ifforeachlastitem - \ifskvprocessempty\ifskv@tempst\ifskv@foreach@swa +\skvnewregisters\bool{% + \ifskvbreakloop\ifforeachlastitem + \ifskvprocessempty\ifskv@foreach@swa \ifskv@foreach@swb\ifskv@foreach@parenth } \skvnewnumbers[skv@]{csvdepth,dolistcnt} \skvrobustdef*\skv@usetempst#1#2{% - \edef#2{\skvifdefbool{skv@tempst}\skvexpandonce\unexpanded{#1}}% + \edef#2{\skvifdefboolTF{skv@tempst}\skvexpandonce\unexpanded{#1}}% } % % \skvdolist{<parser>}{<list>}<holdercmd>{<callback>} % \skvdolist*{<parser>}{<listcmd>}<holdercmd>{<callback>} % -% 1. This can be nested to any depth, with different parsers on each +% 1. \skvdolist can process both csv and tsv/nsv lists. +% 2. This can be nested to any depth, with different parsers on each % level. -% 2. This will not process an empty list; see \skvecommaloop. -% 3. For comma lists, \skvcommaloop and \skvcommaparse are faster. +% 3. This will not process an empty list; see \skvecommaloop. +% 4. For comma lists, \skvcommaloop and \skvcommaparse are faster. % See later. -% 4. For processing kv lists, use \skvkvparse. +% 5. For processing kv lists, use \skvkvparse. % \skvrobustdef*\skvdolist{\skv@testst\skv@dolist} \skvrobustdef*\skv@dolist#1#2#3#4{% @@ -97,7 +122,7 @@ \skv@usetempst{#2}#3% \def\skv@dolist@a{skv@dolist@\skvrom\skv@dolistcnt}% \skvcsdef{\skv@dolist@a}##1##2##3#1{% - \skvifstrcmp{##3}{\skv@dolist@nil}{% + \skvifstrcmpTF{##3}{\skv@dolist@nil}{% % To allow nesting of loop: \skvbreakloopfalse }{% @@ -111,7 +136,7 @@ \@nameuse{\skv@dolist@a}##1{##2}% }% }% - \skvifempty#3{}{% + \skvifemptyTF#3{}{% \edef\reserved@a{\unexpanded{\@nameuse{\skv@dolist@a}#3{#4}}}% \expandafter\reserved@a#3#1\skv@dolist@nil#1% }% @@ -150,7 +175,7 @@ \let\skvreversedo\@iden \skvrobustdef*\skv@removetrailingparser#1#2{% - \skvxifin{\detokenize{#1}\relax}{\skvoxdetok#2\relax}{% + \skvxifinTF{\detokenize{#1}\relax}{\skvoxdetok#2\relax}{% \def\skv@prova##1#1\skv@trim@nil{\unexpanded{##1}}% \edef#2{\expandafter\skv@prova#2\skv@trim@nil}% }{}% @@ -175,10 +200,18 @@ % \ifnum\@tempcnta<4 % \fi % +\skvnewcounts{skv@recurse@cnt} \skvrobustdef\skvrecurse#1\while#2\fi{% + \skv@recurse@cnt\skvz@ \@expandtwoargs\skv@dobody{\skvtrimspace{#2}}{\skvtrimspace{#1}}% } \skvrobustdef\skv@dobody#1#2{% + \advance\skv@recurse@cnt\@ne + \ifnum\skv@recurse@cnt>10000\relax + \@latex@error{Possibly an infinite loop in \string\skvrecurse} + {Maybe you didn't increment some counter or + \MessageBreak the termination condition was never satisfied.}% + \fi #1\relax\expandafter\@iden\else\expandafter\@gobble\fi {#2\relax\skv@dobody{#1}{#2}}% } @@ -186,8 +219,8 @@ % A version of LaTeX's \@tfor that can parse undoubled parameter % characters. % -% \skvtfor<holder.cmd>{<list>}\do{<callback>} -% \skvtfor*<holder.cmd>{<listcmd>}\do{<callback>} +% \skvtfor<holder.cmd>:={<list>}\do{<callback>} +% \skvtfor*<holder.cmd>:={<listcmd>}\do{<callback>} % % Example: % @@ -206,15 +239,15 @@ \skvrobustdef*\skv@tfor#1:={\skv@tf@r#1 } \skvrobustdef\skv@tf@r#1#2\do#3{% \edef#1{\skvtrimspace{#2}}% - \edef#1{\skvifbool{skv@tempst}\skvexpandtwice\skvexpandonce{#1}}% - \skvifempty#1{}{% + \edef#1{\skvifboolTF{skv@tempst}\skvexpandtwice\skvexpandonce{#1}}% + \skvifemptyTF#1{}{% \skvbreakloopfalse \expandafter\skv@tforloop#1\skv@tfor@nil\skv@tfor#1{#3}% }% } \skvrobustdef\skv@tforloop#1#2\skv@tfor#3#4{% \edef#3{\unexpanded{#1}}% - \skvifx#3\skv@tfor@nil{% + \skvifxTF#3\skv@tfor@nil{% \skvbreakloopfalse }{% #4\relax @@ -230,7 +263,7 @@ }% } -% Non-expandable comma loops +%+++++++++++++++ Non-expandable comma loops ++++++++++++++%% % % 1. These follow from \skvdolist and \skvparselist, but they are % specialized for comma lists and they are faster. @@ -245,12 +278,12 @@ \skv@usetempst{#1}#2% % Don't put \skvcsvnormalize#2 here. Use \skvcommaparse instead. % Some callers of \skvcommaloop already have their lists normalized. - \skvifx#2\@empty{}{% + \skvifxTF#2\@empty{}{% \skvexpandnext{\skv@c@mmaloop#2{#3}}#2,\skv@commaloop@nil,% }% } \skvrobustdef\skv@c@mmaloop#1#2#3,{% - \skvifstrcmp{#3}{\skv@commaloop@nil}{% + \skvifstrcmpTF{#3}{\skv@commaloop@nil}{% \skvbreakloopfalse }{% \edef#1{\unexpanded{#3}}% @@ -289,7 +322,6 @@ \skvcsvnormalize#2% \skvcommaloop*#2#2{#3}% } -% % \skvkvparse{<list>}<cmd>{<callback>} % \skvkvparse*{<listcmd>}<cmd>{<callback>} % @@ -303,12 +335,59 @@ \skvkvnormalize#2% \skvcommaloop*#2#2{#3}% } +% \skvcommaprocess{<list>}<holder.cmd> +% \skvcommaprocess*{<listcmd>}<holder.cmd> +% +% If <list> or <listcmd> is a single item, then no looping is required. % +\skvrobustdef*\skvcommaprocess{\skv@testst\skv@commaprocess} +\skvrobustdef*\skv@commaprocess#1#2#3{% + \skv@usetempst{#1}#2% + \skvxifinTF{,}{\skvoxdetok#2}{% + \skvcommaparse*#2#2{#3}% + }{% + \skvdespacecontent#2#3% + }% +} +% \skvcountelements[<parser>]{<list>}{<return.cmd>} +% \skvcountelements*[<parser>]{<listcmd>}{<return.cmd>} +\skvrobustdef*\skvcountelements{\skv@teststopt\skv@countelements,} +\skvrobustdef*\skv@countelements[#1]#2#3{% + \begingroup + \skv@usetempst{#2}\skv@tempa + \@tempcnta\skvz@ + \skvdolist*{#1}\skv@tempa\skv@prova{% + \advance\@tempcnta\@ne + }% + \edef#3{\the\@tempcnta}% + \skvaftergroupdef#3\endgroup +} +% If the number of elements in a list is equal or greater than <nr>. +% \skvifelementcount[<parser>]{<list>}{<nr>}{<true>}{<false>} +% \skvifelementcount*[<parser>]{<listcmd>}{<nr>}{<true>}{<false>} +\skvrobustdef*\skvifelementcount{\skv@teststopt\skv@ifelementcount,} +\skvrobustdef*\skv@ifelementcount[#1]#2#3{% + \begingroup + \skv@usetempst{#2}\skv@tempa + \@tempcnta\skvz@ + \skv@swafalse + \skvdolist*{#1}\skv@tempa\skv@prova{% + \advance\@tempcnta\@ne + \ifnum\@tempcnta=#3\relax + \skv@swatrue\skvbreakloop + \fi + }% + \expandafter\endgroup\ifskv@swa + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi +} % \skv@foreach@normalize[<parser>]<listcmd> \skvrobustdef*\skv@foreach@normalize{\skv@testopt\skv@foreach@norm@lize,} \skvrobustdef*\skv@foreach@norm@lize[#1]#2{% - \skvxifntype{\detokenize{#1}}\skvcsvnormalize\skvmacnormalize[#1]#2% + \skvxifntypeTF{\detokenize{#1}}\skvcsvnormalize\skvmacnormalize[#1]#2% } % \newforeach[<options>] <holders> {<list>} {<callback>} @@ -332,7 +411,7 @@ \skvnewnumbers{foreachdepth,skv@foreach@sisterdepth,skv@foreach@nra,% skv@warnsubparser} \skvnewdef*\skv@foreach@onlyinitially{} -\skvrobustdef*\skv@foreach@assignonce#1{% +\skvrobustdef*\skvforeachonlyinitially#1{% \edef\skv@foreach@onlyinitially{% \skvexpandonce\skv@foreach@onlyinitially \unexpanded{#1}% @@ -341,7 +420,7 @@ % \skv@foreach@addtocallback{<pre.or.post>}{<code.to.add>} \skvrobustdef*\skv@foreach@addtocallback#1#2{% \skvcsedef{skv@foreach@#1callback}{% - \skvifcsundef{skv@foreach@#1callback}{}{% + \skvifcsdefFT{skv@foreach@#1callback}{}{% \skvexpandcsonce{skv@foreach@#1callback}% }% % No \unexpanded for #2 here, since #2 is to be expanded: @@ -352,11 +431,11 @@ \skvnewlet\skv@foreach@codemark\relax \skvrobustdef*\skv@foreach@addtohook#1#2#3{% \begingroup - \skvifdef#2{}{\def#2{}}% + \skvifdefTF#2{}{\def#2{}}% \edef\x{\detokenize{\skv@foreach@codemark#3\skv@foreach@codemark}}% - \skvxifin\x{\skvoxdetok#2}{}{% + \skvxifinTF\x{\skvoxdetok#2}{}{% \edef#2{% - \skvifstrcmp{#1}{pre}{% + \skvifstrcmpTF{#1}{pre}{% \skv@foreach@codemark\unexpanded{#3}\skv@foreach@codemark \skvexpandonce{#2}% }{% @@ -378,7 +457,7 @@ } \skvnewlet\atbeginforeach\appendtobeginforeach \skvrobustdef*\skv@atbeginforeach#1[#2]#3{% - \skvifblank{#2}{% + \skvifblankTF{#2}{% \skvaftercsname{\skv@foreach@addtohook{#1}}% {skv@foreach@atbeginhook@\skvrom\@ne}{#3}% }{% @@ -398,7 +477,7 @@ } \skvnewlet\atendforeach\appendtoendforeach \skvrobustdef*\skv@atendforeach#1[#2]#3{% - \skvifblank{#2}{% + \skvifblankTF{#2}{% \skvaftercsname{\skv@foreach@addtohook{#1}}% {skv@foreach@atendhook@\skvrom\@ne}{#3}% }{% @@ -437,8 +516,8 @@ \next } \skvrobustdef*\skv@foreach@ifholderisonecmd#1#2#3{% - \skvifntype{#2}{% - \skvifescaped{#2}{% + \skvifntypeTF{#2}{% + \skvifescapedTF{#2}{% #3% }{% \skv@err{Value of key '#1' must @@ -453,9 +532,9 @@ } % \skv@foreach@maketester{<cond>}<cond.tester.cmd>{<flag>} % -% 1. Only balanced conditionals beginning with \if...\fi are allowed. -% Restricting the type of allowed conditionals is necessary for -% auto syntax checking. +% 1. Only balanced conditionals beginning with \if... and ending with \fi +% are allowed. Restricting the type of allowed conditionals is +% necessary for auto syntax checking. % 2. <flag> is either 0 or 1, signifying whether or not the condition % should be entered in postcallback. % @@ -466,23 +545,23 @@ % characters. \skv@prova will appear only in the error message. \begingroup \edef\skv@prova{\detokenize{#1}}% - \skvifblank{#1}{% + \skvifblankTF{#1}{% \skv@err{A blank conditional given in \string\newforeach}\@ehd }{% - \skvxifin{\skv@foreach@fi\relax}{\detokenize{#1}\relax}{% - \skvxifin{\relax\skv@foreach@if}{\relax\detokenize{#1}}{% - \edef#2{\noexpand\skvifcondition\unexpanded{#1}}% + \skvxifinTF{\skv@foreach@fi\relax}{\detokenize{#1}\relax}{% + \skvxifinTF{\relax\skv@foreach@if}{\relax\detokenize{#1}}{% + \edef#2{\noexpand\skvifconditionTF\unexpanded{#1}}% \ifnum#3=\@ne \skv@foreach@addtocallback{post}{% - \unexpanded{\skvifcondition#1}{\noexpand\skvbreakloop}{\relax}% + \unexpanded{\skvifconditionTF#1}{\noexpand\skvbreakloop}{}% }% \fi }{% - \skv@err{Illegal conditional '\skv@prova'} + \skv@err{Invalid conditional '\skv@prova'} {Invalid, possibly unbalanced, conditional '\skv@prova'}% }% }{% - \skv@err{Illegal conditional '\skv@prova'}\@ehd + \skv@err{Invalid conditional '\skv@prova'}\@ehd }% }% \skvexpanded{\endgroup @@ -517,7 +596,7 @@ } } -\quickkeys.define{skvforeach}{% +\quickkeys.define{skeyval/foreach}{% .exec/ \def\skv@foreach@parser{,} \def\skv@foreach@subparser{/} @@ -526,7 +605,7 @@ \ifskvindef\else \edef\skv@foreach@parser{\unexpanded{#1}} \skvstripouterbraces{2}\skv@foreach@parser - \skvxifntype{\detokenize{#1}}{% + \skvxifntypeTF{\detokenize{#1}}{% \begingroup % It is assumed that every n-type parser and subparser % must have catcode 12: @@ -540,7 +619,7 @@ \ifskvindef\else \edef\skv@foreach@subparser{\unexpanded{#1}} \skvstripouterbraces{2}\skv@foreach@subparser - \skvxifntype{\detokenize{#1}}{ + \skvxifntypeTF{\detokenize{#1}}{ \begingroup \skvexpandnext{\catcode`}\skv@foreach@subparser=12\relax \skv@rescan\skv@foreach@subparser @@ -552,10 +631,6 @@ \edef\skv@foreach@terminator{\unexpanded{#1}}% \skvstripouterbraces{2}\skv@foreach@terminator ; - list is a macro,macro list/true/ - \edef\skv@foreach@listismacro{0\skvifstrcmp{true}{#1}01}% - /true,false - ; % process up to = <nr> % Maximum number of items to process: process up to,process up to number/\@nil/ @@ -567,7 +642,7 @@ \fi ; process empty list/true/ - \edef\skv@foreach@processempty{0\skvifstrcmp{true}{#1}01}% + \edef\skv@foreach@processempty{0\skvifstrcmpTF{true}{#1}01}% /true,false ; % Eg, exit when=\ifnum\x=20\fi @@ -626,7 +701,7 @@ % count in = \y all \x satisfying <condition> initially <value> % Eg, % count in = \p all \x satisfying \ifnum\x>4\fi, or - % count in = \p all \x satisfying \skvifnum\x>4 + % count in = \p all \x satisfying \skvifnumTF\x>4 % The counting is not additive, meaning that the counter is initialized % to zero on each depth. count in,count/\@nil/ @@ -655,7 +730,7 @@ \ifx\skv@prova\@nnil \skv@err{Invalid empty value for key 'item counter'}\@ehd \else - \skvifescaped{#1}{% + \skvifescapedTF{#1}{% \let\skv@foreach@itemcounter\skv@prova }{% \skv@err{Non-escaped value '\detokenize{#1}' @@ -687,11 +762,11 @@ % Remember outside the loop the holder values. Of course, this % means remembering only the latest values. recover holder values,recover holder values after loop/true/ - \edef\skv@foreach@recoverholders{0\skvifstrcmp{true}{#1}01}% + \edef\skv@foreach@recoverholders{0\skvifstrcmpTF{true}{#1}01}% /true,false ; % This default value of 'link' is required by \skv@foreach@filllist: - .exec/\def\skv@foreach@link{\@nil}; + .exec code/\def\skv@foreach@link{\@nil}; link/\@nil/ \ifskvindef\else \edef\skv@foreach@link{\unexpanded{#1}}% @@ -709,7 +784,7 @@ \skv@err{Value required for key 'grow'}\@ehd \else \skvcsedef{skv@foreach@grow#1}{00} - \edef\skv@prova{\skvifstrcmp{#1}{left}{right}{left}}% + \edef\skv@prova{\skvifstrcmpTF{#1}{left}{right}{left}}% \skvcsedef{skv@foreach@grow\skv@prova}{01}% \fi \fi @@ -721,37 +796,59 @@ ; grow left/true/ \ifskvindef\else - \edef\skv@foreach@growleft{0\skvifstrcmp{true}{#1}01} - \edef\skv@foreach@growright{0\skvifstrcmp{true}{#1}10} + \edef\skv@foreach@growleft{0\skvifstrcmpTF{true}{#1}01} + \edef\skv@foreach@growright{0\skvifstrcmpTF{true}{#1}10} \fi /true,false ; grow right/true/ \ifskvindef\else - \edef\skv@foreach@growright{0\skvifstrcmp{true}{#1}01} - \edef\skv@foreach@growleft{0\skvifstrcmp{true}{#1}10} + \edef\skv@foreach@growright{0\skvifstrcmpTF{true}{#1}01} + \edef\skv@foreach@growleft{0\skvifstrcmpTF{true}{#1}10} \fi /true,false ; % Keep the decimals in rounded numbers or dimensions when list is % auto-completed. The value value of this key is 'true'. keep decimals/true/ - \edef\skv@foreach@keepdecimals{0\skvifstrcmp{true}{#1}01} + \edef\skv@foreach@keepdecimals{0\skvifstrcmpTF{true}{#1}01} /true,false ; keep high decimals,keep only high decimals/true/ - \edef\skv@foreach@keephighdecimals{0\skvifstrcmp{true}{#1}01} + \edef\skv@foreach@keephighdecimals{0\skvifstrcmpTF{true}{#1}01} /true,false ; % This key means that, eg, for \x/\y, do \let\y=\x if \y has no % user value, ie, if the user gives as an item 'a' instead of % 'a/b' or 'a/a'. - inherit/true/ - \edef\skv@foreach@inherit{0\skvifstrcmp{true}{#1}01} + inherit,transfer macro values/true/ + \edef\skv@foreach@inherit{0\skvifstrcmpTF{true}{#1}01} /true,false ; - expand before fill/true/ - \edef\skv@foreach@expandbeforefill{0\skvifstrcmp{true}{#1}01} + expand before fill,expand list before fill/true/ + \edef\skv@foreach@expandlistbeforefill{0\skvifstrcmpTF{true}{#1}01} + /true,false + ; + expand list once,*,list is a macro,macro list/true/ + \edef\skv@foreach@expandlistonce{0\skvifstrcmpTF{true}{#1}01}% + /true,false + ; + expand list twice/true/ + \edef\skv@foreach@expandlisttwice{0\skvifstrcmpTF{true}{#1}01}% + /true,false + ; + % Don't use 'expand' for this key, to avoid confusing it with + % the 'expand' for holder macros: + expand list,fully expand list,expand list fully/true/ + \edef\skv@foreach@expandlistfully{0\skvifstrcmpTF{true}{#1}01}% + /true,false + ; + reverse list,reverse,reflect/true/ + \edef\skv@foreach@reverselist{0\skvifstrcmpTF{true}{#1}01} + /true,false + ; + reverse list,reverse,reflect/true/ + \edef\skv@foreach@reverselist{0\skvifstrcmpTF{true}{#1}01} /true,false ; } @@ -762,11 +859,10 @@ % evaluate dim,*evaluate dim,expand,*expand,count in,*count in, % loop stopper,process up to,grow % -\skvinitializeqkeys{skvforeach}{% +\skvinitializeqkeys{skeyval/foreach}{% parser, subparser, callback terminator, - list is a macro=false, process up to, process empty list=false, item counter, @@ -779,24 +875,28 @@ keep high decimals=false, inherit=false, expand before fill=false, + reverse list=false, + expand list once=false, + expand list twice=false, + expand list fully=false, } \skvnewdef*\skv@foreach@kvlist{} % \setupforeach{<kvlist>} \skvrobustdef*\setupforeach#1{% - \skvifblank{#1}{}{% + \skvifblankTF{#1}{}{% \skvaddtolist\skv@foreach@kvlist{#1}% }% } \skvrobustdef*\skv@foreach@setkeys#1{% - \def\reserved@a{\quickkeys.set{skvforeach}}% + \def\reserved@a{\quickkeys.set{skeyval/foreach}}% \expandafter\reserved@a\expandafter{\skv@foreach@kvlist,#1}% } % evaluate=<holder.macro> as <child.macro> using <formula> % % 1. Evaluation is done with \edef unless \pgfmathparse is present -% in <formula>. +% in <formula> or key 'pgf evaluate' is called. % % 2. <formula> must be a valid formula, eg, % @@ -817,7 +917,7 @@ \skvrobustdef*\skv@foreach@parseevaluate#1{% \begingroup \def\skv@tempxifin##1##2{% - \skvxifin{\detokenize{##1}}{\detokenize{##2}}% + \skvxifinTF{\detokenize{##1}}{\detokenize{##2}}% }% \skv@foreach@swafalse \def\skv@tempd{}% @@ -828,8 +928,8 @@ \ifx\skv@prova\@empty \skv@err{Value of key 'evaluate' has no holder macro}\@ehd \else - \expandafter\skvifescaped\expandafter{\skv@prova}{% - \expandafter\skvifntype\expandafter{\skv@prova}{}{% + \expandafter\skvifescapedTF\expandafter{\skv@prova}{% + \expandafter\skvifntypeTF\expandafter{\skv@prova}{}{% \skv@err{Value of key 'evaluate': more than 1 \MessageBreak token \skvoxdetok\skv@prova. \MessageBreak I can't find holder macro}\@ehd @@ -842,8 +942,8 @@ \ifx\skv@provb\@empty \skv@err{Value of key 'evaluate' has no child macro}\@ehd \else - \expandafter\skvifescaped\expandafter{\skv@provb}{% - \expandafter\skvifntype\expandafter{\skv@provb}{}{% + \expandafter\skvifescapedTF\expandafter{\skv@provb}{% + \expandafter\skvifntypeTF\expandafter{\skv@provb}{}{% \skv@err{Value of key 'evaluate': more than 1 \MessageBreak token \skvoxdetok\skv@provb. \MessageBreak I can't find child macro}\@ehd @@ -910,7 +1010,7 @@ \ifx\@nnil#1\@nnil \skv@err{Value of key 'evaluate' has no holder macro}\@ehd \else - \skvifntype{#1}{% + \skvifntypeTF{#1}{% % Expand the holder macro: \skv@tempa#1as#1using#1\skv@nil }{% @@ -950,7 +1050,7 @@ \skv@err{No \string\pgfmathparse; 'pgfmath' module not loaded}\@ehd \fi \def\skv@tempxifin##1##2{% - \skvxifin{\detokenize{##1}}{\detokenize{##2}}% + \skvxifinTF{\detokenize{##1}}{\detokenize{##2}}% }% \skv@foreach@swafalse \def\skv@tempa##1as##2using##3\skv@nil{% @@ -960,8 +1060,8 @@ \ifx\skv@prova\@empty \skv@err{Value of key 'pgfmath parse' has no holder macro}\@ehd \else - \expandafter\skvifescaped\expandafter{\skv@prova}{% - \expandafter\skvifntype\expandafter{\skv@prova}{}{% + \expandafter\skvifescapedTF\expandafter{\skv@prova}{% + \expandafter\skvifntypeTF\expandafter{\skv@prova}{}{% \skv@err{Value of key 'pgfmath parse': more than 1 \MessageBreak token \skvoxdetok\skv@prova. \MessageBreak I can't find holder macro}\@ehd @@ -974,8 +1074,8 @@ \ifx\skv@provb\@empty \skv@err{Value of key 'pgfmath parse' has no child macro}\@ehd \else - \expandafter\skvifescaped\expandafter{\skv@provb}{% - \expandafter\skvifntype\expandafter{\skv@provb}{}{% + \expandafter\skvifescapedTF\expandafter{\skv@provb}{% + \expandafter\skvifntypeTF\expandafter{\skv@provb}{}{% \skv@err{Value of key 'pgfmath parse': more than 1 \MessageBreak token \skvoxdetok\skv@provb. \MessageBreak I can't find child macro}\@ehd @@ -1041,7 +1141,7 @@ \ifx\@nnil#1\@nnil \skv@err{Value of key 'pgfmath parse' has no holder macro}\@ehd \else - \skvifntype{#1}{% + \skvifntypeTF{#1}{% % Evaluate the holder macro: \skv@tempa#1as#1using#1\skv@nil }{% @@ -1089,7 +1189,7 @@ \skvrobustdef*\skv@foreach@parsecountin#1{% \begingroup \def\skv@tempxifin##1##2{% - \skvxifin{\detokenize{##1}}{\detokenize{##2}}% + \skvxifinTF{\detokenize{##1}}{\detokenize{##2}}% }% \def\skv@tempa##1\skv@nil{% \skv@tempxifin{initially}{##1}{% @@ -1106,8 +1206,8 @@ \ifx\skv@prova\@empty \skv@err{Value of key 'count' has no counter macro}\@ehd \else - \expandafter\skvifescaped\expandafter{\skv@prova}{% - \expandafter\skvifntype\expandafter{\skv@prova}{}{% + \expandafter\skvifescapedTF\expandafter{\skv@prova}{% + \expandafter\skvifntypeTF\expandafter{\skv@prova}{}{% \skv@err{Value of key 'count in': more than 1 \MessageBreak token \skvoxdetok\skv@prova. \MessageBreak I can't find counter macro}\@ehd @@ -1120,7 +1220,7 @@ \ifx\skv@provd\@empty \expandafter\def\skv@prova{0}% \else - \skvifinteger\skv@provd{% + \skvifintegerTF\skv@provd{% \expandafter\let\skv@prova\skv@provd }{% \skv@err{Value of key 'count':\MessageBreak @@ -1136,8 +1236,8 @@ \ifx\skv@provb\@empty\else % If there isn't a holder macro or quantity to test, then no % test is possible: - \expandafter\skvifescaped\expandafter{\skv@provb}{% - \expandafter\skvifntype\expandafter{\skv@provb}{}{% + \expandafter\skvifescapedTF\expandafter{\skv@provb}{% + \expandafter\skvifntypeTF\expandafter{\skv@provb}{}{% \skv@err{Value of key 'count in': more than 1 \MessageBreak token \skvoxdetok\skv@provb. \MessageBreak I can't find holder macro}\@ehd @@ -1169,7 +1269,7 @@ \ifx\@nnil#1\@nnil \skv@err{Value of key 'count' has no counter macro}\@ehd \else - \skvifntype{#1}{% + \skvifntypeTF{#1}{% \skv@tempa#1all satisfying\skv@nil }{% \skv@err{Value of key 'count in': more than 1 @@ -1203,7 +1303,7 @@ \skvrobustdef*\skv@foreach@parseremember#1{% \begingroup \def\skv@tempxifin##1##2{% - \skvxifin{\detokenize{##1}}{\detokenize{##2}}% + \skvxifinTF{\detokenize{##1}}{\detokenize{##2}}% }% \skv@tempxifin{(}{#1}{% \skv@err{Value of key 'remember': '(' found. @@ -1219,7 +1319,7 @@ \skv@err{Value of key 'remember' has no holder macro: \MessageBreak i.e., no macro that holds input}\@ehd \else - \expandafter\skvifescaped\expandafter{\skv@prova}{}{% + \expandafter\skvifescapedTF\expandafter{\skv@prova}{}{% \skv@err{Value of key 'remember': \MessageBreak Holder macro \skvoxdetok\skv@prova not escaped}\@ehd }% @@ -1228,7 +1328,7 @@ \skv@err{Value of key 'remember' has no child macro; \MessageBreak i.e., no macro after 'as'}\@ehd \else - \expandafter\skvifescaped\expandafter{\skv@provb}{% + \expandafter\skvifescapedTF\expandafter{\skv@provb}{% \skv@foreach@swatrue }{% \skv@err{Value of key 'remember': @@ -1286,7 +1386,7 @@ \skvrobustdef*\skv@foreach@parserecall#1{% \begingroup \def\skv@tempxifin##1##2{% - \skvxifin{\detokenize{##1}}{\detokenize{##2}}% + \skvxifinTF{\detokenize{##1}}{\detokenize{##2}}% }% \skv@tempxifin{(}{#1}{% \skv@err{Value of key 'recall': '(' found. @@ -1301,8 +1401,8 @@ \skv@err{Value of key 'recall' has no holder macro: \MessageBreak i.e., no macro that holds input}\@ehd \else - \expandafter\skvifntype\expandafter{\skv@prova}{% - \expandafter\skvifescaped\expandafter{\skv@prova}{% + \expandafter\skvifntypeTF\expandafter{\skv@prova}{% + \expandafter\skvifescapedTF\expandafter{\skv@prova}{% \edef\skv@elt{\expandafter\skvremovescape\skv@prova}% \skv@foreach@swatrue % Initially: @@ -1349,6 +1449,23 @@ \fi }% } +% \skv@foreach@doreverselist{<parser>}{<listcmd>} +\skvnewdef*\skv@foreach@doreverselist#1#2{% + \begingroup + \def\skv@tempb{}% + \def\skv@tempa##1#1##2\skv@reverse@stop{% + \if\relax\detokenize{##2}\relax\skv@reverse@stop\fi + \skv@tempa##2\skv@reverse@stop + \edef\skv@tempb{% + \skvexpandonce\skv@tempb\ifx\skv@tempb\@empty\else#1\fi + \unexpanded{##1}% + }% + }% + \def\skv@reverse@stop##1\skv@reverse@stop{\fi}% + \expandafter\skv@tempa#2#1\skv@reverse@stop + \let#2\skv@tempb + \skvaftergroupdef#2\endgroup +} % Eg, \skv@dots@in<value>\skv@nil...\skv@nnil\skv@stop \skvnewdef*\skv@dots@in#1...#2#3\skv@stop{% @@ -1376,8 +1493,9 @@ \skvrobustdef*\skv@foreach@pushstate{% \skvsavestate\skv@foreach@stack{% + \do\skv@foreach@seenstar \do\skv@foreach@parser\do\skv@foreach@subparser - \do\skv@foreach@listismacro + \do\skv@foreach@listisamacro \do\skv@foreach@processupto\do\skv@foreach@processempty \do\skv@foreach@exittester \do\skv@foreach@grow\do\skv@foreach@growleft @@ -1392,20 +1510,24 @@ \do\foreachlistremainder\do\skv@foreach@mainloop \do\skv@foreach@getnext\do\skv@foreach@getrm \do\skv@foreach@do@a\do\skv@foreach@do@b + \do\skv@foreach@paramlist \do\skv@foreach@holderlist \do\skv@foreach@userlist \do\skv@foreach@inherit \do\skv@foreach@keepdecimals \do\skv@foreach@keephighdecimals \do\skv@foreach@itemcounter - \do\skv@foreach@link\do\skv@foreach@expandbeforefill + \do\skv@foreach@link + \do\skv@foreach@expandlistbeforefill\do\skv@foreach@expandlistonce + \do\skv@foreach@expandlisttwice\do\skv@foreach@expandlistfully \do\skv@listbreakertoks\do\skv@listpausertoks + \do\skv@foreach@reverselist \do\foreachcurrentitem \do\foreachnextitem \do\foreachitemcount \do\foreachprevitem % The following commands are disabled on entry into the loop. - % Hence they need to be stacked: + % Hence they need to be stacked here: \do\prependtobeginforeach \do\appendtobeginforeach \do\atbeginforeach @@ -1422,14 +1544,15 @@ \skvnewdef*\skv@foreach@nnil{\skv@foreach@nil} \skvrobustdef*\newforeach{\skv@testst\skv@newforeach@beginprescan} \skvrobustdef*\skv@newforeach@beginprescan{% - \edef\skv@foreach@st{0\ifskv@tempst0\else1\fi}% + \edef\skv@foreach@seenstar{0\ifskv@tempst0\else1\fi}% \begingroup + \def\skv@foreach@holderlist{}% \def\skv@tempa{% \skvexpanded{\endgroup - \noexpand\skv@foreach@endprescan{\skvexpandonce\skv@tempb}% + \noexpand\skv@foreach@endprescan + {\skvexpandonce\skv@foreach@holderlist}% }% }% - \def\skv@tempb{}% \let\bgroup\relax \skvifnextchar[{% \endgroup @@ -1449,8 +1572,8 @@ }% } \skvrobustdef*\skv@foreach@collectholders#1{% - \edef\skv@tempb{% - \skvexpandonce\skv@tempb\skvtrimspace{#1}% + \edef\skv@foreach@holderlist{% + \skvexpandonce\skv@foreach@holderlist\skvtrimspace{#1}% }% \skvifnextchar[{% \skv@tempa @@ -1467,14 +1590,14 @@ }% } \skvrobustdef*\skv@foreach@endprescan#1[#2]{% - \skvifblank{#1}{% + \skvifblankTF{#1}{% \skv@err{\string\newforeach: no holder macros seen}\@ehd }{% \skv@foreach@scanarg[#2]#1% }% } -\skvrobustdef*\skv@foreach@scanarg{\skv@testopt\skv@foreach@a{}} -\skvrobustdef*\skv@foreach@a[#1]{% +\skvrobustdef*\skv@foreach@scanarg{\skv@testopt\skv@foreach@scanarg@a{}} +\skvrobustdef*\skv@foreach@scanarg@a[#1]{% \skv@foreach@pushstate \skv@foreach@latehookerr % \foreachitemcount must be a macro, not a counter, because it is stacked: @@ -1492,39 +1615,50 @@ % Since \skv@foreach@precallback are initialized in each nest, the % keys have to be reset here. \skv@foreach@setkeys{#1}% + % We've set the keys; let's overrule \skv@foreach@expandlistonce if + % we had seen a star suffix. Don't overrule \skv@foreach@expandlisttwice + % and \skv@foreach@expandlistfully. + \if\skv@foreach@seenstar + \def\skv@foreach@expandlistonce{00}% + \fi + \ifcase0% + \if\skv@foreach@expandlistonce0\else + \if\skv@foreach@expandlisttwice0\else + \if\skv@foreach@expandlistfully0\else 1\fi\fi\fi\relax + \def\skv@foreach@listisamacro{00}% + \else + \def\skv@foreach@listisamacro{01}% + \fi \begingroup % Collect item holders. Don't confuse explicit \bgroup for left brace: \skv@cnta\skvz@ - \def\skv@tempb{}% + \def\skv@foreach@holderlist{}% \let\bgroup\relax - \skvifnextchar i\skv@foreach@c{% - \skvifnextchar\skv@orig@bgroup\skv@foreach@d\skv@foreach@b + \skvifnextchar i\skv@foreach@scanarg@c{% + \skvifnextchar\skv@orig@bgroup + \skv@foreach@scanarg@d\skv@foreach@scanarg@b }% } % #1: one holer macro or subparser. -\skvrobustdef*\skv@foreach@b#1{% - \ifnum\skv@cnta=\skvz@ - \skvifescaped{#1}{}{% - \skv@err{Token '\noexpand#1' is not escaped - \MessageBreak and can't be a holder macro}\@ehd - }% - \else +\skvrobustdef*\skv@foreach@scanarg@b#1{% + % Odd items must be subparser: + \ifodd\skv@cnta \ifnum\skv@cnta=\@ne - \skvifescaped{#1}{% + \skvifescapedTF{#1}{% \skv@err{Token '\noexpand#1' cannot be a subparser; - \MessageBreak it seems to be a holder macro. - \MessageBreak I expected the subparser to be the - \MessageBreak second token here.}\@ehd + \MessageBreak it seems to be a holder macro. I expected + \MessageBreak the subparser to be the token here.}\@ehd }{% \edef\skv@prova{\skvtrimspace{#1}}% \let\elt\skvexpandonce - \def\skv@elt{\elt\skv@foreach@subparser}% - \if\elt\skv@prova\skv@elt\else - % Don't stack \skv@warnsubparser: + \let\skv@elt\skv@foreach@subparser + \if\elt\skv@prova\elt\skv@elt\else + % Don't stack \skv@warnsubparser, so that the following + % warning isn't called more than once in the inner loop. \ifnum\skv@warnsubparser=\skvz@ \skvgadvanceno\skv@warnsubparser\@ne \skv@warn{Scanned subparser '\elt\skv@prova' is different from - \MessageBreak the default or user-supplied subparser '\skv@elt'. + \MessageBreak the default or user-supplied subparser '\elt\skv@elt'. \MessageBreak I have used '\elt\skv@prova', but please submit \MessageBreak '\elt\skv@prova' as the value of the key 'subparser' @@ -1534,83 +1668,92 @@ \fi }% \fi + \else + \skvifescapedTF{#1}{}{% + \skv@err{Token '\noexpand#1' is not escaped + \MessageBreak and can't be a holder macro}\@ehd + }% \fi \advance\skv@cnta\@ne - \edef\skv@tempb{\skvexpandonce\skv@tempb\skvtrimspace{#1}}% - \skvifnextchar i\skv@foreach@c{% - \skvifnextchar\skv@orig@bgroup\skv@foreach@d\skv@foreach@b + \edef\skv@foreach@holderlist{% + \skvexpandonce\skv@foreach@holderlist\skvtrimspace{#1}% + }% + \skvifnextchar i\skv@foreach@scanarg@c{% + \skvifnextchar\skv@orig@bgroup + \skv@foreach@scanarg@d\skv@foreach@scanarg@b }% } -\skvrobustdef*\skv@foreach@c#1#2{% - \skvifstrcmp{#1#2}{in}{% - \skv@foreach@d +\skvrobustdef*\skv@foreach@scanarg@c#1#2{% + \skvifstrcmpTF{#1#2}{in}{% + \skv@foreach@scanarg@d }{% \skv@err{I have seen 'i' but no expected 'in'}\@ehd }% } -\skvrobustdef*\skv@foreach@d{% - \ifx\skv@tempb\@empty +\skvrobustdef*\skv@foreach@scanarg@d{% + \ifx\skv@foreach@holderlist\@empty \skv@err{No item holder macros before 'in' \MessageBreak or before left brace}\@ehd \fi \skvifnextchar\skv@orig@bgroup{% - \skv@foreach@e + \skv@foreach@scanarg@e }{% - \if\skv@foreach@listismacro - \expandafter\skv@foreach@e + \if\skv@foreach@listisamacro + \expandafter\skv@foreach@scanarg@e \else - \if\skv@foreach@st - \expandafter\expandafter\expandafter\skv@foreach@e - \else - \def\reserved@a##1{% - \skvifmacro{##1}{% - \def\skv@ehd{Maybe a star (*) suffix or key 'list is - a macro' is missing.}% - }{% - \let\skv@ehd\@ehd - }% - \skv@err{I expected a left brace for beginning of list, - \MessageBreak since you haven't told me that your - \MessageBreak list is a macro. Instead I found '\detokenize{##1}'. - \MessageBreak If your list is indeed a macro, you can - \MessageBreak either put star (*) after \noexpand\newforeach - \MessageBreak or use the key 'list is a macro'% - }{% - \skv@ehd - }% + \def\reserved@a##1{% + \skvifmacroTF{##1}{% + \def\skv@tempehd{Maybe a star (*) suffix after + \noexpand\newforeach or key 'expand list once', etc., + \MessageBreak is missing.}% + }{% + \let\skv@tempehd\@ehd }% - \expandafter\expandafter\expandafter\reserved@a - \fi + \skv@err{I expected a left brace for beginning of list, + \MessageBreak since you haven't told me that your + \MessageBreak list is a macro. Instead I found '\detokenize{##1}'. + \MessageBreak If your list is indeed a macro, you can + \MessageBreak either put star (*) after \noexpand\newforeach + \MessageBreak or use the key 'expand list once' + \MessageBreak or 'expand list twice' or 'list is a macro', etc.% + }\skv@tempehd + }% + \expandafter\reserved@a \fi }% } % #1: <list> or <listcmd> -\skvrobustdef*\skv@foreach@e#1{% - \edef\skv@tempc{\unexpanded{#1}}% - \skvifnextchar\skv@orig@bgroup\skv@foreach@h{% - \skvifnextchar d\skv@foreach@f\skv@foreach@g +\skvrobustdef*\skv@foreach@scanarg@e#1{% + \edef\skv@foreach@userlist{\unexpanded{#1}}% + \skvifnextchar\skv@orig@bgroup\skv@foreach@scanarg@h{% + \skvifnextchar d\skv@foreach@scanarg@f\skv@foreach@scanarg@g }% } -\skvrobustdef*\skv@foreach@f#1#2{% - \skvifstrcmp{#1#2}{do}{% - \skvifnextchar\skv@orig@bgroup\skv@foreach@h\skv@foreach@g +\skvrobustdef*\skv@foreach@scanarg@f#1#2{% + \skvifstrcmpTF{#1#2}{do}{% + \skvifnextchar\skv@orig@bgroup + \skv@foreach@scanarg@h\skv@foreach@scanarg@g }{% \skv@err{I have seen 'd' but no the expected 'do'}\@ehd }% } % We've exhausted all options for grabbing the callback, so now -% look for terminator (default ;). If there is no terminator ahead, -% the use of \skv@prova will trigger 'the use of ... does not match -% its definition' or 'runaway argument ...'. -\skvrobustdef*\skv@foreach@g{% +% look for terminator (default ;). +% +% 1. If there is no terminator ahead, the use of \skv@prova will trigger +% 'the use of ... does not match its definition' or +% 'runaway argument ...'. +% 2. This covers the case when \newforeach or \foreach comes next in +% the callback. +\skvrobustdef*\skv@foreach@scanarg@g{% \def\skv@prova##1{% \def\skv@prova####1##1{% % Look out for a case like 'parser=<parser>'. % Eg, \newforeach[parser=;]. In this case, the value ';' of % key 'parser' will mistakenly be assumed to be the callback % terminator. It should be enclosed in braces. - \skvxifin{\detokenize{parser=}\relax}{\detokenize{####1}\relax}{% - \skvxifin{[}{\detokenize{####1}}{% + \skvxifinTF{\detokenize{parser=}\relax}{\detokenize{####1}\relax}{% + \skvxifinTF{[}{\detokenize{####1}}{% \skv@err{Put '##1' in braces for key 'parser=##1'. \MessageBreak Try [parser={##1}]} {Maybe parser '##1' is the value of a key/option of @@ -1619,48 +1762,58 @@ one ending a TikZ object. Maybe you need to do [parser={##1}].}% }{% % Otherwise, let's try continue: - \skvexpanded{\noexpand\skv@foreach@h{\skvtrimspace{####1}##1}}% + \skvexpanded{% + \noexpand\skv@foreach@scanarg@h{\skvtrimspace{####1}##1}% + }% }% }{% - \skvexpanded{\noexpand\skv@foreach@h{\skvtrimspace{####1}##1}}% + \skvexpanded{% + \noexpand\skv@foreach@scanarg@h{\skvtrimspace{####1}##1}% + }% }% }% \skv@prova }% - % In case callback terminator is currently active: + % In case callback terminator is currently active, rescan it. \skv@rescan\skv@foreach@terminator \expandafter\skv@prova\expandafter{\skv@foreach@terminator}% } % #1: callback -\skvrobustdef*\skv@foreach@h#1{% +\skvrobustdef*\skv@foreach@scanarg@h#1{% \skvexpanded{\endgroup - % The subparser may have changed along the way (see \skv@foreach@b): + % The subparser may have changed along the way + % (see \skv@foreach@scanarg@b): \skvcmdexit\skv@foreach@subparser - \skv@foreach@i{\skvexpandonce\skv@tempb}{\skvexpandonce\skv@tempc}% + \skv@foreach@mainprocess + {\skvexpandonce\skv@foreach@holderlist}% + {\skvexpandonce\skv@foreach@userlist}% }{#1}% } % #1: holder macros % #2: List or list command % #3: Callback -\skvrobustdef*\skv@foreach@i#1#2#3{% - \if\skv@foreach@st\else - \if\skv@foreach@listismacro - \def\skv@foreach@st{00}% - \else - \def\skv@foreach@st{01}% - \fi - \fi +\skvrobustdef*\skv@foreach@mainprocess#1#2#3{% \edef\skv@foreach@userlist{% - \if\skv@foreach@st + \if\skv@foreach@expandlistonce \expandafter\skvexpandonce \else - \expandafter\unexpanded + \if\skv@foreach@expandlisttwice + \expandafter\expandafter\expandafter\skvexpandtwice + \else + \if\skv@foreach@expandlistfully + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter\@iden + \else + \expandafter\expandafter\expandafter\expandafter + \expandafter\expandafter\expandafter\unexpanded + \fi + \fi \fi {#2}% }% % Initial code, if any: \skvcsuse{skv@foreach@atbeginhook@\skvrom\foreachdepth}% - \skvifdef\foreachprevitem{}{\def\foreachprevitem{}}% + \skvifdefTF\foreachprevitem{}{\def\foreachprevitem{}}% \expandafter\skv@foreach@normalize\expandafter [\skv@foreach@parser]\skv@foreach@userlist \expandafter\skv@foreach@normalize\expandafter @@ -1694,21 +1847,21 @@ }% \def\skv@foreach@do@a####1##1####2\skv@foreach@stop{% \edef\foreachcurrentitem{\skvexpandonce{\@gobble####1}}% - \skvifx\foreachcurrentitem\skv@foreach@nnil{% + \skvifxTF\foreachcurrentitem\skv@foreach@nnil{% \skvbreakloopfalse \foreachlastitemfalse }{% - \skvifx\foreachcurrentitem\skv@listbreakertoks{% + \skvifxTF\foreachcurrentitem\skv@listbreakertoks{% \skv@foreach@getrm{####2}% }{% - \skvifx\foreachcurrentitem\skv@listpausertoks{% + \skvifxTF\foreachcurrentitem\skv@listpausertoks{% \message{^^J! List pause: ^^JType x or X to quit, or <RETURN> to proceed^^J}% \begingroup \endlinechar\m@ne\global\read-1 to\@gtempa \endgroup \skvexpandarg\lowercase{\def\noexpand\@gtempa{\@gtempa}}% - \skvxifstrcmp\@gtempa{x}{% + \skvxifstrcmpTF\@gtempa{x}{% \skv@foreach@getrm{####2}% }{% \skv@foreach@do@b{####2}% @@ -1721,26 +1874,26 @@ }% \def\skv@foreach@do@b####1{% \edef\foreachitemcount{\the\numexpr\foreachitemcount+1}% - \ifnum0=\numexpr - \ifx\skv@foreach@itemcounter\@undefined-1\else+0\fi - \ifx\skv@foreach@itemcounter\@empty-1\else+0\fi - \ifx\skv@foreach@itemcounter\@nnil-1\else+0\fi\relax\relax + \ifcase0% + \ifx\skv@foreach@itemcounter\@undefined 1\fi + \ifx\skv@foreach@itemcounter\@empty 1\fi + \ifx\skv@foreach@itemcounter\@nnil 1\fi\relax \expandafter\let\skv@foreach@itemcounter\foreachitemcount \fi \skv@foreach@lookahead@a\skv@foreach@getnext####1\skv@foreach@stop % In case the user decides to continue after \listpauser: - \skvifx\foreachcurrentitem\skv@listpausertoks{}{% + \skvifxTF\foreachcurrentitem\skv@listpausertoks{}{% \expandafter\skv@foreach@callback\expandafter{\foreachcurrentitem}% }% \let\foreachprevitem\foreachcurrentitem - \ifx\skv@foreach@processupto\@undefined\else - \ifx\skv@foreach@processupto\@nnil\else - \ifnum\foreachitemcount<\skv@foreach@processupto\relax\else - \skvbreakloop - \fi + \ifcase0% + \ifx\skv@foreach@processupto\@undefined 1\fi + \ifx\skv@foreach@processupto\@nnil 1\fi\relax + \ifnum\foreachitemcount<\skv@foreach@processupto\relax\else + \skvbreakloop \fi \fi - \skvifdefbool{skvbreakloop}{% + \skvifdefboolTF{skvbreakloop}{% \skv@foreach@getrm{####1}% }{% \skv@foreach@lookahead@a\skv@foreach@do@a####1\skv@foreach@stop @@ -1755,11 +1908,15 @@ }% \skv@prova####1% }% - \skvifx\skv@foreach@userlist\@empty{% + \skvifxTF\skv@foreach@userlist\@empty{% \if\skv@foreach@processempty\skv@foreach@callback{}\fi }{% \expandafter\skv@foreach@filllist\expandafter {\skv@foreach@parser}\skv@foreach@userlist + \if\skv@foreach@reverselist\skvafterfi + \expandafter\skv@foreach@doreverselist\expandafter + {\skv@foreach@parser}\skv@foreach@userlist + \fi \expandafter\skv@foreach@lookahead@a\expandafter\skv@foreach@do@a \skv@foreach@userlist##1\skv@foreach@nil##1\skv@foreach@stop }% @@ -1776,6 +1933,9 @@ \skvrestorestate\skv@foreach@holderstate\skv@foreach@sisterdepth \fi \skv@foreach@popstate + \ifnum\foreachdepth=\skvz@ + \def\skv@warnsubparser{0}% + \fi } % \skv@foreach@makeprecode{<holder.list>} @@ -1850,12 +2010,11 @@ \skvcmdexit\skv@foreach@precallback }% } - % #1: callback \skvrobustdef*\skv@foreach@makeauxcallback#1{% \begingroup \def\skv@generatesubparser##1{% - \ifnum##1<10\skvexpandonce\skv@foreach@subparser + \ifnum##1<10 \skvexpandonce\skv@foreach@subparser \expandafter\skv@generatesubparser \expandafter{\number\numexpr##1+1\expandafter}% \fi @@ -1863,24 +2022,25 @@ % Add extra subparsers in case some items aren't subparser-complete: \edef\skv@tempa{\skv@generatesubparser{1}}% \let\foreacheov\relax + \let\\\noexpand \skvexpanded{\endgroup % Define auxiliary callback: - \def\noexpand\skv@foreach@auxcallback\skv@foreach@paramlist\foreacheov{% + \def\\\skv@foreach@auxcallback\skv@foreach@paramlist\foreacheov{% % Holder macro assignments: \skvexpandonce\skv@foreach@precallback % User tests/tasks, eg, if requested from 'evaluate' key: \skvexpandonce\skv@foreach@afterprecallback - \noexpand\ifnum\noexpand\foreachitemcount=\@ne - \noexpand\skv@foreach@onlyinitially - \noexpand\fi + \\\ifnum\\\foreachitemcount=\@ne + \\\skv@foreach@onlyinitially + \\\fi \unexpanded{#1}% % User tests/tasks, eg, if requested from the keys 'remember', % 'exit when', etc: \skvexpandonce\skv@foreach@postcallback }% % Define the real callback: - \def\noexpand\skv@foreach@callback####1{% - \noexpand\skv@foreach@auxcallback####1\skv@tempa\foreacheov + \def\\\skv@foreach@callback####1{% + \\\skv@foreach@auxcallback####1\skvxonce\skv@tempa\foreacheov }% }% } @@ -1917,12 +2077,12 @@ } \skvnewdef*\skv@foreach@ifloweralpha#1{% - \skvifblank{#1}{% + \skvifblankTF{#1}{% \@secondoftwo }{% - \skvifntype{#1}{% - \skvifnum`#1>96{% - \skvifnum`#1<123{% + \skvifntypeTF{#1}{% + \skvifnumTF`#1>96{% + \skvifnumTF`#1<123{% \@firstoftwo }{% \@secondoftwo @@ -1936,12 +2096,12 @@ }% } \skvnewdef*\skv@foreach@ifupperalpha#1{% - \skvifblank{#1}{% + \skvifblankTF{#1}{% \@secondoftwo }{% - \skvifntype{#1}{% - \skvifnum`#1>64{% - \skvifnum`#1<91{% + \skvifntypeTF{#1}{% + \skvifnumTF`#1>64{% + \skvifnumTF`#1<91{% \@firstoftwo }{% \@secondoftwo @@ -1965,12 +2125,12 @@ \def\skv@foreach@origunit{}% \def\skv@foreach@filledlist{}% \edef\skv@foreach@parser{\skvtrimspace{#1}}% - \ifx\skv@foreach@parser\@undefined + \ifx\skv@foreach@parser\@empty \def\skv@foreach@parser{,}% \fi \def\skv@foreach@iflinkgiven{% - \skvifdef\skv@foreach@link{% - \skvnotifx\skv@foreach@link\@nnil + \skvifdefTF\skv@foreach@link{% + \skvifxFT\skv@foreach@link\@nnil }{% \skv@err{List auto-completion: 'link' is undefined}\@ehd }% @@ -1987,8 +2147,8 @@ \edef\skv@tempa{\unexpanded{#2}}% \skv@foreach@normalize[#1]\skv@tempa \def\skv@prova##1{% - \skvxifin{...}{\detokenize{##1}}{% - \if\skv@foreach@expandbeforefill + \skvxifinTF{...}{\detokenize{##1}}{% + \if\skv@foreach@expandlistbeforefill \edef\skv@tempa{##1}% \skv@foreach@normalize[#1]\skv@tempa \else @@ -2015,10 +2175,10 @@ \fi \fi % \newforeach format is '<parser>...<parser>': - \skvxifin{\detokenize{#1...#1}}{\detokenize{#2}}{% + \skvxifinTF{\detokenize{#1...#1}}{\detokenize{#2}}{% \skv@foreach@splitonguide{#1}{#2}% \def\skv@prova##1#1##2#1...#1##3#1##4#1##5\skv@nil{% - \skvifblank{##3}{% + \skvifblankTF{##3}{% \skv@err{I can't find upper limit number or dimension, \MessageBreak i.e., after symbool '...'}\@ehd }{% @@ -2032,7 +2192,7 @@ % Complete the list: \skv@foreach@filllist@c{#1}{##1}{##2}{##3}% % In case the list is folded on ellipsis (...): - \skvifblank{##4}{}{\skv@foreach@filllist@a{#1}{##4#1##5}}% + \skvifblankTF{##4}{}{\skv@foreach@filllist@a{#1}{##4#1##5}}% }% }% \expandafter\skv@prova\skv@tempa#1#1\skv@nil @@ -2045,9 +2205,9 @@ % \skv@foreach@zerostepwarn{<lower>}{<upper>}{<pt.or.nil>} \skvrobustdef*\skv@foreach@zerostepwarn#1#2#3{% \skv@warn{The tokens '\detokenize{#1}', '\detokenize{#2}' - give nil step; '1#3' used. \MessageBreak - Maybe you used the font-dependent units \MessageBreak - 'ex' or 'em' before \skv@begindoc@string}% + give nil step; '1#3' used.\MessageBreak + Maybe you used the font-dependent units\MessageBreak + 'ex' or 'em' \ifskv@latex before \skv@begindoctoks\fi}% } % skv@foreach@filllist@c{<parser>}{<lower1>}{<lower2>}{<upperbound>} @@ -2093,10 +2253,10 @@ \def\skv@prova##1{% \skv@foreach@swatrue \skviflacus#2\then\else - \skvifin{##1}{#2}{}\skv@foreach@swafalse + \skvifinTF{##1}{#2}{}\skv@foreach@swafalse \fi - \skvifin{##1}{#3}{}\skv@foreach@swafalse - \skvifin{##1}{#4}{}\skv@foreach@swafalse + \skvifinTF{##1}{#3}{}\skv@foreach@swafalse + \skvifinTF{##1}{#4}{}\skv@foreach@swafalse \ifskv@foreach@swa\else \edef\skv@provb{\ifx\@nnil#2\@nnil\else\unexpanded{#2}, \fi}% \skv@err{No link '##1' in one of @@ -2143,7 +2303,7 @@ % {a^1,a^3,...,a^9} : link = ^, grow = right % {A_1,B_1,...,E_1} : link = _, grow = left % {1--,4--,...,16--} : link = --, grow = left -% {1pt,4pt,...,10pt} : link = pt, grow = left (or addit. info.) +% {1pt,4pt,...,10pt} : link = pt, grow = left, or no addit. info. % {A_2pt,A_4pt,...,A_10pt} : link = _, grow = right % % The items prior to the last 2 items before '<guide>...' or before '...' @@ -2159,7 +2319,7 @@ \begingroup \skv@cnta\skvz@ \def\do##1#1{% - \skvifin{...}{##1}{% + \skvifinTF{...}{##1}{% \def\do####1\skv@nil{}% }{% \advance\skv@cnta\@ne @@ -2205,39 +2365,43 @@ % When we say, 'try PGF format', we don't actually mean the PGF format with % left and right guides, but the syntax '<guide>...' (ie, having only the % left-hand-side or only the right-hand-side guide). For example, -% {A_2pt,A_4pt,A_...,A_10pt}. \skv@foreach@trypgfformat will auto-complete -% this list without knowledge of the values of the keys 'link' and 'grow'. +% +% {A_2pt,A_4pt,A_...,A_10pt} or {1pt,4pt,...pt,10pt} +% +% \skv@foreach@trypgfformat will auto-complete this list without +% knowledge of the values of the keys 'link' and 'grow'. % % skeyval formats: % % {1pt,4pt,...pt,10pt} : no additional info. required % {A_2pt,A_4pt,A_...,A_10pt} : no additional info. required -% {1pt,4pt,...,10pt} : link = pt, grow=right (or no addit. info.) +% {1pt,4pt,...,10pt} : link = pt, grow=right, or no addit. info. % {A_2pt,A_4pt,...,A_10pt} : link =_, grow=right % -% The general PGF format (with left and right guides) is illegal here, -% because the skeyval-for package uses the location of the guide (left or -% right of ...) to determine the direction of growth. +% The general PGF format (with left and right guides), e.g., % % {A_2pt,A_4pt,A_...pt,A_10pt} % +% is illegal here, because the skeyval-for package uses the location +% of the guide (left or right of ...) to determine the direction of growth. +% \skvrobustdef*\skv@foreach@trypgfformat#1#2{% \skv@foreach@splitonguide{#1}{#2}% \def\skv@prova##1#1##2#1##3...##4#1##5#1##6#1##7\skv@nil{% - \skvifblank{##5}{% + \skvifblankTF{##5}{% \skv@err{I can't find upper limit number or dimension, \MessageBreak i.e., after symbool '...'}\@ehd }{% % \skv@foreach@filllist@a may be reentered. Hence - \if\relax\detokenize{##1}\relax\else + \skviflacus{##1}\then\else \edef\skv@foreach@filledlist{% \skvaddlist{#1}\skv@foreach@filledlist \skvtrimspace{##1}% }% \fi \def\do####1{{\skvtrimspace{####1}}}% - \skvifblank{##3}{% - \skvifblank{##4}{% + \skvifblankTF{##3}{% + \skvifblankTF{##4}{% \skv@err{No direction of growth before and/or after \MessageBreak symbol '...'}\@ehd }{% @@ -2249,7 +2413,7 @@ }% }% }{% - \skvifblank{##4}{% + \skvifblankTF{##4}{% \def\skv@foreach@growright{00}% \def\skv@foreach@growleft{01}% \skvexpanded{% @@ -2262,11 +2426,12 @@ \MessageBreak\noexpand\newforeach and \noexpand\newforeach. \MessageBreak I know that PGF's \noexpand\foreach needs it, \MessageBreak but I don't need it. I can - \MessageBreak auto-fill your list without it.}\@ehd + \MessageBreak auto-fill your list with information + \MessageBreak on only one side.}\@ehd }% }% % In case the list is folded on ellipsis (...): - \skvifblank{##6}{}{\skv@foreach@filllist@a{#1}{##6#1##7}}% + \skvifblankTF{##6}{}{\skv@foreach@filllist@a{#1}{##6#1##7}}% }% }% \expandafter\skv@prova\skv@tempa#1#1#1\skv@nil @@ -2286,10 +2451,10 @@ \skvrobustdef*\skv@foreach@trypgfformat@a#1#2#3#4#5{% \skv@foreach@swafalse \skviflacus#3\then\else - \skvxifin{#2}{#3}{}\skv@foreach@swatrue + \skvxifinTF{#2}{#3}{}\skv@foreach@swatrue \fi - \skvxifin{#2}{#4}{}\skv@foreach@swatrue - \skvxifin{#2}{#5}{}\skv@foreach@swatrue + \skvxifinTF{#2}{#4}{}\skv@foreach@swatrue + \skvxifinTF{#2}{#5}{}\skv@foreach@swatrue \ifskv@foreach@swa \skv@err{Guide token '\detokenize{#2}' not found in some \MessageBreak of the elements: I can't complete @@ -2467,8 +2632,6 @@ }% \expandafter\do#3#1\do#1% } - - \skvrobustdef*\skv@foreach@getcomparator{% \begingroup % 'unit' isn't required in alphabetic sequences: @@ -2476,7 +2639,7 @@ \let\skvreversedo\@iden \edef\skv@provb{\skvexpbracenext\skvreverse{\skv@foreach@step}}% \def\skv@prova##1##2##3\skv@nil{% - \skvxifin{,\detokenize{##2##1},}{,\skvoxdetok\skv@validunit,}{% + \skvxifinTF{,\detokenize{##2##1},}{,\skvoxdetok\skv@validunit,}{% \def\skv@foreach@unit{}% }{% \def\skv@foreach@unit{pt}% @@ -2551,7 +2714,7 @@ step '\skv@foreach@step' isn't an integer}\@ehd }% \skv@foreach@addtolist{#1}{#2}#4% - \skvifstrcmp{#2}{#3}{}{% + \skvifstrcmpTF{#2}{#3}{}{% \edef\skv@lowerlimit{#2}% \edef\skv@upperlimit{#3}% \skvexpandnext{\chardef\skv@lowerlimit`}\skv@lowerlimit\relax diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-ltxcmds.tex b/Master/texmf-dist/tex/latex/skeyval/skeyval-ltxcmds.tex index dbdb14df6cf..17b4c19c9d5 100644 --- a/Master/texmf-dist/tex/latex/skeyval/skeyval-ltxcmds.tex +++ b/Master/texmf-dist/tex/latex/skeyval/skeyval-ltxcmds.tex @@ -1,5 +1,5 @@ %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -% This is file 'skeyval-ltxcmds.tex', version 1.1, 2012/10/15. % +% This is file 'skeyval-ltxcmds.tex', version 1.1a, 2012/10/16. % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % @@ -26,29 +26,80 @@ % Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com). % %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -\csname skeyval-ltxcmds-loaded\endcsname -\expandafter\let\csname skeyval-ltxcmds-loaded\endcsname\endinput - +\begingroup% +\let\e\endlinechar\edef\p{\the\e}\e13\edef\n{\the\catcode\e}% +\xdef\skv@ltxcmds@restorecatcodes{% + \let\noexpand\skv@ltxcmds@restorecatcodes\relax% + \endlinechar=\p\relax\catcode\number\e=\n\relax% + \catcode\string`\noexpand`\string=\the\catcode\string``\relax% + \catcode\string`\noexpand=\string=\the\catcode\string`=\relax% +}% +\endgroup% +\endlinechar\string=13\relax% +\catcode13\string=5\relax% +\catcode\string``\string=12\relax +\catcode\string`=\string=12\relax +\long\def\skvgobble#1{} +\def\do#1{\catcode`\expandafter\skvgobble\string#1=\the\catcode`#1\relax} \edef\skv@ltxcmds@restorecatcodes{% - \catcode`\noexpand\@\the\catcode`\@\relax - \let\noexpand\skv@ltxcmds@restorecatcodes\relax + \unexpanded\expandafter{\skv@ltxcmds@restorecatcodes}% + \do\ \do\%\do\@\do\(\do\)\do\[\do\]\do\|\do\:\do\;\do\,\do\.% + \do\>\do\<\do\!\do\*\do\+\do\-\do\^\do\_\do\&\do\$\do\~\do\'% + \do\"\do\ } -\catcode`\@=11\relax +\catcode`\ =10\relax +\catcode`\@=11 \catcode`\(=12 \catcode`\)=12 \catcode`\[=12 +\catcode`\]=12 \catcode`\|=12 \catcode`\:=12 \catcode`\;=12 +\catcode`\,=12 \catcode`\*=12 \catcode`\+=12 \catcode`\-=12 +\catcode`\<=12 \catcode`\>=12 \catcode`\!=12 \catcode`\.=12 +\catcode`\^=07 \catcode`\_=08 \catcode`\&=04 \catcode`\$=03 +\catcode`\~=13 \catcode`\%=14 \catcode`\'=12 \catcode`\"=12 -\message{skeyval-ltxcmds 2012/10/15 v1.1 skeyval TeX header (AM)} +\csname skeyval-ltxcmds-loaded\endcsname +\expandafter\let\csname skeyval-ltxcmds-loaded\endcsname\endinput +\message{skeyval-ltxcmds 2012/10/16 v1.1a skeyval TeX header (AM)} + +\countdef\m@ne=22 \m@ne=-1 +\def\wlog{\immediate\write\m@ne} +\countdef\count@=255 +\dimendef\dimen@=0 +\dimendef\dimen@i=1 +\dimendef\dimen@ii=2 +\skipdef\skip@=0 +\toksdef\toks@=0 +\newif\if@tempswa +\newcount\@tempcnta +\newcount\@tempcntb +\newdimen\@tempdima +\newdimen\@tempdimb +\newdimen\@tempdimc +\newbox\@tempboxa +\newskip\@tempskipa +\newskip\@tempskipb +\newtoks\@temptokena \def\@nnil{\@nil} \def\@empty{} +\def\space{ } +\def\@space{ } \long\def\@firstofone#1{#1} +\let\@iden\@firstofone \long\def\@firstoftwo#1#2{#1} \long\def\@secondoftwo#1#2{#2} \long\def\@gobble#1{} \long\def\@gobbletwo#1#2{} \lowercase{\def\@gobblespace} {} \def\@nameuse#1{\csname#1\endcsname} +\def\@namedef#1{\expandafter\def\csname#1\endcsname} \let\l@ngrel@x\relax +\def\loop#1\repeat{% + \def\iterate{#1\relax\expandafter\iterate\fi}% + \iterate\let\iterate\relax +} +\let\repeat\fi \protected\def\newif#1{% - \count@\escapechar\escapechar\m@ne + \count@\escapechar + \escapechar\m@ne \let#1\iffalse \ltx@booldef#1\iftrue \ltx@booldef#1\iffalse diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-ltxpatch.sty b/Master/texmf-dist/tex/latex/skeyval/skeyval-ltxpatch.sty index e44d3b50f7b..82d624e3985 100644 --- a/Master/texmf-dist/tex/latex/skeyval/skeyval-ltxpatch.sty +++ b/Master/texmf-dist/tex/latex/skeyval/skeyval-ltxpatch.sty @@ -1,5 +1,5 @@ %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -% This is file 'skeyval-ltxpatch.sty', version 1.1, 2012/10/15. % +% This is file 'skeyval-ltxpatch.sty', version 1.1a, 2012/10/16. % % % % The rationale for this package: the patch in 'xkvltxp' package isn't % % strong enough. % @@ -42,9 +42,15 @@ \expandafter\do \fi }% - \edef\skvltxp@restorecodes{\do035,064,123,125,061,059,\do,}% + \edef\skv@ltxp@restorecodes{\do35,64,123,125,61,59,13,\do,}% } \skv@prova + +\edef\skv@ltxp@restorecodes{% + \unexpanded\expandafter{\skv@ltxp@restorecodes}% + \endlinechar\the\endlinechar\relax +} +\endlinechar13 % \catcode035 06 % # \catcode064 11 % @ \catcode123 01 % { @@ -53,8 +59,8 @@ \catcode044 12 % , \def\do#1=#2,{% \ifx\do#1\else - \edef\skvltxp@restorecodes{% - \skvltxp@restorecodes + \edef\skv@ltxp@restorecodes{% + \unexpanded\expandafter{\skv@ltxp@restorecodes}% \catcode#1=\the\catcode#1\relax }% \catcode#1=#2\relax @@ -66,12 +72,13 @@ \NeedsTeXFormat{LaTeX2e}[2011/06/27] \ProvidesPackage{skeyval-ltxpatch} - [2012/10/15 v1.1 Patches for LaTeX2e kernel options processing (AM)] + [2012/10/16 v1.1a Patches for LaTeX2e kernel options processing (AM)] +\ifdefined\skvz@\else\newdimen\skvz@\fi \def\@space{ } \protected\def\skvltxptracingall{% \tracinggroups\@ne\tracingifs\@ne\loggingall\tracingassigns\@ne - \tracingonline\z@\tracingifs\z@ + \tracingonline\skvz@\tracingifs\skvz@ } \let\skvltxploggingall\skvltxptracingall @@ -105,12 +112,13 @@ \edef#1{\expandafter\skvltxp@trimspace\expandafter{#1}}% } -% \skvltxp@normalize isn't meant for normalizing keyval lists. -\protected\def\skvltxp@setupnormalizer#1{% +% \skvltxp@setupnormalizer{<parser>}<normalizer.cmd> +% <normalizer.cmd> should not be used for normalizing keyval lists. +\protected\def\skvltxp@setupnormalizer#1#2{% \begingroup \lccode`\~=`#1\relax \lowercase{\endgroup - \def\skvltxp@normalize##1{% + \def#2##1{% \unexpanded\expandafter {\romannumeral\skvltxp@activeparser#1##1#1~\skv@nil}% }% @@ -138,10 +146,7 @@ }% }% } -\def\skvltxp@commanormalize#1{% - \skvltxp@setupnormalizer{,}% - \edef#1{\expandafter\skvltxp@normalize\expandafter{#1}}% -} +\skvltxp@setupnormalizer{,}\skvltxp@commanormalize \newif\ifbreakkerpaloop \def\kerpaloopdepth{0} @@ -176,13 +181,14 @@ }% \xdef\kerpaloopdepth{\the\numexpr\kerpaloopdepth-1}% } +% \skvltxp@getoptionnames<cmd.in><cmd.out> \def\skvltxp@getoptionnames#1#2{% \def#2{}% - \skvltxp@commanormalize#1% - \def\do##1=##2\skv@nil{% - \edef#2{\ifx#2\@empty\else#2,\fi##1}% + \edef#1{\expandafter\skvltxp@commanormalize\expandafter{#1}}% + \def\do##1=##2=##3\skv@nil{% + \edef#2{\ifx\@empty#2\else#2,\fi##1}% }% - \kerpaloop*{,}#1{\do##1=\skv@nil}% + \kerpaloop*{,}#1{\do##1==\skv@nil}% } \def\@ptionlist#1{% \@ifundefined{opt@#1}{}{\unexpanded\expandafter @@ -192,9 +198,9 @@ \@expandtwoargs\@if@pti@ns{\@ptionlist{#2.#1}}{\unexpanded{#3}}% } \def\@if@pti@ns#1#2{% - \skvltxp@setupnormalizer{,}% - \edef\skv@options@i{\skvltxp@normalize{#1}}% - \edef\skv@options@ii{\skvltxp@normalize{#2}}% +% \skvltxp@setupnormalizer{,}% + \edef\skv@options@i{\skvltxp@commanormalize{#1}}% + \edef\skv@options@ii{\skvltxp@commanormalize{#2}}% \ifx\skv@options@i\skv@options@ii \def\skv@tempa{\expandafter\@firstoftwo\@gobbletwo}% \else @@ -431,7 +437,7 @@ } \let\@@fileswith@pti@ns\@fileswith@pti@ns -\skvltxp@restorecodes +\skv@ltxp@restorecodes \endinput %% End of file `skeyval-ltxpatch.sty'. diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.sty b/Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.sty index 155b5b56b02..280338217ac 100644 --- a/Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.sty +++ b/Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.sty @@ -1,5 +1,5 @@ %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -% This is file 'skeyval-pstkey.sty', version 1.1, 2012/10/15. % +% This is file 'skeyval-pstkey.sty', version 1.1a, 2012/10/16. % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % @@ -26,19 +26,61 @@ % Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com). % %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% +\begingroup +\catcode035 06 % # +\catcode064 11 % @ +\catcode123 01 % { +\catcode125 02 % } +\catcode044 12 % , +\def\skv@prova{\endgroup + \def\do##1,{% + \ifx\do##1\else + \catcode##1\string=\the\catcode##1\relax + \expandafter\do + \fi + }% + \edef\skv@pst@restorecodes{\do35,64,123,125,61,59,13,\do,}% +} +\skv@prova + +\edef\skv@pst@restorecodes{% + \unexpanded\expandafter{\skv@pst@restorecodes}% + \endlinechar\the\endlinechar\relax +} +\endlinechar13 % +\catcode035 06 % # +\catcode064 11 % @ +\catcode123 01 % { +\catcode125 02 % } +\catcode061 12 % = +\catcode044 12 % , +\def\do#1=#2,{% + \ifx\do#1\else + \edef\skv@pst@restorecodes{% + \unexpanded\expandafter{\skv@pst@restorecodes}% + \catcode#1=\the\catcode#1\relax + }% + \catcode#1=#2\relax + \expandafter\do + \fi +} +\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,\do=,% + \NeedsTeXFormat{LaTeX2e}[2011/06/27] \ProvidesPackage{skeyval-pstkey} - [2012/10/15 v1.1 LaTeX/package wrapper for skeyval-pstkey.tex (AM)] + [2012/10/16 v1.1a LaTeX/package wrapper for skeyval-pstkey.tex (AM)] \expandafter\ifx\csname skeyval-pstkey-loaded\endcsname \endinput\else \input skeyval-pstkey \fi \skvdeclareoption*{% - \PackageWarning{skeyval-pstkey}{Unknown option - '\CurrentOption' ignored}% + \PackageWarning{skeyval-pstkey} + {Unknown option '\CurrentOption' ignored}% } \skvprocessoptions +\skv@pst@restorecodes \endinput %% End of file `skeyval-pstkey.sty'. diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.tex b/Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.tex index 83fd3dfff44..bc5952d0377 100644 --- a/Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.tex +++ b/Master/texmf-dist/tex/latex/skeyval/skeyval-pstkey.tex @@ -1,5 +1,5 @@ %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -% This is file 'skeyval-pstkey.tex', version 1.0, 2012/10/15. % +% This is file 'skeyval-pstkey.tex', version 1.1a, 2012/10/16. % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % @@ -26,25 +26,48 @@ % Copyright (c) 2010-2012 Ahmed Musa (amusa22@gmail.com). % %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -\csname skeyval-pstkey-loaded\endcsname -\expandafter\let\csname skeyval-pstkey-loaded\endcsname\endinput - +\begingroup% +\let\e\endlinechar\edef\p{\the\e}\e13\edef\n{\the\catcode\e}% +\xdef\skv@pst@restorecatcodes{% + \let\noexpand\skv@pst@restorecatcodes\relax% + \endlinechar=\p\relax\catcode\number\e=\n\relax% + \catcode\string`\noexpand`\string=\the\catcode\string``\relax% + \catcode\string`\noexpand=\string=\the\catcode\string`=\relax% +}% +\endgroup% +\endlinechar\string=13\relax% +\catcode13\string=5\relax% +\catcode\string``\string=12\relax +\catcode\string`=\string=12\relax +\def\skvgobble#1{} +\def\do#1{\catcode`\expandafter\skvgobble\string#1=\the\catcode`#1\relax} \edef\skv@pst@restorecatcodes{% - \catcode`\noexpand\@\the\catcode`\@\relax - \let\noexpand\skv@pst@restorecatcodes\relax + \unexpanded\expandafter{\skv@pst@restorecatcodes}% + \do\ \do\%\do\@\do\(\do\)\do\[\do\]\do\|\do\:\do\;\do\,\do\.% + \do\>\do\<\do\!\do\*\do\+\do\-\do\^\do\_\do\&\do\$\do\~\do\'% + \do\"\do\ } -\catcode`\@=11\relax +\catcode`\ =10\relax +\catcode`\@=11 \catcode`\(=12 \catcode`\)=12 \catcode`\[=12 +\catcode`\]=12 \catcode`\|=12 \catcode`\:=12 \catcode`\;=12 +\catcode`\,=12 \catcode`\*=12 \catcode`\+=12 \catcode`\-=12 +\catcode`\<=12 \catcode`\>=12 \catcode`\!=12 \catcode`\.=12 +\catcode`\^=07 \catcode`\_=08 \catcode`\&=04 \catcode`\$=03 +\catcode`\~=13 \catcode`\%=14 \catcode`\'=12 \catcode`\"=12 + +\csname skeyval-pstkey-loaded\endcsname +\expandafter\let\csname skeyval-pstkey-loaded\endcsname\endinput \def\skv@@afterfi#1\fi{\fi#1} \def\skv@@afterelse#1\else#2\fi{\fi#1} \ifx\ProvidesFile\@undefined\skv@@afterelse - \message{File 'skeyval-pstkey.tex' 2012/10/15 v1.1 + \message{File 'skeyval-pstkey.tex' 2012/10/16 v1.1a PSTricks specialization of skeyval package (AM)} \input skeyval-core \else\skv@@afterfi \ProvidesFile{skeyval-pstkey.tex} - [2012/10/15 v1.1 PSTricks specialization of skeyval (AM)] + [2012/10/16 v1.1a PSTricks specialization of skeyval (AM)] \@addtofilelist{skeyval-pstkey.tex} \@ifpackageloaded{skeyval}{}{\RequirePackage{skeyval}} \fi diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval-view.sty b/Master/texmf-dist/tex/latex/skeyval/skeyval-view.sty index fc078fd2378..6e40b3d6611 100644 --- a/Master/texmf-dist/tex/latex/skeyval/skeyval-view.sty +++ b/Master/texmf-dist/tex/latex/skeyval/skeyval-view.sty @@ -1,5 +1,5 @@ %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -% This is file 'skeyval-view.sty', version 1.1, 2012/10/15. % +% This is file 'skeyval-view.sty', version 1.1a, 2012/10/16. % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % @@ -39,9 +39,15 @@ \expandafter\do \fi }% - \edef\skvv@restorecodes{\do035,064,123,125,061,059,\do,}% + \edef\skv@view@restorecodes{\do35,64,123,125,61,59,13,\do,}% } \skv@prova + +\edef\skv@view@restorecodes{% + \unexpanded\expandafter{\skv@view@restorecodes}% + \endlinechar\the\endlinechar\relax +} +\endlinechar13 % \catcode035 06 % # \catcode064 11 % @ \catcode123 01 % { @@ -50,8 +56,8 @@ \catcode044 12 % , \def\do#1=#2,{% \ifx\do#1\else - \edef\skvv@restorecodes{% - \skvv@restorecodes + \edef\skv@view@restorecodes{% + \unexpanded\expandafter{\skv@view@restorecodes}% \catcode#1=\the\catcode#1\relax }% \catcode#1=#2\relax @@ -63,7 +69,7 @@ \NeedsTeXFormat{LaTeX2e}[2011/06/27] \ProvidesPackage{skeyval-view} - [2012/10/15 v1.1 Viewer utility for skeyval package (AM)] + [2012/10/16 v1.1a Viewer utility for skeyval package (AM)] \@ifpackageloaded{skeyval}{}{\RequirePackage{skeyval}} \directkeys*{% .prefix=SKVV, @@ -71,12 +77,12 @@ .holder prefix=skvv@, .initialize keys after define, .every unknown option={ - \PackageWarning{skeyval-view}{Unknown option '\CurrentOption'}% + \PackageWarning{skeyval-view}{Unknown option '\CurrentOption' ignored}% }, .new options={ % LaTeX's options processor will zap the option names. So these keys % can't have spaces between their parts. - .ords/{xcolor-options,load-xcolor-with}// + .ord/{xcolor-options,load-xcolor-with}// \edef\skvv@xcoloroptions{\unexpanded{#1}} \skvstripouterbraces{1}\skvv@xcoloroptions, }, @@ -100,17 +106,17 @@ .holder prefix=skvv@, .initialize after define=false, .define keys={ - .ords/{file,wcolsep,weol}/\@nil/ + .ord/{file,wcolsep,weol}/\@nil/ \skvcsedef{skvv@\skvcurrentkey}{\unexpanded{#1}} \skvaftercsname{\skvstripouterbraces{1}}{skvv@\skvcurrentkey} \skvaftercsname\skvdespacecontent{skvv@\skvcurrentkey} , - .ords/{prefix,family,type,default,columns}/\@nil/ + .ord/{prefix,family,type,default,columns}/\@nil/ \skvcsedef{skvv@\skvcurrentkey}{\unexpanded{#1}} \skvaftercsname{\skvstripouterbraces{1}}{skvv@\skvcurrentkey} \skvaftercsname\skvcsvnormalize{skvv@\skvcurrentkey} , - .bools/{view,vlabels,wlabels}/true, + .bool/{view,vlabels,wlabels}/true, .ord/length of default/20/\def\skvv@lod{#1}, .cmd/color/black, }, @@ -152,7 +158,7 @@ }% } \protected\def\skv@ordkey@a#1[#2]#3{% - \skvifstrcmp{#2}{^skv^}{% + \skvifstrcmpTF{#2}{^skv^}{% \skvv@tabulate{#1}{ordinary}{[none]}% }{% \skv@definedefault{#1}{#2}% @@ -162,7 +168,7 @@ } \protected\def\skv@cmdkey#1#2[#3]#4{% \skv@strippointers{#2}\skvcurrentkey - \skvifdefbool{skv@st}{% + \skvifdefboolTF{skv@st}{% \skv@definedefault\skvcurrentkey{#3}% \skvv@tabulate\skvcurrentkey{command}{#3}% }{% @@ -172,26 +178,35 @@ % spaces in key name: \edef\skv@prova{#1\skvcurrentkey}% \edef\skv@prova{\expandafter\skv@zapornot\expandafter - {\expandafter\skv@zapnr\expandafter}\expandafter{\skv@prova}}% + {\expandafter\skv@zapsw\expandafter}\expandafter{\skv@prova}}% \skvcslet{\skv@header\skvcurrentkey.@hp}\skv@prova \skvcsedef{\skv@header\skvcurrentkey.@cbk}{\unexpanded{#4}}% } -\protected\def\skv@choicekey@c[#1]{% - \skvifstrcmp{#1}{^skv^}{% - \skvv@tabulate\skvcurrentkey{choice}{[none]}% - }{% - \skv@definedefault\skvcurrentkey{#1}% - \skvv@tabulate\skvcurrentkey{choice}{#1}% +\protected\def\skv@choicekey@g{% + \skvcommaparse*\skv@currlist\skv@prova{% + \skvexpbracenext\skv@strippointers\skv@prova\skvcurrentkey + \ifx\skv@default\skv@rej + \skvv@tabulate\skvcurrentkey{choice}{[none]}% + \else\skvafterfi + \skvexpanded{% + \noexpand\skvv@tabulate + {\skvxonce\skvcurrentkey}{choice}{\skvxonce\skv@default}% + \noexpand\skv@definedefault + {\skvxonce\skvcurrentkey}{\skvxonce\skv@default}% + }% + \fi + \skvcsedef{\skv@header\skvcurrentkey.@hp}{\skv@hp\skvcurrentkey}% + \skvcsedef{\skv@header\skvcurrentkey.@cbk}{\the\skv@toksa}% }% - \skvifdefbool{skv@pl}\skv@choicekey@e\skv@choicekey@d } \protected\def\skv@boolkey@c#1#2#3#4{% - \skvcsnewif{\skv@zapornot{\skv@zapnr}{#2}}% - \skvifdefbool{skv@st}{% + \skvcsnewif{\skv@zapornot{\skv@zapsw}{#2}}% + \edef\skvv@boolortog{\if\skv@typetogkey toggle\else bool\fi}% + \skvifdefboolTF{skv@st}{% \skv@definedefault{#1}{#3}% - \skvv@tabulate{#1}{bool}{#3}% + \skvv@tabulate{#1}{\skvv@boolortog}{#3}% }{% - \skvv@tabulate{#1}{bool}{[none]}% + \skvv@tabulate{#1}{\skvv@boolortog}{[none]}% }% \edef\skv@tempa##1##2{% \noexpand\skv@sttrue @@ -206,7 +221,7 @@ \skvcommaparse{#1}\skv@prova{% \skvexpbracenext\skv@strippointers\skv@prova\skvcurrentkey \skvexpanded{% - \skvifstrcmp{#3}{^skv^}{% + \skvifstrcmpTF{#3}{^skv^}{% \skvv@tabulate{\skvcurrentkey}{style}{[none]}% }{% \skv@definedefault{\skvcurrentkey}{\unexpanded{#3}}% @@ -314,7 +329,7 @@ } \skvrobustdef*\skvv@ifin#1#2{% \ifx#2\@nnil\else - \skvxifin{,\detokenize{#1},}{,\skvoxdetok{#2},}{}\skv@swafalse + \skvxifinTF{,\detokenize{#1},}{,\skvoxdetok{#2},}{}\skv@swafalse \fi } @@ -324,8 +339,8 @@ .holder prefix=skvvs@, .initialize keys after define, .new keys={ - .ords/{.show,.show table}// - \skvifdefbool{skvindef}{}{ + .ord/{.show,.show table}// + \skvifdefboolTF{skvindef}{}{ \edef\skvvs@show{\unexpanded{#1}} \skvstripouterbraces{2}\skvvs@show \ifx\skvvs@show\@empty\else\skvafterfi @@ -345,8 +360,7 @@ \skvrobustdef*\skvviewkeys{\skvsetkeys[SKVV]{skvvshow}} \skvnewlet\skvshowkeys\skvviewkeys -\skvv@restorecodes - +\skv@view@restorecodes \endinput %% End of file 'skeyval-view.sty'. diff --git a/Master/texmf-dist/tex/latex/skeyval/skeyval.sty b/Master/texmf-dist/tex/latex/skeyval/skeyval.sty index 38871851cd1..fce36938787 100644 --- a/Master/texmf-dist/tex/latex/skeyval/skeyval.sty +++ b/Master/texmf-dist/tex/latex/skeyval/skeyval.sty @@ -1,5 +1,5 @@ %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -% This is file 'skeyval.sty', version 1.1, 2012/10/15. % +% This is file 'skeyval.sty', version 1.1a, 2012/10/16. % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % @@ -39,9 +39,15 @@ \expandafter\do \fi }% - \edef\skv@restorecodes{\do035,064,123,125,061,059,\do,}% + \edef\skv@restorecodes{\do35,64,123,125,61,59,13,\do,}% } \skv@prova + +\edef\skv@restorecodes{% + \unexpanded\expandafter{\skv@restorecodes}% + \endlinechar\the\endlinechar\relax +} +\endlinechar13 % \catcode035 06 % # \catcode064 11 % @ \catcode123 01 % { @@ -51,7 +57,7 @@ \def\do#1=#2,{% \ifx\do#1\else \edef\skv@restorecodes{% - \skv@restorecodes + \unexpanded\expandafter{\skv@restorecodes}% \catcode#1=\the\catcode#1\relax }% \catcode#1=#2\relax @@ -61,25 +67,25 @@ \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,\do=,% -\ProvidesPackage{skeyval}[2012/10/15 v1.1 Robust key-value parser (AM)] +\ProvidesPackage{skeyval}[2012/10/16 v1.1a Robust key-value parser (AM)] \NeedsTeXFormat{LaTeX2e}[2011/06/27] \input skeyval-core \skvrobustdef*\skvAfterEndPackage{% - \skvifcsdef{\@currname.\@currext-skv@endpkghook}{}{% + \skvifcsdefTF{\@currname.\@currext-skv@endpkghook}{}{% \@namedef{\@currname.\@currext-skv@endpkghook}{}% }% \expandafter\g@addto@macro \csname\@currname.\@currext-skv@endpkghook\endcsname } \skvrobustdef*\skvAfterPackage#1{% - \skvAfterBeginDocument{% - \skvifcsdef{ver@#1.\@pkgextension}{}{% + \skvafterbegindocument{% + \skvifcsdefTF{ver@#1.\@pkgextension}{}{% \skv@warn{Package '#1' was never loaded}% }% } - \skvifcsdef{ver@#1.\@pkgextension}{% + \skvifcsdefTF{ver@#1.\@pkgextension}{% \@firstofone }{% \skvappendtomacro{#1.\@pkgextension-skv@endpkghook}% @@ -103,7 +109,7 @@ \skvcommaparse*\@filelist\skv@tempa{% \filename@parse\skv@tempa \ifx\filename@ext\@clsextension - \skvifcsundef{opt@\filename@area\filename@base.\filename@ext}{}{% + \skvifcsdefFT{opt@\filename@area\filename@base.\filename@ext}{}{% \edef\skv@documentclass{% \filename@area\filename@base.\filename@ext }% @@ -127,7 +133,7 @@ \let\skv@classoptionslist\@classoptionslist \let\@classoptionslist\@empty \skvcommaloop*\skv@origclassoptlist\skv@tempa{% - \skvxifin{=}{\skvexpandonce\skv@tempa}{}{% + \skvxifinTF{=}{\skvexpandonce\skv@tempa}{}{% \skvaddtolist*\@classoptionslist\skv@tempa }% }% @@ -137,7 +143,7 @@ % The following packages need access to the original % \@classoptionslist. \skvcommaloop{xkeyval,kvoptions,keyval2e,ltxkeys}\skv@prova{% - \skvxifin{,\skv@prova,}{,\skv@tempa,}{% + \skvxifinTF{,\skv@prova,}{,\skv@tempa,}{% \let\@classoptionslist\skv@origclassoptlist \skvbreakloop }{}% @@ -147,7 +153,7 @@ }% \fi } -\skvifundef\skv@documentclass{% +\skvifdefFT\skv@documentclass{% \let\skv@documentclass\@empty \let\skv@classoptionslist\@empty \edef\@popfilename{% @@ -156,27 +162,26 @@ }{% \skv@filterclassoptions } - -\skvrobustdef*\skvBeforeBeginDocument{% +\skvrobustdef*\skvbeforebegindocument{% \skvgappendtomacro\skv@beforebegindoc } \skvnewdef*\skv@beforebegindoc{} \skvprependtomacro\document{% \endgroup - \let\skvBeforeBeginDocument\@firstofone + \let\skvbeforebegindocument\@firstofone \skv@beforebegindoc - \gdef\skvBeforeBeginDocument{\skv@notprerr\skvBeforeBeginDocument}% + \gdef\skvbeforebegindocument{\skv@notprerr\skvbeforebegindocument}% \global\let\skv@beforebegindoc\relax \begingroup } -\skvrobustdef*\skvAfterBeginDocument{% +\skvrobustdef*\skvafterbegindocument{% \skvgappendtomacro\skv@afterbegindoc } \skvnewdef*\skv@afterbegindoc{} \skvgappendtomacro\document{% - \let\skvAfterBeginDocument\@firstofone + \let\skvafterbegindocument\@firstofone \skv@afterbegindoc - \gdef\skvAfterBeginDocument{\skv@notprerr\skvAfterBeginDocument}% + \gdef\skvafterbegindocument{\skv@notprerr\skvafterbegindocument}% \global\let\skv@afterbegindoc\relax \ignorespaces } @@ -185,8 +190,8 @@ in preamble}\@ehd } \skvnewdef*\skv@everypagehook{} -\skvrobustdef*\skvAtBeginEveryPage{\skvgappendtomacro\skv@everypagehook} -\skvAfterBeginDocument{% +\skvrobustdef*\skvatbegineverypage{\skvgappendtomacro\skv@everypagehook} +\skvafterbegindocument{% \let\skv@savedoutputpage\@outputpage \def\@outputpage{% \let\skv@savedbegindvi\@begindvi @@ -201,23 +206,25 @@ \skvnewdef*\skv@preamblecmdhook{} \skvrobustdef*\skvonlypreamble#1{% - \skvcommaparse{#1}\skv@tempa{% - \skvxifin{\detokenize\expandafter{\expandafter\do\skv@tempa}}% - {\skvoxdetok\skv@preamblecmdhook}{% - \skv@warn{Command '\skvexpandonce\skv@tempa' multiply + \def\do##1{% + \skvxifinTF{\detokenize{\do##1}}{\skvoxdetok\skv@preamblecmdhook}{% + \skv@warn{Command '\noexpand##1' multiply \MessageBreak submitted to \string\skvonlypreamble: ignored}% }{% \xdef\skv@preamblecmdhook{% \skvexpandonce\skv@preamblecmdhook - \unexpanded\expandafter{\expandafter\do\skv@tempa}% + \unexpanded{\do##1}% }% }% }% + \skvcommaparse{#1}\skv@prova{% + \expandafter\do\expandafter{\skv@prova}% + }% } \AtEndOfPackage{% - \skvAfterBeginDocument{% + \skvafterbegindocument{% \def\do#1{% - \skvifdef#1{% + \skvifdefTF#1{% \gdef#1{\@latexerr{'\string#1' is a preamble command}\@ehd}% }{% \@@warning{Undefined command '\unexpanded{#1}' @@ -235,7 +242,7 @@ % \skvunknownoptionhandler[<prefixes>]<<families>>{<handler>} % \skvrobustdef*\skvunknownoptionhandler{% - \skv@testopt\skv@unknownoptionhandler{KV}% + \skv@testopt\skv@unknownoptionhandler\skv@defaultpref } \skvrobustdef*\skv@unknownoptionhandler[#1]{% \skvifnextchar<{\skv@unkn@wnoptionhandler{#1}}% @@ -247,10 +254,10 @@ \skvrobustdef*\skv@testopte#1{\skv@testopta{\skv@t@stopte{#1}}} -\skvrobustdef*\skv@t@stopte#1{\skv@testopt{\skv@t@st@pte{#1}}{KV}} +\skvrobustdef*\skv@t@stopte#1{\skv@testopt{\skv@t@st@pte{#1}}\skv@defaultpref} \skvrobustdef*\skv@t@st@pte#1[#2]{% % Only one prefix is allowed: - \skvxifin{,}{\detokenize{#2}}{% + \skvxifinTF{,}{\detokenize{#2}}{% \skv@err{Only one prefix is allowed, but you gave '#2'}\@ehd }{% \skv@makeprefix{#2}% @@ -260,7 +267,7 @@ } \skvrobustdef*\skv@@t@st@pte#1<#2>{% \edef\skv@fams{#2}% - \skvxifin{,}{\detokenize{#2}}{% + \skvxifinTF{,}{\detokenize{#2}}{% \skvcsvnormalize\skv@fams }{% \skvdespacecontent\skv@fams @@ -310,16 +317,90 @@ }% }% } -\skvrobustdef*\skv@dox@a{\skv@testopt\skv@dox@b{KV}} +\skvrobustdef*\skv@dox@a{\skv@testopt\skv@dox@b\skv@defaultpref} \skvrobustdef*\skv@dox@b[#1]{% \skvifnextchar<% - {\skv@dox@c{#1}}% - {\skv@dox@c{#1}<\@currname.\@currext>}% + {\skv@dox@c{#1}}{\skv@dox@c{#1}<\@currname.\@currext>}% } \skvrobustdef*\skv@dox@c#1<#2>{\skvdefkey[#1]{#2}} +% Declare options with default values that will be used when the options +% are called without user values. +% +% \skvDeclarePassedOptions[<pref>]{<fam>}{<option>=<default>,...} +% +% Example: +% +% \skvDeclarePassedOptions[KV]{fam}{% +% hyperref={colorlinks,breaklinks},xcolor=svgnames +% } +% +\skvrobustdef*\skvDeclarePassedOptions{% + \skv@testopt\skv@declarepassedoptions\skv@defaultpref +} +\skvrobustdef*\skv@declarepassedoptions[#1]#2#3{% + \skvparsekeyvals{#3}\skv@tempa{% + \skvexpbracenext\skv@kvsplit\skv@tempa{% + \skvdeclareoption[#1]<#2>{##1}[##2]{% + \skvifcsdefTF{ver@##1.sty}{% + \skv@warn{Package '##1' has been loaded and + \MessageBreak now you're passing options to it. + \MessageBreak Instruction ignored}% + }{% + \skvPassOptionsToPackage{####1}{##1}% + \AtBeginDocument{% + \skvifpackageloaded{##1}{}{% + \skv@warn{Options were passed to package + \MessageBreak '##1' but it was never loaded}% + }% + }% + }% + }% + }% + }% +} +% \skvPassOptionsToPackage{<opts>}{<pkg>} +\skvrobustdef*\skvPassOptionsToPackage{\skv@passoptions{sty}} +\skvrobustdef*\skvPassOptionsToClass{\skv@passoptions{cls}} +\skvrobustdef*\skv@passoptions#1#2#3{% + \begingroup + \edef\@elt{opt@\skvtrimspace{#3}.#1}% + \skvcsxdef{\@elt}{% + \skvifcsdefFT{\@elt}{}{\@nameuse{\@elt},}% + \skvtrimspace{#2}% + }% + \endgroup +} + +% \skvDeclarePassedOptionsLoadPackage +% [<pref>]{<fam>}{<option>=<default>,...} +% +\skvrobustdef*\skvDeclarePassedOptionsLoadPackage{% + \skv@testopt\skv@declarepassedoptions@load\skv@defaultpref +} +\skvrobustdef*\skv@declarepassedoptions@load[#1]#2#3{% + \skvparsekeyvals{#3}\skv@tempa{% + \skvexpbracenext\skv@kvsplit\skv@tempa{% + \skvdeclareoption[#1]<#2>{##1}[##2]{% + \skvifcsdefTF{ver@##1.sty}{% + \skv@warn{Package '##1' has been loaded and + \MessageBreak now you've asked for it to be + \MessageBreak loaded again. Instruction ignored}% + }{% + \skvafterprocessoptions{% + \RequirePackage[####1]{##1}% + }% + }% + }% + }% + }% +} + +% \skvexecuteoptions[<pref>]<fams>[<na>]{<kvlist>} % \skvexecuteoptions+[<pref>]<fams>[<na>]{<kvlist>} +% % This has no star (*) variant; any star suffix is quietly ignored. +% \skvrobustdef*\skvexecuteoptions{% \skv@testopte{\skv@stfalse\skv@setkeys@a}% } @@ -328,73 +409,76 @@ % % 1. If not using LaTeX, then no processing of options. % 2. The plus (+) variant of \skvprocessoptions will process the options -% in all the listed families. But the star form of \skvprocessoptions -% doesn't seem to make sense here, since - unlike in LaTeX2e - a star -% suffix here would mean 'save unknown keys'. It is meaningless to seek -% to save unknown keys when processing options. Any star (*) suffix on -% \skvprocessoptions is, therefore, quietly ignored. -% 3. Class options are always processed first, but class options ocurring -% also local/package options are dropped from the list of options -% to be processed. +% in all the listed families. The star (*) form of \skvprocessoptions +% -- like in LaTeX2e -- will also copy and use class options. +% 3. Class options are always processed first, but class options that ocurr +% also as local/package options are dropped from the list of options +% to be processed. That is, package options always take priority over +% class options. +% 4. The \ProcessOptionsX of xkeyval package doesn't expect any plus (+) +% suffix: it processes options only in a single family. +% \skvrobustdef*\skvprocessoptions{\skv@testopte\skv@pox} \skvrobustdef*\skv@pox[#1]{% \skv@inpoxtrue \let\@fileswith@pti@ns\@badrequireerror + \edef\skv@userclassorpackage{\@currname.\@currext}% \begingroup - \let\skv@classoptsfound\@empty + \let\skv@clsoptsfound\@empty + \let\skv@clsorpkgopts\@empty \let\skv@exitpoxkeys\@empty - \edef\skv@testclass{\@currname.\@currext}% - \skvifx\skv@testclass\skv@documentclass{% + \skvifxTF\skv@userclassorpackage\skv@documentclass{% \let\@unusedoptionlist\skv@classoptionslist }{% - \skv@swafalse - \ifx\skv@classoptionslist\@empty\else - \ifskv@st\skv@swatrue\fi + \ifcase0\ifx\skv@classoptionslist\@empty\else + \ifx\skv@classoptionslist\relax\else\ifskv@st1\fi\fi\fi\relax + \skv@swafalse + \else + \skv@swatrue \fi - \skvifnotbool{skv@swa}{}{% + \skvifboolFT{skv@swa}{}{% + \def\ifkeyundef##1##2##3{\skvexpanded{\skvifkeydefFT[##1]{##2}{##3}}}% \skvcommaloop*\skv@classoptionslist\CurrentOption{% \expandafter\expandafter\expandafter \skv@g@tkeyname\CurrentOption=\skv@nil\skvcurrentkey - \skvexpanded{% - % Test if key is defined in one of the families. The search will - % stop as soon as the key is found in any of the families. - \skvifkeyundef[\skvcurrentprefix]{\skv@fams}{\skvcurrentkey}% - }{}{% - \edef\skv@classoptsfound{% - \skvexpandonce\skv@classoptsfound - \ifx\skv@classoptsfound\@empty\else,\fi + % Test if key is defined in one of the families. The search will + % stop as soon as the key is found in any of the families. + \ifkeyundef\skvcurrentprefix\skv@fams\skvcurrentkey{}{% + \edef\skv@clsoptsfound{% + \skvexpandonce\skv@clsoptsfound + \ifx\skv@clsoptsfound\@empty\else,\fi \skvexpandonce\CurrentOption }% \expandafter\skv@useoption\expandafter{\CurrentOption}% }% }% - \ifx\skv@classoptsfound\@empty\else\skvafterfi - \skvexpbracenext\skv@getkeynames\skv@classoptsfound\skv@tempd + \ifx\skv@clsoptsfound\@empty\else\skvafterfi + \skvexpbracenext\skv@getkeynames\skv@clsoptsfound\skv@tempd \skvexpbracenext\skv@getpoxkeys\skv@tempd \fi }% }% - \skvletcs\skv@pkgorclsopts{opt@\@currname.\@currext}% - \skvifx\skv@pkgorclsopts\@empty{}{% - \skvifx\skv@pkgorclsopts\relax{}{% - \skvexpbracenext\skv@getkeynames\skv@pkgorclsopts\skv@tempd + \skvletcs\skv@clsorpkgopts{opt@\@currname.\@currext}% + \skvifxTF\skv@clsorpkgopts\@empty{}{% + \skvifxTF\skv@clsorpkgopts\relax{}{% + \skvexpbracenext\skv@getkeynames\skv@clsorpkgopts\skv@tempd \skvexpbracenext\skv@getpoxkeys\skv@tempd }% }% % Package options have higher priority than class options. Hence - % filter class options \skv@classoptsfound that are also present - % as package options \skv@pkgorclsopts: - \ifcase0\ifx\skv@classoptsfound\@empty0\else - \ifx\skv@pkgorclsopts\@empty0\else - \ifx\skv@pkgorclsopts\relax0\else1\fi\fi\fi\relax + % filter class options \skv@clsoptsfound that are also present + % as package options \skv@clsorpkgopts: + \ifcase0\ifx\skv@clsoptsfound\@empty\else + \ifx\skv@clsorpkgopts\@empty\else + \ifx\skv@clsorpkgopts\relax\else1\fi\fi\fi\relax \else\skvafterfi - \skvifx\skv@testclass\skv@documentclass{}{% - \skvcommaloop*\skv@classoptsfound\CurrentOption{% + \skvifxTF\skv@userclassorpackage\skv@documentclass{}{% + \skvcommaloop*\skv@clsoptsfound\CurrentOption{% \expandafter\expandafter\expandafter \skv@g@tkeyname\CurrentOption=\skv@nil\skv@tempa - \skvxifin{,\skvoxdetok\skv@tempa,}{,\skvoxdetok\skv@tempd,}{}{% - \edef\skv@pkgorclsopts{% - \skvexpandonce\skv@pkgorclsopts,\skvexpandonce\CurrentOption + \skvxifinTF{,\skvoxdetok\skv@tempa,}{,\skvoxdetok\skv@tempd,}{}{% + \edef\skv@clsorpkgopts{% + \skvexpandonce\skv@clsorpkgopts,\skvexpandonce\CurrentOption }% }% }% @@ -402,9 +486,10 @@ \fi \skvexpanded{\endgroup \skv@exitpoxkeys - % There may be preset keys even when \skv@pkgorclsopts is empty: + \skvcmdexit\@unusedoptionlist + % There may be preset keys even when \skv@clsorpkgopts is empty: \skvsetkeys\ifskv@pl+\fi[\skvcurrentprefix]{\skv@fams}[#1]% - {\skvexpandonce\skv@pkgorclsopts}% + {\skvexpandonce\skv@clsorpkgopts}% }% \skvcslet{skv@dox@\@currname @\@currext}\relax \skvinitializermkeys*\skvcurrentprefix\skv@fams @@ -415,55 +500,50 @@ \skvcslet{skv@\@currname @\@currext @afterprocess@hook}\relax } -% \skvrestrictedprocessoptions*+[<pref>]{<fams>}[<na>] -% 1. This will not process class options, but only options -% issued to the package. -\skvrobustdef*\skvrestrictedprocessoptions{\skv@testopte\skv@restrictedpox} -\skvrobustdef*\skv@restrictedpox[#1]{% - \skv@inpoxtrue - \let\@fileswith@pti@ns\@badrequireerror - \begingroup - \let\skv@exitpoxkeys\@empty - \let\skv@pkgorclsopts\@empty - \skvletcs\skv@pkgorclsopts{opt@\@currname.\@currext}% - \ifcase0\ifx\skv@pkgorclsopts\@empty0\else - \ifx\skv@pkgorclsopts\relax0\else1\fi\fi\relax - \else\skvafterfi - \skvexpbracenext\skv@getkeynames\skv@pkgorclsopts\skv@tempd - \skvexpbracenext\skv@getpoxkeys\skv@tempd - \fi - \skvexpanded{\endgroup - \skv@exitpoxkeys - \skvsetkeys\ifskv@pl+\fi[\skvcurrentprefix]{\skv@fams}[#1]% - {\skvexpandonce\skv@pkgorclsopts}% - }% - \skvcslet{skv@dox@\@currname @\@currext}\relax - \skvinitializermkeys*\skvcurrentprefix\skv@fams - \skv@inpoxfalse - \let\@fileswith@pti@ns\@@fileswith@pti@ns - \AtEndOfPackage{\let\@unprocessedoptions\relax}% - \csname skv@\@currname @\@currext @afterprocess@hook\endcsname - \skvcslet{skv@\@currname @\@currext @afterprocess@hook}\relax +% \skvprocessoptionswithclassoptions*+[<pref>]{<fams>}[<na>] +% +% 1. The star (*) suffix is always assumed present, even when the +% user hasn't put it. +% +\skvrobustdef*\skvprocessoptionswithclassoptions{% + \skv@testopte\skv@pox@copyclassoptions +} +\skvrobustdef*\skv@pox@copyclassoptions[#1]{\skv@sttrue\skv@pox[#1]} + +% \skvprocessoptionswithoutclassoptions*+[<pref>]{<fams>}[<na>] +% +% 1. The star (*) suffix is always assumed absent, even when the +% user has put it. +% +\skvrobustdef*\skvprocessoptionswithoutclassoptions{% + \skv@testopte\skv@pox@nocopyclassoptions } +\skvrobustdef*\skv@pox@nocopyclassoptions[#1]{\skv@stfalse\skv@pox[#1]} +% \skv@getpoxkeys{<keys>} +% % Get pox keys (ie, keys processed as options) from package or -% class options: +% class options. \skvrobustdef*\skv@getpoxkeys#1{% - \skvcommaloop{#1}\skvcurrentkey{% + \begingroup + \def\xiftest{% \skvexpanded{% - \skvifkeynotinfamilies + \noexpand\skvifkeyinfamiliesFT [\skvcurrentprefix]{\skv@fams}{\skvcurrentkey}% - }{}{% + }% + }% + \skvcommaloop{#1}\skvcurrentkey{% + \xiftest{}{% % \skv@header is formed in the search for the key: \skvletcs\skv@prova{\skv@header.@poxkeys}% - \skvifdef\skv@prova{% - \skvxifin{,\skvoxdetok\skvcurrentkey,}{,\skvoxdetok\skv@prova,}{}{% + \skvifdefTF\skv@prova{% + \skvxifinTF{,\skvoxdetok\skvcurrentkey,}{,\skvoxdetok\skv@prova,}{}{% \skvcsedef{\skv@header.@poxkeys}{\skv@prova,\skvcurrentkey}% }% }{% \skvcsedef{\skv@header.@poxkeys}{\skvcurrentkey}% }% - \skvxifin{\skvoxdetok\skv@header}{\skvoxdetok\skv@exitpoxkeys}{}{% + \skvxifinTF{\skvoxdetok\skv@header}{\skvoxdetok\skv@exitpoxkeys}{}{% \edef\skv@exitpoxkeys{% \skvexpandonce\skv@exitpoxkeys \noexpand\skvcsexit{\skv@header.@poxkeys}% @@ -471,6 +551,10 @@ }% }% }% + \skvexpanded{\endgroup + \skvcmdexit\skv@exitpoxkeys + \skv@exitpoxkeys + }% } % +++++++++ Utilities for handling options via \directkeys +++++++++% @@ -496,104 +580,108 @@ \expandafter\endgroup\skv@tempa \skv@inoptfalse } +% % \dirkeys@executeoptions{<options>} +% +% 1. Ececute options on all the prevailing paths. If any of +% the options isn't found on a path, report error (ie, +% don't save the key to the list of 'remaining keys'). Unknown +% options should be flagged by an error immediately. +% 2. There is no plus (+) variant for this command/handler. +% 3. It is the user's responsibility to ensure that keys exist on +% current paths. This is easier to enforce if there is only one +% current path (prefix and family). +% \skvrobustdef*\dirkeys@executeoptions#1{% \skv@inopttrue \begingroup + % Don't confuse parameter characters in #1 with those of \do: \edef\skv@tempb{\unexpanded{#1}}% \def\skv@tempa{}% \def\do##1##2{% + \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% \edef\skv@tempa{% \skvexpandonce\skv@tempa - \skvsetkeys\ifskv@handlerswa+\fi - [##1]{##2}[\skvcsuse{##1/##2/.@ignoredkeys}]% - {\skvexpandonce\skv@tempb}% + \skvsetkeys[##1]{##2}[\skv@igkeys]{\skvexpandonce\skv@tempb}% }% }% \dirkeys@getcurrentroots\do \expandafter\endgroup\skv@tempa \skv@inoptfalse } + +% \dirkeys@executeoptions@b{<options>} +% +% 1. Ececute options in all the prevailing families. If any of +% the options isn't found in at least one family, report error (ie, +% don't save the key to the list of 'remaining keys'). Unknown options +% should be flagged immediately. +% 2. The plus (+) variant will execute the option in each family in +% which the option is found. +% 3. The difference between \dirkeys@executeoptions and +% \dirkeys@executeoptions@b is that in \dirkeys@executeoptions +% the prefixes can be more than one. Options will be executed for +% all combinations of prefixes and families. +% 4. Prevailing prefixes can't be more than one. +% \skvrobustdef*\dirkeys@executeoptions@b#1{% \skv@inopttrue \begingroup - \def\skv@tempa{}\def\skv@tempb{}\def\skv@tempc{}% + \dirkeys@collectpaths + \skvexpanded{\endgroup + \skvsetkeys+[\skv@tempa]{\skv@tempb}[\skv@tempc]% + }{#1}% + \skv@inoptfalse +} +\skvrobustdef*\dirkeys@collectpaths{% + \skvemptify{\do\skv@tempa\do\skv@tempb\do\skv@tempc}% \def\do##1##2{% - \skvxifin{,##1,}{,\skv@tempa,}{}{% + \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% + \skvxifinTF{,##1,}{,\skv@tempa,}{}{% \edef\skv@tempa{\skv@tempa\ifx\skv@tempa\@empty\else,\fi##1}% }% - \skvxifin{,##2,}{,\skv@tempb,}{}{% + \skvxifinTF{,##2,}{,\skv@tempb,}{}{% \edef\skv@tempb{\skv@tempb\ifx\skv@tempb\@empty\else,\fi##2}% }% \edef\skv@tempc{% - \skv@tempc\ifx\skv@tempc\@empty\else,\fi - \skvcsuse{##1/##2/.@ignoredkeys}% + \skv@tempc\ifx\skv@tempc\@empty\else,\fi\skv@igkeys }% }% \dirkeys@getcurrentroots\do - \@tempcnta\skvz@ - \let\skv@tempd\skv@tempa - \skvcommaloop*\skv@tempa\skv@prova{% - \advance\@tempcnta\@ne - \ifnum\@tempcnta>\@ne - \skv@err{You can't submit more than one prefix here}\@ehd - \skvbreakloop - \fi - }% - \skvexpanded{\endgroup - \skvsetkeys\ifskv@handlerswa+\fi[\skv@tempd]{\skv@tempb}[\skv@tempc]% - }{#1}% - \skv@inoptfalse + \skvifelementcount*\skv@tempa\tw@ + {\skv@err{You can't submit more than one prefix here}\@ehd}{} } \skvrobustdef*\dirkeys@processoptions{% \skv@inopttrue \begingroup \def\skv@tempa{}% \def\do##1##2{% + \skvletcs\skv@igkeys{##1/##2/.@ignoredkeys}% + \skvifdefTF\skv@igkeys{}{\def\skv@igkeys{}}% \edef\skv@tempa{% \skvexpandonce\skv@tempa - \skvprocessoptions\ifskv@handlerswa*\fi\ifskv@handlerswb+\fi - [##1]<##2>[\skvcsuse{##1/##2/.@ignoredkeys}]% + \skvprocessoptions\ifskv@handlerswa*\fi + [##1]<##2>[\skv@igkeys]% }% }% \dirkeys@getcurrentroots\do \expandafter\endgroup\skv@tempa \skv@inoptfalse } - \skvrobustdef*\dirkeys@processoptions@b{% \skv@inopttrue \begingroup - \def\skv@tempa{}\def\skv@tempb{}\def\skv@tempc{}% - \def\do##1##2{% - \skvxifin{,##1,}{,\skv@tempa,}{}{% - \edef\skv@tempa{\skv@tempa\ifx\skv@tempa\@empty\else,\fi##1}% - }% - \skvxifin{,##2,}{,\skv@tempb,}{}{% - \edef\skv@tempb{\skv@tempb\ifx\skv@tempb\@empty\else,\fi##2}% - }% - \edef\skv@tempc{% - \skv@tempc\ifx\skv@tempc\@empty\else,\fi - \skvcsuse{##1/##2/.@ignoredkeys}% - }% - }% - \dirkeys@getcurrentroots\do - \@tempcnta\skvz@ - \let\skv@tempd\skv@tempa - \skvcommaloop*\skv@tempa\skv@prova{% - \advance\@tempcnta\@ne - \ifnum\@tempcnta>\@ne - \skv@err{You can't submit more than one prefix here}\@ehd - \skvbreakloop - \fi - }% + \dirkeys@collectpaths \skvexpanded{\endgroup - \skvprocessoptions\ifskv@handlerswa+\fi - [\skv@tempd]<\skv@tempb>[\skv@tempc]% + \skvprocessoptions\ifskv@handlerswa*\fi + +[\skv@tempa]<\skv@tempb>[\skv@tempc]% }% \skv@inoptfalse } % ++++++++ Keys for the handler <.mega process options> +++++++++ % + \directkeys*{% .prefix=SKV, .family=megapox, @@ -604,8 +692,8 @@ \def\dirkeys@pox@igkeys{#1} \skvstripouterbraces{2}\dirkeys@pox@igkeys , - .ord/.options prefix/KV/ - \skvxifin{,}{\detokenize{#1}}{ + .ord/.options prefix/\skv@defaultpref/ + \skvxifinTF{,}{\detokenize{#1}}{ \skv@err{Only one prefix is allowed in processing options}\@ehd }{ \def\dirkeys@pox@pref{#1} @@ -617,7 +705,7 @@ \skvstripouterbraces{2}\dirkeys@pox@fams , .ord/.copy class options/true/ - \edef\dirkeys@pox@copyclass{\skvifstrcmp{#1}{true}{00}{01}} + \edef\dirkeys@pox@copyclass{\skvifstrcmpTF{#1}{true}{00}{01}} , }, .styles={ @@ -657,32 +745,43 @@ .new options={ \skv@handlerswatrue\dirkeys@declareoptions@b{#1} }, - % Handler <.execute options> has no star variant, since we don't - % want to ignore unknown options from within package or class. .execute options={ - \skv@handlerswafalse\dirkeys@executeoptions{#1} + \dirkeys@executeoptions{#1} }, .execute options+={ - \skv@handlerswatrue\dirkeys@executeoptions@b{#1} + \dirkeys@executeoptions@b{#1} + }, + .execute options*={ + \skv@err + {Handler <.execute options*> is undefined} + {Handler <.execute options> has no star (*) variant, + \MessageBreak since we don't want to ignore unknown + \MessageBreak options from within package or class file.}% + }, + .execute options*+={ + \skv@err + {Handler <.execute options*+> is undefined} + {Handler <.execute options+> has no star (*) variant, + \MessageBreak since we don't want to ignore unknown + \MessageBreak options from within package or class file.}% }, - % 1. All <.process options> handlers will filter out ignored paths - % and keys. + % 1. All <.process options> handlers will filter out ignored keys. % 2. <.process options*> will copy class options. % 3. <.process options+> will set options in all the active families % in which the options exist. % 4. <.process options*+> will copy class options and set options in % all the active families in which the options are found. .process options={ - \skv@handlerswafalse\skv@handlerswbfalse\dirkeys@processoptions + \skv@handlerswafalse\dirkeys@processoptions }, .process options*={ - \skv@handlerswatrue\skv@handlerswbfalse\dirkeys@processoptions + \skv@handlerswatrue\dirkeys@processoptions }, .process options+={ - \skv@handlerswafalse\skv@handlerswbtrue\dirkeys@processoptions@b + \skv@handlerswafalse\dirkeys@processoptions@b }, .process options*+={ - \skv@handlerswatrue\skv@handlerswbtrue\dirkeys@processoptions@b + \skv@handlerswatrue\dirkeys@processoptions@b }, % The handler <.mega process options> will: % 1. Search all families in its key <families>. @@ -703,7 +802,8 @@ .action for unknown option=.action for unknown options, .every unknown option=.action for unknown options, .define options=.declare options, - .processoptions=.process options, .processoptions*=.process options*, + .processoptions=.process options, + .processoptions*=.process options*, .copy class options and process options in all active families= .process options*+, .copy class options and process options in all families= @@ -721,40 +821,40 @@ \expandafter\skvgappendtomacro \csname skv@\@currname @\@currext @afterprocess@hook\endcsname } -\skvnewlet\skvAfterProcessOptions\skvafterprocessoptions \skvnewlet\skvifpackageloaded\@ifpackageloaded \def\skv@visiteduseoptions{01} - \skvrobustdef*\skv@useoption#1{% - \if\skv@visiteduseoptions\else\skvafterfi + \if\skv@visiteduseoptions\else \skvcsvnormalize\@unusedoptionlist \def\skv@visiteduseoptions{00}% \fi \begingroup - \def\do##1=##2=##3\useoption@nil{% + \@onelevel@sanitize\@unusedoptionlist + \skv@kvosplit{\detokenize{#1}}{% \edef\CurrentOption{\skvtrimspace{##1}}% \def\skv@tempa{}% - \def\do####1=####2=####3\useoption@nil{% - \edef\reserved@a{\skvtrimspace{####1}}% - }% \skvcommaloop*\@unusedoptionlist\skv@prova{% - \expandafter\do\skv@prova==\useoption@nil - \ifx\reserved@a\CurrentOption\else - \edef\skv@tempa{% - \skv@tempa\ifx\skv@tempa\@empty\else,\fi\skv@prova - }% - \fi + \skv@kvosplit\skv@prova{% + \edef\reserved@a{\skvtrimspace{####1}}% + \ifx\reserved@a\CurrentOption\else + \edef\skv@tempa{% + \skv@tempa\ifx\skv@tempa\@empty\else,\fi\skv@prova + }% + \fi + }% }% \let\@unusedoptionlist\skv@tempa }% - \@onelevel@sanitize\@unusedoptionlist - \expandafter\do\detokenize{#1}==\useoption@nil \skvaftergroupdef\@unusedoptionlist\endgroup } - \skvonlypreamble{% - \skvdeclareoption,\skvexecuteoptions,\skvprocessoptions,\skv@useoption + \skvdeclareoption,\skvexecuteoptions,\skvprocessoptions,\skv@useoption, + \dirkeys@declareoptions@a,\dirkeys@declareoptions@b, + \dirkeys@megaprocessoptions,\dirkeys@processoptions, + \dirkeys@processoptions@b,\skvprocessoptionswithclassoptions, + \skvprocessoptionswithoutclassoptions,\dirkeys@executeoptions, + \dirkeys@executeoptions@b } %+++++++++++++++++ This package's options section ++++++++++++++++++% @@ -763,22 +863,24 @@ \skv@inoptionsectrue %\skvshowcs{dirkeys@handler@.every unknown option} + \directkeys*{% - .prefix=SKV, - .family=skeyval, - .holder prefix=skv@, .every unknown option={ \@onelevel@sanitize\CurrentOption - \PackageWarning{skeyval}{Unknown option '\CurrentOption'}% + \PackageWarning{skeyval}{Unknown option '\CurrentOption' ignored}% }, + .prefix=SKV, + .family=skeyval, + .holder prefix=skv@, .new options={ + .bool/verbose/true, .bool/tracingkeys/true, - .ords/{keyparser,key parser}/{,}/ + .ord/{keyparser,key parser}/{,}/ \def\skv@keyparser{#1}% \skvstripouterbraces{2}\skv@keyparser, .bool/compatibility/true/ \ifskv@compatibility - \skvAfterProcessOptions{% + \skvafterprocessoptions{% \skvifpackageloaded{skeyval-bc}{}{% \RequirePackage{skeyval-bc}% } @@ -787,7 +889,7 @@ , }, .execute options={ - tracingkeys,keyparser + tracingkeys=false,keyparser,verbose=false }, .mega process options={ .options prefix=SKV, |