%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% % % % This is file 'pgfkeyx.sty', version 0.0.1, April 2012. % % % % 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) 2012 Ahmed Musa (amusa22@gmail.com). % % % %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% \begingroup \catcode064 11 % @ \catcode123 01 % { \catcode125 02 % } \catcode044 12 % , \def\reserved@a{\endgroup \def\do##1,{% \ifx##1\do\else \catcode##1\string=\the\catcode##1 % \expandafter\do \fi }% \edef\pgfkeys@restorecodes{\do035,064,123,125,061,059,\do,}% } \reserved@a \catcode035 06 % # \catcode064 11 % @ \catcode123 01 % { \catcode125 02 % } \catcode061 12 % = \catcode044 12 % , \def\do#1=#2,{% \ifx#1\do\else \edef\pgfkeys@restorecodes{% \pgfkeys@restorecodes \catcode#1=\the\catcode#1 % }% \catcode#1=#2\relax \expandafter\do \fi } \do 032=10,033=12,036=03,038=04,040=12,041=12,042=12,043=12,% 059=12,045=12,047=12,058=12,063=12,091=12,093=12,126=13,\do=,% \NeedsTeXFormat{LaTeX2e}[2011/06/27] \ProvidesPackage{pgfkeyx}[2012/04/13 v0.0.1 Patch for pgfkeys (AM)] \begingroup\expandafter\endgroup\expandafter \ifx\csname ver@pgfkeys.sty\endcsname\@undefined \PackageError{pgfkeyx}{'pgfkeys' package not loaded} {This package requires 'pgfkeys' package to be loaded first.}% \expandafter\endinput \fi \newif\ifpgfkeys@tempst \newif\ifpgfkeysloopbreak \newif\ifpgfkeys@preservebrace % preserve outer braces in key values? \newif\ifpgfkeys@in \newif\ifpgfkeys@tracingkeys % include tracing features in the future. \long\def\pgfkeys@iofi#1{#1} \long\def\pgfkeys@iofii#1#2{#1} \long\def\pgfkeys@iiofii#1#2{#2} \long\protected\def\pgfkeys@ifnextchar@a#1#2#3{% \let\reserved@d=#1\def\reserved@a{#2}\def\reserved@b{#3}% \futurelet\pgfkeys@next\pgfkeys@ifnextchar@c } \lowercase{\lowercase{\let\pgfkeys@sptoken= } } \lowercase{\def\pgfkeys@ifnextchar@b} % {\futurelet\pgfkeys@next\pgfkeys@ifnextchar@c} \def\pgfkeys@ifnextchar@c{% \ifx\pgfkeys@next\pgfkeys@sptoken \let\reserved@c\pgfkeys@ifnextchar@b \else \ifx\pgfkeys@next\reserved@d \let\reserved@c\reserved@a \else \let\reserved@c\reserved@b \fi \fi \reserved@c } \long\protected\def\ifpgfkeysnextchar#1#2#3{% \pgfkeys@ifnextchar@a\bgroup {\pgfkeys@ifnextchar@a{#1}{#2}{#3}}% {\pgfkeys@ifnextchar{#1}{#2}{#3}}% } \long\def\pgfkeys@ifnextchar#1#2#3#4{% \if\string#1\string#4% \expandafter\pgfkeys@iofii \else \expandafter\pgfkeys@iiofii \fi {#2}{#3}#4% } \long\protected\def\pgfkeys@starorlong#1{% \ifpgfkeysstar{\let\l@ngrel@x\relax#1}{\let\l@ngrel@x\long#1}% } \long\protected\def\pgfkeys@testopt#1#2{\ifpgfkeysnextchar[{#1}{#1[{#2}]}} \long\protected\def\ifpgfkeysstar#1{\ifpgfkeysnextchar*{\pgfkeys@iofii{#1}}} \def\pgfkeys@defcmd#1#2#3{% \ifdefined#3% \ifx#3\relax\else \pgfkeys@error{Command '\string#3' already exists}% \fi \fi \l@ngrel@x \ifcat$\detokenize{#2}$\else \ifx#2p\expandafter\expandafter\expandafter\protected\fi \fi \csname#1def\endcsname#3% } \protected\def\pgfkeysrobustdef{\pgfkeys@starorlong{\pgfkeys@defcmd{}{p}}} \pgfkeysrobustdef*\pgfkeysrobustgdef{\pgfkeys@starorlong{\pgfkeys@defcmd{g}{p}}} \pgfkeysrobustdef*\pgfkeysnewdef{\pgfkeys@starorlong{\pgfkeys@defcmd{}{}}} \pgfkeysrobustdef*\pgfkeysnewedef{\pgfkeys@starorlong{\pgfkeys@defcmd{e}{}}} \pgfkeysrobustdef*\pgfkeysnewgdef{\pgfkeys@starorlong{\pgfkeys@defcmd{g}{}}} \pgfkeysrobustdef*\pgfkeysrobustredef{\pgfkeys@starorlong{\pgfkeys@redefcmd{}{p}}} \pgfkeysrobustdef*\pgfkeysnewredef{\pgfkeys@starorlong{\pgfkeys@redefcmd{}{}}} \pgfkeysrobustdef*\pgfkeys@redefcmd#1#2#3{% \ifdefined#3% \ifpgfkeys@tracingkeys \immediate\write\m@ne{Command '\string#3' redefined}% \fi \fi \l@ngrel@x \ifcat$\detokenize{#2}$\else \ifx#2p\expandafter\expandafter\expandafter\protected\fi \fi \csname#1def\endcsname#3% } \pgfkeysrobustdef\pgfkeys@testst#1{% \ifpgfkeysstar{\pgfkeys@tempsttrue#1}{\pgfkeys@tempstfalse#1}% } \pgfkeysrobustdef\pgfkeys@testcl#1{% \ifpgfkeysnextchar!{\pgfkeys@cltrue#1}{\pgfkeys@clfalse#1}% } \pgfkeysrobustdef\pgfkeys@testpl#1{% \ifpgfkeysnextchar+{\pgfkeys@pltrue#1}{\pgfkeys@plfalse#1}% } % \pgfkeysnewlet shouldn't grab second argument! \pgfkeysrobustdef*\pgfkeysnewlet#1{% \ifdefined#1% \pgfkeys@error{Command '\string#1' already exists}% \expandafter\pgfkeys@gobble \else \expandafter\pgfkeys@iofi \fi {\let#1 }% } \pgfkeysnewlet\pgfkeys@nil\relax \pgfkeysnewdef\pgfkeys@cmdeq{\pgfkeys@gobble\pgfkeys@cmdeq} \pgfkeysnewdef\ifpgfkeyscmdeq#1#2{% \ifx#1#2\pgfkeys@cmdeq\expandafter\pgfkeys@iofii\else \expandafter\pgfkeys@iiofii\fi } \pgfkeysnewdef\pgfkeys@gobble#1{} \pgfkeysnewdef*\pgfkeys@space{ } \edef\pgfkeys@backslashchar{\expandafter\pgfkeys@gobble\string\\} \pgfkeysnewdef\pgfkeys@gobbletwo#1#2{} \pgfkeysnewdef*\pgfkeys@stripprefix#1>{} \pgfkeysnewdef\pgfkeys@car#1#2\car@nil{#1} \lowercase{\pgfkeysnewdef*\pgfkeys@gobblespace} {} \pgfkeysnewdef\pgfkeysswap#1#2{#2#1} \pgfkeysnewdef\pgfkeysswapfirstbraced#1#2{#2{#1}} \pgfkeysnewdef\pgfkeysexpandnext#1#2{% \expandafter\pgfkeysswap\expandafter{#2}{#1}% } \pgfkeysnewdef\pgfkeysexpandbracenext#1#2{% \expandafter\pgfkeysswap\expandafter{\expandafter{#2}}{#1}% } \pgfkeysrobustdef*\pgfkeyscsdef#1{\expandafter\def\csname#1\endcsname} \pgfkeysrobustdef*\pgfkeyscsedef#1{\expandafter\edef\csname#1\endcsname} \pgfkeysrobustdef*\pgfkeysnoexpandcs#1{% \unexpanded\expandafter{\csname#1\endcsname}% } \pgfkeysrobustdef*\pgfkeysexpandcsonce#1{% \unexpanded\expandafter\expandafter\expandafter{\csname#1\endcsname}% } \pgfkeysrobustdef\pgfkeysexpanded#1{\begingroup\edef\x{\endgroup#1}\x} \pgfkeysrobustdef\pgfkeysexpandarg#1#2{% \begingroup\toks@{#1}% \pgfkeysexpanded{\endgroup\the\toks@{#2}}% } \pgfkeysrobustdef\pgfkeysexpandargonce#1#2{% \begingroup \toks@{#1}\toks1\expandafter{#2}% \pgfkeysexpanded{\endgroup\the\toks@{\the\toks1}}% } \pgfkeysrobustdef\pgfkeysexpandsecond#1#2{% \begingroup\toks@{#1}% \pgfkeysexpanded{\endgroup\the\toks@#2}% } \pgfkeysrobustdef\pgfkeysexpandsecondonce#1#2{% \begingroup \toks@{#1}\toks1\expandafter{#2}% \pgfkeysexpanded{\endgroup\the\toks@\the\toks1}% } \pgfkeysnewdef*\ifpgfkeysswitch#1{% \ifpgfkeysblank{#1}{% \pgfkeys@iiofii }{% \expandafter\pgfkeys@ifswitch\romannumeral-`\q#1\pgfkeys@nil{% \if#1\expandafter\pgfkeys@iofii\else\expandafter\pgfkeys@iiofii\fi }{% \pgfkeys@error{Invalid switch '#1'}% }% }% } \pgfkeysnewdef*\pgfkeys@ifswitch#1#2\pgfkeys@nil{% \ifpgfkeysblank{#2}\pgfkeys@iiofii\pgfkeys@iofii } \pgfkeysnewdef\ifpgfkeyscond#1\fi{% #1\relax\expandafter\pgfkeys@iofii\else \expandafter\pgfkeys@iiofii\fi } \pgfkeysnewdef*\ifpgfkeysnum#1#{\ifpgfkeyscond\ifnum#1\fi} \pgfkeysrobustdef*\pgfkeys@in#1#2{% \long\def\in@@##1#1##2\in@@{% \edef\in@@{\unexpanded{##2}}% \ifx\in@@\pgfkeys@empty\pgfkeys@infalse\else\pgfkeys@intrue\fi }% \in@@#2{\in@@}#1\in@@ } \pgfkeysrobustdef*\ifpgfkeysin#1#2{% \pgfkeys@in{#1}{#2}% \csname pgfkeys@\ifpgfkeys@in iofii\else iiofii\fi\endcsname } \pgfkeysrobustdef*\ifpgfkeysnotin#1#2{% \ifpgfkeysin{#1}{#2}\pgfkeys@iiofii\pgfkeys@iofii } \pgfkeysrobustdef*\ifpgfkeysxin#1#2{% \pgfkeys@expandtwoargs\ifpgfkeysin{#1}{#2}% } \pgfkeysrobustdef*\pgfkeys@expandtwoargs#1#2#3{% % #1 might be a token list: \begingroup\toks@{#1}% \edef\x{\endgroup\the\toks@{#2}{#3}}\x } \pgfkeysnewdef*\ifpgfkeysdef#1{% \ifpgfkeysblank{#1}\pgfkeys@iiofii{% \ifx#1\@undefined \expandafter\pgfkeys@iiofii \else \ifx#1\relax \expandafter\expandafter\expandafter\pgfkeys@iiofii \else \expandafter\expandafter\expandafter\pgfkeys@iofii \fi \fi }% } \pgfkeysnewdef*\ifpgfkeyscsdef#1{% \ifpgfkeysblank{#1}{% \expandafter\pgfkeys@iiofii\pgfkeys@gobble }{% \ifcsname#1\endcsname \expandafter\pgfkeys@iofi \else \expandafter\expandafter\expandafter \pgfkeys@iiofii\expandafter\pgfkeys@gobble \fi }{% \expandafter\ifpgfkeysdef\csname#1\endcsname }% } \pgfkeysnewdef*\ifpgfkeyskeydef#1{\ifpgfkeyscsdef{pgfk@#1}} \pgfkeysnewredef*\pgfkeysifdefined#1{% \pgfkeys@ifcsname pgfk@#1\endcsname \expandafter\pgfkeys@iofii \else \expandafter\pgfkeys@iiofii \fi } % If you don't want to have \detokenize, here is rather lengthy way for % \ifnull. Note that \ifnull defers from \ifblank: \pgfkeysnewdef\ifpgfkeysnull#1#2#3{% \romannumeral\iffalse{\fi\expandafter\pgfkeys@iiofii\expandafter {\expandafter{\string#1}\expandafter\pgfkeys@iiofii\string}% \expandafter\pgfkeys@iofii\expandafter{\iffalse}\fi0 #3}{0 #2}% } %\pgfkeysnewdef\ifpgfkeysblank#1{% % \expandafter\ifpgfkeysnull\expandafter{\pgfkeys@gobble#1.}% %} \pgfkeysnewdef\ifpgfkeysblank#1{% \ifcat$\detokenize\expandafter{\pgfkeys@gobble#1.}$% \expandafter\pgfkeys@iofii\else\expandafter\pgfkeys@iiofii\fi } \pgfkeysnewdef*\ifpgfkeysbool#1{% \ifpgfkeysblank{#1}{% \pgfkeys@iiofii }{% \ifpgfkeyscsdef{if#1}{% \csname pgfkeys@i\csname if#1\endcsname ofii\else iofii\fi\endcsname }{% \pgfkeys@error{Undefined boolean '#1'}% }% }% } \pgfkeysrobustdef*\pgfkeysaftergroupdef#1\endgroup{% \edef\x{\endgroup\edef\noexpand#1{\noexpand\unexpanded {\unexpanded\expandafter{#1}}}}\x } \ifpgfkeysdef\pdfstrcmp{% \let\pgfkeys@strcmp\pdfstrcmp }{% % Is it true that tikz doesn't load any external packages? If yes, % then we've to find another way around the need for 'pdftexcmds': \RequirePackage{pdftexcmds}% \ifpgfkeysdef\pdf@strcmp{% \let\pgfkeys@strcmp\pdf@strcmp }{% \pgfkeys@error{Neither '\string\pdfstrcmp' nor '\string\pdf@strcmp' could be found}% }% } \pgfkeysnewdef\ifpgfkeysstrcmp#1#2{% \csname pgfkeys@i\ifnum\pgfkeys@strcmp{\detokenize{#1}}% {\detokenize{#2}}=0ofii\else iofii\fi\endcsname } \pgfkeysnewdef\ifpgfkeysxstrcmp#1#2{% \csname pgfkeys@i\ifnum\pgfkeys@strcmp{#1}{#2}=0 ofii\else iofii\fi\endcsname } \pgfkeysnewdef\ifpgfkeysbraced#1{% \ifpgfkeysblank{#1}\pgfkeys@iiofii{% \ifpgfkeysxstrcmp{\detokenize\expandafter{\pgfkeys@gobble#1}}{}{% \ifpgfkeysxstrcmp{\expandafter\pgfkeys@car\detokenize{#1}\car@nil} {\pgfkeys@leftbracechar}\pgfkeys@iofii\pgfkeys@iiofii }{% \pgfkeys@iiofii }% }% } \pgfkeysnewdef\ifpgfkeysleadspace#1#2#3{% \romannumeral\csname pgfkeys@i\ifpgfkeysnull{#1}{iofii}{\iffalse{\fi\pgfkeys@ifleadspace.#1 }}% \endcsname{0 #2}{0 #3}% } \pgfkeysnewdef\pgfkeys@ifleadspace#1 {% don't shift! \expandafter\ifpgfkeysnull\expandafter{\pgfkeys@gobble#1}{ofii}{iofii}% \expandafter\pgfkeys@gobble\expandafter{\iffalse}\fi } \pgfkeysrobustdef*\pgfkeys@sanitizemacro#1{% \edef#1{\expandafter\pgfkeys@stripprefix\meaning#1}% } \begingroup \catcode`\&=7 \pgfkeysnewgdef\pgfkeystrimspace#1{\pgfkeys@trimspace@a.#1& &} \pgfkeysnewgdef\pgfkeys@trimspace@a#1 &{\pgfkeys@trimspace@b#1&} \pgfkeysnewgdef\pgfkeys@trimspace@b#1{% \unexpanded\expandafter{% \romannumeral0% \expandafter\ifpgfkeysleadspace\expandafter{\pgfkeys@gobble#1}{% \pgfkeys@gobble#1% }{% \expandafter\space\pgfkeys@gobble#1% }% }% } \endgroup \pgfkeysrobustdef\pgfkeysdespace#1#2{\edef#2{\pgfkeystrimspace{#1}}} \pgfkeysrobustdef*\pgfkeysdespacecontent#1{% \edef#1{\expandafter\pgfkeystrimspace\expandafter{#1}}% } \pgfkeysnewdef*\pgfkeysgobblescape#1{% \ifpgfkeysblank{#1}{}{% \ifnum\escapechar>255 \string#1% \else \ifnum\escapechar<0 \string#1% \else \ifnum\escapechar=32 \expandafter\pgfkeys@gobblespace\string#1% \else \expandafter\pgfkeys@gobble\string#1% \fi \fi \fi }% } \pgfkeysnewdef*\ifpgfkeysescaped#1{% \ifnum\escapechar>255 \expandafter\pgfkeys@iiofii \else \ifnum\escapechar<0 \expandafter\expandafter\expandafter\pgfkeys@iiofii \else \ifnum\escapechar=32 \expandafter\expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\pgfkeys@iiofii \else \csname pgfkeys@i\if\expandafter\pgfkeys@car\string#1x\@nil \pgfkeys@backslashchar ofii\else iofii\fi \expandafter\expandafter\expandafter\expandafter \expandafter\expandafter\expandafter \endcsname \fi \fi \fi } \pgfkeysnewdef\pgfkeys@alloftwo#1#2{#1#2} \pgfkeysnewdef\ifpgfkeysntype#1{% Bruno Le Floch \ifpgfkeysxstrcmp {\detokenize\expandafter{\pgfkeys@alloftwo#1{}{}}}% {\detokenize{#1{}}}% } % Expandable test option. Use with caution: it can't be used to test % for explicit braces! % Examples: % { % \catcode`\ =13 % \gdef\activespace{ } % } % \def\cmd[#1]{} % \def\x{\pgfkeys@xtestopt\cmd{noarg}} % \x {xy} % \x [arg] {xy} % \expandafter\x \activespace {xy} % \expandafter\x \activespace [arg] {xy} \pgfkeysnewdef*\pgfkeys@xtestopt#1#2#3{% \ifpgfkeysstrcmp{ }{#3}{% \pgfkeys@xtestopt#1{#2}% }{% \ifpgfkeysstrcmp{#3}{[} {#1[}{\ifpgfkeysntype{#3}{#1[#2]#3}{#1[#2]{#3}}}% }% } % This can't be used to test for the presence of explicit left or right brace. \pgfkeysnewdef*\ifpgfkeysxifnextchar#1#2#3#4{% \ifpgfkeysstrcmp{ }{#4}{% \ifpgfkeysxifnextchar#1{#2}{#3}% }{% \ifpgfkeysstrcmp{#4}{#1}{#2}{\ifpgfkeysntype{#4}{#3#4}{#3{#4}}}% }% } % \pgfkeysremoveouterbraces[]{} % To make the test expandable, we need to use expandable testopt. \pgfkeysnewdef*\pgfkeysremoveouterbraces{% \pgfkeys@xtestopt\pgfkeys@removeouterbraces{1}% } \pgfkeysnewdef*\pgfkeys@removeouterbraces[#1]{% \romannumeral\expandafter\pgfkeys@r@moveouterbraces\expandafter{% \romannumeral\ifpgfkeysxstrcmp{\pgfkeystrimspace{#1}}{all}{1000}{#1}000% }% } \pgfkeysnewdef\pgfkeys@r@moveouterbraces#1#2{% \ifpgfkeysblank{#1}{0 \unexpanded{#2}}{% \expandafter\ifpgfkeysblank\expandafter{\pgfkeys@gobble#2}{% \ifpgfkeysbraced{#2}{% \expandafter\pgfkeysswapfirstbraced\expandafter{\pgfkeys@iofi#2}% {\expandafter\pgfkeys@r@moveouterbraces\expandafter{\pgfkeys@gobble#1}}% }{0 \unexpanded{#2}}% }{0 \unexpanded{#2}}% }% } \pgfkeysrobustdef*\pgfkeyscsvnormalize{\pgfkeys@testopt\pgfkeys@csvnormalize,} \pgfkeysrobustdef\pgfkeys@csvnormalize[#1]#2{% \begingroup \pgfkeysdeclarenormalizer{#1}% \@tempswafalse \pgfkeys@normalizelist{#2}% \expandafter\endgroup\expandafter\pgfkeys@temptoks\expandafter {\the\pgfkeys@temptoks}% } \pgfkeysrobustdef\pgfkeyskvnormalize#1{% \begingroup \pgfkeysdeclarenormalizer{,}% \@tempswatrue \pgfkeys@normalizelist{#1^?^}% \def\reserved@a##1^?^##2\pgfkeys@nil{% \pgfkeys@parserequalerr##1##2,=\pgfkeys@nil \pgfkeys@temptoks{##1##2}% }% \expandafter\reserved@a\the\pgfkeys@temptoks\pgfkeys@nil \expandafter\endgroup\expandafter\pgfkeys@temptoks\expandafter {\the\pgfkeys@temptoks}% } \pgfkeysrobustdef\pgfkeysslashnormalize#1{% \pgfkeys@csvnormalize[/]{x#1}% \pgfkeys@temptoks\expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter {\expandafter\expandafter\expandafter\noexpand\expandafter \pgfkeys@gobble\the\pgfkeys@temptoks}% } % A general list normalizer, for arbitrary list parsers: \begingroup \catcode`\~=13 \catcode`\!=13 \pgfkeysrobustgdef*\pgfkeysdeclarenormalizer#1{% \begingroup \lccode`\~=`#1% \lccode`\!=`\=% \lowercase{\endgroup \def\pgfkeys@normalizelist##1{% \pgfkeys@temptoks\expandafter{\romannumeral-`\q \pgfkeys@activeparser#1##1#1~\pgfkeys@nil}% }% \def\pgfkeys@activeparser##1~##2\pgfkeys@nil{% \ifpgfkeysblank{##2}{% \ifpgfkeysbool{@tempswa}{% \pgfkeys@activeequal##1!\pgfkeys@nil }{% \pgfkeys@spaceparser##1 #1\pgfkeys@nil }% }{% \pgfkeys@activeparser##1#1##2\pgfkeys@nil }% }% }% \begingroup \uccode`\~=`\=% \uppercase{\endgroup \def\pgfkeys@activeequal##1~##2\pgfkeys@nil{% \ifpgfkeysblank{##2}{% \pgfkeys@spaceparser##1 #1\pgfkeys@nil }{% \pgfkeys@activeequal##1=##2\pgfkeys@nil }% }% }% \def\pgfkeys@spaceparser##1 #1##2\pgfkeys@nil{% \ifpgfkeysblank{##2}{% \pgfkeys@parserspace##1#1 \pgfkeys@nil }{% \pgfkeys@spaceparser##1#1##2\pgfkeys@nil }% }% \def\pgfkeys@parserspace##1#1 ##2\pgfkeys@nil{% \ifpgfkeysblank{##2}{% \ifpgfkeysbool{@tempswa}{% \pgfkeys@spaceequal##1 =\pgfkeys@nil }{% \pgfkeys@doubleparser##1#1#1\pgfkeys@nil }% }{% \pgfkeys@parserspace##1#1##2\pgfkeys@nil }% }% \def\pgfkeys@spaceequal##1 =##2\pgfkeys@nil{% \ifpgfkeysblank{##2}{% \pgfkeys@equalspace##1= \pgfkeys@nil }{% \pgfkeys@spaceequal##1=##2\pgfkeys@nil }% }% \def\pgfkeys@equalspace##1= ##2\pgfkeys@nil{% \ifpgfkeysblank{##2}{% \pgfkeys@doubleparser##1#1#1\pgfkeys@nil }{% \pgfkeys@equalspace##1=##2\pgfkeys@nil }% }% \def\pgfkeys@doubleparser##1#1#1##2\pgfkeys@nil{% \ifpgfkeysblank{##2}{% \ifpgfkeysbool{@tempswa}{% \pgfkeys@doubleequal##1==\pgfkeys@nil }{% \ifpgfkeysblank{##1}{}{% \pgfkeys@remleadparser##1\pgfkeys@nil }% }% }{% \pgfkeys@doubleparser##1#1##2\pgfkeys@nil }% }% \def\pgfkeys@doubleequal##1==##2\pgfkeys@nil{% \ifpgfkeysblank{##2}{% \ifpgfkeysblank{##1}{}{% \pgfkeys@remleadparser##1\pgfkeys@nil }% }{% \pgfkeys@doubleequal##1=##2\pgfkeys@nil }% }% \def\pgfkeys@remleadparser#1##1\pgfkeys@nil{% \expandafter\space\noexpand##1% }% \def\pgfkeys@parserequalerr##1#1=##2\pgfkeys@nil{% \ifpgfkeysblank{##2}{}{% \pgfkeys@error{There is '#1=' in your key-value list}% }% }% } \endgroup % I haven't studied all of pgf/tikz's looping macros, but we may sometimes % need to break out of the loop prematurely. % Example: % \pgfkeysdeclarelistparser\myloop{,} % \chardef\nr=0 % \myloop{a,b,c}\temp{% % \edef\nr{\the\numexpr\nr+1}% % \ifnum\nr=2 \pgfkeysloopbreak\fi % use only a,b % \edef\y#1{#1\temp}% % } \pgfkeysnewlet\pgfkeysloopbreak\pgfkeysloopbreaktrue \pgfkeysnewdef*\pgfkeys@listparser@nil{\pgfkeys@listparser@nil} \pgfkeysrobustdef*\pgfkeysdeclarelistparser#1#2{% \pgfkeysrobustdef#1##1##2##3{% \pgfkeys@csvnormalize[#2]{##1}% \edef##2{\the\pgfkeys@temptoks}% \ifpgfkeyscmdeq##2\pgfkeys@empty{}{% \pgfkeysexpandnext{% \csname pgfkeys@listparser@\pgfkeysgobblescape#1\endcsname ##2{##3}% }##2#2\pgfkeys@listparser@nil#2% }% }% \pgfkeyscsdef{pgfkeys@listparser@\pgfkeysgobblescape#1}##1##2##3#2{% \pgfkeys@temptoks{##3}% \edef##1{\the\pgfkeys@temptoks}% \ifpgfkeyscmdeq##1\pgfkeys@listparser@nil{}{% ##2\relax \ifpgfkeysloopbreak % To allow nesting of loop: \pgfkeysloopbreakfalse \begingroup \pgfkeyscsdef{pgfkeys@listparser@\pgfkeysgobblescape#1}% ####1\pgfkeys@listparser@nil#2{% \endgroup \pgfkeys@temptoks{####1}% \edef\pgfkeysremainder{\the\pgfkeys@temptoks}% }% \fi \csname pgfkeys@listparser@\pgfkeysgobblescape#1\endcsname##1{##2}% }% }% % <#1@e> is like #1 but will execute once when % is empty: \expandafter\pgfkeysrobustdef \csname\pgfkeysgobblescape#1@e\endcsname##1##2##3{% \pgfkeys@csvnormalize[#2]{##1}% \begingroup \toks@{\csname pgfkeys@listparser@\pgfkeysgobblescape#1\endcsname##2{##3}}% \expandafter\endgroup\the\expandafter\toks@ \the\pgfkeys@temptoks#2\pgfkeys@listparser@nil#2% }% } \pgfkeysdeclarelistparser\pgfkeyscommaloop{,} % \pgfkeysnewbools[]{} \pgfkeysrobustdef*\pgfkeysnewbools{\pgfkeys@testopt\pgfkeys@newbools{}} \pgfkeysrobustdef*\pgfkeys@newbools[#1]#2{% \pgfkeyscommaloop{#2}\pgfkeys@tempa{% \ifpgfkeyscsdef{if#1\pgfkeys@tempa}{% \pgfkeysnoexpandcs{if#1\pgfkeys@tempa}% \pgfkeys@err{Boolean '\the\pgfkeys@temptoks' already exists}% }{% \expandafter\newif\csname if#1\pgfkeys@tempa\endcsname }% }% } \pgfkeysnewbools[pgfkeys@]{cl,pl} \pgfkeysrobustdef*\pgfkeys@trimsuffixcomma{% \begingroup \def\pgfkeys@tempa{% \edef\reserved@a{\the\pgfkeys@temptoks}% \pgfkeys@sanitizemacro\reserved@a \ifpgfkeysxin{,\pgfkeys@nil}{\reserved@a\pgfkeys@nil}{% \def\reserved@a####1,\pgfkeys@nil{% \pgfkeys@temptoks{####1}\pgfkeys@tempa }% \expandafter\reserved@a\the\pgfkeys@temptoks\pgfkeys@nil }{}% }% \pgfkeys@tempa \expandafter\endgroup\expandafter\pgfkeys@temptoks\expandafter {\the\pgfkeys@temptoks}% } \pgfkeysrobustredef\pgfkeys@@set#1#2{% \let\pgfkeysdefaultpath\pgfkeys@root \pgfkeys@set@aux{#1}{#2}% } % \pgfkeys@set@aux is also needed by \pgfkeys@@qset: \pgfkeysrobustdef\pgfkeys@set@aux#1#2{% \pgfkeysslashnormalize{#2}% \expandafter\pgfkeyskvnormalize\expandafter{\the\pgfkeys@temptoks}% \pgfkeys@trimsuffixcomma \expandafter\pgfkeys@parse\the\pgfkeys@temptoks,\pgfkeys@mainstop \def\pgfkeysdefaultpath{#1}% } \pgfkeysrobustredef\pgfkeys@normal#1,{% \pgfkeys@unpack@a#1=\pgfkeysnovalue=\pgfkeys@stop \pgfkeys@parse } \pgfkeysrobustdef\pgfkeys@unpack@a#1={% % No need to despace #1: the list was previously normalized. \edef\pgfkeyscurrentkey{#1}% \ifpgfkeysbool{pgfkeys@preservebrace}{% \pgfkeys@unpack@b\do }{% \pgfkeys@unpack@b }% } \pgfkeysrobustdef\pgfkeys@unpack@b#1=#2\pgfkeys@stop{% % No need to despace #1 here. \ifpgfkeys@preservebrace \pgfkeys@temptoks\expandafter{\pgfkeys@gobble#1}% \else \pgfkeys@temptoks{#1}% \fi % This solution is useful but it isn't yet foolproof because of the way % the original pgfkeys package delimits arguments by \pgfeov. % Robustifying this stage will require changes to pgfkeys' style of % argument grabbing. \edef\pgfkeyscurrentvalue{% \ifpgfkeys@preservebrace \expandafter\ifpgfkeysbraced\expandafter{\the\pgfkeys@temptoks}{% {\the\pgfkeys@temptoks}% }{% \the\pgfkeys@temptoks }% \else \the\pgfkeys@temptoks \fi }% % Using LaTeX-style branches can help offset problems often found with % parsing unbalanced conditionals. \ifpgfkeyscmdeq\pgfkeyscurrentkey\pgfkeys@empty{% % OK, just skip }{% \pgfkeys@add@path@as@needed \ifpgfkeyscmdeq\pgfkeyscurrentvalue\pgfkeysnovalue@text{% \pgfkeysifdefined{\pgfkeyscurrentkey/.@def}{% \pgfkeysgetvalue{\pgfkeyscurrentkey/.@def}\pgfkeyscurrentvalue }{% % Proposal: % If there is no user value and no default, we should check if % their is an handler for the name of this key or if value is % forbidden. If nothing is found, we should alert the user. % To reduce the cost of checking, this should be based on user % preference. }% }{}% \ifpgfkeyscmdeq\pgfkeyscurrentvalue\pgfkeysvaluerequired{% \pgfkeysvalueof{/errors/value required/.@cmd}\pgfkeyscurrentkey \pgfkeyscurrentvalue\pgfeov }{% \pgfkeys@case@one }% }% } \pgfkeysrobustredef\pgfkeysalso#1{% % First strip all outer brace of #1; otherwise parsing may fail. \edef\pgfkeys@tempa{\pgfkeysremoveouterbraces[all]{#1}}% \expandafter\pgfkeysslashnormalize\expandafter{\pgfkeys@tempa}% \expandafter\pgfkeyskvnormalize\expandafter{\the\pgfkeys@temptoks}% \pgfkeys@trimsuffixcomma \expandafter\pgfkeys@parse\the\pgfkeys@temptoks,\pgfkeys@mainstop } % No change to the original \pgfqkeys, but \pgfkeys@@qset requires patching: \pgfkeysrobustredef*\pgfqkeys{% \expandafter\pgfkeys@@qset\expandafter{\pgfkeysdefaultpath}% } \pgfkeysrobustredef\pgfkeys@@qset#1#2#3{% \pgfkeysexpandarg\pgfkeysslashnormalize{#2}% \expandafter\pgfkeyskvnormalize\expandafter{\the\pgfkeys@temptoks}% \edef\pgfkeysdefaultpath{\the\pgfkeys@temptoks/}% \pgfkeys@set@aux{#1}{#3}% } % \pgfqkeysalso also needs to call the list normalizer: \pgfkeysrobustredef\pgfqkeysalso#1#2{% \pgfkeysexpandarg\pgfkeysslashnormalize{#1}% \expandafter\pgfkeyskvnormalize\expandafter{\the\pgfkeys@temptoks}% \edef\pgfkeysdefaultpath{\the\pgfkeys@temptoks/}% \pgfkeysalso{#2}% } \pgfkeysnewdef*\pgfkeys@generateparameters#1#2{% \ifnum#1<\numexpr#2+1\relax ####\number#1% \expandafter\pgfkeys@generateparameters \expandafter{\number\numexpr#1+1\expandafter}% \expandafter{\number#2\expandafter}% \fi } \pgfkeysnewredef\pgfkeysdefnargs#1#2#3{\pgfkeysdefnargs@{#1}{#2}{#3}{\def}} \pgfkeysnewredef\pgfkeysedefnargs#1#2#3{\pgfkeysdefnargs@{#1}{#2}{#3}{\edef}} \pgfkeysnewredef\pgfkeysdefnargs@#1#2#3#4{% \ifnum#2>9\relax \pgfkeys@error{\string\pgfkeysdefnargs: I expected #2<=9 arguments but I saw #2}% \else \pgfkeyscsedef{pgfk@#1/.@args}{\pgfkeys@generateparameters{1}{#2}}% \fi \pgfkeysgetvalue{#1/.@args}\pgfkeys@tempargs \def\pgfkeys@temp{\expandafter#4\csname pgfk@#1/.@@body\endcsname}% \expandafter\pgfkeys@temp\pgfkeys@tempargs{#3}% \edef\pgfkeys@tempargs{\noexpand\pgfkeysvalueof{#1/.@@body}}% \def\pgfkeys@temp{\pgfkeysdef{#1}}% \expandafter\pgfkeys@temp\expandafter{\pgfkeys@tempargs##1}% \pgfkeyssetvalue{#1/.@body}{#3}% } \pgfkeys{% % Use default values to set the key. If the key has no default or % if value is required, an error will be raised: /handlers/.restore default/.code=\pgfkeys{\pgfkeyscurrentpath}% } \pgfkeys{% /handlers/.restore key defaults/.code=\pgfkeysalso{#1}% } \pgfkeys{/handlers/.normal code/.code=#1} % New handlers for boolean keys: % Syntaxes: % .is if with no callback= % .is if with 1 callback={}{} % .is if with 2 callbacks={}{}{} % In this way, I know I am dealing with , and not with another % (auxiliary) boolean as in conventional '.is if' handler. \pgfkeys{% /handlers/.is if with no callback/.code={% \pgfkeys@boolean@handler{#1}{##1}{}{}% }, /handlers/.is if with 1 callback/.code 2 args={% \pgfkeys@boolean@handler{#1}{##1}{#2}{}% }, /handlers/.is if with one callback/.style 2 args={% \pgfkeyscurrentpath/.is if with 1 callback={#1}{#2}% }, /handlers/.is if with 2 callbacks/.code n args={3}{% \pgfkeys@boolean@handler{#1}{##1}{#2}{#3}% } } \pgfkeysrobustredef*\pgfkeys@savresname#1{% \ifcase#1\relax % The idea is, for a given key '/my path/key/.code', to set % path := '/my path' % name := 'key/.code' % key := '/my path/key/.code' \let\pgfkeyssavedkey=\pgfkeyscurrentkey \let\pgfkeyssavedname=\pgfkeyscurrentname \edef\pgfkeyssavedpath{\pgfkeyscurrentpath}% \edef\pgfkeyscurrentkey{\pgfkeyscurrentpath}% \pgfkeys@split@path \let\pgfkeyssavednameb\pgfkeyscurrentname \or % Recover: \let\pgfkeyscurrentkey=\pgfkeyssavedkey \let\pgfkeyscurrentname=\pgfkeyssavedname % Don't do \edef\pgfkeyscurrentpath{\pgfkeyssavedpath} here, since % \pgfkeyscurrentpath is determined by \pgfkeys@pathtoks. \else \pgfkeys@error{Number '#1' out of range [0,1]}% \fi } \pgfkeysrobustredef\pgfkeys@boolean@handler#1#2#3#4{% \pgfkeys@savresname{0}% % Let's not redefine 'if\pgfkeyscurrentname' is it already exists, % so that we don't change its current state: \ifpgfkeyscsdef{if\pgfkeyscurrentname}{}{% % Can use \outer-defined \newif: \csname newif\expandafter\endcsname \csname if\pgfkeyscurrentname\endcsname }% \begingroup \def\reserved@a{\pgfkeyssavedpath/.code=}% \expandafter\expandafter\expandafter\endgroup\expandafter\expandafter \expandafter\pgfkeysalso\expandafter\expandafter\expandafter{% \expandafter\reserved@a\expandafter\pgfkeys@boolean@handler@b \expandafter{\pgfkeyssavednameb}{#2}{#3}{#4}, \pgfkeyssavedpath/.default=#1% }% \pgfkeys@savresname{1}% } \pgfkeysrobustredef\pgfkeys@boolean@handler@b#1#2#3#4{% \ifpgfkeysxin{,\pgfkeystrimspace{#2},}{,true,false,}{% \ifpgfkeyscsdef{#1#2}{% \csname#1#2\endcsname \ifpgfkeysblank{#3#4}{}{\ifpgfkeysbool{#1}{#3}{#4}}% }{% \pgfkeysvalueof{/errors/boolean expected/.@cmd}% \pgfkeyscurrentkey{#2}\pgfeov }% }{% \pgfkeysvalueof{/errors/boolean expected/.@cmd}% \pgfkeyscurrentkey{#2}\pgfeov }% } \pgfkeys@restorecodes \endinput %% End of file 'pgfkeyx.sty' %%