%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% % % % This is file 'skeyval.sty', version 0.5. % % % % Please see the package documentation for user guide. % % % % This package and accompanying files may be distributed and/or modified under % % the conditions of the LaTeX Project Public License, either version 1.3 of % % this license or any later version. The latest version of this license is in % % http://www.latex-project.org/lppl.txt and version 1.3 or later is part of all % % distributions of LaTeX version 2005/12/01 or later. % % % % The LPPL maintenance status of this software is 'author-maintained'. % % % % This software is provided 'as it is', without warranty of any kind, either % % expressed or implied, including, but not limited to, the implied warranties of % % merchantability and fitness for a particular purpose. % % % % Copyright (c) 2010 Ahmed Musa (a.musa@rocketmail.com). % % % %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% \begingroup \catcode064 11% @ \catcode123 01% { \catcode125 02% } \def\SKV@tempa{\endgroup \edef\SKV@restorecodes{% \catcode035 \the\catcode035% # \catcode064 \the\catcode064% @ \catcode123 \the\catcode123% { \catcode125 \the\catcode125% } \catcode061 \the\catcode061% = }% } \SKV@tempa \catcode035 06% # \catcode064 11% @ \catcode123 01% { \catcode125 02% } \def\SKV@ensurecode#1#2{% \edef\SKV@restorecodes{% \SKV@restorecodes \catcode#1 \the\catcode#1\relax }% \catcode#1 #2\relax } \AtEndOfPackage{\SKV@restorecodes} \SKV@ensurecode{061}{12}% = \SKV@ensurecode{044}{12}% , \SKV@ensurecode{058}{12}% : \SKV@ensurecode{059}{12}% ; \SKV@ensurecode{010}{12}% ^^J \SKV@ensurecode{126}{13}% ~ \def\SKV@rcsid$#1: #2 #3 #4 #5${#4 v#3} \ProvidesPackage{skeyval}% [\SKV@rcsid $Id: skeyval.sty,v 0.5 2010/02/26 09:00:00 Ahmed Musa $ Extensions to the xkeyval parser (AM)] \NeedsTeXFormat{LaTeX2e}[1996/12/01] \@ifpackageloaded{xkeyval}\relax{\RequirePackage{xkeyval}[2008/08/13]} \ifnum0=0% \ifx\eTeXversion\SKV@undefined 1\else\ifnum\eTeXversion<\tw@ 1\fi\fi \else \@latex@error{eTeX not loaded or old version}{% This package requires eTeX version 2 or later.}% \fi \@ifdefinable\SKV@ifdefinable\relax \def\SKV@ifdefinable#1{% \edef\reserved@a{\expandafter\@gobble\string#1}% \ifdefined#1% \ifx#1\relax \expandafter\expandafter\expandafter\@firstofone \else \expandafter\expandafter\expandafter\@notdefinable \fi \else \edef\reserved@b{\expandafter\@carcube\reserved@a xxx\@nil}% \ifx\reserved@b\@qend \expandafter\expandafter\expandafter\@notdefinable \else \ifx\reserved@a\@qrelax \expandafter\expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\@notdefinable \else \expandafter\expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\@firstofone \fi \fi \fi } \SKV@ifdefinable\SKV@def{\protected\def\SKV@def{\@star@or@long\SKV@aux@def}} \SKV@ifdefinable\SKV@aux@def{% \def\SKV@aux@def#1{\SKV@ifdefinable#1{\l@ngrel@x\def#1}}} \SKV@ifdefinable\SKV@gdef{\protected\def\SKV@gdef{\@star@or@long\SKV@aux@gdef}} \SKV@ifdefinable\SKV@aux@gdef{% \def\SKV@aux@gdef#1{\SKV@ifdefinable#1{\global\l@ngrel@x\def#1}}} \SKV@ifdefinable\SKV@edef{\protected\def\SKV@edef{\@star@or@long\SKV@aux@edef}} \SKV@ifdefinable\SKV@aux@edef{% \def\SKV@aux@edef#1{\SKV@ifdefinable#1{\l@ngrel@x\edef#1}}} \SKV@ifdefinable\SKV@pdef{\protected\def\SKV@pdef{\@star@or@long\SKV@aux@pdef}} \SKV@ifdefinable\SKV@aux@pdef{% \def\SKV@aux@pdef#1{\SKV@ifdefinable#1{\protected\l@ngrel@x\def#1}}} \SKV@ifdefinable\SKV@pedef{\protected\def\SKV@pedef{\@star@or@long\SKV@aux@pedef}} \SKV@ifdefinable\SKV@aux@pedef{% \def\SKV@aux@pedef#1{\SKV@ifdefinable#1{\protected\l@ngrel@x\edef#1}}} \SKV@pdef\SKV@defined@err#1{\def\reserved@a{#1}\@notdefinable} \SKV@def\SKV@for@ifdefinable#1{% \SKV@CommandGenParser{,}% \SKV@for@b#1\SKV@tempa{% \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil \if\expandafter\expandafter\expandafter\SKV@car\expandafter \string\SKV@tempa\SKV@nil\@backslashchar \SKV@err{Backslash not allowed}\@ehc \fi \SKV@ifnameundef\SKV@tempa{}{\SKV@defined@err\SKV@tempa}% }% } \SKV@pdef\SKV@info#1{\PackageInfo{skeyval}{#1\@gobble}} \SKV@pdef\SKV@warn#1{\PackageWarningNoLine{skeyval}{#1}} \SKV@pdef\SKV@err#1#2{\PackageError{skeyval}{#1}{#2}} \SKV@def*\SKV@nil{\noexpand\SKV@nil} \SKV@def*\SKV@nnil{\SKV@nil} \SKV@def\SKV@car#1#2\SKV@nil{#1} \gdef\@notprerr{\SKV@err{You've issued a preamble command here}% {Take command to preamble.}} \SKV@pdef\SKV@afterfi#1\fi{\fi#1} \SKV@pdef\SKV@afterelsefi#1\else#2\fi{\fi#1} \SKV@def\SKV@aftercsname#1#2{\expandafter#1\csname#2\endcsname} \SKV@def\SKV@findescape#1{% \begingroup\escapechar92 \expandafter\endgroup \if\expandafter\SKV@car\string#1\SKV@nil\@backslashchar \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } \SKV@def*\SKV@expandox#1{\unexpanded\expandafter{#1}} \SKV@def*\SKV@expandnameox#1{\SKV@aftercsname\SKV@expandox{#1}} \SKV@def*\SKV@expandtx#1{\unexpanded\expandafter\expandafter\expandafter{#1}} \SKV@def*\SKV@expandnametx#1{\SKV@aftercsname\SKV@expandtx{#1}} \SKV@def*\SKV@noexpandcs#1{\SKV@aftercsname\noexpand{#1}} \SKV@pdef\SKV@undef#1{\let#1\SKV@undefined} \SKV@pdef\SKV@gundef#1{\global\let#1\SKV@undefined} \SKV@pdef\SKV@nameundef#1{\SKV@aftercsname\let{#1}\SKV@undefined} \SKV@pdef\SKV@namegundef#1{\global\SKV@aftercsname\let{#1}\SKV@undefined} \SKV@def\SKV@ifdef#1{% \ifdefined#1% \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } \SKV@def\SKV@ifundef#1{% \ifdefined#1% \ifx#1\relax \expandafter\expandafter\expandafter\@firstoftwo \else \expandafter\expandafter\expandafter\@secondoftwo \fi \else \expandafter\@firstoftwo \fi } \SKV@def*\SKV@ifnamedef#1{% \ifcsname#1\endcsname \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi } \SKV@def*\SKV@ifnameundef#1{% \ifcsname#1\endcsname \expandafter\ifx\csname#1\endcsname\relax \expandafter\expandafter\expandafter\@firstoftwo \else \expandafter\expandafter\expandafter\@secondoftwo \fi \else \expandafter\@firstoftwo \fi } \SKV@def\SKV@remparser#1#2{% \def\tok@i{#1}\edef\tok@ii{#1#2}% \ifx#2\@empty\else \def\SKV@remove#1##1\SKV@nil{\def\tok@ii{##1}}% \SKV@r@move\let#2\tok@ii \fi } \SKV@def*\SKV@r@move{\expandafter\SKV@rem@ve\tok@ii\SKV@nil} \SKV@def*\SKV@rem@ve{\futurelet\@temptoks\SKV@remo@e} \SKV@def*\SKV@remo@e#1\SKV@nil{% \if\@temptoks\tok@i \expandafter\SKV@remove\tok@ii\SKV@nil \SKV@r@move \fi } \SKV@def\SKV@apptomacro@a#1#2{% \SKV@findescape{#1}{}{% \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}% }% \SKV@ifundef{#1}{% \edef#1{\unexpanded{#2}}% }{% \edef#1{\SKV@expandox#1\unexpanded{#2}}% }% } \SKV@def\SKV@apptomacro@b#1#2{% \SKV@findescape{#1}{}{% \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}% }% \SKV@ifundef{#1}{% \edef#1{\SKV@expandox{#2}}% }{% \xdef#1{\SKV@expandox#1\SKV@expandox{#2}}% }% } \SKV@def\SKV@preptomacro@a#1#2{% \SKV@findescape{#1}{}{% \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}% }% \SKV@ifundef{#1}{% \edef#1{\unexpanded{#2}}% }{% \edef#1{\unexpanded{#2}\SKV@expandox#1}% }% } \SKV@def\SKV@preptomacro@b#1#2{% \SKV@findescape{#1}{}{% \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}% }% \SKV@ifundef{#1}{% \edef#1{\SKV@expandox{#2}}% }{% \edef#1{\SKV@expandox{#2}\SKV@expandox#1}% }% } \SKV@def\SKV@gapptomacro@a#1#2{% \SKV@findescape{#1}{}{% \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}% }% \SKV@ifundef{#1}{% \xdef#1{\unexpanded{#2}}% }{% \xdef#1{\SKV@expandox#1\unexpanded{#2}}% }% } \SKV@def\SKV@gapptomacro@b#1#2{% \SKV@findescape{#1}{}{% \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}% }% \SKV@ifundef{#1}{% \xdef#1{\SKV@expandox{#2}}% }{% \xdef#1{\SKV@expandox#1\SKV@expandox{#2}}% }% } \SKV@def\SKV@gpreptomacro@a#1#2{% \SKV@findescape{#1}{}{% \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}% }% \SKV@ifundef{#1}{% \xdef#1{\unexpanded{#2}}% }{% \xdef#1{\unexpanded{#2}\SKV@expandox#1}% }% } \SKV@def\SKV@gpreptomacro@b#1#2{% \SKV@findescape{#1}{}{% \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}% }% \SKV@ifundef{#1}{% \xdef#1{\SKV@expandox{#2}}% }{% \xdef#1{\SKV@expandox{#2}\SKV@expandox#1}% }% } \SKV@def*\@afterpackageloaded#1{% \SKV@ifnamedef{ver@#1.\@pkgextension}{% \let\SKV@tempa\@firstofone }{% \def\SKV@tempa{\SKV@aftercsname\SKV@apptomacro@a{#1.\@pkgextension @afpl}}% }% \SKV@tempa } \SKV@preptomacro@a\@popfilename{% \SKV@nameuse{\@currname.\@currext @afpl}% \SKV@nameundef{\@currname.\@currext @afpl}% } \@onlypreamble\@afterpackageloaded \SKV@def\ReserveKeyPrefixNames#1{\SKV@apptomacro@a\SKV@rkpnames{,#1}} \SKV@def\ReserveMacroPrefixNames#1{\SKV@apptomacro@a\SKV@rmpnames{,#1}} \SKV@def\ReserveFamilyNames#1{\SKV@apptomacro@a\SKV@rfnames{,#1}} \SKV@def*\SKV@rkpnames{XKV} \SKV@def*\SKV@rmpnames{XKV} \SKV@def*\SKV@rfnames{XKV} \SKV@pdef*\SKV@CommandGenParser#1{% \def\parser{#1}% \protected\long\def\SKV@for@a##1##2##3{% \edef##2{\unexpanded{##1}}% \SKV@oifblank{##2}\SKV@fornoop\SKV@forloop ##2{##3}##1#1\SKV@nil#1% }% \long\def\SKV@forloop##1##2##3#1{% \edef##1{\unexpanded{##3}}% \ifx##1\SKV@nnil \expandafter\@gobbletwo \else ##2\expandafter\SKV@forloop \fi ##1{##2}% }% \long\def\SKV@fornoop##1\SKV@nil#1{}% } \SKV@pdef\SKV@for@b#1{\expandafter\SKV@for@a\expandafter{#1}} \SKV@pdef*\SKV@tfor@a#1#2#3{\SKV@ifblank{#2}{}{\@tf@r#1{#2}\do{#3}}} \SKV@pdef*\SKV@tfor@b#1#2#3{% \SKV@expandargs{3}{\SKV@tfor@a#1}{{\SKV@expandox{#2}}}{{#3}}\SKV@nil } \SKV@def\SKV@checksanitizec#1#2{% \XKV@ch@cksanitize{#1}#2;% \ifin@\else\XKV@ch@cksanitize{#1}#2,\fi \ifin@\@selective@sanitize[0]{,;}#2\fi } \SKV@def*\SKV@CommandKeyParser#1{% \long\def\SKV@define@keylist##1{% \ifXKV@st \long\expandafter\def\expandafter\SKV@tempa\expandafter{##1}% \else \long\def\SKV@tempa{##1}% \fi \SKV@expandargs{3}\SKV@checksanitizec{{\SKV@expandox{\SKV@tempa}}}% \SKV@tempa\SKV@nil \def\SKV@nob{\z@}% \expandafter\SKV@readkeylist\SKV@tempa#1\SKV@nil }% \long\def\SKV@readkeylist##1#1##2\SKV@nil{% \SKV@ifblank{##1}\relax {% \SKV@ifstrequal{##1}{\stopread}{% \def\SKV@nob{\@ne}% \stopread##2\SKV@nil }{% \SKV@define@mult@keys##1\SKV@nil }% }% \ifnum\SKV@nob=\z@ \SKV@ifblank{##2}\relax{\SKV@readkeylist##2\SKV@nil}% \fi }% } \SKV@def\SKV@expandargs#1#2#3#4\SKV@nil{% \begingroup \protected@edef\SKV@tempa{\endgroup \ifcase#1\relax \unexpanded{#2}{#3}% \or \unexpanded{#2#3}{#4}% \or \unexpanded{#2}{#3}{#4}% \or \unexpanded{#2}#3\unexpanded{#4}% \else \SKV@err{Unknown expansion type '#1' for \string\SKV@expandargs}% {Use the right expansion identifier (0 - 3)}% \fi }% \SKV@tempa } \SKV@pdef\SKV@checkchoice#1#2#3#4{% \SKV@expandargs{3}{\XKV@cc*+[\val\nr]}{{#1}{#2}}{{#3}{#4}}\SKV@nil } \SKV@pdef*\SKV@inputerr#1#2{% \SKV@err{Erroneous value '#1' for key '#2'}{% Please use the correct value for key '#2'.}% } \SKV@def\SKV@ifblank#1{\SKV@ifbl@nk#1\SKV@nil\SKV@nil\@secondoftwo\@firstoftwo:} \SKV@def\SKV@ifbl@nk#1#2\SKV@nil#3#4#5:{#4} \SKV@def\SKV@oifblank#1{\SKV@expandargs{0}\SKV@ifblank{\SKV@expandox{#1}}\SKV@nil} \SKV@def\SKV@xifblank#1{\SKV@expandargs{0}\SKV@ifblank{#1}\SKV@nil} \SKV@def\SKV@ifstrequal#1#2{% \begingroup \edef\SKV@tempa{\detokenize{#1}}% \edef\SKV@tempb{\detokenize{#2}}% \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil \SKV@expandargs{1}\KV@@sp@def\SKV@tempb\SKV@tempb\SKV@nil \ifx\SKV@tempa\SKV@tempb \aftergroup\@firstoftwo \else \aftergroup\@secondoftwo \fi \endgroup } \SKV@def\SKV@oifstrequal#1#2{% \@expandtwoargs\SKV@ifstrequal{\SKV@expandox{#1}}{\SKV@expandox{#2}}% } \SKV@def\SKV@xifstrequal#1#2{\@expandtwoargs\SKV@ifstrequal{#1}{#2}} \SKV@def\SKV@ifstrempty#1{% \romannumeral-`\@\csname @\if @\detokenize{#1}@first\else second\fi oftwo\endcsname } \SKV@def\SKV@oifstrempty#1{% \SKV@expandargs{0}\SKV@ifstrempty{\SKV@expandox{#1}}\SKV@nil} \SKV@def\SKV@xifstrempty#1{\SKV@expandargs{0}\SKV@ifstrempty{#1}\SKV@nil} \SKV@def*\SKV@keylistparser@err{% \SKV@err{Key list parser '\SKV@keyparser' not allowed}% {Use semicolon (preferable) or colon as parser.}% } \define@boolkey+[KV]{skeyval}[SKV@]{xchoicelist}[true]{}{% \SKV@inputerr{#1}{xchoicelist}% } \define@boolkey+[KV]{skeyval}[SKV@]{inputonce}[true]{}{% \SKV@inputerr{#1}{inputonce}% } \define@cmdkey[KV]{skeyval}[SKV@]{genparser}[,]{% \@onelevel@sanitize\SKV@genparser \SKV@expandargs{1}\KV@@sp@def\SKV@genparser\SKV@genparser\SKV@nil \SKV@expandargs{0}\SKV@CommandGenParser\SKV@genparser\SKV@nil } \define@cmdkey[KV]{skeyval}[SKV@]{keyparser}[;]{% \@onelevel@sanitize\SKV@keyparser \SKV@xifblank\SKV@keyparser\SKV@keylistparser@err\relax \SKV@expandargs{1}\KV@@sp@def\SKV@keyparser\SKV@keyparser\SKV@nil \begingroup \edef\SKV@tempa{\detokenize{,}}% \ifx\SKV@keyparser\SKV@tempa \aftergroup\SKV@keylistparser@err \fi \endgroup \SKV@expandargs{0}\SKV@CommandKeyParser\SKV@keyparser\SKV@nil } \SKV@def*\SKV@keyprefix@err{% \SKV@err{Key prefix '\SKV@keyprefix' is not allowed}% {Use another prefix instead of '\SKV@keyprefix'.}% } \define@cmdkey[KV]{skeyval}[SKV@]{keyprefix}[KV]{% \SKV@xifblank\SKV@keyprefix\SKV@keyprefix@err\relax \SKV@expandargs{1}\KV@@sp@def\SKV@keyprefix\SKV@keyprefix\SKV@nil \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rkpnames}}\SKV@tempa\SKV@nil \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \ifx\SKV@keyprefix\SKV@tempa\SKV@afterfi\SKV@keyprefix@err\fi }% } \SKV@def*\SKV@keyfamily@err{% \SKV@err{Key family '\SKV@keyfamily' is not allowed}% {Use another family name instead of '\SKV@keyfamily'.}% } \define@cmdkey[KV]{skeyval}[SKV@]{keyfamily}[fam]{% \SKV@xifblank\SKV@keyfamily\SKV@keyfamily@err\relax \SKV@expandargs{1}\KV@@sp@def\SKV@keyfamily\SKV@keyfamily\SKV@nil \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rfnames}}\SKV@tempa\SKV@nil \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \ifx\SKV@keyfamily\SKV@tempa\SKV@afterfi\SKV@keyfamily@err\fi }% } \SKV@def*\SKV@macroprefix@err{% \SKV@err{Macro prefix '\SKV@macroprefix' is not allowed}% {Use another macro prefix.}% } \define@cmdkey[KV]{skeyval}[SKV@]{macroprefix}[mp@]{% \SKV@xifblank\SKV@macroprefix\SKV@macroprefix@err\relax \SKV@expandargs{1}\KV@@sp@def\SKV@macroprefix\SKV@macroprefix\SKV@nil \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rmpnames}}\SKV@tempa\SKV@nil \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \ifx\SKV@macroprefix\SKV@tempa\SKV@afterfi\SKV@macroprefix@err\fi }% } \DeclareOptionX*{\SKV@warn{Unknown option '\CurrentOption' ignored}} \ExecuteOptionsX[KV]{genparser,keyparser,keyprefix, keyfamily,macroprefix,inputonce} \ProcessOptionsX*[KV]\relax \SKV@pdef*\skvoptions#1{\setkeys[KV]{skeyval}{#1}} \SKV@def*\SKV@despacelist#1#2{% \SKV@CommandGenParser{#1}% \let\SKV@tempa#2% \let#2\@empty \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil \SKV@apptomacro@b#2{\expandafter#1\SKV@tempa}% }% \ifx#2\@empty\else \SKV@remparser{#1}#2% \fi } \SKV@def\SKV@named@f#1#2{% \ifcsname#2\endcsname \expandafter\ifx\csname#2\endcsname\relax\else \def\reserved@a{#2}% \expandafter\expandafter\expandafter\@notdefinable \fi \else \expandafter#1\csname#2\expandafter\endcsname \fi } \SKV@def*\SKV@newnamedef#1{\SKV@named@f\def{#1}} \SKV@def*\SKV@newnamegdef#1{\SKV@named@f\gdef{#1}} \SKV@def*\SKV@newnameedef#1{\SKV@named@f\edef{#1}} \SKV@def*\SKV@newnamexdef#1{\SKV@named@f\xdef{#1}} \SKV@def*\SKV@namedef#1{\SKV@aftercsname\def{#1}} \SKV@def*\SKV@namegdef#1{\SKV@aftercsname\gdef{#1}} \SKV@def*\SKV@nameedef#1{\SKV@aftercsname\edef{#1}} \SKV@def*\SKV@namexdef#1{\SKV@aftercsname\xdef{#1}} \SKV@def*\SKV@nameuse#1{% \ifcsname#1\endcsname\csname#1\expandafter\endcsname\fi} \SKV@def\SKV@ifnextchar#1#2#3{% \let\SKV@@tempc=#1\def\SKV@@tempa{#2}\def\SKV@@tempb{#3}% \futurelet\@temptoks\SKV@ifnextch@r } \SKV@def\SKV@ifnextch@r{% \ifx\@temptoks\SKV@@tempc\let\SKV@@tempb\SKV@@tempa\fi \SKV@@tempb } \SKV@def\SKV@testopt#1#2{\SKV@ifnextchar[{#1}{#1[{#2}]}} \SKV@def\SKV@ifstar#1#2{% \SKV@ifnextchar*{\begingroup \def\SKV@tempa*{\endgroup #1}\SKV@tempa}{#2}% } \SKV@def*\SKV@newlet#1#2{% \SKV@ifdef#1{% \SKV@err{Command '\string#1' already defined}{% I can't let '\string#1' to '\string#2'.}% }{% \SKV@ifdef#2{% \let#1#2% }{% \SKV@err{Command '\string#2' undefined}{% I can't let '\string#1' to '\string#2'.}% }% }% } \SKV@pdef*\SKV@newtoks#1{\SKV@ifdefinable#1{\@nameuse{newtoks}#1}} \SKV@pdef*\SKV@newcount#1{\SKV@ifdefinable#1{\@nameuse{newcount}#1}} \SKV@pdef*\SKV@newdimen#1{\SKV@ifdefinable#1{\@nameuse{newdimen}#1}} \SKV@def*\nameletcs#1#2{% \SKV@ifdef{#2}{% \SKV@aftercsname\let{#1}#2% }{% \SKV@err{Command '\string#2' undefined}\@ehc }% } \SKV@def*\csletname#1#2{% \SKV@ifnamedef{#2}{% \expandafter\let\expandafter#1\csname#2\endcsname }{% \SKV@err{Command '\@backslashchar#2' undefined}\@ehc }% } \SKV@def*\nameletname#1#2{% \SKV@ifnamedef{#2}{% %\expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname \SKV@aftercsname\let{#1\SKV@aftercsname}{#2}% }{% \SKV@err{Command '\@backslashchar#2' undefined}\@ehc }% } \SKV@def*\@nameletcs#1#2{\SKV@aftercsname\let{#1}#2} \SKV@def*\@csletname#1#2{% \begingroup\expandafter\endgroup \expandafter\let\expandafter#1\csname#2\endcsname } \SKV@def*\@nameletname#1#2{% \begingroup\expandafter\endgroup \expandafter\let\csname#1\SKV@aftercsname\endcsname{#2}% } \SKV@pdef*\SKV@numdef#1#2{% \SKV@findescape{#1}{}{\SKV@err{Backslash required in '#1'}\@ehc}% \SKV@ifstrempty{#2}{\SKV@err{Empty argument for counter '#1'}\@ehc}{}% \SKV@ifundef{#1}{% \newcount#1#1=\numexpr#2\relax }{% #1=\numexpr#2\relax }% } \SKV@pdef*\SKV@numnamedef#1{\SKV@aftercsname\SKV@numdef{#1}} \SKV@pdef*\SKV@numgdef#1#2{% \SKV@findescape{#1}{}{\SKV@err{Backslash required in '#1'}\@ehc}% \SKV@ifstrempty{#2}{\SKV@err{Empty argument for counter '#1'}\@ehc}{}% \SKV@ifundef{#1}{% \newcount#1\global#1=\numexpr#2\relax }{% \global#1=\numexpr#2\relax }% } \SKV@pdef*\SKV@numnamegdef#1{\SKV@aftercsname\SKV@numgdef{#1}} \SKV@pdef*\SKV@dimdef#1#2{% \SKV@findescape{#1}{}{\SKV@err{Backslash required in '#1'}\@ehc}% \SKV@ifstrempty{#2}{\SKV@err{Empty argument for dimension '#1'}\@ehc}{}% \SKV@ifundef{#1}{% \newdimen#1#1=\dimexpr#2\relax }{% #1=\dimexpr#2\relax }% } \SKV@pdef*\SKV@dimnamedef#1{\SKV@aftercsname\SKV@dimdef{#1}} \SKV@pdef*\SKV@dimgdef#1#2{% \SKV@findescape{#1}{}{\SKV@err{Backslash required in '#1'}\@ehc}% \SKV@ifstrempty{#2}{\SKV@err{Empty argument for dimension '#1'}\@ehc}{}% \SKV@ifundef{#1}{% \newdimen#1\global#1=\dimexpr#2\relax }{% \global#1=\dimexpr#2\relax }% } \SKV@pdef*\SKV@dimnamegdef#1{\SKV@aftercsname\SKV@dimgdef{#1}} \SKV@pdef*\define@compboolkeys{% \let\SKV@def@boolkey\define@boolkey \SKV@testopt{\SKV@compbool@opta}{KV}% } \SKV@pdef*\newcompboolkeys{% \let\SKV@def@boolkey\newboolkey \SKV@testopt{\SKV@compbool@opta}{KV}% } \SKV@def*\SKV@compbool@opta[#1]#2{% \SKV@testopt{\SKV@define@compboolkeys[#1]{#2}}{mp@}} \SKV@def\SKV@define@compboolkeys[#1]#2[#3]#4[#5]#6#7#8{% \SKV@namedef{#1@#2@#4@func}{% #7\SKV@nameuse{if#3#4}\SKV@nameuse{#3#6false}\else \SKV@nameuse{#3#6true}\fi}% \SKV@namedef{#1@#2@#6@func}{% #8\SKV@nameuse{if#3#6}\SKV@nameuse{#3#4false}\else \SKV@nameuse{#3#4true}\fi}% \begingroup\protected@edef\SKV@tempa{\endgroup \unexpanded{% \SKV@def@boolkey+[#1]{#2}[#3]{#4}[#5]{% \SKV@nameuse{#1@#2@#4@func}% }{% \SKV@inputerr{##1}{#4}% }% \SKV@def@boolkey+[#1]{#2}[#3]{#6}[#5]{% \SKV@nameuse{#1@#2@#6@func}% }{% \SKV@inputerr{##1}{#6}% }% }% }% \SKV@tempa } \SKV@def\SKV@star@or@long#1{% \SKV@ifstar{% \let\l@ngrel@x\relax \def\SKV@star@or@none{*}#1% }{% \let\l@ngrel@x\long \def\SKV@star@or@none{}#1% }% } \SKV@pdef\requirecmd{\SKV@star@or@long\SKV@require@cmd} \SKV@def\SKV@require@cmd#1{% \ifdefined#1% \SKV@afterelsefi \expandafter\CheckCommand\SKV@star@or@none \else \SKV@afterfi \expandafter\newcommand\SKV@star@or@none \fi {#1}% } \def\@check@eq#1#2{% \unless\ifx#1#2% \SKV@warn{% Previous definition of \string#1\MessageBreak doesn't match your new definition.\MessageBreak *** I haven't redefined \string#1\space *** }% \fi } \SKV@pdef*\SKV@undeftoggle@err#1{% \SKV@err{Toggle '#1' undefined}% {You need to first define '#1' before use.}% } \SKV@pdef*\deftog#1{% \SKV@ifnamedef{SKV@toggle@#1}{% \SKV@warn{Toggle '#1' redefined\on@line}% }{}% \nameletcs{SKV@toggle@#1}\@secondoftwo } \SKV@pdef*\newtog#1{% \SKV@ifnamedef{SKV@toggle@#1}{% \SKV@err{Toggle '#1' already defined}% {Please provide a new toggle or redefine '#1'.}% }{% \nameletcs{SKV@toggle@#1}\@secondoftwo }% } \SKV@pdef*\providetog#1{% \SKV@ifnamedef{SKV@toggle@#1}{% \SKV@info{Toggle '#1' already defined.\MessageBreak Not redefined\on@line}% }{% \nameletcs{SKV@toggle@#1}\@secondoftwo }% } \SKV@pdef*\requiretog#1{% \SKV@aftercsname\requirecmd{SKV@toggle@#1}[2]{##2}% } \SKV@pdef*\settog#1#2{% \SKV@ifnamedef{SKV@toggle@#1}{% \SKV@ifnamedef{SKV@t@ggle#2}{% \nameletname{SKV@toggle@#1}{SKV@t@ggle#2}% }{% \SKV@err{% Inadmissible value '#2' for toggle '#1' }{% Valid values for toggles are 'true' and 'false'. }% }% }{% \SKV@undeftoggle@err{#1}% }% } \SKV@pdef*\togtrue#1{% \SKV@ifnamedef{SKV@toggle@#1}{% \nameletcs{SKV@toggle@#1}\SKV@t@ggletrue }{% \SKV@undeftoggle@err{#1}% }% } \SKV@pdef*\togfalse#1{% \SKV@ifnamedef{SKV@toggle@#1}{% \nameletcs{SKV@toggle@#1}\SKV@t@gglefalse }{% \SKV@undeftoggle@err{#1}% }% } \SKV@newlet\SKV@t@ggletrue\@firstoftwo \SKV@newlet\SKV@t@gglefalse\@secondoftwo \SKV@pdef*\iftog#1{% \SKV@ifnamedef{SKV@toggle@#1}{% \@nameuse{SKV@toggle@#1}% }{% \SKV@undeftoggle@err{#1}% }% } \SKV@pdef*\ifnottog#1{% \SKV@ifnamedef{SKV@toggle@#1}{% \@nameuse{SKV@toggle@#1}\@secondoftwo\@firstoftwo }{% \SKV@undeftoggle@err{#1}\@gobbletwo }% } \SKV@pdef*\SKV@definedkey@err#1{% \SKV@ifnamedef{\XKV@header#1}{% \SKV@err{% Key '#1' already defined in family '\XKV@tfam' }{% Use another key name for '#1'. }% }{}% } \SKV@pdef*\define@togkey{\XKV@t@stopta{\XKV@testoptd\SKV@define@togkey{}}} \SKV@def*\SKV@define@togkey#1#2[#3]{% \SKV@reservedkey@err{#2}% \SKV@suspendedkey@err{#2}% \ifXKV@pl \SKV@afterelsefi \expandafter\SKV@d@f@ne@togkey \else \SKV@afterfi \expandafter\SKV@d@fine@togkey \fi \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}% } \SKV@def*\SKV@d@fine@togkey#1#2#3#4#5{% \SKV@d@f@ne@t@gkey#1{#2}{#3}{#4}% {{\settog{#3}{\XKV@resa}#5}}% } \SKV@def*\SKV@d@f@ne@togkey#1#2#3#4#5#6{% \SKV@d@f@ne@t@gkey#1{#2}{#3}{#4}% {{\settog{#3}{\XKV@resa}#5}{#6}}% } \SKV@def*\SKV@d@f@ne@t@gkey#1#2#3#4#5{% \deftog{#3}% \ifXKV@st\XKV@define@default{#2}{#4}\fi \ifXKV@pl \def#1##1{\XKV@pltrue\XKV@sttrue \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5% }% \else \def#1##1{\XKV@plfalse\XKV@sttrue \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5% }% \fi } \SKV@pdef*\define@togkeys{% \XKV@plfalse\XKV@testoptd\SKV@define@togkeys{}} \SKV@def*\SKV@define@togkeys#1#2[#3]{% \XKV@sp@deflist\SKV@tempa{#2}% \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@expandargs{3}\SKV@d@fine@togkeys{{\SKV@tempa}}{{#1}{#3}}\SKV@nil }% } \SKV@def*\SKV@d@fine@togkeys#1#2#3{% \SKV@aftercsname\SKV@d@f@ne@t@gkey{\XKV@header#1}% {#1}{#2#1}{#3}{{\settog{#2#1}{\XKV@resa}}}% } \SKV@pdef*\newordkey{\XKV@testoptb\SKV@newordkey} \SKV@def*\SKV@newordkey#1{% \SKV@definedkey@err{#1}% \SKV@ifnextchar[{\XKV@d@fine@k@y{#1}}% {\SKV@namedef{\XKV@header#1}####1}% } \SKV@pdef*\newcmdkey{\XKV@testoptd\SKV@newcmdkey{cmd}} \SKV@def*\SKV@newcmdkey#1#2[#3]#4{% \SKV@definedkey@err{#2}% \ifXKV@st\XKV@define@default{#2}{#3}\fi \edef\SKV@tempa{\noexpand\def\@nameuse{\XKV@header#2}####1}% \edef\SKV@tempb{\noexpand\def\@nameuse{#1#2}\unexpanded{{##1}#4}}% \expandafter\SKV@tempa\expandafter{\SKV@tempb}% \SKV@undef\SKV@tempa\SKV@undef\SKV@tempb } \SKV@pdef*\newcmdkeys{\XKV@testoptd\SKV@newcmdkeys{cmd}} \SKV@def*\SKV@newcmdkeys#1#2[#3]{% \XKV@sp@deflist\SKV@tempa{#2}% \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \edef\SKV@tempa{\noexpand\SKV@newcmdkey{#1}{\SKV@tempa}}% \SKV@tempa[#3]{}% }% } \SKV@pdef*\newchoicekey{\XKV@testopta{\XKV@testoptb\SKV@newchoicekey}} \SKV@def*\SKV@newchoicekey#1{% \SKV@definedkey@err{#1}% \@testopt{\XKV@d@fine@choicekey{#1}}{}% } \SKV@pdef*\newboolkey{\XKV@t@stopta{\XKV@testoptd\SKV@newboolkey{}}} \SKV@def*\SKV@newboolkey#1#2[#3]{% \SKV@definedkey@err{#2}% \ifXKV@pl \SKV@afterelsefi \expandafter\XKV@d@f@ne@boolkey \else \SKV@afterfi \expandafter\XKV@d@fine@boolkey \fi \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}% } \SKV@pdef*\newboolkeys{\XKV@plfalse\XKV@testoptd\SKV@newboolkeys{}} \SKV@def*\SKV@newboolkeys#1#2[#3]{% \XKV@sp@deflist\SKV@tempa{#2}% \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@definedkey@err\SKV@tempa \SKV@expandargs{3}\XKV@d@fine@boolkeys{{\SKV@tempa}}{{#1}{#3}}\SKV@nil }% } \SKV@pdef*\newtogkey{\XKV@t@stopta{\XKV@testoptd\SKV@newtogkey{}}} \SKV@def*\SKV@newtogkey#1#2[#3]{% \SKV@definedkey@err{#2}% \ifXKV@pl \SKV@afterelsefi \expandafter\SKV@d@f@ne@togkey \else \SKV@afterfi \expandafter\SKV@d@fine@togkey \fi \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}% } \SKV@pdef*\newtogkeys{\XKV@plfalse\XKV@testoptd\SKV@newtogkeys{}} \SKV@def*\SKV@newtogkeys#1#2[#3]{% \XKV@sp@deflist\SKV@tempa{#2}% \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@definedkey@err\SKV@tempa \SKV@expandargs{3}\SKV@d@fine@togkeys{{\SKV@tempa}}{{#1}{#3}}\SKV@nil }% } \SKV@pdef*\define@comptogkeys{% \let\SKV@def@togkey\define@togkey \SKV@testopt{\SKV@comptog@opta}{KV}% } \SKV@pdef*\newcomptogkeys{% \let\SKV@def@togkey\newtogkey \SKV@testopt{\SKV@comptog@opta}{KV}% } \SKV@def*\SKV@comptog@opta[#1]#2{% \SKV@testopt{\SKV@define@comptogkeys[#1]{#2}}{mp@}} \SKV@def\SKV@define@comptogkeys[#1]#2[#3]#4[#5]#6#7#8{% \SKV@namedef{#1@#2@#4@func}{% #7\iftog{#3#4}{\togfalse{#3#6}}{\togtrue{#3#6}}}% \SKV@namedef{#1@#2@#6@func}{% #8\iftog{#3#6}{\togfalse{#3#4}}{\togtrue{#3#4}}}% \begingroup\protected@edef\SKV@tempa{\endgroup \unexpanded{% \SKV@def@togkey+[#1]{#2}[#3]{#4}[#5]{% \SKV@nameuse{#1@#2@#4@func}% }{% \SKV@inputerr{##1}{#4}% }% \SKV@def@togkey+[#1]{#2}[#3]{#6}[#5]{% \SKV@nameuse{#1@#2@#6@func}% }{% \SKV@inputerr{##1}{#6}% }% }% }% \SKV@tempa } \SKV@pdef*\stopread#1\SKV@nil{\long\edef\SKV@remainder{\unexpanded{#1}}} \def\SKV@noa{\z@}\def\SKV@nob{\z@}\def\SKV@noc{\z@} \SKV@pdef*\define@keylist{% \let\SKV@def@key\define@key \let\SKV@def@cmdkey\define@cmdkey \let\SKV@def@boolkey\define@boolkey \let\SKV@def@togkey\define@togkey \let\SKV@def@choicekey\define@choicekey \SKV@ifstar{\XKV@sttrue\SKV@define@keylist}% {\XKV@stfalse\SKV@define@keylist}% } \SKV@pdef*\newkeylist{% \let\SKV@def@key\newordkey \let\SKV@def@cmdkey\newcmdkey \let\SKV@def@boolkey\newboolkey \let\SKV@def@togkey\newtogkey \let\SKV@def@choicekey\newchoicekey \SKV@ifstar{\XKV@sttrue\SKV@define@keylist}% {\XKV@stfalse\SKV@define@keylist}% } \SKV@def\ChoiceKeyValues#1#2{% \ifSKV@xchoicelist \SKV@nameedef{\SKV@keyprefix @\SKV@keyfamily @#1@altlist}{#2}% \else \SKV@ifnameundef{\SKV@keyprefix @\SKV@keyfamily @#1@altlist}{% \SKV@newnameedef{\SKV@keyprefix @\SKV@keyfamily @#1@altlist}{#2}% }{% \SKV@err{% You have attempted to set two \MessageBreak \string\ChoiceKeyValues\space for the choice\MessageBreak key '#1' in the same family '\SKV@keyfamily' }{% You can only do that if you set 'xchoicelist'=true. }% }% \fi } \SKV@newlet\CKVS\ChoiceKeyValues \SKV@def*\SKV@detok@z@p#1{% \edef#1{\expandafter\detokenize\expandafter{#1}\space}% \edef#1{\expandafter\zap@space#1\@empty}% } \SKV@def*\SKV@detok@zsp#1{% \begingroup \def\SKV@no{\z@}% \SKV@CommandGenParser{,}% \SKV@for@b#1\SKV@tempa{% \edef\SKV@no{\the\numexpr\SKV@no+\@ne}% \edef\SKV@tempa{\expandafter\detokenize\expandafter{\SKV@tempa}\space}% \edef\SKV@tempa{\expandafter\zap@space\SKV@tempa\@empty}% \SKV@namexdef{SKV@zsp\SKV@no}{\SKV@expandox{\SKV@tempa}}% }% \endgroup } \SKV@def*\SKV@detok@dsp#1{% \begingroup \def\SKV@no{\z@}% \SKV@CommandGenParser{,}% \SKV@for@b#1\SKV@tempa{% \edef\SKV@no{\the\numexpr\SKV@no+\@ne}% \edef\SKV@tempa{\expandafter\detokenize\expandafter{\SKV@tempa}}% \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil \SKV@namexdef{SKV@dsp\SKV@no}{\SKV@expandox{\SKV@tempa}}% }% \endgroup } \SKV@def*\SKV@if@err{% \SKV@err{You can't use '\protect\if' and '\protect\fi' in key macro}% {Use '\protect\fif' and '\protect\ffi' instead.}% } \SKV@def\SKV@define@mult@keys#1,#2,#3,#4\SKV@nil{% \begingroup \SKV@ifblank{#4}{}{% \def\SKV@tempa{\if,\fi,\fif}% \SKV@detok@dsp\SKV@tempa \def\SKV@tempb{#4}\SKV@detok@z@p\SKV@tempb \@expandtwoargs\in@{\@nameuse{SKV@dsp1}}\SKV@tempb \ifin@\SKV@afterfi\SKV@if@err\fi \@expandtwoargs\in@{\@nameuse{SKV@dsp3}}\SKV@tempb \ifin@ \SKV@afterelsefi \SKV@namegdef{\SKV@keyprefix @\SKV@keyfamily @#2@func}{#4}% \else \SKV@afterfi \SKV@namexdef{\SKV@keyprefix @\SKV@keyfamily @#2@func}{\SKV@expandox{#4}}% \fi }% \protected@edef\SKV@tempa{\endgroup \ifcase#1\relax \def\SKV@noc{\@ne}% \or \noexpand\SKV@def@key[\SKV@keyprefix]{\SKV@keyfamily}% {#2}[#3]{% \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}% }% \or \noexpand\SKV@def@cmdkey[\SKV@keyprefix]{\SKV@keyfamily}% [\SKV@macroprefix]{#2}[#3]{% \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}% }% \or \noexpand\SKV@def@boolkey+[\SKV@keyprefix]{\SKV@keyfamily}% [\SKV@macroprefix]{#2}[#3]{% \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}% }{% \unexpanded{\SKV@inputerr{##1}{#2}}% }% \or \noexpand\SKV@def@togkey+[\SKV@keyprefix]{\SKV@keyfamily}% [\SKV@macroprefix]{#2}[#3]{% \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}% }{% \unexpanded{\SKV@inputerr{##1}{#2}}% }% \or \SKV@ifnameundef{\SKV@keyprefix @\SKV@keyfamily @#2@altlist}{% \def\SKV@noa{\@ne}% }{}% \noexpand\SKV@def@choicekey*+[\SKV@keyprefix]{\SKV@keyfamily}{#2}% [\unexpanded{\val\nr}]{% \SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@altlist}% }[#3]{% \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}% }{% \unexpanded{\SKV@inputerr{##1}{#2}}% }% \else \def\SKV@noc{\@ne}% \fi }% \SKV@tempa \ifnum\SKV@noa=\@ne \SKV@afterfi \SKV@err{% Choice key '#2' can't be defined.\MessageBreak Alternate key values list for '#2' is empty }{% You need to first define admissible\MessageBreak key values through '\string\ChoiceKeyValues'\MessageBreak for choice key '#2'. }% \fi \ifnum\SKV@noc=\@ne \SKV@afterfi \SKV@err{Unknown key type/identifier '#1'}% {You can only use key types 1 to 5.}% \fi } \SKV@pdef*\in@tog#1#2{% \def\in@@##1#1##2##3\in@@{% \ifx\in@##2\togfalse{in@}\else\togtrue{in@}\fi }% \in@@#2#1\in@\in@@ } \newtog{in@} \SKV@pdef*\in@tok#1#2{% \begingroup \edef\SKV@tempa{\detokenize{#1}}% \edef\SKV@tempb{\detokenize{#2}}% \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil \SKV@expandargs{1}\KV@@sp@def\SKV@tempb\SKV@tempb\SKV@nil \SKV@expandargs{3}{\def\in@@##1}\SKV@tempa{% ##2##3\in@@{\global\ifx\in@##2\in@false\else\in@true\fi}% }\SKV@nil \SKV@expandargs{3}\in@@{\SKV@tempb\SKV@tempa}{\in@\in@@}\SKV@nil \endgroup } \def\XKV@makepf#1{% \KV@@sp@def\XKV@prefix{#1}% \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rkpnames}}\SKV@tempa\SKV@nil \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \XKV@knftrue \XKV@whilist\SKV@tempa\SKV@tempa\ifXKV@knf\fi{% \ifx\XKV@prefix\SKV@tempa\XKV@knffalse\fi }% \unless\ifXKV@knf \SKV@afterfi \SKV@err{Prefix '\SKV@tempa' is not allowed}% {Use another prefix instead of '\SKV@tempa'}% \fi \edef\SKV@pref{\ifx\XKV@prefix\@empty\else\XKV@prefix\fi}% \edef\XKV@prefix{\ifx\XKV@prefix\@empty\else\XKV@prefix @\fi}% } \def\XKV@makehd#1{% \SKV@expandargs{1}\KV@@sp@def\XKV@header{#1}\SKV@nil \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rfnames}}\SKV@tempa\SKV@nil \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \XKV@knftrue \XKV@whilist\SKV@tempa\SKV@tempa\ifXKV@knf\fi{% \ifx\XKV@header\SKV@tempa\XKV@knffalse\fi }% \unless\ifXKV@knf \SKV@afterfi \SKV@err{Family '\SKV@tempa' is not allowed}% {Use another family instead of '\SKV@tempa'}% \fi \edef\XKV@header{% \XKV@prefix\ifx\XKV@header\@empty\else\XKV@header @\fi}% } \def\XKV@define@key#1{% \SKV@reservedkey@err{#1}% \SKV@suspendedkey@err{#1}% \SKV@ifnextchar[{\XKV@d@fine@k@y{#1}}{\SKV@d@fine@k@y{#1}}% } \def\XKV@d@fine@k@y#1[#2]#3{%! \XKV@define@default{#1}{#2}% \SKV@namedef{\XKV@header#1}##1{#3}% } \def\SKV@d@fine@k@y#1#2{\SKV@namedef{\XKV@header#1}##1{#2}} \def\XKV@define@cmdkey#1#2[#3]#4{% \SKV@reservedkey@err{#2}% \SKV@suspendedkey@err{#2}% \ifXKV@st\XKV@define@default{#2}{#3}\fi \edef\SKV@tempa{\noexpand\def\@nameuse{\XKV@header#2}####1}% \edef\SKV@tempb{\noexpand\def\@nameuse{#1#2}\unexpanded{{##1}#4}}% \expandafter\SKV@tempa\expandafter{\SKV@tempb}% \SKV@undef\SKV@tempa\SKV@undef\SKV@tempb } \def\XKV@define@choicekey#1{% \SKV@reservedkey@err{#1}% \SKV@suspendedkey@err{#1}% \@testopt{\XKV@d@fine@choicekey{#1}}{}% } \def\XKV@define@boolkey#1#2[#3]{% \SKV@reservedkey@err{#2}% \SKV@suspendedkey@err{#2}% \ifXKV@pl \SKV@afterelsefi\expandafter\XKV@d@f@ne@boolkey \else \SKV@afterfi\expandafter\XKV@d@fine@boolkey \fi \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}% } \SKV@pdef*\reserve@keys{\@testopt\SKV@reserve@keys{KV}} \SKV@def*\SKV@reserve@keys[#1]#2#3{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \expandafter\SKV@res@rve@keys\expandafter{\SKV@tempa}{#2}{#3}% }% } \SKV@def*\SKV@res@rve@keys#1#2#3{% \XKV@makepf{#1}% \XKV@checksanitizeb{#2}\XKV@fams \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil \SKV@for@b\XKV@fams\XKV@tfam{% \XKV@makehd\XKV@tfam \SKV@res@rve@k@ys{#3}% }% } \SKV@def*\SKV@res@rve@k@ys#1{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@ifnamedef{\XKV@header\SKV@tempa}{% \SKV@err{% Key '\SKV@tempa' with prefix '\SKV@pref' in family \MessageBreak '\XKV@tfam' is already defined }{% Key '\SKV@tempa' in family '\XKV@tfam' can't be reserved. \MessageBreak You may wish to remove it before reserving it. \MessageBreak In that case, you can use '\string\remove@keys'. }% }{% \SKV@nameedef{\XKV@header\SKV@tempa}{% \SKV@err{% Key '\SKV@tempa' with prefix '\SKV@pref' in family '\XKV@tfam' \MessageBreak was reserved\on@line }{% Unreserve '\SKV@tempa' before use. }% }% \SKV@namedef{\XKV@header\SKV@tempa @reser}{}% }% }% } \let\SKV@no\@empty \SKV@pdef\SKV@aftergroup{% \SKV@ifstar{\SKV@aft@rgroup\@firstofone}{\SKV@aft@rgroup\unexpanded}% } \SKV@def\SKV@aft@rgroup#1#2{% \edef\SKV@no{\the\numexpr\SKV@no+1}% \SKV@namexdef{SKV@aft@rgr@up\SKV@no}{% \SKV@namegundef{SKV@aft@rgr@up\SKV@no}% #1{#2}% }% \SKV@aftercsname\aftergroup{SKV@aft@rgr@up\SKV@no}% } \SKV@pdef\SKV@afterassignment{% \SKV@ifstar{\SKV@aft@rassignment\@firstofone}% {\SKV@aft@rassignment\unexpanded}% } \SKV@def\SKV@aft@rassignment#1#2{% \begingroup \edef\SKV@no{\the\numexpr\SKV@no+1}% \SKV@namexdef{SKV@aft@rassignm@nt\SKV@no}{% \SKV@namegundef{SKV@aft@rassignm@nt\SKV@no}% #1{#2}% }% \expandafter\endgroup\expandafter\afterassignment \csname SKV@aft@rassignm@nt\SKV@no\endcsname } \SKV@def*\SKV@reservedkey@err#1{% \SKV@ifnamedef{\XKV@header#1@reser}{% \let\next\SKV@err }{% \let\next\@gobbletwo }% \next{% Key '#1' with prefix '\SKV@pref'\MessageBreak is reserved in family '\XKV@tfam' }{% Unreserve '#1' before use. }% } \SKV@def*\ifkeyreserved{\@testopt\SKV@ifkeyreserved{KV}} \SKV@def*\SKV@ifkeyreserved[#1]#2#3{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \XKV@knftrue \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \expandafter\SKV@ifkey@reserved\expandafter{\SKV@tempa}{#2}{#3}% }% \ifXKV@knf \expandafter\@secondoftwo \else \expandafter\@firstoftwo \fi } \SKV@def*\SKV@ifkey@reserved#1#2#3{% \XKV@makepf{#1}% \XKV@checksanitizeb{#2}\XKV@fams \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil \KV@@sp@def\XKV@tkey{#3}% \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{% \XKV@makehd\XKV@tfam \SKV@ifnamedef{\XKV@header\XKV@tkey @reser}{\XKV@knffalse}{}% }% } \SKV@def*\ifkeysuspended{\@testopt\SKV@ifkeysuspended{KV}} \SKV@def*\SKV@ifkeysuspended[#1]#2#3{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \XKV@knftrue \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \expandafter\SKV@ifkey@suspended\expandafter{\SKV@tempa}{#2}{#3}% }% \ifXKV@knf \expandafter\@secondoftwo \else \expandafter\@firstoftwo \fi } \SKV@def*\SKV@ifkey@suspended#1#2#3{% \XKV@makepf{#1}% \XKV@checksanitizeb{#2}\XKV@fams \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil \KV@@sp@def\XKV@tkey{#3}% \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{% \XKV@makehd\XKV@tfam \SKV@ifnamedef{\XKV@header\XKV@tkey @sus}{\XKV@knffalse}{}% }% } \SKV@def*\ifkeydefined{\@testopt\SKV@ifkeydefined{KV}} \SKV@def*\SKV@ifkeydefined[#1]#2#3{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \XKV@knftrue \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \expandafter\SKV@ifk@ydefined\expandafter{\SKV@tempa}{#2}{#3}% }% \ifXKV@knf \expandafter\@secondoftwo \else \expandafter\@firstoftwo \fi } \SKV@def*\SKV@ifk@ydefined#1#2#3{% \XKV@makepf{#1}% \XKV@checksanitizeb{#2}\XKV@fams \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil \KV@@sp@def\XKV@tkey{#3}% \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{% \XKV@makehd\XKV@tfam \SKV@ifnamedef{\XKV@header\XKV@tkey}{\XKV@knffalse}{}% }% } \SKV@def*\SKV@disabledkey@err{% \SKV@err{% Key '\SKV@disabledkey' with prefix '\SKV@pref' in family \MessageBreak '\XKV@tfam' was disabled\on@line }{% You can't set or reset '\SKV@disabledkey' at this\MessageBreak late stage. Perhaps you're required to set it \MessageBreak earlier, in the document's preamble. }% } \protected\def\disable@keys{% \SKV@ifstar{\@testopt\XKV@disable@keys{KV}}% {\@testopt\SKV@disable@keys{KV}}% } \SKV@def*\SKV@disable@keys[#1]#2#3{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \expandafter\SKV@dis@ble@keys\expandafter{\SKV@tempa}{#2}{#3}% }% } \SKV@def*\SKV@dis@ble@keys#1#2#3{% \XKV@makepf{#1}% \XKV@checksanitizeb{#2}\XKV@fams \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil \SKV@for@b\XKV@fams\XKV@tfam{% \XKV@makehd\XKV@tfam \SKV@dis@ble@k@ys{#3}% }% } \SKV@def*\SKV@dis@ble@k@ys#1{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@ifnameundef{\XKV@header\SKV@tempa}{% \SKV@warn{Key '\SKV@tempa' with prefix '\SKV@pref' \MessageBreak is undefined in family '\XKV@tfam': \MessageBreak can't be disabled\on@line}% }{% \SKV@dis@ble@k@y@\SKV@tempa }% }% } \SKV@def*\SKV@dis@ble@k@y@#1{% \edef\SKV@disabledkey{#1}% \SKV@ifnameundef{\XKV@header#1@default}{% \edef#1{\noexpand\XKV@define@key{#1}}% }{% \edef#1{\noexpand\XKV@define@key{#1}[]}% }% \SKV@expandargs{0}#1\SKV@disabledkey@err\SKV@nil \SKV@info{Key '\SKV@disabledkey' with prefix '\SKV@pref' in family '\XKV@tfam' \MessageBreak was disabled\on@line}% } \SKV@def*\SKV@suspendedkey@err#1{% \SKV@ifnamedef{\XKV@header#1@sus}{% \SKV@err{% Key '#1' was suspended from family '\XKV@tfam' }{% You can use \string\restore@key\space to restore '#1'. }% }{}% } \SKV@def*\SKV@suspendedkey@e@r{% \SKV@err{% Key '\SKV@suspendedkey' in family '\XKV@tfam' was \MessageBreak suspended\on@line }{% You can use \string\restore@key\space to restore '\SKV@suspendedkey'. }% } \SKV@pdef*\suspend@keys{\@testopt\SKV@suspend@keys{KV}} \SKV@def*\SKV@suspend@keys[#1]#2#3{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \expandafter\SKV@s@spend@keys\expandafter{\SKV@tempa}{#2}{#3}% }% } \SKV@def*\SKV@s@spend@keys#1#2#3{% \XKV@makepf{#1}% \XKV@checksanitizeb{#2}\XKV@fams \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil \SKV@for@b\XKV@fams\XKV@tfam{% \XKV@makehd\XKV@tfam \SKV@s@sp@nd@keys{#3}% }% } \SKV@def*\SKV@s@sp@nd@keys#1{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@ifnameundef{\XKV@header\SKV@tempa}{% \SKV@warn{Key '\SKV@tempa' with prefix '\SKV@pref' \MessageBreak is undefined in family '\XKV@tfam': \MessageBreak can't be suspended\on@line}% }{% \SKV@s@sp@nd@k@ys\SKV@tempa }% }% } \SKV@def*\SKV@s@sp@nd@k@ys#1{% \SKV@ifnamedef{\XKV@header#1@sus}{% \SKV@err{% Key '#1' with prefix '\SKV@pref' was suspended from family '\XKV@tfam' }{% You can use \string\restore@key\space to restore '#1'. }% }{% \edef\SKV@suspendedkey{#1}% \global\nameletname{\XKV@header#1@sus}{\XKV@header#1}% \SKV@nameedef{\XKV@header#1}{\SKV@suspendedkey@e@r}% \SKV@info{Key '\SKV@suspendedkey' with prefix '\SKV@pref' in \MessageBreak family '\XKV@tfam' was suspended\on@line}% }% } \SKV@pdef*\restore@keys{\@testopt\SKV@restore@keys{KV}} \SKV@def*\SKV@restore@keys[#1]#2#3{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \expandafter\SKV@r@store@keys\expandafter{\SKV@tempa}{#2}{#3}% }% } \SKV@def*\SKV@r@store@keys#1#2#3{% \XKV@makepf{#1}% \XKV@checksanitizeb{#2}\XKV@fams \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil \SKV@for@b\XKV@fams\XKV@tfam{% \XKV@makehd\XKV@tfam \SKV@r@st@re@keys{#3}% }% } \SKV@def*\SKV@r@st@re@keys#1{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@ifnameundef{\XKV@header\SKV@tempa}{% \SKV@warn{Key '\SKV@tempa' with prefix '\SKV@pref' \MessageBreak is undefined in family '\XKV@tfam': \MessageBreak can't be restored\on@line}% }{% \SKV@r@st@re@k@ys\SKV@tempa }% }% } \SKV@def*\SKV@r@st@re@k@ys#1{% \SKV@ifnameundef{\XKV@header#1@sus}{% \SKV@err{Key '#1' wasn't suspended from family \MessageBreak '\XKV@tfam': can't be restored\on@line}\@ehc }{% \edef\SKV@restoredkey{#1}% \nameletname{\XKV@header#1}{\XKV@header#1@sus}% \SKV@nameundef{\XKV@header#1@sus}% \SKV@info{Key '\SKV@restoredkey' with prefix '\SKV@pref' in family \MessageBreak '\XKV@tfam' restored\on@line}% }% } \SKV@pdef*\remove@keys{\@testopt\SKV@remove@keys{KV}} \SKV@def*\SKV@remove@keys[#1]#2#3{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@CommandGenParser{,}% \SKV@for@b\SKV@tempa\SKV@tempa{% \expandafter\SKV@r@move@keys\expandafter{\SKV@tempa}{#2}{#3}% }% } \SKV@def*\SKV@r@move@keys#1#2#3{% \XKV@makepf{#1}% \XKV@checksanitizeb{#2}\XKV@fams \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil \SKV@for@b\XKV@fams\XKV@tfam{% \XKV@makehd\XKV@tfam \SKV@r@m@ve@keys{#3}% }% } \SKV@def*\SKV@r@m@ve@keys#1{% \XKV@checksanitizeb{#1}\SKV@tempa \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@ifnameundef{\XKV@header\SKV@tempa}{% \SKV@warn{Key '\SKV@tempa' with prefix '\SKV@pref' \MessageBreak is undefined in family '\XKV@tfam': \MessageBreak I can't remove or unreserve it\on@line}% }{% \SKV@r@m@ve@k@ys\SKV@tempa }% }% } \SKV@def*\SKV@r@m@ve@k@ys#1{% \begingroup \edef\SKV@tempa{\XKV@header#1,\XKV@header#1@default, \XKV@header#1@func,%\XKV@header#1@value, \XKV@header#1@altlist,\XKV@header#1@reser }% \SKV@for@b\SKV@tempa\SKV@tempa{% \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil \SKV@namegundef{\SKV@tempa}% }% \endgroup \SKV@info{Key '#1' with prefix '\SKV@pref' in family '\XKV@tfam' \MessageBreak was removed\on@line}% } \SKV@newlet\unreserve@keys\remove@keys \def\setkeys{% \def\fif##1{% \SKV@findescape{##1}{% \SKV@err{Bad argument '\string##1'}% {Backslash in '\string##1' not allowed.}% }{}% \csname if##1\endcsname }% \let\ffi\fi \XKV@testopta{\XKV@testoptc\XKV@setkeys}% } \def\XKV@setkeys[#1]#2{% \XKV@checksanitizea{#2}\XKV@resb \SKV@normalizea\XKV@resb \let\XKV@naa\@empty \XKV@for@o\XKV@resb\XKV@tempa{% \expandafter\XKV@g@tkeyname\XKV@tempa=\@nil\XKV@tempa \XKV@addtolist@x\XKV@naa\XKV@tempa }% \ifnum\XKV@depth=\z@\let\XKV@rm\@empty\fi \XKV@usepresetkeys{#1}{preseth}% \expandafter\XKV@s@tkeys\expandafter{\XKV@resb}{#1}% \XKV@usepresetkeys{#1}{presett}% \let\CurrentOption\@empty } \SKV@def*\SKV@remspaceletter#1#2{% \begingroup \XKV@toks\expandafter{#2 #1}% \def\SKV@tempa##1 #1##2\SKV@nil{% \SKV@ifblank{##2}{% \XKV@toks{##1}% }{% \XKV@toks{##1#1##2}% \expandafter\SKV@tempa\the\XKV@toks\SKV@nil }% }% \expandafter\SKV@tempa\the\XKV@toks\SKV@nil \xdef#2{\the\XKV@toks}% \endgroup } \SKV@def*\SKV@remletterspace#1#2{% \begingroup \XKV@toks\expandafter{#2#1 }% \def\SKV@tempa##1#1 ##2\SKV@nil{% \SKV@ifblank{##2}{% \XKV@toks{##1}% }{% \XKV@toks{##1#1##2}% \expandafter\SKV@tempa\the\XKV@toks\SKV@nil }% }% \expandafter\SKV@tempa\the\XKV@toks\SKV@nil \xdef#2{\the\XKV@toks}% \endgroup } \SKV@def*\SKV@remletterletter#1#2{% \begingroup \XKV@toks\expandafter{#2#1#1}% \def\SKV@tempa##1#1#1##2\SKV@nil{% \XKV@toks{##1#1##2}% \SKV@ifblank{##2}{}{\expandafter\SKV@tempa\the\XKV@toks\SKV@nil}% }% \expandafter\SKV@tempa\the\XKV@toks\SKV@nil \def\SKV@tempa##1#1#1\SKV@nil{\gdef#2{##1}}% \expandafter\SKV@tempa\the\XKV@toks#1\SKV@nil \endgroup } \def\SKV@remcommaequal#1#2{% \begingroup \XKV@toks\expandafter{#2#1}% \def\SKV@tempa##1#1##2\SKV@nil{% \SKV@ifblank{##2}{% \XKV@toks{##1}% }{% \XKV@toks{##1=##2}% \expandafter\SKV@tempa\the\XKV@toks\SKV@nil }% }% \expandafter\SKV@tempa\the\XKV@toks\SKV@nil \xdef#2{\the\XKV@toks}% \endgroup } \SKV@def*\SKV@normalizea#1{% \@expandtwoargs\in@{ ,}{\SKV@expandox{#1}}% \ifin@\SKV@remspaceletter{,}#1\fi \@expandtwoargs\in@{, }{\SKV@expandox{#1}}% \ifin@\SKV@remletterspace{,}#1\fi \@expandtwoargs\in@{,,}{\SKV@expandox{#1}}% \ifin@\SKV@remletterletter{,}#1\fi \@expandtwoargs\in@{ =}{\SKV@expandox{#1}}% \ifin@\SKV@remspaceletter{=}#1\fi \@expandtwoargs\in@{= }{\SKV@expandox{#1}}% \ifin@\SKV@remletterspace{=}#1\fi \@expandtwoargs\in@{==}{\SKV@expandox{#1}}% \ifin@\SKV@remletterletter{=}#1\fi \@expandtwoargs\in@{,=}{\SKV@expandox{#1}}% \ifin@\SKV@remcommaequal{,=}#1\fi \@expandtwoargs\in@{=,}{\SKV@expandox{#1}}% \ifin@\SKV@remcommaequal{=,}#1\fi } \SKV@pdef\AtStartOfDocument{\AtBeginDocument} \SKV@pdef\BeforeStartOfDocument{\SKV@gapptomacro@a\SKV@beforestartdocument} \SKV@def*\SKV@beforestartdocument{} \SKV@preptomacro@a\document{% \endgroup \let\BeforeStartOfDocument\@firstofone \SKV@beforestartdocument \protected\long\def\BeforeStartOfDocument{\expandafter\@notprerr\@gobble}% \SKV@undef\SKV@beforestartdocument \begingroup } \SKV@pdef\AfterStartOfDocument{\SKV@gapptomacro@a\SKV@afterstartdocument} \SKV@def*\SKV@afterstartdocument{} \SKV@apptomacro@a\document{% \let\AfterStartOfDocument\@firstofone \SKV@afterstartdocument \protected\long\def\AfterStartOfDocument{\expandafter\@notprerr\@gobble}% \SKV@undef\SKV@afterstartdocument\ignorespaces } \SKV@def*\SKV@gobblescape{% \ifnum\escapechar>255\else \ifnum\escapechar<0\else \expandafter\expandafter\csname @gobble\ifnum\escapechar=32 space\fi \expandafter\expandafter\expandafter\endcsname \fi\fi \string } \SKV@def*\SKV@save#1{% \SKV@findescape{#1}{}{\SKV@err{'#1' not a control sequence}\@ehc} \SKV@ifnamedef{Saved\SKV@gobblescape#1}{% \SKV@err{% \string#1\space already saved. You've to restore\MessageBreak it or undefine \SKV@noexpandcs{Saved\SKV@gobblescape#1}% before\MessageBreak you can save \string#1\space again }\@ehc }{% \nameletcs{Saved\SKV@gobblescape#1}{#1}% }% } \SKV@def*\SKV@restore#1{% \SKV@findescape{#1}{}{\SKV@err{'#1' not a control sequence}\@ehc} \SKV@ifnamedef{Saved\SKV@gobblescape#1}{% \csletname{#1}{Saved\SKV@gobblescape#1}% \SKV@nameundef{Saved\SKV@gobblescape#1}% }{% \SKV@warn{% \@nameuse{Saved\SKV@gobblescape#1} undefined: can't be restored\on@line. \MessageBreak Note that each call of \string\SKV@restore\space undefines \MessageBreak the saved command }% }% } \providecommand*\input@path{} \SKV@pdef*\InputFileOnce{% \edef\SKV@no{\z@}\SKV@save\input@path \SKV@testopt\SKV@InputFileOnce{.}% } \SKV@def*\SKV@InputFileOnce[#1]#2{% \SKV@gapptomacro@a\input@path{{#1/}}% \if X\SKV@nameuse{#2@read}\relax \ifSKV@inputonce \SKV@afterelsefi \SKV@err{! File '#2' already read}{File '#2' can't be read again.}% \fi \else \SKV@namegdef{#2@read}{X}% \InputIfFileExists{#2}{}{% \typein[\Answer]{^^J! File '\string#2' does not exist.^^J Enter filename or 'n' and to continue.}% \if n\Answer\relax\else \SKV@expandargs{0}{\SKV@InputFileOnce[#1]}\Answer\SKV@nil \fi }% \fi \ifnum\SKV@no=\z@\SKV@restore\input@path\fi \edef\SKV@no{\@ne}% } \endinput %%% End of file skeyval.sty %%%