%% %% This is file `keycommand.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% keycommand.dtx (with options: `package') %% %% This is a generated file. %% %% keycommand : key-value interface for commands and environments in LaTeX [v3.1415 2010/04/27] %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.3 of this license or (at your option) any later %% version. The latest version of this license is in %% http://www.latex-project.org/lppl.txt %% %% This work consists of the main source file keycommand.dtx %% and the derived files %% keycommand.sty, keycommand.pdf, keycommand.ins, %% keycommand-example.tex %% %% keycommand : an easy way to define commands with optional keys %% Copyright (C) 2009-2010 by Florent Chervet %% \NeedsTeXFormat{LaTeX2e}% LaTeX 2.09 can't be used (nor non-LaTeX) [2005/12/01]% LaTeX must be 2005/12/01 or younger (see kvsetkeys.dtx). \ProvidesPackage{keycommand} [2010/04/27 v3.1415 - key-value interface for commands and environments in LaTeX] \def\kcmd@pkg@name{keycommand} \RequirePackage{etex,kvsetkeys,xkeyval,etoolbox} \protected\def\kcmd@Xsetkeys{\XKV@sttrue\XKV@plfalse\XKV@testoptc\XKV@setkeys}% in case \setkeys \let\kcmd@AtEnd\@empty \def\TMP@EnsureCode#1#2{% \edef\kcmd@AtEnd{% \kcmd@AtEnd \catcode#1 \the\catcode#1\relax }% \catcode#1 #2\relax } \TMP@EnsureCode{32}{10}% space \TMP@EnsureCode{61}{12}% = sign \TMP@EnsureCode{45}{12}% - sign \TMP@EnsureCode{62}{12}% > sign \TMP@EnsureCode{46}{12}% . dot \TMP@EnsureCode{47}{8}% / slash (etextools) \AtEndOfPackage{\kcmd@AtEnd\undef\kcmd@AtEnd} \iffalse%\ifdefined\pdfmatch% use \pdfmatch if present \long\def\kcmd@ifstrdigit#1{\csname @\ifnum\pdfmatch {\detokenize{^[[:space:]]*[[:digit:]][[:space:]]*$}}{\detokenize{#1}}=1 % first\else second\fi oftwo\endcsname} \else% use filter, very efficient ! \def\kcmd@ifstrdigit#1{% \kcmd@nbk#1//% {\expandafter\expandafter\expandafter\kcmd@ifstrdigit@i \expandafter\expandafter\expandafter{\detokenize\expandafter{\number\number0#1}}}% {\@secondoftwo}//% } \def\kcmd@ifstrdigit@i#1{% \def\kcmd@ifstrdigit@ii##1#1##2##3\kcmd@ifstrdigit@ii{% \csname @\ifx##20first\else second\fi oftwo\endcsname }\kcmd@ifstrdigit@ii 00 01 02 03 04 05 06 07 08 09 0#1 \relax\kcmd@ifstrdigit@ii } \fi \def\kcmd@keyfam#1{\detokenize{keycmd->}\expandafter\@gobble\string#1} \def\kcmd@nbk#1#2/#3#4#5//{#4}% \newrobustcmd\kcmd@normalize@setkeys[4]{% \kv@normalize{#4}\toks@{}% \expandafter\kv@parse@normalized\expandafter{\kv@list}{\kcmd@normalize@braces{#2}}% \edef\kv@list{\kcmd@Xsetkeys{\unexpanded{#2}}{\the\toks@}}\kv@list \kcmd@nbk#3//% undeclared keys are assigned to "OtherKeys" {\cslet{#2@#3}\XKV@rm}% (if specified, ie not empty) {\expandafter\kcmd@nbk\XKV@rm//% (otherwise a recoverable error is thown) {\PackageError\kcmd@pkg@name{The key-value pairs :\MessageBreak \XKV@rm\MessageBreak cannot be processed for key-command \string#1\MessageBreak See the definition of the key-command!}{}}{}//}//% } \long\def\kcmd@normalize@braces#1#2#3{% This is kvsetkeys processor for normalizing braces \toks@\expandafter{\the\toks@,#2}% \ifx @\detokenize{#3}@\else \toks@\expandafter{\the\toks@={{{#3}}}}\fi } \def\kcmd@check@typeofkey#1{% expands to \kcmd@check@typeofkey@bool#1bool //% {\kcmd@check@typeofkey@enumst#1enum* //% {\kcmd@check@typeofkey@enum#1enum //% {\kcmd@check@typeofkey@choicest#1choice* //% {\kcmd@check@typeofkey@choice#1choice //% 05//}4//}3//}2//}1//} \def\kcmd@check@typeofkey@bool #1bool #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@bool #1bool #2//{#2} \def\kcmd@check@typeofkey@enumst #1enum* #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@enumst #1enum* #2//{#2} \def\kcmd@check@typeofkey@enum #1enum #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@enum #1enum #2//{#2} \def\kcmd@check@typeofkey@choicest #1choice* #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@choicest #1choice* #2//{#2} \def\kcmd@check@typeofkey@choice #1choice #2//{\kcmd@nbk#1//} \def\kcmd@get@keyname@choice #1choice #2//{#2} \protected\long\def\kcmd@definekey#1#2#3#4#5{% define the keys using xkeyval macros \ifcase\kcmd@check@typeofkey{#4}\relax% standard #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,#4}% \define@cmdkey{#3}[{#3@}]{#4}[{#5}]{}% \or% bool #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@bool#4//}% \kcmd@define@boolkey#1{#3}{\kcmd@get@keyname@bool#4//}{#5}% \or% enum* #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@enumst#4//}% \kcmd@define@choicekey#1*{#3}{\kcmd@get@keyname@enumst#4//}{#5}{\expandonce\val}% \or% enum #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@enum#4//}% \kcmd@define@choicekey#1{}{#3}{\kcmd@get@keyname@enum#4//}{#5}{\expandonce\val}% \or% choice* #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@choicest#4//}% \kcmd@define@choicekey#1*{#3}{\kcmd@get@keyname@choicest#4//}{#5}{\number\nr}% \or% choice #2\csedef{#3.keylist}{\csname#3.keylist\endcsname,\kcmd@get@keyname@choice#4//}% \kcmd@define@choicekey#1{}{#3}{\kcmd@get@keyname@choice#4//}{#5}{\number\nr}% \fi \ifx#2\global\relax #2\csletcs{KV@#3@#4}{KV@#3@#4}% globalize #2\csletcs{KV@#3@#4@default}{KV@#3@#4@default}% globalize default value \fi } \long\def\kcmd@firstchoiceof#1,#2\kcmd@nil{\unexpanded{#1}} \long\def\kcmd@define@choicekey#1#2#3#4#5#6{% \begingroup\edef\kcmd@define@choicekey{\endgroup \noexpand\define@choicekey#2+{#3}{#4} [\noexpand\val\noexpand\nr]% {\unexpanded{#5}}% list of allowed values [{\kcmd@firstchoiceof#5,\kcmd@nil}]% default value {\csedef{#3@#4}{\unexpanded{#6}}}% define key value if in the allowed list {\kcmd@error@handler\noexpand#1{#3}{#4}{\kcmd@firstchoiceof#5,\kcmd@nil}}% error handler }\kcmd@define@choicekey } \def\kcmd@define@boolkey#1#2#3#4{\begingroup \kcmd@nbk#4//{\def\default{#4}}{\def\default{true}}//% \edef\kcmd@define@boolkey{\endgroup \noexpand\define@choicekey*+{#2}{#3}[\noexpand\val\noexpand\nr]% {false,true} [{\unexpanded\expandafter{\default}}]% {\csedef{#2@#3}{\noexpand\number\noexpand\nr}}% {\kcmd@error@handler\noexpand#1{#2}{#3}{\unexpanded\expandafter{\default}}}% }\kcmd@define@boolkey } \protected\long\def\kcmd@error@handler#1#2#3#4{% \PackageError\kcmd@pkg@name{% Value `\val\space' is not allowed in key #3\MessageBreak for key-command \string#1.\MessageBreak I'll use the default value `#4' for this key.\MessageBreak See the definition of the key-command!}{% \csdef{#2@#3}{#4}}} \protected\def\kcmd@undefinekeys#1#2{% #1 = global, #2 = family \ifcsundef{#2.keylist} {\cslet{#2.keylist}\@gobble} {\expandafter\expandafter\expandafter\docsvlist \expandafter\expandafter\expandafter{% \csname #2.keylist\endcsname}% \cslet{#2.keylist}\@gobble}% } \def\kcmd@undefinekey#1#2#3{% #1 = global, #2 = family, #3 = key #1\csundef{KV@#2@#3}% #1\csundef{KV@#2@#3@default}% } \def\kcmd@setdefaults#1{% \ifcsundef{#1.keylist}{} {\expandafter\expandafter\expandafter\docsvlist \expandafter\expandafter\expandafter{% \csname#1.keylist\endcsname}}% } \protected\long\def\kcmd@def#1#2[#3][#4][#5]#6#7{% \ifx#1\kcmd@donot@provide \endgroup \else \@tempswafalse\@ifdefinable#1{\@tempswatrue}% \if@tempswa \edef\kcmd@fam{\kcmd@keyfam{#1}}% \expandafter\kcmd@defcommand\expandafter{\kcmd@fam}#1[{#3}][{#4}][{#5}]{#6}{#2}{#7}% \else\endgroup \fi \fi } \protected\long\def\kcmd@defcommand#1#2[#3][#4][#5]#6#7#8{% \let\commandkey\relax \let\getcommandkey\relax \let#2\relax \cslet{#1}\relax \cslet{#1.commankey}\relax \cslet{#1.getcommandkey}\relax \def\do{\kcmd@undefinekey{\kcmd@gbl}{#1}}% \edef\kcmd@defcommand{\endgroup \kcmd@undefinekeys{\kcmd@gbl}{#1}% undefines all keys for this keycommand family \ifx\kcmd@unexpandchar\@empty\else \kcmd@mount@unexpandchar{#1}{\unexpanded\expandafter{\kcmd@unexpandchar}}% \fi \unexpanded{\kv@parse{#3,#4}}{\kcmd@definekey\noexpand#2{\kcmd@gbl}{#1}}% defines keys \csdef{#1.commandkey}####1{\noexpand\csname#1@####1\endcsname}% \csdef{#1.getcommandkey}####1{% \unexpanded{\unexpanded\expandafter\expandafter\expandafter}{% \noexpand\csname#1@####1\endcsname}}% \kcmd@ifplus% \newkeycommand+ / \newkeyenvironment+ \protected\csdef{#1}{% \kcmd@yargedef{\kcmd@gbl}{\kcmd@long}\csname#1\endcsname {\number#5}{\noexpand#7}{\csname#1.unexpandchar\endcsname}}% \ifx#7\@gobble\else \protected\def#7{\kcmd@yargedef#7}% \fi \else% \newkeycommand / \newkeyenvironment \csdef{#1}{% \kcmd@yargdef{\kcmd@gbl}{\kcmd@long}\csname#1\endcsname {\number#5}{\noexpand#7}}% \ifx#7\@gobble\else \def#7####1{% that means we have to define a key-environment \def#7{% \let\getcommandkey\csname#1.getcommandkey\endcsname \let\commandkey\csname#1.commandkey\endcsname ####1}% }% \fi \fi \def\noexpand\do####1{\unexpanded{\expandafter\noexpand\csname}KV@#1@####1@default% \endcsname}% \let\commandkey\relax \let\getcommandkey\relax \let#2\relax \kcmd@gbl\protected\edef#2{% entry point \let\getcommandkey\noexpand\noexpand\csname#1.getcommandkey\endcsname \kcmd@ifplus \let\commandkey\getcommandkey \else \let\commandkey\noexpand\noexpand\csname#1.commandkey\endcsname \fi \noexpand\kcmd@setdefaults{#1}% \ifx#7\@gobble \noexpand\noexpand\noexpand\@testopt {\kcmd@setkeys#2{#1}{\kcmd@otherkey{#4}}}{}% \else \noexpand\noexpand\noexpand\@testopt {\kcmd@setkeys#2{#1}{\kcmd@otherkey{#4}}}{}% \fi }% \csname#1\endcsname% expand \kcmd@yargedef or \kcmd@yargdef }\kcmd@defcommand{#6}{#8}% #6 = definition, #8 = definition end-envir } \protected\long\def\kcmd@setkeys#1#2#3[#4]{% #1=key-command, #2=family, #3=otherkey, #4=key=value pairs \kcmd@normalize@setkeys{#1}{#2}{#3}{#4}\csname#2\endcsname } \long\def\kcmd@otherkey#1{\kcmd@nbk#1//{\kcmd@otherkey@name#1=\kcmd@nil}{}//} \long\def\kcmd@otherkey@name#1=#2\kcmd@nil{#1} \protected \def \kcmd@mount@unexpandchar#1#2{% \protected\csdef{#1.unexpandchar}{\begingroup \catcode`\~\active \lccode`\~`#2 \lccode`#2 0\relax \lowercase{% \expandafter\endgroup\expandafter\def\expandafter~{% \catcode`#2\active \long\def~########1~{\unexpanded{########1}}}% ~}% }% } \protected \def \kcmd@yargdef #1#2#3#4#5{\begingroup \def \kcmd@yargd@f ##1#4##2##{\afterassignment#5\endgroup #1#2\expandafter\def\expandafter#3\@gobble ##1#4% }\kcmd@yargd@f 0##1##2##3##4##5##6##7##8##9###4% } \protected \def \kcmd@yargedef#1#2#3#4#5#6{\begingroup \kcmd@nargs{#4}% \protected\long\def\kcmd@yarg@edef##1##2{\endgroup #1\edef#3{\begingroup #6% #2\edef#3\unexpanded{##2}{\endgroup\unexpanded{##1}% }#3}% }% \protected\def\kcmd@envir##1{% \edef\next{\kcmd@yarg@edef{\def\noexpand#5{\expandonce{#5##1}}\expandonce{#3##1}}}\next }% \protected\def\kcmd@command##1{% \edef\next{\kcmd@yarg@edef{\expandonce{#3##1}}}\next }% \protected\def\kcmd@yargedef##1{% \kcmd@yargedef@##1 0####1####2####3####4####5####6####7####8####9#####4% }% \ifx#5\@gobble % keycommand \def\next{\kcmd@command}% \else % key-environmment \def\next{\kcmd@envir}% \fi \let\@next\relax \def\kcmd@yargedef@##1##2#4##3##{% \ifx\@next\relax \edef\@next{\next{\expandonce{\kcmd@nargs}}{\expandonce{\@gobble##2#4}}}% \ifx#5\@gobble \edef\@next{\expandonce\@next\noexpand#5}% \else \edef\@next{\edef\noexpand\@next{\noexpand\unexpanded{\expandonce\@next}}#5}% \fi \fi \afterassignment\@next \expandafter\def\expandafter##1\@gobble##2#4% }% \kcmd@yargedef#3% } \def\kcmd@nargs#1{\edef\kcmd@nargs%##1##2##3##4##5##6##7##8##9% {\ifnum#1>0{####1% \ifnum#1>1}{####2% \ifnum#1>2}{####3% \ifnum#1>3}{####4% \ifnum#1>4}{####5% \ifnum#1>5}{####6% \ifnum#1>6}{####7% \ifnum#1>7}{####8% \ifnum#1>8}{####9% \fi\fi\fi\fi\fi\fi\fi\fi}\fi}% }% \newrobustcmd*\newkeycommand{\begingroup \let\kcmd@gbl\@empty\kcmd@star@or@long\new@keycommand} \newrobustcmd*\renewkeycommand{\begingroup \let\kcmd@gbl\@empty\kcmd@star@or@long\renew@keycommand} \newrobustcmd*\providekeycommand{\begingroup \let\kcmd@gbl\@empty\kcmd@star@or@long\provide@keycommand} \def\kcmd@star@or@long#1{\@ifstar {\let\kcmd@long\@empty\kcmd@plus#1} {\def\kcmd@long{\long}\kcmd@plus#1}} \def\kcmd@@ifplus#1{\@ifnextchar +{\@firstoftwo{#1}}}% same as LaTeX's \@ifstar \def\kcmd@plus#1{\kcmd@@ifplus {\def\kcmd@ifplus{\iftrue}\kcmd@testopt#1} {\def\kcmd@ifplus{\iffalse}\kcmd@testopt#1}} \def\kcmd@testopt#1{\@testopt{\kcmd@unexpandchar#1}{}} \def\kcmd@unexpandchar#1[#2]{% \kcmd@ifplus \kcmd@nbk#2// {\def\kcmd@unexpandchar{#2}% only once inside group... \def\kcmd@unexpandchar@activate{\catcode`#2 \active}% }{% \let\kcmd@unexpandchar\@empty \let\kcmd@unexpandchar@activate\relax }//% \else \let\kcmd@unexpandchar\@empty \kcmd@nbk#2//% {\PackageError\kcmd@pkg@name{shortcut option for \string\unexpanded\MessageBreak You can't use a shortcut option for \string\unexpanded\MessageBreak without the \string+ form of \string\newkeycommand!}% {I will ignore this option and proceed.}% }% {}//% \fi#1} \def\new@keycommand#1{\@testopt{\@newkeycommand#1}0} \long\def\@newkeycommand#1[#2]{% #2 = key=values or N=mandatory args \kcmd@ifplus \kcmd@unexpandchar@activate \fi% activates unexpand-char before reading definition \kcmd@ifstrdigit{#2}% {\@new@key@command#1[][][{#2}]}% no kv, no optkey, number of args {\@testopt{\@new@keycommand#1[{#2}]}0}}% kv, check for optkey/nr of args \long\def\@new@keycommand#1[#2][#3]{% \kcmd@ifstrdigit{#3}% {\@new@key@command#1[{#2}][][{#3}]}% no optkey {\@testopt{\@new@key@command#1[{#2}][{#3}]}0}} \long\def\@new@key@command#1[#2][#3][#4]#5{% \kcmd@def#1\@gobble[{#2}][{#3}][{#4}]{#5}{}} \def\renew@keycommand#1{\begingroup \escapechar\m@ne\edef\@gtempa{{\string#1}}% \expandafter\@ifundefined\@gtempa {\endgroup\@latex@error{\noexpand#1undefined}\@ehc} \endgroup \let\@ifdefinable\@rc@ifdefinable \new@keycommand#1% } \def\provide@keycommand#1{\begingroup \escapechar\m@ne\edef\@gtempa{{\string#1}}% \expandafter\@ifundefined\@gtempa {\endgroup\new@keycommand#1} {\endgroup\def\kcmd@donot@provide{\renew@keycommand\kcmd@donot@provide }\kcmd@donot@provide}% } \let\kcmd@donot@provide\@empty% it must not be undefined \newrobustcmd*\newkeyenvironment{\begingroup \let\kcmd@gbl\@empty\kcmd@star@or@long\new@keyenvironment} \newrobustcmd\renewkeyenvironment{\begingroup \let\kcmd@gbl\@empty\kcmd@star@or@long\renew@keyenvironment} \def\new@keyenvironment#1{\@testopt{\@newkeyenva{#1}}{}} \long\def\@newkeyenva#1[#2]{% \kcmd@ifstrdigit{#2}% {\@newkeyenv{#1}{[][][{#2}]}} {\@testopt{\@newkeyenvb{#1}[{#2}]}{}}} \long\def\@newkeyenvb#1[#2][#3]{% \kcmd@ifstrdigit{#3}% {\@newkeyenv{#1}{[{#2}][][{#3}]}} {\@testopt{\@newkeyenvc{#1}{[{#2}][{#3}]}}0}} \long\def\@newkeyenvc#1#2[#3]{\@newkeyenv{#1}{#2[{#3}]}} \long\def\@newkeyenv#1#2{% \kcmd@ifplus \kcmd@unexpandchar@activate \fi \kcmd@keyenvir@def{#1}{#2}% } \long\def\kcmd@keyenvir@def#1#2#3#4{% \expandafter\let\csname end#1\endcsname\relax \expandafter\kcmd@def\csname #1\expandafter\endcsname\csname end#1\endcsname#2{#3}{#4}% } \def\renew@keyenvironment#1{% \@ifundefined{#1}% {\@latex@error{Environment #1 undefined}\@ehc }\relax \cslet{#1}\relax \new@keyenvironment{#1}} \newcommand*\ifcommandkey[1]{\csname @\expandafter\expandafter\expandafter \kcmd@nbk\commandkey{#1}//{first}{second}//% oftwo\endcsname} \newrobustcmd*\showcommandkeys[1]{\let\do\showcommandkey\docsvlist{#1}} \newrobustcmd*\showcommandkey[1]{key \string"#1\string" = % \detokenize\expandafter\expandafter\expandafter{\commandkey{#1}}\par} \endinput %% %% End of file `keycommand.sty'.