%+++++++++++++++++++++++++++++++++++++ LICENSE ++++++++++++++++++++++++++++++++++++++%
%                                                                                    %
% This is file 'keyreader.sty', version 0.2.                                         %
%                                                                                    %
% This package reads multiple keys to be defined by xkeyval.sty.                     %
%                                                                                    %
% 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) 2010 Ahmed Musa (a.musa@rocketmail.com).                             %
%                                                                                    %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\begingroup
\catcode064 11% @
\catcode123 01% {
\catcode125 02% }
\def\x{\endgroup
  \edef\kr@restorecodes{%
    \catcode035 \the\catcode035% #
    \catcode064 \the\catcode064% @
    \catcode123 \the\catcode123% {
    \catcode125 \the\catcode125% }
    \catcode061 \the\catcode061% =
  }%
}
\x
\@makeother{\=}%
\catcode035=06% #
\catcode064=11% @
\catcode123=01% {
\catcode125=02% }
\def\kr@ensurecode#1#2{%
  \edef\kr@restorecodes{%
    \kr@restorecodes
    \catcode#1=\the\catcode#1\relax
  }%
  \catcode#1=#2\relax
}
\AtEndOfPackage{\kr@restorecodes}
\kr@ensurecode{044}{12}% ,
\kr@ensurecode{058}{12}% :
\kr@ensurecode{059}{12}% ;
\kr@ensurecode{038}{03}% &
\ProvidesPackage{keyreader}%
  [2010/01/13 v0.2 Read multiple keys for the xkeyval parser (AM)]
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\@ifpackageloaded{xkeyval}{}{\RequirePackage{xkeyval}[2008/08/13]}
\protected\long\def\kr@warn#1{\PackageWarningNoLine{keyreader}{#1}}
\protected\long\def\kr@err#1{\PackageError{keyreader}{#1}{\@ehc}}
\protected\long\def\kr@afterfi#1\fi{\fi#1}
\def\kr@CommandListParser#1{%
  \long\def\kr@define@keylist##1##2{%
    \mathchardef\kr@tempcntb=\z@
    ##1\kr@readlist##2#1&
  }%
  \long\def\kr@readlist##1#1##2&{%
    \kr@ifblank{##1}{}%
    {%
      \edef\@i{\detokenize{##1}}%
      \edef\@ii{\detokenize{\stopread}}%
      \ifx\@i\@ii
        \mathchardef\kr@tempcntb=\@ne
        \stopread##2&
      \else
        \kr@define@key##1&
      \fi
    }%
    \ifnum\kr@tempcntb=\z@
      \kr@ifblank{##2}{}{\kr@readlist##2&}%
    \fi
  }%
}
\define@cmdkey[KV]{keyreader}[kr@]{parser}[;]{%
  \if\kr@parser,\kr@afterfi\kr@err{Parser can't be comma}\fi
  \kr@CommandListParser{#1}%
}
\define@cmdkey[KV]{keyreader}[kr@]{keyprefix}[KV]{}
\define@cmdkey[KV]{keyreader}[kr@]{keyfamily}[fam]{}
\define@cmdkey[KV]{keyreader}[kr@]{macroprefix}[mp@]{}
\define@boolkey[KV]{keyreader}[kr@]{xchoicelist}[true]{}
\DeclareOptionX*{\kr@warn{Unknown option '\CurrentOption' ignored}}
\ExecuteOptionsX[KV]<keyreader>{parser,keyprefix,keyfamily,macroprefix}
\ProcessOptionsX*[KV]<keyreader>\relax
\newcommand\krsetup[1]{\setkeys[KV]{keyreader}{#1}}
\def\kr@defcommand#1#2{%
  \ifcsname#2\endcsname
    \expandafter\ifx\csname#2\endcsname\relax\else
      \def\reserved@a{#2}%
      \expandafter\expandafter\expandafter\@notdefinable
    \fi
  \else
    \expandafter#1\csname#2\expandafter\endcsname
  \fi
}
\def\kr@namedef#1{\kr@defcommand\def{#1}}
\def\kr@nameedef#1{\kr@defcommand\edef{#1}}
\def\kr@nameuse#1{\ifcsname#1\endcsname\csname#1\expandafter\endcsname\fi}
\def\kr@ifnameundef#1{%
  \ifcsname#1\endcsname
    \expandafter\ifx\csname#1\endcsname\relax
      \expandafter\expandafter\expandafter\@firstoftwo
    \else
      \expandafter\expandafter\expandafter\@secondoftwo
    \fi
  \else
    \expandafter\@firstoftwo
  \fi
}
\long\def\kr@ifnextchar#1#2#3{% \new@ifnextchar
  \let\tmp@d=#1\def\tmp@a{#2}\def\tmp@b{#3}%
  \futurelet\@let@token\kr@ifnch
}
\long\def\kr@ifnch{\ifx\@let@token\tmp@d\let\tmp@b\tmp@a\fi\tmp@b}
\long\def\kr@testopt#1#2{\kr@ifnextchar[{#1}{#1[{#2}]}}
\long\def\kr@ifstar#1#2{\kr@ifnextchar*{\def\tmp@a*{#1}\tmp@a}{#2}}
\long\def\kr@ifblank#1{\kr@ifbl@nk#1&&\@secondoftwo\@firstoftwo:}
\long\def\kr@ifbl@nk#1#2&#3#4#5:{#4}
\long\def\kr@expandonce#1{\unexpanded\expandafter{#1}}
\long\def\kr@csexpandonce#1{\expandafter\kr@expandonce\csname#1\endcsname}
\@ifdefinable\stopread{\long\def\stopread#1&{\long\def\kr@remainder{#1}}}
\long\def\kr@inputerr#1#2{\kr@err{Erroneous value '#1' for key '#2'}}
\mathchardef\kr@tempcnta=\z@\mathchardef\kr@tempcntb=\z@
\mathchardef\kr@tempcntc=\z@
\protected\long\def\define@keylist{%
  \kr@ifstar{\kr@define@keylist\expandafter}{\kr@define@keylist\@firstofone}%
}
\def\ChoiceKeyValues#1#2{%
  \ifkr@xchoicelist
    \expandafter\edef\csname kr@altlist@\kr@keyfamily @#1\endcsname{#2}%
  \else
    \kr@ifnameundef{kr@altlist@\kr@keyfamily @#1}{%
      \kr@nameedef{kr@altlist@\kr@keyfamily @#1}{#2}%
    }{%
      \kr@err{You have attempted to set two \MessageBreak
        \string\ChoiceKeyValues\space for the same choice key,\MessageBreak
        in the same family}%
    }%
  \fi
}
\@ifdefinable\CKVS{\global\let\CKVS\ChoiceKeyValues}
\def\kr@define@key#1,#2,#3,#4&{%
  \begingroup
  \protected@edef\x{\endgroup
    \ifcase#1\relax
      \mathchardef\kr@tempcntc=\@ne
    \or
      \noexpand\define@key[\kr@keyprefix]{\kr@keyfamily}%
        {#2}[#3]{\kr@expandonce{#4}}%
    \or
      \noexpand\define@cmdkey[\kr@keyprefix]{\kr@keyfamily}%
        [\kr@macroprefix]{#2}[#3]{\kr@expandonce{#4}}%
    \or
      \noexpand\define@boolkey+[\kr@keyprefix]{\kr@keyfamily}%
        [\kr@macroprefix]{#2}[#3]{\kr@expandonce{#4}}%
        {\unexpanded{\kr@inputerr{##1}{#2}}}%
    \or
      \kr@ifnameundef{kr@altlist@\kr@keyfamily @#2}{\mathchardef\kr@tempcnta=\@ne}{}
      \noexpand\define@choicekey*+[\kr@keyprefix]{\kr@keyfamily}{#2}%
        [\unexpanded{\val\nr}]{\kr@nameuse{kr@altlist@\kr@keyfamily @#2}}[#3]%
        {\kr@expandonce{#4}}{\unexpanded{\kr@inputerr{##1}{#2}}}%
    \else
      \mathchardef\kr@tempcntc=\@ne
    \fi
  }\x
  \ifnum\kr@tempcnta=\@ne\kr@afterfi
    \kr@err{%
      Alternate key values list for '#2' is empty:
      \MessageBreak choicekey can't be defined.
      \MessageBreak You need to first define admissible
      \MessageBreak key values through '\string\ChoiceKeyValues'
      \MessageBreak for choice key '#2'
    }%
  \fi
  \ifnum\kr@tempcntc=\@ne\kr@afterfi
    \kr@err{Unknown key type/identifier '#1'}%
  \fi
}
\def\define@comp@boolkeys{\kr@testopt{\kr@comp@opta}{KV}}
\def\kr@comp@opta[#1]#2{\kr@testopt{\kr@define@comp@boolkeys[#1]{#2}}{mp@}}
\def\kr@define@comp@boolkeys[#1]#2[#3]#4[#5]#6#7#8{%
  \kr@namedef{comp@#2@#4}{\kr@nameuse{if#3#4}\kr@nameuse{#3#6false}\fi}%
  \kr@namedef{comp@#2@#6}{\kr@nameuse{if#3#6}\kr@nameuse{#3#4false}\fi}%
  \kr@namedef{func@#2@#4}{#7}%
  \kr@namedef{func@#2@#6}{#8}%
  \begingroup\protected@edef\x{\endgroup
    \unexpanded{\define@boolkey+[#1]{#2}[#3]{#4}[#5]{%
      \kr@nameuse{comp@#2@#4}\kr@nameuse{func@#2@#4}}%
      {\kr@inputerr{##1}{#4}}%
    }%
    \unexpanded{\define@boolkey+[#1]{#2}[#3]{#6}[#5]{%
      \kr@nameuse{comp@#2@#6}\kr@nameuse{func@#2@#6}}%
      {\kr@inputerr{##1}{#6}}%
    }%
  }\x
}
\def\disabledkeyerr{%
  \kr@err{Key '\disabledkey' has been disabled.\MessageBreak
  You can't set or reset it at this late stage.\MessageBreak
  You should have set it earlier in the\MessageBreak
  \string\documentclass\space or \string\usepackage}%
}
\def\krdisable@keys{\XKV@testoptb\kr@dis@ble@keys}
\long\def\kr@dis@ble@keys#1{%
  \XKV@checksanitizeb{#1}\kr@tempa
  \XKV@for@o\kr@tempa\kr@tempa{%
    \XKV@ifundefined{\XKV@header\kr@tempa}{%
      \kr@warn{Key '\kr@tempa' undefined: can't be disabled}%
    }{%
      \global\let\disabledkey\kr@tempa
    }%
    \XKV@ifundefined{\XKV@header\kr@tempa @default}{%
      \edef\kr@tempc{\noexpand\XKV@define@key{\kr@tempa}}%
    }{%
      \edef\kr@tempc{\noexpand\XKV@define@key{\kr@tempa}[]}%
    }%
    \expandafter\kr@tempc\expandafter{\disabledkeyerr}%
  }%
}

\endinput

%%% End of file keyreader.sty %%%