%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% % This is file 'skeyval-testpkg.sty', version 1.3, 2013/05/15. % % % % 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. % % % % The following files constitute the skeyval bundle and must be % % distributed as a whole: % % % % README, skeyval.sty, skeyval-core.tex, skeyval-for.tex, % % skeyval-view.sty, skeyval-ltxpatch.sty, skeyval-ltxcmds.tex, % % skeyval-pstkey.sty, skeyval-pstkey.tex, skeyval-testclass.cls, % % skeyval-testpkg.sty, skeyval-pokayoke1, skeyval-pokayoke2, % % skeyval-view-pokayoke1. % % % % Copyright (c) 2010-2013 Ahmed Musa (amusa22@gmail.com). % %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% \ProvidesPackage{skeyval-testpkg} [2013/05/15 v1.3 skeyval test package (AM)] \NeedsTeXFormat{LaTeX2e} \@ifpackageloaded{skeyval}{}{\RequirePackage{skeyval}} \RequirePackage{graphicx} \skvdisabledkeysmessagetype{warning} %%++++++++++++++++ Passing options to packages +++++++++++++++++++%% \skvdeclarebooloption[SKVT][skvtp@]{verbose}[true]{} % Declare options with default values that will be used when the options % are called without user values. % \skvdeclarepassedoptionsloadpackage[SKVT]{testpkg}{% hyperref={colorlinks,breaklinks},xcolor=svgnames } %%+++++++++++++++++++ Producing arbitrary texts +++++++++++++++++%% % The key 'align' could have defined using \skvchoicekey, as in % 'shadowbox' family below. \newcommand*\justified{} \skvordkey[SKVT]{abrtext}{align}[right]{% \skvifcase\skvxifstrcmpTF{#1} {left}{\def\mpfalign{flushleft}} {right}{\def\mpfalign{flushright}} {center}{\def\mpfalign{center}} {justified}{\def\mpfalign{justified}} \elsedo \PackageError{skeyval-testpkg} {Invalid value `#1' for align} {You have issued an illegal value `#1' for option `align'.}% \endif } \skvzcmdkey[SKVT]{abrtext}[mpf]{text style}[\rmfamily]{} \skvcmdkey[SKVT]{abrtext}[mpf]{author}[Karl Berry]{} \skvzboolkey[SKVT]{abrtext}[mpf]{show author}[true]{} % Using pointers to expand values of keys while setting keys: \def\alignval{right} \def\alignvalb{\alignval} \def\stextstyle{\sffamily} \skvsetkeys[SKVT]{abrtext}{ align=.expand twice{\alignvalb}, text style=.expand once{\stextstyle},author,show author } %%+++++++++++++++++++++++++++ Citations +++++++++++++++++++++++++++%% % Keys defined by \skvdefinekeys are automatically initialiized when % the option 'initialize' is true. In general, to save initialize % key values at key definition, you need to call \skvsaveinitialvaluekeys % before defining the keys. \skvsaveinitialvaluekeys[SKVT]{citation}{put frame,width,show author,author, textcolor,fonttype,leftmargin,rightmargin,preskip,framecolor,shadecolor, frame thickness} \newbox\skv@testbox \skvdefinekeys*[SKVT]{citation}[ctt@]{% .cmd/width/\hsize, .zbool/show author/true, .cmd/author//, % empty default .zbool/put frame/true, .cmd/framecolor/black, .cmd/shadecolor/white, .cmd/textcolor/black, .zcmd/frame thickness/.4pt, .cmd/fonttype/\normalfont, .cmd/leftmargin/\leftmargin, .cmd/rightmargin/\rightmargin, .cmd/preskip/0ex, .cmd/width/\textwidth, .ord/dummy key/\@nil, } % Keys defined by \skvdefinekeys are automatically initialiized when % the option 'initialize' is true. When \skvsaveinitialvaluekeys has been % called for a set of keys, those keys can be initialized via % \skvinitializekeys: \skvinitializekeys[SKVT]{citation}[dummy key] \newcommand\newcitation[2][]{% \skvsetkeys[SKVT]{citation}{#1}% \sbox\skv@testbox{% \ctt@fonttype \textit{\textcolor{\ctt@textcolor}{\ctt@author}}% }% \list{}{% \setlength\leftmargin{\ctt@leftmargin}% \setlength\rightmargin{\ctt@leftmargin}% }% \vspace*{\ctt@preskip}% \item\relax \ifctt@putframe \begingroup \fboxrule\ctt@framethickness\relax \fcolorbox{\ctt@framecolor}{\ctt@shadecolor}{% \fi \parbox{\ctt@width}{% \ctt@fonttype\textcolor{\ctt@textcolor}{\ignorespaces#2}% \ifctt@showauthor \hspace*{\fill}\nolinebreak[1]% \quad\hspace*{\fill}\finalhyphendemerits\z@\relax \usebox\skv@testbox \fi }% \ifctt@putframe}\endgroup\fi \endlist % Restore default values of keys: \skvinitializekeys[SKVT]{citation}[] } %%++++++++++++++++++++++++ Shadow boxes ++++++++++++++++++++++%% \newdimen\shadowspread \skvdefinekeys*[SKVT]{shadowbox}[shb@]{% .zbool/put frame/true, .bool/shadow/true, .cmd/framecolor/black, .cmd/shadecolor/white, .cmd/shadowcolor/gray!55, .cmd/boxwidth/1.5cm, .ord/framesize/.5pt/\def\currfboxrule{#1}, .ord/shadowsize/2pt/\shadowspread=\dimexpr#1\relax, .choice/align/center/{% center.do=\def\curralign##1{\hfil##1\hfil}, right.do=\def\curralign##1{\hfill##1}, left.do=\def\curralign##1{##1\hfill}, justified.do=\let\curralign\@iden } } \skvdefinekeys*[SKVT]{testfam}[shb@]{% .zbool/put shadow/true,% Test zbool .zcmd/shade color/gray!55, % Test .zcmd } \skvdisablekeys[SKVT]{testfam}{put shadow, shade color} % Presetting and posetting keys. % % 1. 'Presetting keys' means set the following keys whenever % \setkeys is called. These keys should be set BEFORE the keys % listed in the current argument of \setkeys are set, provided % that these keys aren't listed in the current argument of \setkeys. % If these keys appear in the current argument of \setkeys, % then obviously the user has new values for them or he wants % the keys to be set with their default values. % % 2. 'Postsetting keys' means set the following keys whenever % \setkeys is called. These keys should be set AFTER the keys % listed in the current argument of \setkeys are set, provided % that these keys aren't listed in the current argument of \setkeys. % % 3. The command \presetkeys of the xkeyval package expects both % 'head' and 'tail'. The skeyval package splits \presetkeys into two, % hopefully less confusing, commands: \skvpresetkeys and % \skvpostsetkeys. % % 4. There is also command \skvpreposetkeys, which combines % \skvpresetkeys and \skvpostsetkeys. This expects both head and % tail and is equivalent to xkeyval's \presetkeys. \skvpresetkeys[SKVT]{shadowbox}{% put frame,framecolor=black,framesize=.8pt,boxwidth=1.5cm,align=center, shadecolor=gray!15 } \skvpostsetkeys[SKVT]{shadowbox}{% shadow=.use value{put frame},shadowcolor=.use value{framecolor}!40, shadowsize=\dimexpr.use value{framesize}*5\relax } \newcommand*\newshadowbox[2][]{% \skvsetkeys[SKVT]{shadowbox}{#1}% \begingroup \ifshb@putframe \fboxrule=\dimexpr\currfboxrule\relax \else \fboxrule=0pt \fi \ifshb@shadow\else\shadowspread=0pt \fi \sbox\z@{\fcolorbox{\shb@framecolor}{\shb@shadecolor}{% \hb@xt@\shb@boxwidth{\curralign{#2}}% }}% \hskip\shadowspread \color{\shb@shadowcolor}% \rule[-\dp0]{\wd0}{\dimexpr\ht0+\dp0\relax}% \llap{\raisebox{\shadowspread}{\box0\hskip\shadowspread}}% \endgroup } %%++++++++++++++++++++++++ The \directkeys command ++++++++++++++++++++%% % The following are meant to demonstrate the use of the macro \directkeys: \ifdefined\skvtestcnt \skvtestcnt\z@ \else \newcount\skvtestcnt \fi \def\logsetting{% \advance\skvtestcnt\@ne \typeout{'\skvcurrentkey' set: no. \ifnum\skvtestcnt<10 0\fi\the\skvtestcnt, % path: \skvcurrentprefix/\skvcurrentfamily}% } \directkeys{% % #1 will be the user-value of the handler 'some handler'. .new handlers = { .some handler=\def\x##1{##1*#1}, .phantom handler=, }, .handler let = { .another handler=.some handler, .do nothing handler=.phantom handler }, .kill handlers={ .another handler, .do nothing handler }, .define handlers={ .j handler=\def\x##1{##1*#1}, .j handler=\def\y##1{##1*#1}, }, .define narg handlers={ .j1 handler={2}{\def\x##1{##1*#1*#2}}, .j2 handler={3}{\def\x##1{##1*#1*#2*#3}} }, .new narg handlers={ % Error: handler j1 already exists: % .j1 handler={2}{\def\x##1{##1*#1*#2}}, .k handler={2}{\def\x##1{##1*#1*#2}}, .l handler={3}{\def\x##1{##1*#1*#2*#3}} }, .reserve handlers={reservedx , reservedy}, .holder prefix = mp@, .prefix = KV, .families = {fam1, fam2}, .add family = {fam3}, .add families = {fama,famb,famc}, .ignore families = {fama,famb,famc}, .restore families = {fama,famb}, .restore paths = {KVA/fama,KVD/famc}, % .ignore keys = {keyb,keyc}, .new keys = { .ord/keya/keya-default, .cmd/keyb/keyb-default/\def\x##1{##1#1}, .cmd/keyc/keyc-default, .choice*/keyd/center /{ right.do=\def\val@r{#1}, left.do=\def\val@l{#1}, center.do=\def\val@c{#1} } /\def\yes{value accepted} /\def\no{value rejected}, .bool/keye/true/ \ifskvindef\else\logsetting\fi \ifmp@keye\def\y##1{##1#1}\fi , .bool/keyf/true/, .bool/keyg/true/ }, .push path, .path = KV/fam1, .set keys = {keyd}, .pop path, .ignore keys = {keyb,keyc}, % Stop processing this list: % .list break, .restore keys = {keyb,keyc}, .preset keys = {keyb,keyc}, .postset keys = {keyb,keyc}, % Save unknown keys in the default macro \@@rmkeys: .save unknown keys = true, .save unknown keys in = \macroa, .set keys = {keya,keyb,keyc,keyd,keye}, .set keys = {keya=keya-value,keyb=\def\y####1{####1}}, .set keys* = {keya=keya-value,keyf}, .set keys* = {keya=keya-value,keyf}, .ignore keys = {keyf}, .set rmkeys*, % Execute arbitrary code: .exec code=\def\x#1{#1}, % Nesting of \directkeys is possible. Pre-entry and post-entry % topologies are independent. At the end of the nest, % prevailing variables of \directkeys revert to their previous % (pre-door) values: \directkeys{ .paths = {KVA/fam3,KVB/fam3}, .holder prefix = hp@, .define keys = { .cmd/keya/keya-default/\def\x##1{##1#1}, .ord/keyb/keyb-default, }, .set keys = {keya=vala}, }, .exec code = \def\keycval{true}, % Prepend slot keye to key1 and key2: .prepend slot={key1/{keye=.expanded{\keycval}},key2/{keye=false}}, % Multi-prepend slots: .prepend slot={{key3,key4}/{keye=true,keyf=true},key5/{keye=false}}, % Prepend slot keyd to key6: .prepend slot={key6/{keyd=right}}, % Append slots keye and keyf to key7 and key8. % '.slots' and '.slot' are equivalent to '.append slots' % and '.append slot'. .append slot={key7/{keye=true},key8/{keyf=false}}, % The next two link keyb and keyc to key9. #1 here refers to the % current value of key9. The same effect can be achieved directly % via the '.link' handler: .prepend slot={key9/{keyb=#1}}, .append slot={key9/{keyc=#1}}, .set keys = {key9=val9}, % Link keye and keyf to key10 and key11. The values of key10 and % key11 are used to set keye and keyf. key10 and key11 are hence % 'parent keys'. .link = {key10/keye, {key11,key12}/{keyf,keyg}}, .set keys = {key10=true}, .ignore key = keyf, .save unknown keys in = \macrob, .setkeys = {keya,keyb,keyf}, .disable keys = {keye,keyf}, } %%++++++++++++++++++++++ Collecting body of environment +++++++++++++++++%% \skvmakekeys[ .prefix=KV, .family=collectbody, .hp=mp, .initialize, .endlinechar=-1 ]{% .cmd/title//, .zcmd/title scale/1, .zcmd/body scale/1, .cmd/width/\textwidth, .zcmd/title text style//, .zcmd/body text style//, .cmd/action// } \newsavebox{\boxbody} \newenvironment{collectbody}[1][]{% \skvusekeys[.prefix=KV,.family=collectbody]{#1}% \ifx\mptitle\@empty\else\skvafterfi \begin{center}% \scalebox{\mptitlescale}{\mptitletextstyle\mptitle}% \end{center}% \fi \begin{lrbox}{\boxbody}% \begin{minipage}{\mpwidth}% \mpbodytextstyle\mpaction }{% \end{minipage}% \end{lrbox}% \scalebox{\mpbodyscale}{\usebox{\boxbody}}% } %%+++++++++++++++++++++ Changing the key parser ++++++++++++++++++++%% \setupskeyval{key parser={;}} \skvafterdefinekeys{\setupskeyval{keyparser={,}}} \skvdefinekeys*[SKVT]{example}[exm@]{% .zbool/put frame/true; .cmd/shadecolor/green; .ord/framesize/.5pt/\def\currfboxrule{#1}; .choice/align/center/{% center.do=\def\curralign##1{\hfil##1\hfil}, right.do=\def\curralign##1{\hfill##1}, left.do=\def\curralign##1{##1\hfill}, justified.do=\let\curralign\@iden }; } %%++++++++++++++++++++++++++ Options section ++++++++++++++++++++++%% \def\skvtp@unknownoptions{} \skvunknownoptionhandler[SKVT]{% \edef\skvtp@unknownoptions{% \skvtp@unknownoptions\ifx\skvtp@unknownoptions\@empty\else,\fi #3% }% \AtEndDocument{% \ifx\skvtp@unknownoptions\@empty\else \PackageWarningNoLine{skeyval-testpkg} {Unknown keys: \skvtp@unknownoptions}% \fi }% } \skvexecuteoptions[SKVT]{align=.expanded{\alignval}, text style=.expand once{\stextstyle},author,show author } \skvprocessoptions*+[SKVT]\relax %\skvrestrictedprocessoptions*+[SKVT]\relax \skvcomment Here you could also use: \directkeys{ .mega process options*={ .prefix=SKVT, .families={abrtext,shadowbox,citation,testpkg}, } } or \directkeys{ .prefix=SKVT, .families={abrtext,shadowbox,citation,testpkg}, .copy class options and process options in all families, } \endcomment \endinput