diff options
author | Karl Berry <karl@freefriends.org> | 2011-07-26 23:27:28 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2011-07-26 23:27:28 +0000 |
commit | 0339ee8be4b30971917d1b81561d1891e786c972 (patch) | |
tree | 2186272898d66b9d2ba8531c98725b4a4c8473ab /Master/texmf-dist/tex/latex/ltxkeys | |
parent | 0a04967062b7de7c64f902743994a3edd7caac9f (diff) |
new latex package ltxkeys (14jul11)
git-svn-id: svn://tug.org/texlive/trunk@23243 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/ltxkeys')
-rw-r--r-- | Master/texmf-dist/tex/latex/ltxkeys/ltxkeys.sty | 2036 |
1 files changed, 2036 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/ltxkeys/ltxkeys.sty b/Master/texmf-dist/tex/latex/ltxkeys/ltxkeys.sty new file mode 100644 index 00000000000..62cb38a1a3a --- /dev/null +++ b/Master/texmf-dist/tex/latex/ltxkeys/ltxkeys.sty @@ -0,0 +1,2036 @@ +%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% +% % +% This is file 'ltxkeys.sty', version 0.1.0, 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 (amusa22@gmail.com). % +% % +%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% +\RequirePackage{catoptions}[2011/07/07] +\UseNormalCatcodes +\StyleFilePurpose{Robust and fast key-value parser} +\StyleFileRCSInfo +$Id: ltxkeys.sty,v 0.1.0 2011/07/07 09:00:00 Ahmed Musa Exp $ +\ProvidesPackage{ltxkeys}[\StyleFileInfo] +\NeedsTeXFormat{LaTeX2e}[1996/12/01] +\SetStyleFileMessages[ltxkeys@]{info}{warn}{err} +\newvariables{if}[ltxkeys@]{break,st,pl,sw,sv,noval,pxop,exop,kf, + rm,ssk,dec,dep,twk,verbose,inputvalid}[false] +\newvariables{if}{inputvalid}[false] +\robust@def*\SetSlaveWithMaster{\global\ltxkeys@ssktrue} +\robust@def*\SetNoSlaveWithMaster{\global\ltxkeys@sskfalse} +\SetNoSlaveWithMaster +\newvariables{count}[ltxkeys@]{csvdepth,keydepth}[\z@pt] +\newletcs\ltxkeys@nil\relax +\new@def*\ltxkeys@nnil{\ltxkeys@nil} +\ifdefTF\cpt@documentclass{}{% + \ltxkeys@err{No \string\documentclass}\@ehc + \emptifycsset{\cpt@documentclass,\cpt@classoptionslist}% +} +\robust@def*\ltxkeys@gobble@to@nil{% + \begingroup + \defpass\reserved@a##1\ltxkeys@nil{\endgroup}% +} +\robust@def*\ltxkeys@testst#1{\cpt@ifstar{\ltxkeys@sttrue#1}{\ltxkeys@stfalse#1}} +\robust@def*\ltxkeys@testpl#1{\cpt@ifplus{\ltxkeys@pltrue#1}{\ltxkeys@plfalse#1}} +\robust@def*\ltxkeys@teststpl#1{\ltxkeys@testst{\ltxkeys@testpl{#1}}} +\robust@def*\ltxkeys@state{% + \ltxkeys@keys,\ltxkeys@prefs,\ltxkeys@fams,\ltxkeys@nakeys,\ltxkeys@tpref,% + \ltxkeys@ttpref,\ltxkeys@tfam,\ltxkeys@tkey,\ltxkeys@tval,\ifltxkeys@st,% + \ifltxkeys@pl,\ifltxkeys@kf,\ifltxkeys@pxop,\ifltxkeys@exop,\CurrentKeyval,% + \CurrentKey,\CurrentVal +} +\robust@def*\ltxkeys@trimspaces{\begingroup\ltxkeys@tr@mspaces} +\robust@def*\ltxkeys@trimspacesincs#1{\s@expandarg\ltxkeys@trimspaces{#1}#1} +\defpass\reserved@a#1{% + \long\def\ltxkeys@tr@mspaces##1##2{% + \edef\reserved@a{% + \expandcsonce{\romannumeral-`\q + \ltxkeys@trimspace.##1\trimsp@nil#1\trimsp@nil}% + }% + \ifxTF##2\reserved@a{% + \cptpassacross##2\endgroup + }{% + \let##2=\reserved@a + \expandafter\ltxkeys@tr@mspaces\expandafter{##2}##2% + }% + }% + \long\def\ltxkeys@trimspace##1#1\trimsp@nil{% + \ltxkeys@tr@mspace##1\trimsp@nil + }% + \long\def\ltxkeys@tr@mspace##1\trimsp@nil##2{% + \expandafter\noexpand\@gobble##1% + }% +}{ } +\newvariables{tog}{rem@repl,rem@repl@all} +\robust@def*\ltxkeys@removeoneelement{\cpt@testopt\ltxkeys@rem@veoneelement,} +\robust@def\ltxkeys@rem@veoneelement[#1]#2#3{% + \ifcpt@check\cpt@checklistparser{#1}\relax\fi + \begingroup + \edef\parser{\detokenize{#1}}% + \def\ltxkeys@tempa##1{% + \def\ltxkeys@remove####1#1##1#1####2\remove@nil{% + \def#2{####1#1####2}% + \cpt@trimparser[#1]#2% + }% + \xifinsetTF{\detokenize{#1##1#1}}{\parser\cptoxdetok{#2}\parser}{% + \expandafter\ltxkeys@remove\expandafter#1#2#1\remove@nil + \iftogFT{rem@repl@all}{}{% + \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}% + }% + }{}% + }% + \iftogTF{rem@repl}{% + \edef\ltxkeys@tempb{\unexpanded{#3}}% + }{% + \cpt@sttrue\cpt@csvnormalize[#1]#2% + \ltxkeys@trimspaces{#3}\ltxkeys@tempb + }% + \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}% + \postgroupdef#2\endgroup +} +\robust@def*\ltxkeys@removeelements{\cpt@testopt\ltxkeys@rem@veelements,} +\robust@def\ltxkeys@rem@veelements[#1]#2#3{% + \begingroup + \cpt@sttrue\cpt@csvnormalize[#1]#2% + \cpt@checkfalse + \togtrue{rem@repl}% + \long\def\csv@do##1{% + \ltxkeys@removeoneelement[#1]#2{##1}% + }% + \csv@@parse[#1]{#3}% + \postgroupdef#2\endgroup +} +% \ltxkeys@replaceoneelement[<parser>]{<cs>}{<search>}{<replace>} +\robust@def*\ltxkeys@replaceoneelement{% + \cpt@testopt\ltxkeys@repl@ceoneelement,% +} +\robust@def\ltxkeys@repl@ceoneelement[#1]#2#3#4{% + \ifcpt@check\cpt@checklistparser{#1}\relax\fi + \begingroup + \edef\parser{\detokenize{#1}}% + \def\ltxkeys@tempa##1{% + \def\ltxkeys@replace####1#1##1#1####2\rep@nil{% + \def#2{####1#1#4#1####2}% + \cpt@trimparser[#1]#2% + }% + \xifinsetFT{\detokenize{#1##1#1}}{\parser\cptoxdetok#2\parser}{}{% + \expandafter\ltxkeys@replace\expandafter#1#2#1\rep@nil + \iftogFT{rem@repl@all}{}{% + \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}% + }% + }% + }% + \iftogTF{rem@repl}{% + \edef\ltxkeys@tempb{\unexpanded{#3}}% + }{% + \cpt@sttrue\cpt@csvnormalize[#1]#2% + \ltxkeys@trimspaces{#3}\ltxkeys@tempb + }% + \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}% + \postgroupdef#2\endgroup +} +\robust@def*\ltxkeys@replaceelements{\cpt@testopt\ltxkeys@repl@ceelements,} +\robust@def\ltxkeys@repl@ceelements[#1]#2#3#4{% + \begingroup + \edef\ltxkeys@tempa{\unexpanded{#3}}% + \edef\ltxkeys@tempb{\unexpanded{#4}}% + \def\csv@do##1{\cpt@sttrue\cpt@csvnormalize[#1]##1}% + \csv@@loop[,]{#2,\ltxkeys@tempa,\ltxkeys@tempb}% + \def\ltxkeys@tempc##1#1##2\noboundary##3#1##4\noboundary{% + \ltxkeys@replaceoneelement[#1]#2{##1}{##3}% + \ifblankTF{##2}{}{% + \ifblankTF{##4}{}{% + \ltxkeys@tempc##2\noboundary##4\noboundary + }% + }% + }% + \cpt@checkfalse + \togtrue{rem@repl}% + \cptexpandsecond\ltxkeys@tempc{% + \expandcsonce\ltxkeys@tempa#1\noboundary + \expandcsonce\ltxkeys@tempb#1\noboundary + }% + \postgroupdef#2\endgroup +} +\robust@def*\ltxkeys@oneoftwo#1\endgroup{% + \let\@firstoftwo\relax + \let\@secondoftwo\relax + \edefpass\ltxkeys@tempa{\endgroup + \ifcase#1\relax + \if@boolTF{cpt@choicefd}\@firstoftwo\@secondoftwo + \or + \if@boolTF{cpt@choicefd}\@secondoftwo\@firstoftwo + \else + \ltxkeys@err{Invalid number '#1'}\noexpand\@ehc + \fi + }% +} +\robust@def*\ltxkeys@getorder#1#2{% + \def\ltxkeys@order{-1}% + \begingroup + \lowercase{\ltxkeys@trimspaces{#1}\ltxkeys@tempa}% + \@tempcnta\z@pt + \toks@{}% + \def\ltxkeys@do##1{% + \oifstrcmpFT\ltxkeys@tempa{##1}{}{% + \cptexpanded{% + \toks@{\def\noexpand\ltxkeys@order{\the\@tempcnta}}% + }% + \ltxkeys@breaktrue + }% + \advance\@tempcnta\@ne + }% + \ltxkeys@csvparse{#2}% + \expandafter\endgroup\the\toks@ +} +\robust@def*\ltxkeys@ifeltcountTF{\cpt@testopt\ltxkeys@ifeltcount{=}} +\robust@def*\ltxkeys@ifeltcount[#1]#2#3{% + \begingroup + \def\ltxkeys@do##1{\advance\@tempcnta by1}% + \@tempcnta\z@pt + \ltxkeys@csvloop{#2}% + \expandafter\endgroup\csname @\ifnum\@tempcnta#1\numexpr#3% + first\else second\fi oftwo\endcsname +} +\robust@def*\ltxkeys@nomatcherr{% + \ltxkeys@err{User input '\reserved@e' not in list: + \MsgBrk '\reserved@f'}\@ehc + \@gobble +} +% A re-implementation of xkeyval's \XKV@checkchoice for +% arbitrary parser and more robustness: +\robust@def*\ltxkeys@checkchoice{% + \cpt@teststpl{\cpt@testopt\ltxkeys@cc@a,}% +} +\robust@def*\ltxkeys@cc@a[#1]{% + \ifcpt@check\cpt@checklistparser{#1}{}\fi + \cpt@testopt{\ltxkeys@cc@b#1}{}% +} +\robust@def*\comma@cc{% + \cpt@teststpl{\cpt@testopt{\ltxkeys@cc@b,}{}}% +} +\robust@def*\CheckInput#1#2{% + \lowercase{\edef\nominations{\unexpanded{#2}}}% + \cpt@sttrue\cpt@pltrue + \ltxkeys@cc@b,[\userinput\nr]{#1}{#2}{% + \inputvalidtrue + }{% + \inputvalidfalse + }% +} +\robust@def*\ltxkeys@cc@b#1[#2]#3#4{% + \begingroup + \ifcpt@st\lowercase{\fi + \ltxkeys@trimspaces{#3}\user@input + \edef\valid@vals{\unexpanded{#4}}% + \ifcpt@st}\fi + \def\ltxkeys@ccparser{#1}% + \cpt@sttrue\cpt@csvnormalize[#1]\valid@vals + \cptexpandsecond{% + \ifblankTF{#2}\ltxkeys@cc@d{\ltxkeys@cc@c#2}\ltxkeys@nil + }{% + {\expandcsonce\user@input}{\expandcsonce\valid@vals}% + }% +} +\robust@def*\ltxkeys@cc@c#1#2\ltxkeys@nil#3#4{% + \ifblankTF{#2}{\ltxkeys@cc@d#1}{\ltxkeys@cc@e#1#2}{#3}{#4}% +} +\robust@def*\ltxkeys@cc@d#1#2#3{% + \def\reserved@a{#1}% + \ifxTF\reserved@a\ltxkeys@nnil{% + \def\ltxkeys@tempa{}% + }{% + \def\ltxkeys@tempa{\def#1{#2}}% + }% + \edef\x{\cptoxdetok\ltxkeys@ccparser}% + \edef\x{{\x\detokenize{#2}\x}{\x\detokenize{#3}\x}}% + \expandafter\ifinsetTF\x{% + \if@boolTF{cpt@pl}{% + \rightaddtocs\ltxkeys@tempa\@firstoftwo + }{% + \rightaddtocs\ltxkeys@tempa\@firstofone + }% + }{% + \if@boolTF{cpt@pl}{% + \rightaddtocs\ltxkeys@tempa\@secondoftwo + }{% + \rightaddtocs\ltxkeys@tempa{% + \expandafter\ltxkeys@nomatcherr\@gobble + }% + }% + }% + \cptpassexpanded{% + \endgroup + \def\noexpand\reserved@e{\expandcsonce\user@input}% + \def\noexpand\reserved@f{\expandcsonce\valid@vals}% + \expandcsonce\ltxkeys@tempa + }% +} +\robust@def*\ltxkeys@cc@e#1#2#3#4{% + \chardef#2\z@pt + \cpt@choicefdfalse + \def\csv@do##1{% + \def#1{##1}% + \ifstrcmpTF{##1}{#3}{% + \cpt@choicefdtrue\cptbreakloop + }{% + \pushnumber#2% + }% + }% + \expandafter\csv@@loop\expandafter[\ltxkeys@ccparser]{#4}% + \cptpassexpanded{% + \endgroup + \ifcpt@choicefd + \def\noexpand#1{\expandcsonce#1}% + \def\noexpand#2{\the\numexpr#2}% + \ifcpt@pl\noexpand\@firstoftwo\else\noexpand\@firstofone\fi + \else + \def\noexpand#1{\unexpanded{#3}}% + \def\noexpand#2{-1}% + \ifcpt@pl + \noexpand\@secondoftwo + \else + \def\noexpand\reserved@e{\expandcsonce\user@input}% + \def\noexpand\reserved@f{\expandcsonce\valid@vals}% + \unexpanded{\expandafter\ltxkeys@nomatcherr\@gobble}% + \fi + \fi + }% +} + +% \ltxkeys@ifincsvlistTF*[parser](no.){sublist}{mainlist}{true}{false} +\robust@def*\ltxkeys@ifincsvlistTF{\cpt@teststopt\ltxkeys@ifincsvlist,} +\robust@def*\ltxkeys@ifincsvlist[#1]{% + \cpt@testpnopt{\ltxkeys@if@ncsvlist#1}{1}% +} +\robust@def*\ltxkeys@if@ncsvlist#1(#2)#3#4{% + \begingroup + \edef\parser{\detokenize{#1}}% + \ifcpt@st\lowercase{\fi + \edef\ltxkeys@tempa{\unexpanded{#3}}% + \edef\ltxkeys@tempb{\unexpanded{#4}}% + \ifcpt@st}\fi + \cpt@sttrue\cpt@csvnormalize[#1]\ltxkeys@tempb + \cpt@cnta\z@pt\def\itemspresent{}% + \def\csv@do##1{% + \xifinsetFT{\detokenize{#1##1#1}} + {\parser\cptoxdetok\ltxkeys@tempb\parser}{}{% + \edef\itemspresent{\cptliststack,\itemspresent\unexpanded{##1}}% + \advance\cpt@cnta\@ne + }% + \ifnum\cpt@cnta>\numexpr#2-1\relax\cptbreakloop\fi + }% + \csv@@parse*[#1]\ltxkeys@tempa + \ifnum\cpt@cnta>\numexpr#2-1\relax + \edef\nritems{\the\cpt@cnta}% + \else + \def\itemspresent{}\def\nritems{-1}% + \fi + \cptexpandsecond\endgroup{% + \cpt@csexit\itemspresent\cpt@csexit\nritems + \ifx\itemspresent\@empty\noexpand\@secondoftwo\else + \noexpand\@firstoftwo\fi + }% +} +% \ltxkeys@ifintsvlistTF(no){sublist}{mainlist}{true}{false} +\robust@def*\ltxkeys@ifintsvlistTF{% + \cpt@testst{\cpt@testpnopt\ltxkeys@ifintsvlist{1}}% +} +\robust@def*\ltxkeys@ifintsvlist(#1)#2#3{% + \begingroup + \ifcpt@st\lowercase{\fi + \edef\ltxkeys@tempa{\unexpanded{#2}}% + \edef\ltxkeys@tempb{\unexpanded{#3}}% + \ifcpt@st}\fi + \def\itemspresent{}\cpt@cnta\z@pt + \def\tsv@do##1{% + \xifinsetFT{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{}{% + \edef\itemspresent{\cptliststack{}\itemspresent\unexpanded{##1}}% + \advance\cpt@cnta\@ne + }% + \ifnum\cpt@cnta>\numexpr#1-1\relax\cptbreakloop\fi + }% + \s@expandarg\tsv@@parse\ltxkeys@tempa + \ifnum\cpt@cnta>\numexpr#1-1\relax + \edef\nritems{\the\cpt@cnta}% + \else + \def\itemspresent{}\def\nritems{-1}% + \fi + \cptexpandsecond\endgroup{% + \cpt@csexit\itemspresent\cpt@csexit\nritems + \ifx\itemspresent\@empty\noexpand\@secondoftwo\else + \noexpand\@firstoftwo\fi + }% +} +% \ltxkeys@ifinTF*(no.){sublist}{mainlist}{true}{false} +\robust@def*\ltxkeys@ifinTF{% + \cpt@testst{\cpt@testpnopt\ltxkeys@ifin{1}}% +} +\robust@def*\ltxkeys@ifin(#1)#2#3{% + \begingroup + \ifcpt@st\lowercase{\fi + \edef\ltxkeys@tempa{\unexpanded{#2}}% + \edef\ltxkeys@tempb{\unexpanded{#3}}% + \ifcpt@st}\fi + \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@tempa + \cpt@cnta\z@pt\def\itemspresent{}% + \def\do##1,{% + \ifnot@nil{##1}{% + \xifinsetFT{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{}{% + \edef\itemspresent{\cptliststack,\itemspresent\unexpanded{##1}}% + \advance\cpt@cnta\@ne + }% + \ifnumcmpTF\cpt@cnta>\numexpr#1-1{\gobble@to@sentinel\@nil,}{\do}% + }% + }% + \expandafter\do\ltxkeys@tempa,\@nil,% + \ifnum\cpt@cnta>\numexpr#1-1\relax + \edef\nritems{\the\cpt@cnta}% + \else + \def\itemspresent{}\def\nritems{-1}% + \fi + \cptexpandsecond\endgroup{% + \cpt@csexit\itemspresent\cpt@csexit\nritems + \ifcsemptyTF\itemspresent{\noexpand\@secondoftwo} + {\noexpand\@firstoftwo}% + }% +} +\robust@def*\ltxkeys@inpkgcls#1{% + \ifinstylefileTF{}{% + \ltxkeys@err{Command '\detokenize{#1}' issued outside + style file}{The command '\detokenize{#1}' is available + only in style files.}% + }% +} +\new@def*\ltxkeys@parsestack{} +\newletcs\ltxkeys@break\ltxkeys@breaktrue +\robust@def*\ltxkeys@csvloop{% + \let\ltxkeys@nlz\cptfalse + \let\ltxkeys@inkv\cptfalse + \cpt@testst\ltxkeys@parse@a +} +\robust@def*\ltxkeys@csvparse{% + \let\ltxkeys@nlz\cpttrue + \let\ltxkeys@inkv\cptfalse + \cpt@testst\ltxkeys@parse@a +} +\robust@def*\ltxkeys@kvloop{% + \let\ltxkeys@nlz\cptfalse + \let\ltxkeys@inkv\cpttrue + \cpt@testst\ltxkeys@parse@a +} +\robust@def*\ltxkeys@kvparse{% + \let\ltxkeys@nlz\cpttrue + \let\ltxkeys@inkv\cpttrue + \cpt@testst\ltxkeys@parse@a +} +\robust@def*\ltxkeys@parse@a#1{% + \cpt@stchoose{cpt@st}{#1}\ltxkeys@arg\ltxkeys@parse@a + \global\advance\ltxkeys@csvdepth\@ne + \letcsntocsn{ifltxkeys@break@\romannumeral\ltxkeys@csvdepth} + {ifltxkeys@break}% + \letcsntocs{ltxkeys@doo@\romannumeral\ltxkeys@csvdepth}\ltxkeys@doo + \xdef\ltxkeys@parsestack{% + \letcsntocsn{ifltxkeys@break} + {ifltxkeys@break@\romannumeral\ltxkeys@csvdepth}% + \letcsntocsn{ltxkeys@doo}{ltxkeys@doo@\romannumeral\ltxkeys@csvdepth}% + \ltxkeys@nil{\expandcsonce\ltxkeys@parsestack}% + }% + \ifdefTF\ltxkeys@do + {\let\ltxkeys@doo\ltxkeys@do}{\cpt@notdeferr\ltxkeys@do}% + \def\ltxkeys@parse@b{% + \if@boolTF{ltxkeys@break}{% + \defpass\reserved@a####1\ltxkeys@nil,{}% + }{% + \ltxkeys@parse@c.% + }% + }% + \long\def\ltxkeys@parse@c##1,{% + \edef\ltxkeys@arg{\expandcsonce{\@gobble##1}}% + \ifxTF\ltxkeys@arg\ltxkeys@nnil{}{% + \ifxTF\@empty\ltxkeys@arg{}{% + \expandafter\ltxkeys@doo\expandafter{\ltxkeys@arg}\relax + }% + \ltxkeys@parse@b + }% + }% + \ifpsiboolTF{ltxkeys@nlz}{% + \cpt@sttrue + \usename{cpt@\if\ltxkeys@inkv kv\else csv\fi normalize}[,]\ltxkeys@arg + }{}% + \ltxkeys@breakfalse + \expandafter\ltxkeys@parse@b\ltxkeys@arg,\ltxkeys@nil,% + \def\reserved@a##1\ltxkeys@nil{##1\gdef\ltxkeys@parsestack}% + \expandafter\reserved@a\ltxkeys@parsestack + \global\advance\ltxkeys@csvdepth\m@one + \ifnum\ltxkeys@csvdepth=\z@pt\undefcs\ltxkeys@do\fi +} +\robust@def*\ltxkeys@testopt@a#1{\cpt@testopt{\ltxkeys@testopt@b#1}{KV}} +\robust@def*\ltxkeys@testopt@b#1[#2]#3{% + \ltxkeys@makepf{#2}% + \ltxkeys@makehdr{#3}#1% +} +\robust@def*\ltxkeys@testopt@c#1{% + \begingroup + \catcode`\,=12\relax + \cpt@testopt{\ltxkeys@testopt@d#1}{KV}% +} +\robust@def*\ltxkeys@testopt@d#1[#2]#3{% + \ifltxkeys@pl\else + \def\temp@err##1{% + \ltxkeys@err{Multiple ##1 in \noexpandcsn + {ltxkeys@set\ifltxkeys@rm rm\fi keys}% + without '+' suffix}\@ehc + }% + \ltxkeys@ifeltcountTF[>]{#2}\@ne{% + \temp@err{prefixes}% + }{% + \ltxkeys@ifeltcountTF[>]{#3}\@ne{% + \temp@err{families}% + }{}% + }% + \fi + \endgroup + \def\ltxkeys@prefs{#2}% + \def\ltxkeys@fams{#3}% + \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@prefs + \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@fams + \cpt@testopt{#1}{}% +} +\robust@def*\ltxkeys@testopt@e#1#2{% + \ltxkeys@testopt@a{% + \cptexpandarg{\cpt@testopt{\ltxkeys@testopt@f#1}}{#2\ltxkeys@hdr}% + }% +} +\robust@def*\ltxkeys@testopt@f#1[#2]#3{% + \if@boolTF{ltxkeys@sw}{% + \cpt@ifbrack{\ltxkeys@sttrue#1{#2}{#3}}{\ltxkeys@stfalse#1{#2}{#3}[]}% + }{% + \cpt@ifbrack{\ltxkeys@bracedefault{\ltxkeys@sttrue#1{#2}{#3}}}% + {\ltxkeys@stfalse#1{#2}{#3}[]}% + }% +} +\robust@def*\ltxkeys@testopt@g#1#2{% + \cptexpandarg\ltxkeys@testopt@a{\noexpandcsn{ltxkeys@#1}{#2}}% +} +\robust@def*\ltxkeys@bracedefault#1[{% + \begingroup + \toks@{#1}% + \defpass\ltxkeys@tempa##1]{% + \toks1\expandafter{\@gobble##1}% + \cptexpandsecond{\endgroup}{\the\toks@[{\the\toks1}]}% + }.% +} +\robust@def*\ltxkeys@testopt@@a#1{\ltxkeys@testst{\ltxkeys@testopt@@b#1}} +\robust@def*\ltxkeys@testopt@@b#1{\cpt@testopt{\ltxkeys@testopt@@c#1}{KV}} +\robust@def*\ltxkeys@testopt@@c#1[#2]{% + \def\ltxkeys@prefs{#2}% + \cpt@testfam{\ltxkeys@testopt@@d#1}% +} +\robust@def*\ltxkeys@testopt@@d#1<#2>{% + \edef\ltxkeys@fams{#2}% + \cpt@testopt{#1}{}% +} +\robust@def*\ltxkeys@findneedvalue#1{% + \ltxkeys@findpointer\needvalue{#1}\ltxkeys@tkey{% + \ltxkeys@addtopointedkeys{needvalue}\ltxkeys@tkey + }{}% +} +\robust@def*\ltxkeys@findpointer#1#2#3{% + \def\reserved@a##1#1##2##3\ltxkeys@nil{% + \edef#3{\unexpanded{##2}}% + \ifxTF#3\ltxkeys@nnil{% + \edef#3{\unexpanded{##1}}% + \ltxkeys@trimspacesincs#3% + \@secondoftwo + }{% + \ltxkeys@trimspacesincs#3% + \@firstoftwo + }% + }% + \reserved@a#2#1{\ltxkeys@nil}\ltxkeys@nil +} +\robust@def*\ltxkeys@addtopointedkeys#1#2{% + \letcstocsn\reserved@a{\ltxkeys@hdr#1@keys}% + \ifdefTF\reserved@a{% + \xifinsetTF{,\cptoxdetok{#2},}{,\cptoxdetok\reserved@a,}{}{% + \csn@xdef{\ltxkeys@hdr#1@keys}% + {\cptliststack,\reserved@a\expandcsonce{#2}}% + }% + }{% + \csn@xdef{\ltxkeys@hdr#1@keys}{\expandcsonce{#2}}% + }% +} +\robust@def*\ltxkeys@makepf#1{% + \s@expandarg\ltxkeys@trimspaces{#1}\ltxkeys@ttpref + \edef\ltxkeys@tpref{% + \ifcsnullTF\ltxkeys@ttpref{}{\ltxkeys@ttpref @}% + }% +} +\robust@def*\ltxkeys@makehdr#1{% + \s@expandarg\ltxkeys@trimspaces{#1}\ltxkeys@tfam + \edef\ltxkeys@hdr{% + \ltxkeys@tpref\ifcsnullTF\ltxkeys@tfam{}{\ltxkeys@tfam @}% + }% +} +\robust@def*\ltxkeys@saveinitialkeyvals#1#2#3{% + \xifinsetTF{\detokenize{\savevalue}}{\cptoxdetok{#2}}{% + \ltxkeys@err{\noexpand\savevalue pointer not allowed + \MsgBrk when defining a key}\@ehc + }{}% + \ifltxkeys@twk\else + \ifltxkeys@sv + \letcstocsn\ltxkeys@tempa{\ltxkeys@hdr initial@keyvals}% + \csn@xdef{\ltxkeys@hdr initial@keyvals}{% + \cptliststack,\ltxkeys@tempa\expandcsonce{#2}=% + \ifstrcmpTF{#1}{bool}{false}{\unexpanded{#3}}% + }% + \fi + \fi + \ifltxkeys@verbose + \wlog{Key defined: \ltxkeys@ttpref, \ltxkeys@tfam, \ltxkeys@tkey.}% + \fi +} +% \ltxkeys@ordkey[pref]{fam}{key}[dft]{fn} +\robust@def*\ltxkeys@ordkey{% + \ltxkeys@svtrue\ltxkeys@swfalse + \ltxkeys@testopt@a\ltxkeys@ordkey@a +} +\robust@def*\ltxkeys@ordkey@a#1{% + \ltxkeys@findneedvalue{#1}% + \cpt@ifbrack{% + \ltxkeys@bracedefault + {\ltxkeys@sttrue\s@expandarg\ltxkeys@ordkey@b\ltxkeys@tkey}% + }{% + \ltxkeys@stfalse\s@expandarg\ltxkeys@ordkey@b\ltxkeys@tkey[]% + }% +} +\robust@def*\ltxkeys@ordkey@b#1[#2]#3{% + \if@boolFT{ltxkeys@st}{}{\ltxkeys@definedefault{#1}{#2}}% + \ltxkeys@saveinitialkeyvals{}{#1}{#2}% + \csn@def{\ltxkeys@hdr#1}##1{#3}% +} +% \ltxkeys@cmdkey[pref]{fam}[mp]{key}[dft]{fn} +\robust@def*\ltxkeys@cmdkey{% + \ltxkeys@svtrue\ltxkeys@swfalse + \ltxkeys@testopt@e\ltxkeys@cmdkey@a{cmd}% +} +\robust@def*\ltxkeys@cmdkey@a#1#2[#3]#4{% + \ltxkeys@findneedvalue{#2}% + \if@boolFT{ltxkeys@st}{}{\ltxkeys@definedefault\ltxkeys@tkey{#3}}% + \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#3}% + \begingroup + \edef\ltxkeys@tempa{\endgroup\csn@def{\ltxkeys@hdr\ltxkeys@tkey}####1}% + \edef\ltxkeys@tempb##1{% + {\csn@edef{#1\ltxkeys@tkey}{\noexpand\unexpanded{####1}}##1}% + }% + \expandafter\ltxkeys@tempa\ltxkeys@tempb{#4}% +} +% \ltxkeys@boolkey[pref]{fam}[mp]{key}[dft]{fn} +% \ltxkeys@boolkey+[pref]{fam}[mp]{key}[dft]{fn}{keyvalerr} +\robust@def*\ltxkeys@boolkey{% + \ltxkeys@svtrue\ltxkeys@swtrue + \ltxkeys@testpl{\ltxkeys@testopt@e\ltxkeys@boolkey@a{bool}}% +} +\robust@def*\ltxkeys@boolkey@a#1#2[#3]{% + \ltxkeys@findneedvalue{#2}% + \ltxkeys@saveinitialkeyvals{bool}\ltxkeys@tkey{#3}% + \aftercsname{\if@boolTF{ltxkeys@pl}\ltxkeys@boolkey@c\ltxkeys@boolkey@b}% + {\ltxkeys@hdr\ltxkeys@tkey}{\ltxkeys@tkey}{#1\ltxkeys@tkey}{#3}% +} +\robust@def*\ltxkeys@boolkey@b#1#2#3#4#5{% + \ltxkeys@boolkey@d#1{#2}{#3}{#4}% + {{\ltxkeys@setbool\ltxkeys@resa\usename{#3\ltxkeys@resa}#5}}% +} +\robust@def*\ltxkeys@boolkey@c#1#2#3#4#5#6{% + \ltxkeys@boolkey@d#1{#2}{#3}{#4}% + {{\ltxkeys@setbool\ltxkeys@resa\usename{#3\ltxkeys@resa}#5}{#6}}% +} +\robust@def*\ltxkeys@boolkey@d#1#2#3#4#5{% + \csn@newif{#3}% + \if@boolFT{ltxkeys@st}{}{\ltxkeys@definedefault{#2}{#4}}% + \cptexpandarg{\def#1##1}{% + \csn@def{#3}{####1}% + \noexpandcsn{cpt@pl\ifltxkeys@pl true\else false\fi}% + \unexpanded + {\cpt@sttrue\ltxkeys@cc@b,[\ltxkeys@resa]{##1}{true,false}#5}% + }% +} +% \ltxkeys@biboolkeys[pref]{fam}[mp]{key1,key2}[dft]{key1-fn}{key2-fn} +% \ltxkeys@biboolkeys+[pref]{fam}[mp]{key1,key2}[dft]{key1-fn}{key2-fn} +% {<fallback>} +\robust@def*\ltxkeys@biboolkeys{% + \ltxkeys@svtrue\ltxkeys@swtrue + \ltxkeys@testpl{\ltxkeys@testopt@e\ltxkeys@biboolkeys@a{}}% +} +\robust@def*\ltxkeys@biboolkeys@a#1#2[#3]{% + \if@boolTF{ltxkeys@pl}\ltxkeys@biboolkeys@c\ltxkeys@biboolkeys@b + {#1}{#2}{#3}% +} +\robust@def*\ltxkeys@biboolkeys@b#1#2#3#4#5{% + \ltxkeys@biboolkeys@d{#1}{#2}{#3}% + \ltxkeys@tempa{#4}% + \ltxkeys@tempb{#5}% +} +\robust@def*\ltxkeys@biboolkeys@c#1#2#3#4#5#6{% + \ltxkeys@biboolkeys@d{#1}{#2}{#3}% + \ltxkeys@tempa{#4}{#6}% + \ltxkeys@tempb{#5}{#6}% +} +\robust@def*\ltxkeys@biboolkeys@d#1#2#3{% + \ltxkeys@ifeltcountTF[=]{#2}\tw@{}{% + \ltxkeys@err{Biboolean keys '#2' not equal to 2}\@ehc + \@gobble + }% + \def\ltxkeys@keys{#2}% + \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@keys + \def\ltxkeys@tempa##1,##2\ltxkeys@nil##3##4{% + \ltxkeys@findneedvalue{##1}% + \let\ltxkeys@tkeya\ltxkeys@tkey + \ltxkeys@findneedvalue{##2}% + \cpt@newv@riables{tog}{\ltxkeys@hdr}{##1,##2}[false]% + \cptexpandsecond\ltxkeys@biboolkeys@e + {{\ltxkeys@tkeya}{\ltxkeys@tkey}}{#1}{#3}{##3}{##4}% + }% + \cptexpandsecond\ltxkeys@tempa + {\ltxkeys@keys\ltxkeys@nil{\ltxkeys@ttpref}{\ltxkeys@tfam}}% + \undefcs\ltxkeys@tkeya +} +\robust@def\ltxkeys@biboolkeys@e#1#2#3#4#5#6{% + \ifltxkeys@pl + \long\def\ltxkeys@tempa##1##2{% + \aftercsname\ltxkeys@boolkey@d{\ltxkeys@hdr#1}{#1}{#3#1}{#4}{{% + \ltxkeys@setbool\ltxkeys@resa\usename{#3#1\ltxkeys@resa}% + ##1\relax + \ltxkeys@biboolkeys@f{#1}{#2}{#3#1}{#5}{#6}% + }{##2}}% + }% + \long\def\ltxkeys@tempb##1##2{% + \aftercsname\ltxkeys@boolkey@d{\ltxkeys@hdr#2}{#2}{#3#2}{#4}{{% + \ltxkeys@setbool\ltxkeys@resa\usename{#3#2\ltxkeys@resa}% + ##1\relax + \ltxkeys@biboolkeys@f{#2}{#1}{#3#2}{#5}{#6}% + }{##2}}% + }% + \else + \long\def\ltxkeys@tempa##1{% + \aftercsname\ltxkeys@boolkey@d{\ltxkeys@hdr#1}{#1}{#3#1}{#4}{% + \ltxkeys@setbool\ltxkeys@resa\usename{#3#1\ltxkeys@resa}% + ##1\relax + \ltxkeys@biboolkeys@f{#1}{#2}{#3#1}{#5}{#6}% + }% + }% + \long\def\ltxkeys@tempb##1{% + \aftercsname\ltxkeys@boolkey@d{\ltxkeys@hdr#2}{#2}{#3#2}{#4}{% + \ltxkeys@setbool\ltxkeys@resa\usename{#3#2\ltxkeys@resa}% + ##1\relax + \ltxkeys@biboolkeys@f{#2}{#1}{#3#2}{#5}{#6}% + }% + }% + \fi +} +\robust@def\ltxkeys@biboolkeys@f#1#2#3#4#5{% + \iftogTF{\ltxkeys@hdr#1}{}{% + \settogtrue{\ltxkeys@hdr#2}% + \cptexpandarg{\ltxkeys@setkeys[#4]{#5}}{#2=\thebool@reverse{#3}}% + \settogfalse{\ltxkeys@hdr#2}% + }% +} +% \ltxkeys@stylekey[<pref>]{<fam>}[<mp>]{<key>}[<dft>](<deps>){<fn>} +\robust@def*\ltxkeys@stylekey{% + \ltxkeys@svtrue\ltxkeys@swfalse + \ltxkeys@testst{% + \cpt@cnta\ifltxkeys@st1\else0\fi\relax + \ltxkeys@testopt@e\ltxkeys@stylekey@a{style}% + }% +} +\robust@def*\ltxkeys@stylekey@a#1#2[#3]{% + \cpt@testpnopt{\ltxkeys@stylekey@b{#1}{#2}{#3}}{}% +} +\robust@def*\ltxkeys@stylekey@b#1#2#3(#4)#5{% + \ltxkeys@findneedvalue{#2}% + \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#3}% + \ifltxkeys@st + \s@expandarg\ltxkeys@definedefault\ltxkeys@tkey{#3}% + \fi + \cptexpandtwoargs\cpt@in + {\detokenize\expandafter{\unexpanded\expandafter + {\csname\ltxkeys@hdr\ltxkeys@tkey @value\endcsname}}} + {\detokenize{#4}}% + \csn@edef{\ltxkeys@hdr\ltxkeys@tkey @dependants}{\unexpanded{#4}}% + \cptpassexpanded{% + \long\csn@def{\ltxkeys@hdr\ltxkeys@tkey}####1{% + \csn@edef{#1\ltxkeys@tkey}{\noexpand\unexpanded{####1}}% + \edef\noexpand\parentval{\noexpand\unexpanded{####1}}% + \ifcpt@in + \csn@xdef{\ltxkeys@hdr\ltxkeys@tkey @value}% + {\noexpand\unexpanded{####1}}% + \fi + \unexpanded{#5}\relax + \ltxkeys@setdependants{\number\cpt@cnta}{#1}% + }% + }% +} +\robust@def*\ltxkeys@setdependants#1#2{% + \letcstocsn\ltxkeys@tempa{\ltxkeys@hdr\ltxkeys@tkey @dependants}% + \ifcsemptyTF\ltxkeys@tempa{}{% + \cpt@sttrue\cpt@csvnormalize[;]\ltxkeys@tempa + \if@boolTF{ltxkeys@dec}{}{% + \cptexpandargonce{\ltxkeys@s@tdependants{#1}{#2}}\ltxkeys@tempa + }% + }% +} +\robust@def*\ltxkeys@s@tdependants#1#2#3{% + \begingroup + \toks0{}\toks1{}\toks2{}% + \def\csv@do##1{% + \ltxkeys@s@td@pendants{##1}% + \ltxkeys@s@td@p@ndants{#1}% + }% + \expandafter\csv@@loop\expandafter[\ltxkeys@keyparser]{#3}% + \let\ifblankTF\relax + \cptpassexpanded{% + \endgroup + \noexpand\ltxkeys@deptrue + \ifblankTF{\the\toks0}{}% + {\ltxkeys@setkeys[\expandcsonce\ltxkeys@ttpref]% + {\expandcsonce\ltxkeys@tfam}{\the\toks0}}% + \ifblankTF{\the\toks1}{}% + {\ltxkeys@declarekeys[\ltxkeys@ttpref]<\ltxkeys@tfam>[#2]{\the\toks1}}% + \ifblankTF{\the\toks2}{}{% + \ltxkeys@err{Undefined dependant keys:^^J||\the\toks2||}{% + I have come across undefined dependant keys. You can + \MsgBrk use the star (*) form of '\string\ltxkeys@stylekey' + \MsgBrk to define and set dependant keys on the fly. + }% + }% + }% + \ltxkeys@depfalse +} +\robust@def*\ltxkeys@s@td@pendants#1{% + \begingroup + \emptifycsset{\key@name,\key@default,\key@macro}% + \@temptokena{#1}% + \def\ltxkeys@splita##1/##2/{% + \ifblankTF{##1##2}{% + \gobble@to@ltxkeys@nil + }{% + \ltxkeys@trimspaces{##1}\key@type + \def\stripstar####1*\@empty####2\@nil{\edef\key@type{####1}}% + \expandafter\stripstar\key@type\@empty*\@empty\@nil + \xifstrcmpFT\key@type{sty}{}{% + \ltxkeys@err{A dependant key can't have dependants: + \MsgBrk ||\the\@temptokena||}\@ehc + }% + \xifinsetTF\key@type{,ord,cmd,bool,choice,}{}{% + \ltxkeys@err{Invalid key type '\key@type' in dependant key(s) + \MsgBrk ||\the\@temptokena||}\@ehc + }% + \ifblankTF{##2}{% + \ltxkeys@err{Empty key name in dependant key(s)\MsgBrk + ||\the\@temptokena||}\@ehc + }{% + \ltxkeys@findneedvalue{##2}% + \let\key@name\ltxkeys@tkey + }% + \ltxkeys@splitb.% + }% + }% + \def\ltxkeys@splitb##1/##2/##3\ltxkeys@nil{% + \edef\key@default{\expandcsonce{\@gobble##1}}% + \ltxkeys@trimspacesincs\key@default + \xifstrcmpTF{\cptoxdetok\key@default}{\detokenize{\parentval}}{% + \edef\key@default{\expandcstwice\key@default}% + }{}% + \edef\key@macro{\unexpanded{##2}}% + }% + \ltxkeys@splita#1////\ltxkeys@nil + \cptpassexpanded{% + \endgroup + \cpt@csexit\key@type\cpt@csexit\key@name + \cpt@csexit\key@default\cpt@csexit\key@macro + }% +} +\robust@def*\ltxkeys@s@td@p@ndants#1{% + \ifcsndefTF{\ltxkeys@hdr\key@name}{% + \cptpassexpanded{% + \toks0{\the\toks0\oifblankTF{\the\toks0}{}{,}% + \expandcsonce\key@name=\expandcsonce\key@default}% + }% + }{% + \cptpassexpanded{% + \ifnum\numexpr#1=\@ne + \toks1{% + \the\toks1\oifblankTF{\the\toks1}{}{;}% + \key@type/\key@name + \ifcsnullTF\key@default{}{/\expandcsonce\key@default}% + \ifcsnullTF\key@macro{}{/\expandcsonce\key@macro}% + }% + \else + \toks2{\the\toks2\oifblankTF{\the\toks2}{}{,}% + \expandcsonce\key@name}% + \fi + }% + }% +} +% \ltxkeys@choicekey +% *+[<pref]{<fam>}[<mp>]{<key>}[<bin>]{<alt>}[<dft>]{<f1>}{<f2>} +\robust@def*\ltxkeys@choicekey{% + \ltxkeys@svtrue\ltxkeys@swfalse + \ltxkeys@teststpl{% + \ltxkeys@testopt@a{\cpt@testopt\ltxkeys@choicekey@a{chc\ltxkeys@hdr}}% + }% +} +\robust@def*\ltxkeys@choicekey@a[#1]#2{% + \begingroup + \def\siso@do##1{\catcode`##1\string=12\relax}% + \siso@@loop{=,.}% + \cpt@testopt{\expandafter\endgroup\ltxkeys@choicekey@b{#1}{#2}}{}% +} +\robust@def*\ltxkeys@choicekey@b#1#2[#3]#4{% + \ltxkeys@makechclist{#4}{0}% + \cpt@ifbrack{% + \ltxkeys@sttrue\ltxkeys@bracedefault + {\ltxkeys@choicekey@c{#2}{#1#2}{#3}{#4}}% + }{% + \ltxkeys@stfalse\ltxkeys@choicekey@c{#2}{#1#2}{#3}{#4}[]% + }% +} +\robust@def*\ltxkeys@choicekey@c#1#2#3#4[#5]{% + \ltxkeys@findneedvalue{#1}% + \ifltxkeys@st\ltxkeys@definedefault\ltxkeys@tkey{#5}\fi + \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#5}% + \cptexpanded{% + \ifltxkeys@pl\ltxkeys@choicekey@e\else\ltxkeys@choicekey@d\fi + \cptmakecs{\ltxkeys@hdr\ltxkeys@tkey}% + }% + {#2}{#3}{#4}% +} +\robust@def*\ltxkeys@choicekey@d#1#2#3#4#5{% + \ltxkeys@choicekey@f{#1}{#2}{#3}{#4}{{#5\relax}}% +} +\robust@def*\ltxkeys@choicekey@e#1#2#3#4#5#6{% + \ltxkeys@choicekey@f{#1}{#2}{#3}{#4}{{#5\relax}{#6\relax}}% +} +\robust@def*\ltxkeys@choicekey@f#1#2#3#4#5{% + \ifinsetTF{/.code=}{#4}{% + \def\ltxkeys@tempa{\ltxkeys@executechclist}% + }{% + \def\ltxkeys@tempa{\@gobble}% + }% + \edef#1{% + \edef\cptmakecs{#2}{\noexpand\unexpanded{####1}}% + \cptmakecs{cpt@st\ifltxkeys@st true\else false\fi}% + \cptmakecs{cpt@pl\ifltxkeys@pl true\else false\fi}% + \unexpanded{\ltxkeys@cc@b,[#3]}{####1}{\expandcsonce\ltxkeys@chclist}% + \unexpanded{#5}\expandcsonce\ltxkeys@tempa{\unexpanded{#4}}% + }% + \def\ltxkeys@tempa{\def#1####1}% + \expandafter\ltxkeys@tempa\expandafter{#1}% +} +\robust@def*\ltxkeys@makechclist#1#2{% + \begingroup + \def\ltxkeys@chclist{}% + \def\ltxkeys@tempb##1/.code=##2\ltxkeys@nil{% + \ltxkeys@trimspaces{##1}\ltxkeys@tempa + \ifcase#2\relax + \cptaddtolist*[,]\ltxkeys@chclist\ltxkeys@tempa + \or + \cptpassexpanded{\lowercase{% + \def\noexpand\ltxkeys@tempa{\expandcsonce\ltxkeys@tempa}% + \def\noexpand\ltxkeys@tval{\expandcsonce\ltxkeys@tval}% + }}% + \oifstrcmpFT\ltxkeys@tempa\ltxkeys@tval{}{% + \edef\ltxkeys@chclist{\unexpanded{##2}}% + \cptbreakloop + }% + \else + \ltxkeys@err{Invalid number '#2' in \string\ltxkeys@makechclist}\@ehc + \fi + }% + \def\csv@do##1{% + \ifinsetTF{/.code=}{##1}{% + \ltxkeys@tempb##1\ltxkeys@nil + }{% + \ltxkeys@tempb##1/.code=\ltxkeys@nil + }% + }% + \ifinsetTF{/.code=}{#1}{% + \expandafter\csv@@parse\expandafter[\ltxkeys@keyparser]{#1}% + }{% + \csv@@parse[,]{#1}% + }% + \postgroupdef\ltxkeys@chclist\endgroup +} +\robust@def*\ltxkeys@executechclist#1{% + \begingroup + \ltxkeys@makechclist{#1}{1}% + \expandafter\endgroup\ltxkeys@chclist +} +\robust@def*\ltxkeys@definedefault#1#2{% + \xifstrcmpTF{\detokenize{#2}}{\detokenize{\parentval}}{% + \s@expandarg\ltxkeys@trimspaces{#2}\ltxkeys@tempa + }{% + \ltxkeys@trimspaces{#2}\ltxkeys@tempa + }% + \csn@edef{\ltxkeys@hdr#1@default}{% + \noexpandcsn{\ltxkeys@hdr#1}{\expandcsonce\ltxkeys@tempa}% + }% +} +\robust@def*\ltxkeys@getkeyname#1=#2\ltxkeys@nil#3{% + \ltxkeys@trimspaces{#1}#3% +} +\robust@def*\ltxkeys@getkeynames#1{% + \def\ltxkeys@keynames{}% + \def\ltxkeys@do##1{% + \ltxkeys@getkeyname##1=\ltxkeys@nil\ltxkeys@tkey + \edef\ltxkeys@keynames{% + \cptliststack,\ltxkeys@keynames\expandcsonce\ltxkeys@tkey + }% + }% + \ifblankTF{#1}{}{\ltxkeys@csvparse{#1}}% +} +\robust@def*\option@keys{% + \ltxkeys@inpkgcls\option@keys + \cpt@testst\ltxkeys@optionk@ys +} +\robust@def*\ltxkeys@optionk@ys{% + \if@boolTF{cpt@st}{% + \ltxkeys@testopt@g{optionkeys}{not}% + }{% + \ltxkeys@testopt@g{optionkeys}{}% + }% +} +\robust@def*\notoption@keys{% + \ltxkeys@inpkgcls\notoption@keys + \ltxkeys@testopt@g{optionkeys}{not}% +} +\robust@def*\ltxkeys@optionkeys#1#2{% + \def\ltxkeys@do##1{% + \ifcsndefTF{\ltxkeys@hdr##1}{% + \ifcsndefTF{\ltxkeys@hdr#1option@keys}{% + \xifinsetTF{,\detokenize{##1},} + {,\cptsxdetok{\@nameuse{\ltxkeys@hdr#1option@keys}},}{}{% + \csn@edef{\ltxkeys@hdr#1option@keys}{% + \expandcsnonce{\ltxkeys@hdr#1option@keys},% + \unexpanded{##1}% + }% + }% + }{% + \csn@def{\ltxkeys@hdr#1option@keys}{##1}% + }% + }{% + \ltxkeys@err{Key '##1' is undefined in family '\ltxkeys@tfam' + \MsgBrk Only defined keys can be made '#1option' keys.}\@ehc + }% + }% + \ltxkeys@csvparse{#2}% +} +\robust@def*\makeoption@keys{\cpt@teststopt\ltxkeys@makeoptionkeys{KV}} +\robust@def*\ltxkeys@makeoptionkeys[#1]#2{% + \let\ifmakeoptst\ifcpt@st + \ifcsndefTF{#1@#2@initial@keyvals}{% + \edef\ltxkeys@tempa{\expandcsnonce{#1@#2@initial@keyvals}}% + }{% + \ltxkeys@err{No initial key-values for family '#2'}\@ehc + }% + \s@expandarg\ltxkeys@getkeynames\ltxkeys@tempa + \ifcsnullTF\ltxkeys@keynames{}{% + \cptexpandarg{\usename{\ifmakeoptst not\fi option@keys}[#1]{#2}}{% + \expandcsonce\ltxkeys@keynames + }% + }% + \undefcs\ifmakeoptst +} +\robust@def*\makenotoption@keys{% + \cpt@sttrue\cpt@testopt\ltxkeys@makeoptionkeys{KV}% +} +\robust@def*\ltxkeys@testoptionkey#1{% + \ifcsndefFT{\ltxkeys@hdr#1option@keys}{}{% + \cpt@choicefdfalse + \def\ltxkeys@do##1{% + \s@expandarg\ifstrcmpTF\ltxkeys@tkey{##1}{% + \cpt@choicefdtrue\ltxkeys@break + }{}% + }% + \aftercsname{\ltxkeys@csvloop*}{\ltxkeys@hdr#1option@keys}% + \if@boolFT{cpt@choicefd}{}{% + \ltxkeys@err{The following key should + \ifnullTF{#1}\@gobblespace{#1} appear in + \MsgBrk\noexpand\usepackage or \string\RequirePackage: + ^^J||\ltxkeys@ttpref, \ltxkeys@tfam, \ltxkeys@tkey||% + }\@ehc + }% + }% +} +\robust@def*\ltxkeys@testneedvalkey{% + \begingroup + \cpt@choicefdfalse + \def\ltxkeys@do##1{% + \s@expandarg\ifstrcmpTF\ltxkeys@tkey{##1}{% + \cpt@choicefdtrue\ltxkeys@break + }{}% + }% + \aftercsname{\ltxkeys@csvloop*}{\ltxkeys@hdr needvalue@keys}% + \ifcpt@choicefd + \ltxkeys@err{You're required to supply a value for + \MsgBrk key '\ltxkeys@tkey' in family '\ltxkeys@tfam'}{% + Please supply a value for key '\ltxkeys@tkey' of families + \MsgBrk'\ltxkeys@fams' and rerun. The author of this key + \MsgBrk meant it to require a user value. + }% + \fi + \endgroup +} +\new@def*\ltxkeys@setbool#1{% + \xifstrcmpTF{#1}{on}{% + \def#1{true}% + }{% + \xifstrcmpTF{#1}{off}{% + \def#1{false}% + }{% + \edef#1{#1}% + }% + }% +} +\robust@def*\ltxkeys@accumkeyvals#1{% + \ltxkeys@ifinTF(1)% + {\ltxkeys@setmnkey,\setmnkey,\setaliaskey}{#1}% + \ltxkeys@twktrue\ltxkeys@twkfalse + \begingroup + \edef\key@vals{% + \cptliststack,\key@vals\expandcsonce\key@name=% + \ifltxkeys@dep + \expandcsonce\key@default + \else + \oifstrcmpTF\key@default{true}{false}{% + \expandcsonce\key@default + }% + \fi + }% + \ifltxkeys@ssk + \gletcs\key@vals\key@vals + \else + \ifltxkeys@twk\else + \gletcs\key@vals\key@vals + \fi + \fi + \endgroup +} +% \ltxkeys@definekeys[pref]<fam>[macropf]{<keyname>=<dft>/<callback>; ...} +\robust@def*\ltxkeys@definekeys{% + \begingroup + \endlinechar\m@one + \cpt@teststopt\ltxkeys@definekeys@a{KV}% +} +\robust@def*\ltxkeys@definekeys@a[#1]{% + \gletcs\ifdefkeyst\ifcpt@st + \cpt@testfam{\ltxkeys@definekeys@b#1}% +} +\robust@def*\ltxkeys@definekeys@b#1<#2>{% + \cpt@testopt + {\expandafter\endgroup\ltxkeys@definekeys@c{#1}{#2}}{}% +} +\robust@def*\ltxkeys@definekeys@c#1#2[#3]#4{% + \begingroup + \ltxkeys@trimspaces{#1}\key@prefix + \ltxkeys@trimspaces{#2}\key@family + \ltxkeys@trimspaces{#3}\macro@prefix + \toks@{\undefcs\ifdefkeyst}% + \def\key@vals{}% + \def\ltxkeys@splita##1={% + \begingroup + \defpass\reserved@a####1\ltxkeys@nil{\endgroup + \ltxkeys@splitb##1/####1//\ltxkeys@nil + }.% + }% + \def\ltxkeys@splitb##1/##2/##3/##4\ltxkeys@nil{% + \ifblankTF{##1}{% + \ifblankTF{##2##3}{}{% + \ltxkeys@err{Empty key name while in + \string\ltxkeys@definekeys}\@ehc + }% + }{% + \ltxkeys@findneedvalue{##1}% + \let\key@name\ltxkeys@tkey + \ifdefkeyst + \ifcsndefFT{\key@prefix @\key@family @\key@name}{}{% + \ltxkeys@err{Key '\key@name' already defined in family + \MsgBrk '#2' with prefix '#1'}\@ehc + }% + \fi + \ifblankTF{##2}{% + \def\key@default{}% + }{% + \s@expandarg\ltxkeys@trimspaces{\@gobble##2}\key@default + }% + \ltxkeys@accumkeyvals{##3}% + \def\defwith{\ltxkeys@boolkey}% + \oifstrcmpTF\key@default{true}{}{% + \oifstrcmpTF\key@default{false}{}{% + \def\defwith{\ltxkeys@cmdkey}% + }% + }% + \cptexpanded{% + \toks@{\the\toks@ + \cptmakecs{ltxkeys@twk\ifltxkeys@twk true\else false\fi}% + \defwith[\key@prefix]{\key@family}% + \ifx\macro@prefix\@empty\else[\macro@prefix]\fi + {\key@name}[\expandcsonce\key@default]{\unexpanded{##3}}% + }% + }% + }% + }% + \long\def\csv@do##1{% + \cpt@checkeq##1\cpt@nil{% + \ltxkeys@splita##1\ltxkeys@nil + }{% + \ltxkeys@splitb##1///\ltxkeys@nil + }% + }% + \expandafter\csv@@parse\expandafter[\ltxkeys@keyparser]{#4}% + \cptexpandsecond\endgroup{% + \the\toks@ + \noexpand\ltxkeys@twkfalse + \ifcsnullTF\key@vals{}{\noexpand\ltxkeys@setkeys + [\key@prefix]{\key@family}{\expandcsonce\key@vals}% + }% + }% +} +\new@def*\ltxkeys@badkeytypes{} +\robust@def*\ltxkeys@keytypeerr#1{% + \edef\ltxkeys@badkeytypes{\cptliststack,\ltxkeys@badkeytypes#1}% +} +% \ltxkeys@declarekeys[pref]<fam>[macropf]{<keytype>/<keyname> +% /<dft>/<callback><parser> ...} +\robust@def*\ltxkeys@declarekeys{% + \begingroup + \endlinechar\m@one + \cpt@teststopt\ltxkeys@declarekeys@a{KV}% +} +\robust@def*\ltxkeys@declarekeys@a[#1]{% + \gletcs\ifdefkeyst\ifcpt@st + \cpt@testfam{\ltxkeys@declarekeys@b{#1}}% +} +\robust@def*\ltxkeys@declarekeys@b#1<#2>{% + \cpt@testopt{\expandafter\endgroup\ltxkeys@declarekeys@c{#1}#2}{}% +} +\robust@def*\ltxkeys@declarekeys@c#1#2[#3]#4{% + \ltxkeys@dectrue + \begingroup + \ltxkeys@trimspaces{#1}\key@prefix + \ltxkeys@trimspaces{#2}\key@family + \ltxkeys@trimspaces{#3}\macro@prefix + \def\key@vals{}% + \toks@{\undefcs\ifdefkeyst}% + \def\ltxkeys@splita##1/##2/{% + \ifblankTF{##1##2}{% + \gobble@to@ltxkeys@nil + }{% + \ifblankTF{##2}{% + \ltxkeys@err{Empty key name in \string\ltxkeys@declarekeys}\@ehc + }{% + \ltxkeys@trimspaces{##1}\key@type + \ltxkeys@findneedvalue{##2}% + \let\key@name\ltxkeys@tkey + \ifdefkeyst + \ifcsndefFT{\key@prefix @\key@family @\key@name}{}{% + \ltxkeys@err{Key '\key@name' already defined in family + \MsgBrk '#2' with prefix '#1'}\@ehc + }% + \fi + \oifstrcmpFT\key@type{choice}{}{% + \s@expandarg\ltxkeys@splitchoice\key@name + }% + \ltxkeys@splitb.% + }% + }% + }% + \def\ltxkeys@splitb##1/##2/##3/##4\ltxkeys@nil{% + \edef\key@default{\expandcsonce{\@gobble##1}}% + \ifcsnullTF\key@default{% + \oifstrcmpFT\key@type{bool}{}{\def\key@default{true}}% + }{% + \ltxkeys@trimspacesincs\key@default + }% + \oifinsetFT{sty}\key@type{}{\ltxkeys@declarekeys@d{##3}}% + \ltxkeys@accumkeyvals{##2}% + \def\ltxkeys@tempa{ord}% + \edef\ltxkeys@tempa{% + [\key@prefix]{\key@family}% + \ifx\key@type\ltxkeys@tempa\else\ifx\macro@prefix\@empty\else + [\macro@prefix]\fi\fi + {\key@name}% + }% + \cptpassexpanded{% + \toks@{\the\toks@ + \cptmakecs{ltxkeys@twk\ifltxkeys@twk true\else false\fi}% + \IfStrEqCase[\ltxkeys@keytypeerr{\expandcsonce\key@type}]% + {\key@type}{% + {sty}{% + \ltxkeys@stylekey\ltxkeys@tempa + [\expandcsonce\key@default](\expandcsonce\dependant)% + {\unexpanded{##2}}% + }% + {sty*}{% + \ltxkeys@stylekey*\ltxkeys@tempa + [\expandcsonce\key@default](\expandcsonce\dependant)% + {\unexpanded{##2}}% + }% + {cmd}{% + \ltxkeys@cmdkey\ltxkeys@tempa + [\expandcsonce\key@default]{\unexpanded{##2}}% + }% + {bool}{% + \ltxkeys@boolkey+\ltxkeys@tempa + [\expandcsonce\key@default]{\unexpanded{##2}}% + {\ltxkeys@keyvalerr}% + }% + {choice}{% + \ltxkeys@choicekey*+\ltxkeys@tempa + [\unexpanded{\val\nr}]{\expandcsonce\ltxkeys@alt}% + [\expandcsonce\key@default]{\unexpanded{##2}}% + {\ltxkeys@keyvalerr}% + }% + {ord}{% + \ltxkeys@ordkey\ltxkeys@tempa + [\expandcsonce\key@default]{\unexpanded{##2}}% + }% + }% + }% + }% + }% + \ifdefTF\ltxkeys@keyparser{% + \stripallouterbracesincs\ltxkeys@keyparser + }{% + \def\ltxkeys@keyparser{;}% + }% + \def\csv@do##1{% + \ltxkeys@splita##1/////\ltxkeys@nil + }% + \expandafter\csv@@loop\expandafter[\ltxkeys@keyparser]{#4}% + \cptexpandsecond\endgroup{% + \the\toks@ + \noexpand\ltxkeys@twkfalse + \edef\noexpand\key@vals{\ox@unexpanded\key@vals}% + }% + \ifx\ltxkeys@badkeytypes\@empty\else + \cpt@err{Invalid key types '\ltxkeys@badkeytypes'}\@ehc + \fi + \ifcsnullTF\key@vals{}{% + \cptexpandargonce{\ltxkeys@setkeys[#1]{#2}}\key@vals + }% + \ltxkeys@decfalse +} +\robust@def\ltxkeys@declarekeys@d#1{% + \begingroup + \ifblankTF{#1}{% + \def\dependant{}% + }{% + \ifinsetFT{>}{#1}{% + \ltxkeys@err{Missing key type and name in dependant key + ^^J\detokenize{#1}'}{No '>' in dependant key.}% + \def\dependant{}% + }{% + \def\ltxkeys@tempa##1>##2>##3>##4>##5\ltxkeys@nil{% + \edef\dependant{\unexpanded{##1/##2/##3/##4}}% + }% + \ltxkeys@tempa#1>>>>\ltxkeys@nil + }% + }% + \postgroupdef\dependant\endgroup +} +\robust@def*\ltxkeys@setmnkey#1{% + \xifinsetTF{,}{\detokenize{#1}}{% + \ltxkeys@err{\noexpand\ltxkeys@setmnkey doesn't accept key list}\@ehc + }{% + \cpt@testopt{\ltxkeys@settmnkey@a#1}{}% + }% +} +\robust@def*\ltxkeys@settmnkey@a#1[#2]{% + \cptexpandsecond\ltxkeys@setkeys{% + [\ltxkeys@ttpref]{\ltxkeys@tfam}{% + #1=\ifnullTF{#2}{\expandcsonce\ltxkeys@tval}{\unexpanded{#2}}% + }% + }% +} +\newletcs\setmnkey\ltxkeys@setmnkey +\newletcs\setaliaskey\ltxkeys@setmnkey +\robust@def*\ltxkeys@splitchoice#1{% + \begingroup + \def\ltxkeys@tempa##1.##2##3\ltxkeys@nil{\endgroup + \ltxkeys@trimspaces{##1}\key@name + \ifstrcmpTF{##2}{.}{% + \ltxkeys@err{Invalid alternate value list for key '#1'}\@ehc + }{% + \cptifmacroTF{##2}{% + \edef\ltxkeys@alt{\expandcsonce{##2}}% + }{% + \edef\ltxkeys@alt{\unexpanded{##2}}% + }% + \despacecontent\ltxkeys@alt + }% + }% + \ltxkeys@tempa#1..\ltxkeys@nil +} +\robust@def*\ltxkeys@setinitialkeyvals#1#2{% + \ifcsndefFT{#1@#2@initial@keyvals}{}{% + \ifcsnnullTF{#1@#2@initial@keyvals}{}{% + \cptpassexpanded{% + \noexpand\ltxkeys@setkeys[#1]{#2}% + {\expandcsnonce{#1@#2@initial@keyvals}}% + }% + }% + }% +} +% \ltxkeys@initializekeys[<prefix>]{<fams>}[<na>] +\robust@def*\ltxkeys@initializekeys{% + \cpt@testopt\ltxkeys@in@tializekeys{KV}% +} +\robust@def*\ltxkeys@in@tializekeys[#1]#2{% + \cpt@testopt{\ltxkeys@in@ti@lizekeys{#1}{#2}}{}% +} +\robust@def*\ltxkeys@in@ti@lizekeys#1#2[#3]{% + \begingroup + \def\ltxkeys@resa{}% + \def\ltxkeys@do##1{% + \edef\ltxkeys@resa{% + \cptliststack,\ltxkeys@resa + \ifcsndefFT{#1@##1@initial@keyvals}{}{% + \expandcsnonce{#1@##1@initial@keyvals}% + }% + }% + }% + \ltxkeys@csvparse{#2}% + \ltxkeys@getkeynames{#3}% + \cptexpandsecond{\endgroup\ltxkeys@setkeys*+[#1]{#2}}% + {[\ltxkeys@keynames]{\ltxkeys@resa}}% +} + +% \ltxkeys@launchkeys[<prefix>]{<fams>}{<curr>} +\robust@def*\ltxkeys@launchkeys{\cpt@testopt\ltxkeys@l@unchkeys{KV}} +\robust@def*\ltxkeys@l@unchkeys[#1]#2#3{% + \ltxkeys@in@ti@lizekeys{#1}{#2}[#3]% + \ifblankTF{#3}{}{\ltxkeys@setkeys[#1]{#2}{#3}}% +} + +% \ltxkeys@setkeys*+[<prfs>]{<fams>}[<na>]{<curr>} +\robust@def*\ltxkeys@setkeys{% + \ltxkeys@rmfalse + \ltxkeys@teststpl{\ltxkeys@testopt@c\ltxkeys@setkeys@a}% +} +\robust@def*\ltxkeys@setrmkeys{% + \ltxkeys@rmtrue + \ltxkeys@teststpl{\ltxkeys@testopt@c\ltxkeys@setrmkeys@a}% +} +\robust@def*\ltxkeys@setrmkeys@a[#1]{% + \cptexpandarg{\ltxkeys@setkeys@a[#1]} + {\expandcsnonce{\ltxkeys@hdr rmkeys}}% +} +\robust@def*\ltxkeys@setkeys@a[#1]#2{% + \cpt@choicefdfalse + \def\siso@do##1{% + \ifstrcmpTF{#2}{##1}\cpt@choicefdtrue\relax + }% + \siso@@loop{.,;:+-=*^_/[()]}% + \ifcpt@choicefd + \ltxkeys@err{Invalid key list '#2'}\@ehc + \fi + \ifnum\ltxkeys@keydepth=\z@pt + \csn@def{\ltxkeys@hdr rmkeys}{}% + \def\ltxkeys@undefinedkeys{}% + \fi + \edef\ltxkeys@nakeys{\unexpanded{#1}}% + \ifcsemptyTF\ltxkeys@nakeys{}{% + \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@nakeys + }% + \def\ltxkeys@do##1{% + \edef\CurrentKeyval{\unexpanded{##1}}% + \ltxkeys@setkeys@b##1=\ltxkeys@nil + }% + \ltxkeys@kvparse{#2}% + \emptifycsset{\CurrentPref,\CurrentFam,\CurrentKeyval, + \CurrentKey,\CurrentVal}% + \ltxkeys@exopfalse\ltxkeys@pxopfalse + \ifcsnullTF\ltxkeys@undefinedkeys{}\ltxkeys@logunknownkeys +} +\robust@def*\ltxkeys@setkeys@b#1=#2\ltxkeys@nil{% + \ifinsetTF{\needvalue}{#1}{% + \ltxkeys@err{\noexpand\needvalue pointer not allowed + \MsgBrk when setting keys}\@ehc + }{}% + \ltxkeys@findpointer\savevalue{#1}\ltxkeys@tkey + \ltxkeys@svtrue\ltxkeys@svfalse + \let\CurrentKey\ltxkeys@tkey + \ifinsetTF{=\ltxkeys@nil}{#2\ltxkeys@nil}{% + \ltxkeys@novalfalse + \begingroup + \defpass\reserved@a##1=##2\ltxkeys@nil{\endgroup + \edef\ltxkeys@tval{\expandcsonce{\@gobble##1}}% + \let\CurrentVal\ltxkeys@tval + }% + .#2\ltxkeys@nil + }{% + \ltxkeys@novaltrue + \def\ltxkeys@tval{}% + }% + \ifcsemptyTF\ltxkeys@tkey{% + \ifltxkeys@noval\else + \ltxkeys@err{No key specified for value + '\expandcsonce\ltxkeys@tval' + \MsgBrk in families '\ltxkeys@fams'}\@ehc + \fi + }{% + \xifinsetTF{,\ltxkeys@tkey,}{,\ltxkeys@nakeys,}{}{% + \ltxkeys@setkeys@c + }% + }% +} +\robust@def*\ltxkeys@setkeys@c{% + \ltxkeys@kffalse + \if@boolTF{ltxkeys@pl}{% + \def\ltxkeys@do##1{% + \def\CurrentPref{##1}% + \ltxkeys@makepf{##1}% + \def\ltxkeys@do####1{% + \def\ltxkeys@tfam{####1}% + \let\CurrentFam\ltxkeys@tfam + \ltxkeys@makehdr\ltxkeys@tfam + \ltxkeys@setkeys@d + }% + \ltxkeys@csvloop*\ltxkeys@fams + }% + \ltxkeys@csvloop*\ltxkeys@prefs + }{% + \def\ltxkeys@do##1{% + \if@boolTF{ltxkeys@kf}{% + \ltxkeys@break + }{% + \def\CurrentPref{##1}% + \ltxkeys@makepf{##1}% + \def\ltxkeys@do####1{% + \if@boolTF{ltxkeys@kf}{% + \ltxkeys@break + }{% + \def\ltxkeys@tfam{####1}% + \let\CurrentFam\ltxkeys@tfam + \ltxkeys@makehdr\ltxkeys@tfam + \ltxkeys@setkeys@d + }% + }% + \ltxkeys@csvloop*\ltxkeys@fams + }% + }% + \ltxkeys@csvloop*\ltxkeys@prefs + }% + \if@boolTF{ltxkeys@kf}{% + \if@boolFT{ltxkeys@pxop}{}{% + \ifx\ltxkeys@testname\cpt@documentclass + \cpt@removecurroption\CurrentKeyval + \fi + }% + }{% + \ifcsndefTF{\ltxkeys@hdr default@ds}{% + \begingroup + \let\xp\expandcsonce + \cptexpandsecond{% + \endgroup\usename{\ltxkeys@hdr default@ds}% + }{% + {\xp\ltxkeys@ttpref}{\xp\ltxkeys@tfam}% + {\xp\ltxkeys@tkey}{\xp\ltxkeys@tval}% + }% + }{% + \if@boolTF{ltxkeys@pxop}{% + \ifxTF\@currext\@clsextension{}\ltxkeys@unknownoptionerror + }{% + \if@boolTF{ltxkeys@st}{% + \cptexpandargonce{\aftercsname{\cptfiltermergekv[,]} + {\ltxkeys@hdr rmkeys}}\CurrentKeyval\nofilter + }{% + \ltxkeys@getinnoval + \cptexpandarg{\cptfiltermergecsv[;]\ltxkeys@undefinedkeys}{% + \ltxkeys@ttpref,\ltxkeys@tfam,\ltxkeys@tkey,\InnocentVal + }\nofilter + }% + }% + }% + }% +} +\robust@def*\ltxkeys@setkeys@d{% + \ifcsndefFT{\ltxkeys@hdr\ltxkeys@tkey}{}{% + \ltxkeys@kftrue + \if@boolTF{ltxkeys@pxop}{% + \ltxkeys@testoptionkey{not}% + }{% + \if@boolTF{ltxkeys@exop}{}{\ltxkeys@testoptionkey{}}% + }% + \if@boolTF{ltxkeys@sv}{% + \edef\ltxkeys@tempa{\ltxkeys@tkey{\expandcsonce\ltxkeys@tval}}% + \ltxkeys@addtopointedkeys{savevalue}\ltxkeys@tempa + }{}% + \if@boolTF{ltxkeys@noval}{% + \ifcsndefTF{\ltxkeys@hdr needvalue@keys}{\ltxkeys@testneedvalkey}{}% + \ifcsndefTF{\ltxkeys@hdr\ltxkeys@tkey @default}{% + \cptsevenxp\ltxkeys@usedefault + \usename{\ltxkeys@hdr\ltxkeys@tkey @default}\ltxkeys@nil + }{% + \ltxkeys@err{No value specified for key '\ltxkeys@tkey'}\@ehc + }% + }{% + \s@expandarg\ltxkeys@replacepointers\ltxkeys@tval + \if@boolTF{ltxkeys@verbose}{% + \ltxkeys@getinnovalnopad + \wlog{Key executed: \ltxkeys@ttpref, \ltxkeys@tfam, + \ltxkeys@tkey, \InnocentVal; on level '\the\ltxkeys@keydepth'.}% + }{}% + \cpt@pushstate\ltxkeys@setkeys\ltxkeys@state\ltxkeys@keydepth + \csname\ltxkeys@hdr\ltxkeys@tkey\expandafter + \endcsname\expandafter{\ltxkeys@tval}\relax + \cpt@popstate\ltxkeys@setkeys\ltxkeys@keydepth + }% + }% +} +\robust@def*\ltxkeys@usedefault#1#2\ltxkeys@nil{% + \begingroup + \csn@def{\ltxkeys@hdr\ltxkeys@tkey}##1{% + \toks@{\def\ltxkeys@tval{##1}}% + }% + \usename{\ltxkeys@hdr\ltxkeys@tkey @default}% + \expandafter\endgroup\the\toks@ + \s@expandarg\ltxkeys@replacepointers\ltxkeys@tval + \if@boolTF{ltxkeys@verbose}{% + \ltxkeys@getinnovalnopad + \wlog{Key executed: \ltxkeys@ttpref, \ltxkeys@tfam, + \ltxkeys@tkey, \InnocentVal\@space(default); + on level '\the\ltxkeys@keydepth'.}% + }{}% + \cpt@pushstate\ltxkeys@setkeys\ltxkeys@state\ltxkeys@keydepth + \cptifmacroTF{#1}{% + \expandafter#1\expandafter{\ltxkeys@tval}\relax + }{% + \ltxkeys@err{Faulty key macro '\detokenize{#1}'}\@ehc + }% + \cpt@popstate\ltxkeys@setkeys\ltxkeys@keydepth +} + +\robust@def*\ltxkeys@getsavedval#1{% + \def\reserved@a##1#1##2##3\ltxkeys@nil{% + \ifblankTF{##3}\@firstoftwo{% + \def\reserved@a{##2}\@secondoftwo + }% + }% + \cptsevenxp\reserved@a\@nameuse + {\ltxkeys@hdr savevalue@keys}#1{\ltxkeys@nil}\ltxkeys@nil +} +\robust@def*\ltxkeys@replacepointers#1{% + \def\ltxkeys@resa{}% + \@tempswafalse + \ifbracedTF{#1}{% + \ltxkeys@r@placepointers{#1}\usevalue\ltxkeys@nil + }{% + \ltxkeys@r@placepointers#1\usevalue\ltxkeys@nil + }% + \let\ltxkeys@resa\relax +} +\robust@def*\ltxkeys@r@placepointers#1\usevalue#2{% + \def\reserved@a{#2}% + \ifxTF\reserved@a\ltxkeys@nnil{% + \edef\ltxkeys@tval{\unexpanded{#1}}% + \if@tempswa + \ifltxkeys@verbose + \ltxkeys@getinnovalnopad + \wlog{Value '\InnocentVal' of key '\ltxkeys@tkey' + inherited from key '\ltxkeys@tempb'.}% + \fi + \fi + }{% + \ltxkeys@getsavedval{#2}{% + \ltxkeys@err{No value recorded for key '#2'}\@ehc + \ltxkeys@r@placepointers + }{% + \@tempswatrue + \def\ltxkeys@tempb{#2}% + \oifinset@sp@TF,{#2}\ltxkeys@resa{% + \ltxkeys@err{Dangerous back linking of pointers}{% + Key pointer replacement terminated due + \MsgBrk to possible back linking.}% + \@gobble + }{% + \edef\ltxkeys@resa{\cptliststack,\ltxkeys@resa#2}% + \s@expandarg\ifbracedTF\reserved@a{% + \s@expandarg\ltxkeys@r@placepointers\reserved@a + }{% + \expandafter\ltxkeys@r@placepointers\reserved@a + }% + }% + }% + }% +} +\robust@def*\ltxkeys@storevalue{% + \ltxkeys@testpl{\ltxkeys@testopt@a\ltxkeys@st@revalue}% +} +\robust@def*\ltxkeys@st@revalue#1#2{% + \ifinsetFT{,}{#1}{}{% + \ltxkeys@err{Illegal multiple keys for \string\ltxkeys@storevalue}% + \@ehc + }% + \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}% + \ltxkeys@getsavedval{#1}{% + \ifltxkeys@pl + \expandafter\@firstofone + \else + \ltxkeys@err{% + No value recorded for key '#1' of + \MsgBrk family '\ltxkeys@tfam' and prefix '\ltxkeys@ttpref' + }{% + You have asked me to store the value of key '#1' + \MsgBrk (of family '\ltxkeys@tfam' and prefix '\ltxkeys@ttpref') + in the macro '\detokenize{#2}', + \MsgBrk but I can't find a value for key '#1'. Perhaps + \MsgBrk you haven't yet executed key '#1' or you didn't + \MsgBrk ask me to save its value. + }% + \fi + }{% + \let#2=\reserved@a + }% +} +\robust@def*\ltxkeys@getinnoval{\@tempswatrue\ltxkeys@g@tinnoval} +\robust@def*\ltxkeys@getinnovalnopad{\@tempswafalse\ltxkeys@g@tinnoval} +\robust@def*\ltxkeys@g@tinnoval{% + \ifxTF\ltxkeys@tval\@empty{% + \def\InnocentVal{???}% + }{% + \def\InnocentVal{}% + \def\ltxkeys@tempa{\\}% + \def\do##1##2##3##4##5##6##7##8##9\@@{% + \def\siso@do####1{% + \edef\InnocentVal{\InnocentVal\ifx\siso@arg\ltxkeys@tempa + \if@tempswa\@space\fi\else\if\siso@arg\cpt@leftbracechar[\else + \if\siso@arg\cpt@rightbracechar]\else####1\fi\fi\fi}% + }% + \siso@@loop{##1##2##3##4##5##6##7##8}% + }% + \expandafter\do\detokenize\expandafter + {\ltxkeys@tval}\\\\\\\\\\\\\\\\\\\@@ + + }% +} +\robust@def*\ltxkeys@keyvalerr{% + \ltxkeys@getinnovalnopad + \ltxkeys@err{Erroneous value '\InnocentVal' for key or option + \MsgBrk'\ltxkeys@tkey'}\@ehc +} +\robust@def*\ltxkeys@unknownkeyhandler{% + \cpt@testopt\ltxkeys@unkn@wnkeyhandler{KV}% +} +\robust@def*\ltxkeys@unkn@wnkeyhandler[#1]#2#3{% + \begingroup + \toks@{}% + \toks1{##1##2##3##4}% + \toks2{\ltxkeys@getinnovalnopad#3}% + \def\ltxkeys@do##1{% + \ltxkeys@makepf{##1}% + \def\ltxkeys@do####1{% + \ltxkeys@makehdr{####1}% + \toks@\expandafter{\the\expandafter\toks@\expandafter + \csn@def\expandafter{\ltxkeys@hdr default@ds}% + \the\toks1{\the\toks2}}% + }% + \ltxkeys@csvparse{#2}% + }% + \ltxkeys@csvparse{#1}% + \edef\reserved@a{\s@expandarg\@iden{\the\toks@}}% + \expandafter\endgroup\reserved@a +} + +\robust@def*\ltxkeys@logunknownkeys{% + \ltxkeys@l@gunknownkeys + \ltxkeys@err{The above keys are undefined and % + couldn't be set}\@ehc +} +\robust@def*\ltxkeys@l@gunknownkeys{% + \gletcs\ltxkeys@l@gunknownkeys\relax + \begingroup + \cpt@cnta\z@pt + \edef\ltxkeys@skipa{}% + \cptwhilenum\cpt@cnta<20\do{% + \edef\ltxkeys@skipa{\expandcsonce\ltxkeys@skipa\@space}% + \advance\cpt@cnta\@ne + }% + \typeout{^^J\ltxkeys@skipa*** Unknown keys ***^^J}% + \def\ltxkeys@tempb{\\}% + \def\align@do##1##2##3##4##5##6##7##8##9\@@{% + \def\ltxkeys@tempc{##9}% + \def\siso@do####1{% + \ifx\siso@arg\ltxkeys@tempb + \edef\ltxkeys@skipb{\@space\ltxkeys@skipb}% + \fi + }% + \siso@@loop{##1##2##3##4##5##6##7##8}% + }% + \edef\ltxkeys@tempa{% + *Prefix,*Family,*Name,*Value;\expandcsonce\ltxkeys@undefinedkeys + }% + \def\ltxkeys@splita##1,##2,##3,##4\ltxkeys@nil{% + \def\ltxkeys@msg{}% + \def\ltxkeys@do####1{% + \let\ltxkeys@skipb\@empty + \align@do####1\\\\\\\\\\\\\\\\\\\@@ + \expandafter\align@do\ltxkeys@tempc\\\\\\\\\\\\\\\\\\\@@ + \edef\ltxkeys@msg{\expandcsonce\ltxkeys@msg####1\ltxkeys@skipb}% + }% + \ltxkeys@csvparse{##1,##2,##3,##4}% + \typeout{\ltxkeys@msg}% + }% + \def\csv@do##1{% + \ltxkeys@splita##1\ltxkeys@nil + }% + \csv@@loop*[;]\ltxkeys@tempa + \typeout{^^J\ltxkeys@skipa*******************^^J}% + \endgroup +} +\robust@def*\ltxkeys@disablekeys{\ltxkeys@testst\ltxkeys@dis@blekeys} +\robust@def*\ltxkeys@dis@blekeys{% + \let\ifdisablest\ifltxkeys@st + \begingroup + \catcode`\,=12\relax + \cpt@testopt{\ltxkeys@dis@bl@keys}{KV}% +} +\robust@def*\ltxkeys@dis@bl@keys[#1]#2#3{% + \endgroup + \def\ltxkeys@prefs{#1}% + \def\ltxkeys@fams{#2}% + \def\ltxkeys@keys{#3}% + \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@prefs + \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@fams + \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@keys + \def\ltxkeys@do##1{% + \ltxkeys@makepf{##1}% + \def\ltxkeys@do####1{% + \def\ltxkeys@tfam{####1}% + \ltxkeys@makehdr{####1}% + \ltxkeys@dis@bl@k@ys + }% + \s@expandarg\ltxkeys@csvloop\ltxkeys@fams + }% + \s@expandarg\ltxkeys@csvloop\ltxkeys@prefs +} +\robust@def\ltxkeys@dis@bl@k@ys{% + \def\ltxkeys@do##1{% + \ifcsndefFT{\ltxkeys@hdr##1}{% + \ifltxkeys@verbose + \ltxkeys@warn{Key '##1' undefined in families '\ltxkeys@tfam': + \MsgBrk can't be disabled}% + \fi + }{% + \edef\ltxkeys@tempa{% + \noexpand\ltxkeys@err{% + Key '##1' of family '\ltxkeys@tfam' has been disabled + }{% + Key '##1' has been disabled.\MsgBrk + You can't set or reset it at this late stage.\MsgBrk + Perhaps you should have set it earlier in\MsgBrk + \noexpand\documentclass or \string\usepackage. + }% + }% + \cptpassexpanded{% + \ifdisablest\noexpand\AtBeginDocument{\fi + \ifcsndefTF{\ltxkeys@hdr##1@default}{% + \noexpand\ltxkeys@ordkey[\ltxkeys@ttpref]% + {\ltxkeys@tfam}{##1}[]{\expandcsonce\ltxkeys@tempa}% + }{% + \noexpand\ltxkeys@ordkey[\ltxkeys@ttpref]% + {\ltxkeys@tfam}{##1}{\expandcsonce\ltxkeys@tempa}% + }% + \ifdisablest}\fi + }% + }% + }% + \s@expandarg\ltxkeys@csvloop\ltxkeys@keys + \undefcs\ifdisablest +} +\robust@def*\ltxkeys@nostarform#1#2{% + \if\detokenize{#1*.}% + \ltxkeys@err{No star (*) form of command \string#2}\@ehc + \fi +} +\robust@def*\ltxkeys@declareoption{% + \let\ltxkeys@tempa\ltxkeys@ordkey + \let\@fileswith@pti@ns\@badrequireerror + \cpt@ifstar\ltxkeys@unknownoptionhandler\ltxkeys@d@cl@reoption +} +\robust@def\ltxkeys@unknownoptionhandler{% + \cpt@testopt\ltxkeys@unkn@wnoptionhandler{KV}% +} +\robust@def*\ltxkeys@unkn@wnoptionhandler[#1]{% + \cpt@testfam{\ltxkeys@unkn@wnopti@nhandler#1}% +} +\robust@def*\ltxkeys@unkn@wnopti@nhandler#1<#2>#3{% + \ltxkeys@unkn@wnkeyhandler[#1]{#2}{#3}% +} +\robust@def*\ltxkeys@declarecmdoption#1{% + \let\@fileswith@pti@ns\@badrequireerror + \ltxkeys@d@clareoption{#1}{cmd}% +} +\robust@def*\ltxkeys@declarebooloption#1{% + \let\@fileswith@pti@ns\@badrequireerror + \ltxkeys@d@clareoption{#1}{bool}% +} +\robust@def*\ltxkeys@declarechoiceoption#1{% + \let\@fileswith@pti@ns\@badrequireerror + \ltxkeys@d@clareoption{#1}{choice}% +} +\robust@def*\ltxkeys@d@clareoption#1#2{% + \aftercsname + {\ltxkeys@nostarform{#1}}{ltxkeys@declare#2option}% + \edef\ltxkeys@tempa{\noexpandcsn{ltxkeys@#2key}}% + \let\@fileswith@pti@ns\@badrequireerror + \ltxkeys@d@cl@reoption#1% +} +\robust@def*\ltxkeys@d@cl@reoption{% + \cpt@testopt\ltxkeys@d@cl@r@option{KV}% +} +\robust@def*\ltxkeys@d@cl@r@option[#1]{% + \cpt@testfam{\ltxkeys@d@cl@r@opti@n#1}% +} +\robust@def*\ltxkeys@d@cl@r@opti@n#1<#2>{% + \ltxkeys@tempa[#1]{#2}% +} +\robust@def*\ltxkeys@executeoptions#1{% + \ltxkeys@nostarform{#1}\ltxkeys@executeoptions + \ltxkeys@exoptrue\ltxkeys@stfalse\ltxkeys@pltrue + \ltxkeys@rmfalse + \ltxkeys@testopt@@b\ltxkeys@setkeys@a#1% +} +\emptify\ltxkeys@processedoptions +\robust@def*\ltxkeys@processoptions{% + \ltxkeys@pltrue\ltxkeys@rmfalse + \ltxkeys@testopt@@a\ltxkeys@pr@cessoptions +} +\robust@def*\ltxkeys@pr@cessoptions[#1]{% + \def\ltxkeys@poxlist{}% + \ltxkeys@pxoptrue + \let\@fileswith@pti@ns\@badrequireerror + \edef\ltxkeys@testname{\@currname.\@currext}% + \ifxTF\ltxkeys@testname\cpt@documentclass{% + \let\@unusedoptionlist\cpt@classoptionslist + }{% + \if@boolFT{ltxkeys@st}{}{% + \def\ltxkeys@do##1{% + \edef\CurrentKeyval{\unexpanded{##1}}% + \ltxkeys@getkeyname##1=\ltxkeys@nil\ltxkeys@tkey + \begingroup + \let\xp\expandcsonce + \edef\x{[\xp\ltxkeys@prefs]{\xp\ltxkeys@fams}{\xp\ltxkeys@tkey}}% + \expandafter\endgroup\expandafter\ltxkeys@ifkeydefFT\x{}{% + \ifcsnullTF\@unusedoptionlist{% + \cptgaddtolist\ltxkeys@processedoptions{##1}% + }{% + \cpt@removecurroption{##1}% + }% + \cptaddtolist\ltxkeys@poxlist{##1}% + }% + }% + \ifcsnullTF\cpt@classoptionslist{}% + {\ltxkeys@csvloop*\cpt@classoptionslist}% + }% + }% + \begingroup + \edef\ltxkeys@tempa{\cpt@optionlist{\@currname.\@currext}}% + \cptexpanded{\endgroup + \ifcsnullTF\ltxkeys@tempa{}{% + \cptaddtolist\noexpand\ltxkeys@poxlist{\expandcsonce\ltxkeys@tempa}% + }% + }% + \ifcsnullTF\ltxkeys@poxlist{}{% + \cptexpandargonce{\ltxkeys@setkeys@a[#1]}\ltxkeys@poxlist + }% + \gundefcs\ltxkeys@poxlist + \csn@def{\ltxkeys@hdr @rmkeys}{}% + \ltxkeys@pxopfalse + \let\@fileswith@pti@ns\@@fileswith@pti@ns + \AtEndOfPackage{\let\@unprocessedoptions\relax}% +} +\robust@def*\ltxkeys@ifkeydefTF{\begingroup\ltxkeys@ifkeydef0} +\robust@def*\ltxkeys@ifkeydefFT{\begingroup\ltxkeys@ifkeydef1} +\robust@def*\ltxkeys@ifkeydef#1{\cpt@testopt{\ltxkeys@ifk@ydef#1}{KV}} +\robust@def*\ltxkeys@ifk@ydef#1[#2]#3#4{% + \def\ltxkeys@prefs{#2}% + \def\ltxkeys@fams{#3}% + \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@fams + \ltxkeys@trimspaces{#4}\ltxkeys@tkey + \cpt@choicefdfalse + \def\ltxkeys@do##1{% + \if@boolTF{cpt@choicefd}{% + \ltxkeys@break + }{% + \ltxkeys@makepf{##1}% + \ltxkeys@ifk@yd@f + }% + }% + \ltxkeys@csvparse*\ltxkeys@prefs + \ltxkeys@oneoftwo#1\endgroup +} +\robust@def*\ltxkeys@ifk@yd@f{% + \def\ltxkeys@do##1{% + \ltxkeys@makehdr{##1}% + \ifcsndefTF{\ltxkeys@hdr\ltxkeys@tkey}{% + \cpt@choicefdtrue\ltxkeys@break + }{}% + }% + \ltxkeys@csvloop*\ltxkeys@fams +} +\robust@def*\ltxkeys@emergencystop{% + \immediate\write\sixt@@n{OK, I'm exiting now.}% + \interactionmode\z@pt + \ifnumcmpTF\currentgrouptype>\z@pt{% + \endgroup\aftergroup\@@end + }{% + \aftergroup\@@end + }% +} +\robust@def*\ltxkeys@unknownoptionerror{% + \@tx@warn{Unknown option '\CurrentOption' for package '\@currname'}% + \typein[\answer]{% + ^^JUnknown option '\CurrentOption' for package '\@currname'. + ^^JThe option '\CurrentOption' was not declared in package + ^^J'\@currname'. Perhaps you misspelled its name. + ^^JEnter 'x' and <return> to stop or any character and + <return> to continue. + }% + \xifstrcmpTF\answer{x}\ltxkeys@emergencystop\relax +} +\cpt@cleanup\ltxkeys@processedoptions +\cptonlypreamble{% + \ltxkeys@declareoption,\ltxkeys@declarecmdoption, + \ltxkeys@declarebooloption,\ltxkeys@declarechoiceoption, + \ltxkeys@processoptions,\ltxkeys@executeoptions, + \ltxkeys@unknownoptionhandler,\ltxkeys@unknownkeyhandler +} +\ltxkeys@declareoption*[KV]<ltxkeys>{% + \ltxkeys@warn{Unknown option '\CurrentKey' with + value '\InnocentVal' ignored.}% +} +\ltxkeys@declarecmdoption[KV]<ltxkeys>[ltxkeys@]{keyparser}[{;}]{% + \stripallouterbracesincs\ltxkeys@keyparser +} +\ltxkeys@declarebooloption[KV]<ltxkeys>[ltxkeys@]{verbose}[true]{} +\ltxkeys@executeoptions[KV]<ltxkeys>{keyparser}\relax +\ltxkeys@processoptions*[KV]<ltxkeys>\relax + +\endinput |