%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
%                                                                          %
% This is file 'keyval2e.sty', version 0.0.1, July 2011                    %
%                                                                          %
% 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}{}{\RequirePackage{catoptions}[2011/07/20]}
\UseNormalCatcodes
\StyleFilePurpose{Lightweight and robust key-value parser (AM)}
\StyleFileRCSInfo
$Id: keyval2e.sty,v 0.0.1 2011/08/11 09:00:00 Ahmed Musa Exp $
\ProvidesPackage{keyval2e}[\StyleFileInfo]
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\SetStyleFileMessages[kve@]{info}{warn}{err}
\robust@def*\kve@parse{\cpt@teststopt\kve@parse@a,}
\robust@def*\kve@parse@a[#1]#2#3{%
  \cpt@stchoose{cpt@st}{#2}\reserved@e\kve@parse
  \ifx\@empty\reserved@e\begingroup\cpt@defrelax\fi
  \pushfunctions\kve@parse
    {\ifloopbreak,\kve@do,\kve@act}\cpt@csvdepth
  \cpt@sttrue\cpt@csvnormalize[#1]\reserved@e
  \def\kve@act##1{#3}%
  \def\kve@do##1#1{%
    \edef\reserved@a{\unexpanded\expandafter{\@gobble##1}}%
    \ifxTF\reserved@a\cpt@nnil{}{%
      \expandafter\kve@act\expandafter{\reserved@a}\relax
      \@nameuse{@\ifloopbreak second\else first\fi oftwo}%
      {\kve@do.}{\gobble@to@sentinel\cpt@nil#1}%
    }%
  }%
  \loopbreakfalse
  \expandafter\kve@do\expandafter.\reserved@e#1\cpt@nil#1%
  \popfunctions\kve@parse\cpt@csvdepth\cpt@relax
}
% \kve@definekeys[<pref>]{<fam>}[<mp>]{keya/defa/callback,...}
\robust@def*\kve@definekeys{%
  \begingroup\endlinechar\m@one
  \cpt@teststopt\kve@d@finekeys{KV}%
}
\newletcs\kve@definekey\kve@definekeys
\robust@def*\kve@d@finekeys[#1]#2{%
  \cpt@testopt{\kve@d@f@nekeys{#1}{#2}}{kvmp@}%
}
\robust@def*\kve@d@f@nekeys#1#2[#3]#4{%
  \gletcs\ifcpt@defkeyst\ifcpt@st
  \endgroup
  \ifx\noindent#4\noindent\begingroup\cpt@defrelax\fi
  \def\kve@d@f@n@keys##1{%
    \ifcpt@defkeyst
      \newcsndef*{#1@#2@\currkey}####1{%
        \newcsndef*{#3\currkey}{####1}##1\relax
      }%
    \else
      \csndef{#1@#2@\currkey}####1{%
        \csndef{#3\currkey}{####1}##1\relax
      }%
    \fi
  }%
  \csndef{#1@#2@initialkeyvals}{}%
  \def\kve@splita##1/{\def\currkey{##1}\kve@splitb.}%
  \def\kve@splitb##1/##2/##3\kve@nil{%
    \edef\currval{\unexpanded\expandafter{\@gobble##1}}%
    \csnedef{#1@#2@\currkey @default}{%
      \cptmakecs{#1@#2@\currkey}{\expandcsonce\currval}%
    }%
    \kve@d@f@n@keys{##2}%
    \letcstocsn\kve@tempa{#1@#2@initialkeyvals}%
    \csnedef{#1@#2@initialkeyvals}{%
      \cptliststack,\kve@tempa\currkey=%
      \oifstrcmpTF\currval{true}{false}{\expandcsonce\currval}%
    }%
  }%
  \kve@parse{#4}{\kve@splita##1///\kve@nil}%
  \kve@setdefaults[#1]{#2}[]\cpt@relax
}
% \kve@setkeys[pref]{<fam>}[na]{<keyval>}
\robust@def*\kve@setkeys{\cpt@testopt\kve@setkeys@a{KV}}
\robust@def*\kve@setkeys@a[#1]#2{\cpt@testopt{\kve@setkeys@b{#1}{#2}}{}}
\robust@def*\kve@setkeys@b#1#2[#3]#4{%
  \ifx\noindent#4\noindent\begingroup\cpt@defrelax\fi
  \pushfunctions\kve@setkeys{\currpref,\currfam,\currkey,%
    \currval,\currkeyval}\kve@keydepth
  \def\currpref{#1}\def\currfam{#2}%
  \edef\kve@na{\cptcommanormalize{#3}}%
  \def\kve@splita##1={\def\currkey{##1}\kve@splitb.}%
  \def\kve@splitb##1=##2\kve@nil{%
    \edef\currval{\unexpanded\expandafter{\@gobble##1}}%
    \edef\currkeyval{\expandcsonce\currkey=\expandcsonce\currval}%
    \xifinsetTF{,\cptoxdetok\currkey,}{,\cptoxdetok\kve@na,}
      {}
      {\kve@setkeys@c{#1}{#2}}%
  }%
  \cpt@stfalse\cpt@kvnormalize[,]{#4}%
  \kve@parse*\normalized@list{\kve@splita##1==\kve@nil}%
  \popfunctions\kve@setkeys\kve@keydepth
  \cpt@relax
}
\robust@def*\kve@setkeys@c#1#2{%
  \ifcsndefTF{#1@#2@\currkey}{%
    \ifcsemptyTF\currval{%
      \begingroup
      \csndef{#1@#2@\currkey}##1{\toks@{\def\currval{##1}}}%
      \csname#1@#2@\currkey @default\endcsname
      \expandafter\endgroup\the\toks@
    }{}%
    \csname#1@#2@\currkey\expandafter
      \endcsname\expandafter{\currval}\relax
  }{%
    \kve@err{Key '\currkey' not defined}
      {Key '\currpref,\currfam,\currkey' is undefined}%
  }%
}
\robust@def*\kve@getkeynames#1{%
  \def\kve@keynames{}%
  \ifblankTF{#1}{}{%
    \begingroup
    \cpt@stfalse\cpt@kvnormalize[,]{#1}%
    \def\kve@g@tkeynames##1=##2\kve@nil{%
      \edef\kve@keynames{%
        \cptliststack,\kve@keynames\cpttrimspaces{##1}%
      }%
    }%
    \kve@parse*\normalized@list{\kve@g@tkeynames##1=\kve@nil}%
    \postgroupdef\kve@keynames\endgroup
  }%
}
% \kve@setdefaults[<pref>]{<fam>}[<na>]
\robust@def*\kve@setdefaults{\cpt@testopt\kve@s@tdefaults{KV}}
\newletcs\kve@setwithdefaults\kve@setdefaults
\robust@def*\kve@s@tdefaults[#1]#2{%
  \cpt@testopt{\kve@s@td@faults{#1}{#2}}{}%
}
\robust@def*\kve@s@td@faults#1#2[#3]{%
  \ifcsndefTF{#1@#2@initialkeyvals}{%
    \cptexpanded{%
      \kve@setkeys[#1]{#2}[#3]
        {\expandcsnonce{#1@#2@initialkeyvals}}%
    }%
  }{%
    \kve@err{No initial key values for family '#2'}
      {No initial key-value pairs saved for '#1,#2'.}%
  }%
}
% \kve@setafterdefaults[<pref>]{<fam>}[<na>]{<curr-keyval>}
\robust@def*\kve@setafterdefaults{%
  \cpt@testopt\kve@s@tafterdefaults{KV}%
}
\robust@def*\kve@s@tafterdefaults[#1]#2{%
  \cpt@testopt{\kve@s@taft@rdefaults{#1}{#2}}{}%
}
\robust@def*\kve@s@taft@rdefaults#1#2[#3]#4{%
  \ifx\noindent#4\noindent\begingroup\cpt@defrelax\fi
  \kve@getkeynames{#4}%
  \letcstocsn\kve@tempa{#1@#2@initialkeyvals}%
  \ifdefTF\kve@tempa{%
    \cptexpanded{%
      \kve@setkeys[#1]{#2}[\kve@keynames,#3]
        {\expandcsonce\kve@tempa}%
      \kve@setkeys[#1]{#2}[#3]{\unexpanded{#4}}%
    }%
  }{%
    \kve@err{No initial key values for family '#2'}
      {No initial key-value pairs saved for '#1,#2'.}%
  }%
  \cpt@relax
}
\robust@def*\kve@keyvalerr{%
  \kve@getinnoval*[10]\currval
  \kve@err{Invalid value '\innoval' for key '\currkey'}
    {Key '\currkey' has an inadmissible value '\innoval'.}%
}
\robust@def*\kve@getinnoval{\cpt@teststopt\kve@g@tinnoval{10}}
\robust@def*\kve@g@tinnoval[#1]#2{%
  \begingroup
  \def\innoval{}\@tempcnta\z@pt
  \def\siso@do##1{%
    \advance\@tempcnta by1
    \ifnum\@tempcnta<#1\relax\edef\innoval{\innoval##1}\fi
  }%
  \cptexpandarg\siso@@loop
    {\if@boolTF{cpt@st}\cptoxdetok\detokenize{#2}}%
  \edef\innoval{\innoval\ifnum\@tempcnta>#1\string\ETC\fi}%
  \postgroupdef\innoval\endgroup
}
\robust@def*\kve@checkbool#1#2#3{%
  \lowercase{\xifinsetTF{,\cpttrimspaces{#1},}}
    {,true,false,}{#2}{#3}%
}
\robust@def*\kve@checkchoice#1#2#3{%
  \expandafter\cptswapfirstbraced\expandafter
  {\romannumeral-`\q\cpttrimspace{#1}}
  {\kve@ch@ckchoice#2,\cpt@mil:\cpt@mil,\cpt@nil}{#3}%
}
\robust@def*\kve@ch@ckchoice#1:#2,#3\cpt@nil#4#5{%
  \ifblankTF{#3}{\unexpanded{#5}}{%
    \xifstrcmpTF{\cpttrimspaces{#1}}{\unexpanded{#4}}{%
      \unexpanded{#2}%
    }{%
      \kve@ch@ckchoice#3\cpt@nil{#4}{#5}%
    }%
  }%
}

\endinput