%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
%                                                                          %
% This is file 'skeycommand.sty', version 0.4.                             %
%                                                                          %
% 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) 2011 Ahmed Musa (a.musa@rocketmail.com).                   %
%                                                                          %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\@ifpackageloaded{catoptions}{%
  \@ifpackagelater{catoptions}{2011/10/22}{}{%
    \@latex@error{Loaded version of catoptions package is
      not current}\@ehc
  }%
}{%
  \RequirePackage{catoptions}[2011/10/22]%
}
\UseNormalCatcodes
\StyleFilePurpose{Create commands and environments with keys (AM)}
\StyleFileRCSInfo
$Id: skeycommand.sty,v 0.4 2011/10/20 09:00:00 Ahmed Musa Exp $
\ProvidesPackage{skeycommand}[\StyleFileInfo]
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\SetStyleFileMessages[skc@]{info}{warn}{err}
\loadifnotloaded{ltxkeys}[2011/10/22]
\newvariables{if}[skc@]{inkey}[false]
\ltxkeys@biboolkeys[SKC]{skeycommand}[skc@]{verbose,silent}[true]{%
  \ifskc@verbose\cpt@verbosetrue\fi
}{%
  \ifskc@silent\cpt@verbosefalse\fi
}
\ltxkeys@declareoption*{\skc@warn{Unknown option '\CurrentOption' ignored}}
\ltxkeys@executeoptions[SKC]<skeycommand>{verbose=false}
\ltxkeys@processoptions*[SKC]<skeycommand>\relax
\robust@def*\skeycommand#1{%
  \ifblankTF{#1}{\ltxkeys@setkeys[SKC]{skeycommand}{#1}}%
}
\robust@def*\skc@testltopt#1#2{\ifnextcharTF<{#1}{#1<{#2}>}}
\robust@def*\skc@testpnopt#1#2{\ifnextcharTF({#1}{#1({#2})}}
\robust@def*\skc@scantoksa#1{%
  \begingroup
  \def\siso@do##1{\catcode`##1\string=12\relax}%
  \siso@@loop{=,;|-+?><}%
  \cptscantokens#1%
  \postgroupdef#1\endgroup
}
\robust@def*\skc@scantoksb{\cpt@testcl\skc@sc@ntoksb}
\robust@def\skc@sc@ntoksb#1{%
  \def\csv@do##1{%
    \cptscantokens{##1}%
    \ifcpt@cl\global\fi\let##1=##1%
  }%
  \csv@@parse[,]{#1}%
}
\robust@def*\skc@definekeys{%
  \begingroup
  \endlinechar\m@one
  \cpt@testopt\skc@d@finekeys{SKC}%
}
\robust@def*\skc@d@finekeys[#1]#2{%
  \cpt@testopt{\expandafter\endgroup\skc@d@f@nekeys{#1}{#2}}{}%
}
\robust@def*\skc@d@f@nekeys#1#2[#3]#4{%
  \begingroup
  \ltxkeys@makepf{#1}%
  \ltxkeys@makehdr{#2}%
  \trim@@space{#1}\skc@keypref
  \trim@@space{#2}\skc@keyfam
  \trim@@space{#3}\skc@macpref
  \toks@{}%
  \def\skc@keyvals{}%
  \def\skc@splita##1={%
    \begingroup
    \defpass\skc@rsvda####1\skc@nil{\endgroup
      \skc@splitb##1/####1/^?/\skc@nil
    }.%
  }%
  \def\skc@splitb##1/##2/##3/##4\skc@nil{%
    \ifblankTF{##1}{%
      \ifblankTF{##2##3}{}{\skc@err{Empty key name}\@ehc}%
    }{%
      \ltxkeys@findpointers{##1}%
      \let\skc@keyname\ltxkeys@tkey
      \ifcsndefTF{\skc@keypref @\skc@keyfam @\skc@keyname}{%
        \skc@err{Key '\skc@keyname' already defined in family
        \MsgBrk '#2' with prefix '#1'}\@ehc
      }{}%
      \ifstrcmpTF{##2}{^?}{%
        \def\skc@keydefault{}%
      }{%
        \simpleexpandarg\trim@@space{\@gobble##2}\skc@keydefault
      }%
      \ifstrcmpTF{##3}{^?}{%
        \def\skc@keycallback{}%
      }{%
        \trim@@space{##3}\skc@keycallback
      }%
      \edef\skc@keyvals{%
        \csliststack,\skc@keyvals\expandcsonce\skc@keyname=%
        \oifstrcmpTF\skc@keydefault{true}{false}{%
          \expandcsonce\skc@keydefault
        }%
      }%
      \def\skc@defkey{\ltxkeys@boolkey}%
      \oifstrcmpTF\skc@keydefault{true}{}{%
        \oifstrcmpTF\skc@keydefault{false}{}{%
          \def\skc@defkey{\ltxkeys@cmdkey}%
        }%
      }%
      \cptpassexpanded{%
        \toks@{\the\toks@
          \skc@defkey[\skc@keypref]{\skc@keyfam}[\skc@macpref]%
          {\skc@keyname}[\expandcsonce\skc@keydefault]%
          {\expandcsonce\skc@keycallback}%
        }%
      }%
    }%
  }%
  \long\def\csv@do##1{%
    \cpt@checkeq##1\cpt@nil{%
      \skc@splita##1\skc@nil
    }{%
      \skc@splitb##1/^?/^?/\skc@nil
    }%
  }%
  \csv@@parse[,]{#4}%
  \cptexpandsecond\endgroup{%
    \the\toks@
    \ifcsnullTF\skc@keyvals{}{\noexpand\ltxkeys@setkeys
      [\skc@keypref]{\skc@keyfam}{\expandcsonce\skc@keyvals}%
    }%
  }%
}
\def\skc@everyeoehook{}
\robust@def*\EveryEndOfKeyEnviron#1{%
  \ifnullTF{#1}{%
    \gdef\skc@everyeoehook{}%
  }{%
    \xdef\skc@everyeoehook{%
      \unexpanded{#1}\expandcsonce\skc@everyeoehook
    }%
  }%
  \begingroup
  \edef\skc@tempa{\string\@ignoretrue}%
  \edef\skc@tempb{\string\ignorespacesafterend}%
  \edef\skc@tempc{%
    \expandafter\strip@prefix\meaning\skc@everyeoehook
  }%
  \oifinsetTF\skc@tempa\skc@tempc{%
    \oifinsetTF\skc@tempb\skc@tempc{%
      \skc@err{Bad '\string\EveryEndOfKeyEnviron'}{%
        You can't have both '\string\@ignoretrue' and
        '\string\ignorespacesafterend' in
        '\string\EveryEndOfKeyEnviron'.}%
    }{%
      \skc@checkbadeoe\@ignoretrue
    }%
  }{%
    \oifinsetFT\skc@tempb\skc@tempc{}{%
      \skc@checkbadeoe\ignorespacesafterend
    }%
  }%
  \endgroup
}
\new@def*\skc@checkbadeoe#1{%
  \begingroup
  \edef\skc@tempa##1{\def##1####1\detokenize{#1}####2\relax}%
  \skc@tempa\skc@tempa{%
    \ifblankTF{##2}{%
      \ifskc@verbose
        \skc@info{Good last token '\detokenize{#1}' in
          '\string\EveryEndOfKeyEnviron'}%
      \fi
    }{%
      \xifinsetTF{\detokenize{#1}}{\detokenize{##2}}{%
        \skc@err{'\detokenize{#1}' repeated in
          '\string\EveryEndOfKeyEnviron'.}{%
          Multiple '\detokenize{#1}' not allowed in
          '\string\EveryEndOfKeyEnviron'.}%
      }{%
        \skc@err{Bad last token in '\string\EveryEndOfKeyEnviron'}%
          {'\detokenize{#1}' not the last token in
          '\string\EveryEndOfKeyEnviron'.}%
      }%
    }%
  }%
  \cptexpandsecond\skc@tempa
    {\expandafter\strip@prefix\meaning\skc@everyeoehook\relax}%
  \endgroup
}
\newletcs\skceveryeoe=\EveryEndOfKeyEnviron
\EveryEndOfKeyEnviron\ignorespacesafterend
\robust@def*\newkeycmd{\cpt@starorlong\skc@keycmd@i}
\robust@def*\csnnewkeycmd{\aftercsname\newkeycmd}
\new@def*\skc@keycmd@i#1{%
  \let\long@or@relax\l@ngrel@x
  \ifescapedTF{#1}{}{%
    \skc@err{Illegal command name:
      \MsgBrk command not escaped}\@ehc
  }%
  \def\skc@cmdname{#1}%
  \edef\skc@currfam{\cptgobblescape{#1}}%
  \edef\skc@macpref{\cptthreexp\@carcube
    \expandafter\@gobble\string#1xxx\@nil @}%
  \skc@scantoksb{\skc@currfam,\skc@macpref}%
  \skc@testltopt\skc@keycmd@ii\skc@macpref
}
\new@def\skc@keycmd@ii<#1>{%
  \cptexpandarg\skc@macprefixerr{#1}%
  \edef\skc@macpref{#1}%
  \skc@testpnopt\skc@keycmd@iii{}%
}
\new@def\skc@keycmd@iii(#1){%
  \ifnullFT{#1}{}\skc@nilkeylisterr
  \cptexpandsecond\skc@definekeys
    {[SKC]{\skc@currfam}[\skc@macpref]}{#1}%
  \cpt@testopt\skc@keycmd@iv{0}%
}
\new@def\skc@keycmd@iv[#1]{%
  \skc@paramnoerr{#1}%
  \cpt@testopt{\skc@keycmd@v#1}{}%
}
\new@def\skc@keycmd@v#1[#2]#3{%
  \skc@inkeytrue
  \skc@keycmd@vi{#1}{#2}{#3}%
  \ifx\long@or@relax\relax
    \def\skc@rsvdb{\newtwooptcmd*}%
  \else
    \let\skc@rsvdb\newtwooptcmd
  \fi
  \skc@rsvda{\expandafter\skc@rsvdb\skc@cmdname}%
  \skc@inkeyfalse
}
\robust@def*\skc@keycmd@vi#1#2#3{%
  \edef\skc@rsvda##1{%
    ##1[\the\numexpr#1+1]\ifblankTF{#2}{}{[\unexpanded{#2}]}{%
      \ltxkeys@setkeys[SKC]{\skc@currfam}{####\the\numexpr#1+1}%
      \unexpanded{#3}%
    }%
  }%
}
\robust@def*\renewkeycmd{\cpt@starorlong\skc@renewkeycmd@i}
\robust@def*\csnrenewkeycmd{\aftercsname\renewkeycmd}
\new@def*\skc@renewkeycmd@i#1{%
  \ifdefTF#1{}{%
    \skc@err{Command '\string#1' undefined}%
      {Undefined command '\string#1' can't be redefined.\MsgBrk
        Use '\string\newkeycmd' instead.}%
  }%
  \let\ifcsdefinable\rc@ifcsdefinable
  \skc@keycmd@i#1%
}
\robust@def*\newkeyenviron{\cpt@starorlong\skc@keyenviron@i}
\robust@def*\csnnewkeyenviron{\aftercsname\newkeyenviron}
\new@def\skc@keyenviron@i#1{%
  \let\long@or@relax\l@ngrel@x
  \ifescapedTF{#1}{%
    \skc@err{Illegal environment name:
      \MsgBrk no escape expected}\@ehc
  }{}%
  \ifcsndefFT{#1}{}{%
    \skc@err{You have submitted an existing macro
      '\string#1' as an\MsgBrk environment name}%
      {'\string#1' not allowed as environment name.}%
  }%
  \edef\skc@currfam{#1}%
  \edef\skc@macpref{\@carcube#1xxx\@nil @}%
  \edef\skc@cmdname{\noexpandcsn{#1}}%
  \skc@testltopt\skc@keyenviron@ii\skc@macpref
}
\new@def\skc@keyenviron@ii<#1>{%
  \cptexpandarg\skc@macprefixerr{#1}%
  \edef\skc@macpref{#1}%
  \skc@testpnopt\skc@keyenviron@iii{}%
}
\new@def\skc@keyenviron@iii(#1){%
  \ifnullFT{#1}{}\skc@nilkeylisterr
  \cptexpandsecond\skc@definekeys
    {[SKC]{\skc@currfam}[\skc@macpref]}{#1}%
  \cpt@testopt\skc@keyenviron@v{0}%
}
\new@def\skc@keyenviron@v[#1]{%
  \skc@paramnoerr{#1}%
  \cpt@testopt{\skc@keyenviron@vi#1}{}%
}
\new@def\skc@keyenviron@vi#1[#2]#3#4{%
  \skc@inkeytrue
  \skc@keycmd@vi{#1}{#2}{#3}%
  \ifx\long@or@relax\relax
    \def\skc@rsvdb{\newtwooptcmd*}%
  \else
    \let\skc@rsvdb\newtwooptcmd
  \fi
  \skc@rsvda{\expandafter\skc@rsvdb\skc@cmdname}%
  \edef\skc@rsvda##1{%
    \long@or@relax\def\noexpandcsn{end\skc@currfam}%
    {##1\expandcsonce\skc@everyeoehook}%
  }%
  \skc@rsvda{#4}%
  \skc@inkeyfalse
}
\robust@def*\renewkeyenviron{\cpt@starorlong\skc@renewkeyenviron@i}
\robust@def*\csnrenewkeyenviron{\aftercsname\renewkeyenviron}
\new@def*\skc@renewkeyenviron@i#1{%
  \ifcsndefTF{#1}{}{%
    \skc@err{Environment '#1' undefined}%
      {Undefined environment '#1' can't be redefined.}%
  }%
  \undefcsn{#1}\undefcsn{end#1}%
  \skc@keyenviron@i{#1}%
}
\robust@def*\newtwooptcmd{\cpt@starorlong\skc@newcommand@i}
\new@def*\skc@newcommand@i#1{%
  \let\long@or@relax\l@ngrel@x
  \cpt@testopt{\skc@newcommand@ii#1}0%
}
\new@def*\skc@newcommand@ii#1[#2]{%
  \cpt@ifbrack{\skc@xargdef#1{#2}}{\skc@argdef#1{#2}}%
}
\new@def\skc@argdef#1#2#3{\ifcsdefinable#1{\skc@yargdef#1{1}{#2}{#3}}}
\new@def\skc@xargdef#1#2[#3]#4{%
  \ifcsdefinable#1{%
    \edef\skc@rsvda##1##2##3{%
      \def##1{##2\noexpandcsn{\string#1}{##3}}%
    }%
    \skc@rsvda#1{\@protected@testopt#1}{#3}%
    \aftercsname\skc@yargdef{\string#1}{2}{#2}{#4}%
  }%
}
\new@def\skc@yargdef#1#2#3{%
  \ifnum#2=2\relax
    \edef\skc@shear##11{[\detokenize{####1}]}%
  \else
    \let\skc@shear\@gobble
  \fi
  \cptexpandarg\skc@yargd@f{\the\numexpr#3}#1%
}
\new@def*\skc@dotparse@a#1{%
  \begingroup
  \toks@{}%
  \def\reserved@f##1.##2\skc@nil{%
    \oifinsetTF{[}{##1}{%
      \toks@\expandafter{\the\toks@##1}%
    }{%
      \toks@\expandafter{\the\toks@{##1}}%
    }%
    \ifnullTF{##2}{}{\reserved@f##2\skc@nil}%
  }%
  \reserved@f#1.\skc@nil
  \edef\reserved@f{\the\toks@}%
  \postgroupdef\reserved@f\endgroup
}
\new@def*\skc@dotparse@b#1{%
  \begingroup
  \toks@{}%
  \def\reserved@f##1.##2\skc@nil{%
    \toks@\expandafter{\the\toks@##1}%
    \ifnullTF{##2}{}{\reserved@f##2\skc@nil}%
  }%
  \reserved@f#1.\skc@nil
  \edef\reserved@f{\the\toks@}%
  \postgroupdef\reserved@f\endgroup
}
\new@def\skc@yargd@f#1#2{%
  \begingroup
  \edef\skc@rsvdb{\detokenize{0####1.####2.####3.####4.####5.%
    ####6.####7.####8.####9.#####1}}%
  \def\skc@rsvda##1#1##2\skc@nil{%
    \def\skc@rsvdb{##1}%
    \def\skc@rsvda####1{%
      \def\skc@rsvda########1####1########2\skc@nil{%
        \ifnullTF{########1}{%
          \edef\skc@tempa{\skc@shear####1########2#1}%
          \let\skc@tempb\skc@tempa
          \let\skc@tempc\skc@tempa
        }{%
          \edef\skc@rsvda{\skc@shear########1####1}%
          \simpleexpandarg\skc@dotparse@a\skc@rsvda
          \let\skc@tempa\reserved@f
          \simpleexpandarg\skc@dotparse@b\skc@rsvda
          \let\skc@tempb\reserved@f
          \edef\skc@rsvda{########2#1}%
          \simpleexpandarg\skc@dotparse@b\skc@rsvda
          \edef\skc@tempc{\skc@tempb(\reserved@f)}%
        }%
      }%
      \expandafter\skc@rsvda\skc@rsvdb\skc@nil
    }%
    \ifnum#1=\z@pt
      \cptemptifycsset{\skc@tempa,\skc@tempb,\skc@tempc}%
    \else
      \simpleexpandarg\skc@rsvda{\the\numexpr#1-1}%
    \fi
  }%
  \expandafter\skc@rsvda\skc@rsvdb\skc@nil
  \skc@scantoksb{\skc@tempa,\skc@tempb,\skc@tempc}%
  \edef\skc@rsvda{\cptgobblescape{#2@skc@}}%
  \let\reserved@e\relax
  \let#2\relax
  \cptpassexpanded{\endgroup
    \def\reserved@e{%
      \long@or@relax
      \def\noexpandcsn\skc@rsvda\expandcsonce\skc@tempc
    }%
    \ifnumcmpTF#1<\tw@{%
      \ifxTF\skc@shear\@gobble{%
        \ifskc@inkey
          \long@or@relax\def#2%
            {\skc@testpnopt\noexpandcsn\skc@rsvda{}}%
          \long@or@relax\def\noexpandcsn\skc@rsvda(\skc@tempc)%
        \else
          \long@or@relax\def#2\skc@tempb
            {\noexpandcsn\skc@rsvda{\skc@tempa}}%
          \reserved@e
        \fi
      }{%
        \long@or@relax\def#2\skc@tempb
          {\noexpandcsn\skc@rsvda\skc@tempa}%
        \reserved@e
      }%
    }{%
      \long@or@relax\def#2\skc@tempb
        {\skc@testpnopt{\noexpandcsn\skc@rsvda\skc@tempa}{}}%
      \reserved@e
    }%
  }%
}
\new@def\skc@reargdef#1[#2]{\skc@yargdef#1{1}{#2}}
\robust@def*\renewtwooptcmd{\cpt@starorlong\skc@renewcommand@i}
\new@def*\skc@renewcommand@i#1{%
  \ifdefTF#1{}{%
    \skc@err{Undefined command '\string#1' can't be
      redefined}\@ehc
  }%
  \let\ifcsdefinable\rc@ifcsdefinable
  \skc@newcommand@i#1%
}
\new@def*\newtwooptenviron{\cpt@starorlong\skc@newenvironment@i}
\new@def*\skc@newenvironment@i#1{%
  \let\long@or@relax\l@ngrel@x
  \cpt@testopt{\skc@newenv@a#1}0%
}
\new@def*\skc@newenv@a#1[#2]{%
  \cpt@ifbrack{\skc@newenv@b#1[#2]}{\skc@newenv{#1}{[#2]}}%
}
\new@def\skc@newenv#1#2#3#4{%
  \ifcsndefTF{#1}{}{\letcsntocsn{#1}{end#1}}%
  \aftercsname\skc@newcommand@i{#1}#2{#3}%
  \long@or@relax\@namedef{end#1}{#4}%
}
\new@def*\skc@newenv@b#1[#2][#3]{\skc@newenv{#1}{[#2][{#3}]}}
\new@def*\renewtwooptenviron{\cpt@starorlong\skc@renewenvironment@i}
\new@def*\skc@renewenvironment@i#1{%
  \ifcsndefTF{#1}{}{%
    \skc@err{Undefined environment '#1' can't be redefined}\@ehc
  }%
  \undefcsn{#1}\undefcsn{end#1}%
  \skc@newenvironment@i{#1}%
}
\robust@def*\skc@nilprefixerr{%
  \skc@err{No macro prefix submitted. The prefix will\MsgBrk
    be used to hold your values for the declared keys}{%
    Keycommand requires macro prefix. I guess you\MsgBrk
    submitted an empty prefix using '<>'. I can use\MsgBrk
    the default macro prefix (the first three\MsgBrk
    letters of your key command) if you don't submit\MsgBrk
    any prefix. In that case leave out '<>' from your\MsgBrk
    command.
  }%
}
\new@def*\skc@ifdigitpresent#1{%
  \begingroup
  \cpt@choicefdfalse
  \def\tsv@do##1{%
    \ifinsetTF{##1}{0123456789}{%
      \cpt@choicefdtrue\cptbreakloop
    }{}%
  }%
  \tsv@@parse{#1}%
  \expandafter\endgroup\ifcpt@choicefd
    \expandafter\@iden\else\expandafter\@gobble\fi
}
\new@def*\skc@macprefixlist{}
\robust@def*\skc@macprefixerr#1{%
  \xifblankTF{#1}{%
    \skc@nilprefixerr
  }{%
    \xifinsetTF{,#1,}{,\skc@macprefixlist,}{%
      \skc@err{Macro prefix '#1' already used,
        \MsgBrk or name '#1' illegal}\@ehc
    }{%
      \edef\skc@macprefixlist{\csliststack,\skc@macprefixlist#1}%
      \skc@ifdigitpresent{#1}{%
        \skc@err{'\string#1' is likely a wrong macro prefix}{%
          I expected letters here, not digits.\MsgBrk
          OK, digits are actually acceptable as macro\MsgBrk
          prefix but you need to be wary of them if they\MsgBrk
          appear in your control sequences. Also, I fear\MsgBrk
          you may have wrongly entered the number of\MsgBrk
          arguments of your key command here, instead\MsgBrk
          of putting it in the right place, ie, in square brackets.
        }%
      }%
    }%
  }%
}
\robust@def*\skc@nilkeylisterr{%
  \skc@err{No key list submitted or wrong command syntax.\MsgBrk
    Please see the user guide.}{Key-commands require keys.
    Perhaps you submitted\MsgBrk an empty key list, or your
    arguments to command\MsgBrk are inconsistent. Please see
    the user guide.\MsgBrk
  }%
}
\new@def*\skc@paramnoerr#1{%
  \ifnum#1<9\relax\else
    \skc@err{Number '\string#1' of parameters too large}{%
      You're limited to 8 parameters here.\MsgBrk
      If necessary, you can use keys to submit\MsgBrk
      more variables. In fact, you can use keys to\MsgBrk
      submit all your variables.
    }%
  \fi
}

\endinput

%%% End of file skeycommand.sty %%%
