%+++++++++++++++++++++++++++++++++++++ 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]{parser,keyprefix,keyfamily,macroprefix} \ProcessOptionsX*[KV]\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#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 %%%