\makeatletter \RequirePackage{skeyval-ltxpatch} % With 'skeyval-ltxpatch' loaded, class options will not be zapped and % expandable commands can be passed as options. \documentclass[ text style=\ttfamily, show author=true, insertwatermark, watermarktext={skeyval-test1\\[.25ex]Page~\thepage}, watermarkcolor=brown!80!yellow ]{skeyval-testclass} %\show\@unusedoptionlist \skvifpackageloaded{xcolor}{}{\usepackage[dvipsname]{xcolor}} \usepackage{lipsum} % The command \cmdalign is just for illustrating how key values % may be expanded at key setting time: \def\cmdalign{justified} \usepackage[ author=Albert X\"avier Einstein, align=.expanded{\cmdalign}, show author=true, unknown-option, ]{skeyval-testpkg} % Keys whose names are zapped internally: \skvzcmdkeys[KV]{fam}[mp@]{provide value,give value}[true]{} \skvzboolkeys[KV]{fam}[mp@]{provide value,give value}[true]{} % Parenthesized keys are keys with names that have parentheses. % The following is a key of 3 arguments. The default values are % \x, \y, and \numexpr\x*2. \skvpntkey[KV]{fam}{evaluate (?) as (?) using (?)}[\x\y{\numexpr\x*2}]{% \def\argone{#1}\def\argtwo{#2}\def\argthree{#3}% % '\detokenize{\pgfmath}' won't work here! \skvxifinTF{\relax\string\pgfmath}{\relax\detokenize{#3}}{% #3% }{% \edef#2{#3}% }% } % The above parenthesized key can be set as follows: \def\cmda{2} \skvsetkeys[KV]{fam}{% evaluate (\cmda) as (\cmdb) using (\pgfmathsetmacro\cmdb{\cmda*10}) } %\show\argthree \newcommand*\vgap{\endgraf\medskip} \def\keycval{xx} %% +++++++++++++++ Examples of using \directkeys command +++++++++ %% % Note: When the value of a handler contains equality sign (=) or % comma (,), it should be enclosed in braces. \directkeys*{ .exec=\skvtestcnt\z@, .prefix = KV1, .family = fam1, .holder prefix = mp@, .add paths={KV2/fam2,KV3/fam3}, .ignore roots={KV2/fam2,KV3/fam3}, .restore roots={KV2/fam2,KV3/fam3}, .save initial values of keys, .initialize keys after define=false, .new keys = { .ord/keya/{dfta,dftb}/ \def\cmda##1{#1*##1*#2}\logsetting , .arg/keya/{#1,#2}, .cmd/keyb/{1cm,2cm}/ \edef\boxht{\the\dimexpr#1*2\relax} \edef\boxwd{\the\dimexpr#1*10\relax}, .choice/keyc/center/{right,left,center,justified}, .bool/keyd/true, .cmd/keye/dfte/\def\cmde##1{##1#1}, .cmd/keyf/dftf/\def\cmdf##1{##1#1}, .ord/.need value{keyg}/dftg, .ord/.forbid value{keyh}/dfth, }, .args={ keyb={#1,#2} }, .set={ keya={val1,val2},keyb={2.5cm,5cm} }, .get value={KV1}{fam1}{keya}\cmda, .ignore keys={ keyd,keye }, .set with defaults={ keyd,keye,keyf,keyg }, .restore keys = keye, .link={keye2/keye}, % Choices for keye can be declared directly: .estate pattern={keye,keye2}/{ 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 }, .exec code ={ \def\leftval{left}\def\rightval{right} \def\rrightval{\rightval} }, % key1 and key2 are undefined. They will be defined internally % with the default values of keyc and keyd: .prepend style={ key1/{keyc=.expanded{\rightval}},key2/{keyd=false} }, .append style={ key1/{keye=right,keyf=valf} }, % When key3 and key4 are set, use their expanded values to set keye: .elink={ {key3,key4}/keye }, .style expand twice={ key5/{keyf=#1,keyg=#1} }, .set keys={ key3=.expand once{\leftval}, key5=.expand twice{\rrightval} }, .prepend link={ {key6,key7}/{keye,keyf},{key8,key9}/{keye,keyg} }, .exec code=\skvsetkeys[KV1]{fam1}{key6=center}, % Set keya and keyb on previously declared and the following paths. % Enter known keys in \mysuccesslist. Try 14 families; stop when % 12 families have been hit (ie, keys have been set in them % successfully): .search also set keys={ .add prefixes={KV3,KV4}, .add families={fam3,fam4}, .try=14, .upper goal=12, .success list=\mysuccesslist, .kv={keya={val1,val2},keyb={1cm,2cm}} }, % .exec code={\show\mysuccesslist}, \directkeys*{ .exec=\skvtestcnt\z@\def\mysuccesslist{}, .paths={KUA/fam1,KUB/fam2}, .define keys={ .ord/{keya,keyb,keyc}/.na/ \def\y##1{#1*##1} \typeout{***}\logsetting , } }, % '.try set keys' works independent of previously declared paths: .try set keys={ .prefixes={KUA,KUB,KUC}, .families={fam1,fam2,fam3,fam4}, .try=8, .upper goal=4, .lower goal=2, .ignore keys={keyb,keyc}, .success list=\mysuccesslist, .kv={keya=vala,keyb=valb,keyc=valc} }, % .exec code={\show\mysuccesslist}, } \dirkeys*{ .exec=\skvtestcnt\z@\def\mysuccesslist{}, .paths={KUA/fam1,KUB/fam2}, .hp=mp@, .ignore keys={keyd}, .define keys={ .initialize keys after define=true, .save initial values of keys, .exec code/\skvtestcnt\z@, % keya has no default but has a complex callback: .ord/keya/.na/{ \skvtestcnt\z@\def\mysuccesslistb{} \dirkeys{ .path={KVX/famx}, .sa set keys={% .prefixes={KUA,KUB}, .families={fam1,fam2}, .try=8, .upper goal=4, .lower goal=1, .success list=\mysuccesslistb, .kv={keyb=valb} }, % .exec code=\show\mysuccesslistb, } } , % No default: .ord/{keyb,keyc,keyd}/.na/\def\x##1{#1*##1}\logsetting, .exec code=\def\cmda#1{\if0#1\fi}, % No callback: .choice/keye/center/{center,left,right}, .choice/keye2/center/{ center.do=\def\giv@c{#1}, left.do=\def\giv@l{#1}, right.do=\def\giv@r{#1} }/.na/\@@warning{Invalid value '\detokenize{#1}' for keye2}, }, .try set keys={% .prefixes={KUA,KUB}, .families={fam1,fam2,fam3,fam4}, .try=1, .upper goal=1, .lower goal=1, .ignore keys={keyc,keyd}, .success list=\mysuccesslist, .kv={keya=vala,keyc=valc,keyd=vald} }, % .exec code={\show\mysuccesslist}, } \makeatother \begin{document} \title{The \texttt{\textcolor{blue}{skeyval}} Package\\[1ex] Version 1.1a\\[1ex] \textsf{Test document 1}} \author{Ahmed Musa} \maketitle %%+++++++++++++++++++ Producing arbitrary texts +++++++++++++++++++++%% \noindent An author writing an article for publication in \textsc{TUGboat} is encouraged to create it on a computer file and submit it on magnetic tape. \par \hfill{\small Barbara Beeton, 1981} \par\bigskip \begin{\mpfalign} \skvxifstrcmpTF\mpfalign{justified}{\noindent}{} \mpftextstyle The printer should refuse to employ wandering men, foreigners who, after having committed some grievous error, can easily disappear and return to their own country. \hfill{\small Hieronymus Hornschuch (1608)}\endgraf \end{\mpfalign} \begingroup \par\bigskip \noindent If you want to find out anything from the theoretical physicists about the methods they use, I advise you to stick closely to one principle: don't listen to their words, fix your mind on their deeds. \ifmpfshowauthor \nobreak \quad\hskip\fill\finalhyphendemerits0\relax \textcolor{red}{\mpfauthor} \fi \endgroup %%++++++++++++++++++++++ Shadow boxes ++++++++++++++++++++++++%% \par\bigskip \begin{center} \hrule \par\bigskip \newshadowbox{test 1} \newshadowbox[framecolor=magenta,shadecolor=cyan,shadowsize=8pt, align=left]{test 2} \newshadowbox[shadow=false,boxwidth=1cm]{test 3} \newshadowbox[framesize=2pt,framecolor=red,shadowcolor=green]{test 4} \newshadowbox[put frame=false,shadow,shadowsize=9pt,shadecolor=yellow, shadowcolor=violet!50,align=right]{test 5} \par\bigskip \hrule \end{center} %%++++++++++++++++++++++++++ Citation ++++++++++++++++++++++++%% \par\bigskip \noindent \newcitation[ author=George Bernard Shaw (1856--1950), show author, leftmargin=0pt, rightmargin=0pt, put frame, framecolor=blue, shadecolor=yellow!25!green!14, frame thickness=1pt, ]{% A man of great common sense and good taste; meaning thereby a man without originality and/or moral courage. } \par\bigskip \noindent \newcitation[ author=George Bernard Shaw (1856--1950), show author, leftmargin=0pt, rightmargin=0pt, put frame=false, framecolor=yellow!30!blue, shadecolor=yellow!25, frame thickness=5pt, width=.8\textwidth, ]{% A man of great common sense and good taste; meaning thereby a man without originality and/or moral courage. } \par\bigskip \noindent \newcitation[ author=Mohammed Ali, show author, leftmargin=0pt, rightmargin=0pt, put frame, framecolor=red!70!green, shadecolor=magenta!5!red!4, frame thickness=10pt, ]{% I always say I was `the greatest'; I have never said I was the smartest. \vgap At home I am a nice, quiet guy, but I don't want the world to know. Humble people, I have found, don't get very far. \vgap To win, you must have the skill and the will. But the will must be stronger than the skill. \vgap I'm the best golfer; I just haven't played it yet. } %++++++++++++++++++ Collecting body of environment +++++++++++++++++++% \bigskip \begin{collectbody}[ title=Example of collect body, title scale=.8, title text style=\ttfamily\color{red} ] \lipsum[1] \end{collectbody} \end{document} %%+++++++++++++++++++++ Examples of \skvmakekeys +++++++++++++++++++%% \skvmakekeys[ .prefix=KVA, .families={fam1,fam2}, .hp=thp@, .all new, .define in all families, .initialize=true ]{% .ord/{keya,keyb}/default-a, .cmd/{keyc,keyd}/.na/\def\y##1{#1**##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}, } %\skvshowcs{KVA/fam2/keyf.@cbk} %\skvshowcs{KVA/fam1/keyb.@defa} \def\keybval{xx} \skvsetkeys[KVA]{fam1}{keyb=.expand once{\keybval}} %%+++++++++++++++++++++ Examples of \skvusekeys +++++++++++++++++++%% \skvmakekeys[ .prefix=KVA, .families={fam1,fam2}, .hp=thp@, .all new ]{% .ord/keya/{default-a}/\def\y##1{##1*#1*##1}, .ord/keyb/defa-b, } \def\keybval{xx} \skvusekeys[ .prefix=KVA, .families={fam1,fam2}, .set in all families, .save unknown keys ]{% keya, keyb=.expand once{\keybval} } % Families fam3 and fam4 aren't defined. Hence, with 'save unknown keys' % set to 'true' by default, keys keya and keyb are saved as rm keys with % their default values. \skvusekeys[ .prefix=KVA, .families={fam3,fam4}, .set in all families, .save unknown keys ]{% keya,keyb=.expand once{\keybval} } %\skvshowcs{KVA/fam3/.@rmkeys} %\skvshowcs{KVA/fam4/.@rmkeys} %%+++++++++++++++ Key values with unbalanced conditionals ++++++++++++%% \skvcmdkey[SKVT]{fam}[mpf]{keya}[keya-defa]{\def\keyaval{#1}} \skvsetkeys[SKVT]{fam}{keya=\fi} %%+++++++++++++++++++++ Examples of \skvkeyslet +++++++++++++++++++%% \skvsaveinitialvaluekeys[KV]{fam}{keya,keyb,keyc} %\skvshowcs{KV/fam/.@needini} \skvmakekeys[ .prefix=KV, .family=fam, .hp=thp@, .all new, .initialize, .save initial values ]{% .ord/keya/defa-a/\def\keyay##1{##1*#1*##1}, .cmd/{keyb,keyc}/defa-b/\def\keyby##1{##1*#1*##1}, .cmd/keyd, } %\skvshowcs{KV/fam/.@inikv} \skvignorekeys[KV]{fam}{keyb,keyc} \skvkeyslet[KV]{fam}{keyA=keya,keyB=keyb,keyC=keyc} \skvshowcs{KV/fam/.@needini} %++++++++++++++++++ Evaluating boolean expressions +++++++++++++++++++% \skvifexprTF{% not ( expr { \skvifdefTF\xa } and expr { \skvifemptyTF\xa } ) or ( expr { \skvifdefTF\xb } or expr { \skvifxTF\xa\xb } ) }{% \def\x{T}% }{% \def\x{F}% } %++++++++++++++++++++++++++++ \cicadaloop +++++++++++++++++++++++++++% \makeatletter \skvtestcnt\z@ \def\blist{{X};\fi;{Y};Z} \def\stack{} \let\romn\romannumeral \cicadaloop{{a},\if,{b},c}\if01\fi{% \advance\skvtestcnt by\@ne \@tempcntb\z@\@tempswafalse \cicadaloop*[;]\blist\if@tempswa\fi{% \advance\@tempcntb by\@ne \typeout{Doing \romn\skvtestcnt, \romn\@tempcntb: \detokenize{#1, ##1}}% \edef\stack{% \unexpanded\expandafter{\stack}\noexpand\do {\romn\skvtestcnt,\romn\@tempcntb}{\unexpanded{#1;##1}}% }% \ifnum\@tempcntb>\tw@\@tempswatrue\fi }% } \makeatother % End of file skeyval-pokayoke1.tex