%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% % % % This is file 'ltxkeys.sty', version 0.0.1, July 2011. % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % % either version 1.3 of this license or any later version. The latest % % version of this license is in http://www.latex-project.org/lppl.txt % % and version 1.3 or later is part of all distributions of LaTeX % % version 2005/12/01 or later. % % % % The LPPL maintenance status of this software is 'author-maintained'. % % % % This software is provided 'as it is', without warranty of any kind, % % either expressed or implied, including, but not limited to, the % % implied warranties of merchantability and fitness for a particular % % purpose. % % % % Copyright (c) 2011 Ahmed Musa (amusa22@gmail.com). % % % %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% \RequirePackage{catoptions}[2011/07/30] \UseNormalCatcodes \StyleFilePurpose{Robust and fast key-value parser} \StyleFileRCSInfo $Id: ltxkeys.sty,v 0.0.1 2011/07/30 09:00:00 Ahmed Musa Exp $ \ProvidesPackage{ltxkeys}[\StyleFileInfo] \NeedsTeXFormat{LaTeX2e}[1996/12/01] \SetStyleFileMessages[ltxkeys@]{info}{warn}{err} \robust@def*\ltxkeys@error#1#2{\ltxkeys@err{#1}{#2}\@gobble} \robust@def*\ltxkeys@vwarn#1{% \ifltxkeys@verbose\wlog{[ltxkeys debug] -- #1.}\fi } \robust@def*\ltxkeys@vinfo#1{% \ifltxkeys@verbose\wlog{[ltxkeys debug] ++ #1.}\fi } \newvariables{if}[ltxkeys@]{break,st,pl,sw,sv,nv,noval,pxop,exop,% inpreset,kf,rm,ssk,dec,dep,twk,verbose,swa}[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@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% }% }{ } \robust@def*\ltxkeys@oneoftwo#1\endgroup{% \let\@firstoftwo\relax \let\@secondoftwo\relax \cptpassexpanded{% \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}}% }% \loopbreaktrue }% \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 \@tempcnta\z@pt \def\ltxkeys@do##1{% \advance\@tempcnta by1 }% \ltxkeys@csvloop{#2}% \aftercsname\endgroup{@\ifnum\@tempcnta#1\numexpr#3% first\else second\fi oftwo}% } \robust@def*\ltxkeys@nomatcherr{% \ltxkeys@error{User input '\reserved@e' not in list: \MsgBrk '\reserved@f'}\@ehc } \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*\ltxkeys@commacheckchoice{% \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}\us@rinput \edef\nomin@tions{\unexpanded{#4}}% \ifcpt@st}\fi \def\ltxkeys@ccparser{#1}% \cpt@sttrue\cpt@csvnormalize[#1]\nomin@tions \cptexpandsecond{% \ifblankTF{#2}\ltxkeys@cc@d{\ltxkeys@cc@c#2}\ltxkeys@nil }{% {\expandcsonce\us@rinput}{\expandcsonce\nomin@tions}% }% } \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\us@rinput}% \def\noexpand\reserved@f{\expandcsonce\nomin@tions}% \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\loopbreak }{% \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\us@rinput}% \def\noexpand\reserved@f{\expandcsonce\nomin@tions}% \unexpanded{\expandafter\ltxkeys@nomatcherr\@gobble}% \fi \fi }% } \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\ltxkeys@itemspresent{}% \def\csv@do##1{% \xifinsetFT{\detokenize{#1##1#1}} {\parser\cptoxdetok\ltxkeys@tempb\parser}{}{% \edef\ltxkeys@itemspresent {\cptliststack,\ltxkeys@itemspresent\unexpanded{##1}}% \advance\cpt@cnta\@ne }% \ifnum\cpt@cnta>\numexpr#2-1\relax\loopbreak\fi }% \csv@@parse*[#1]\ltxkeys@tempa \ifnum\cpt@cnta>\numexpr#2-1\relax \edef\ltxkeys@nritems{\the\cpt@cnta}% \else \def\ltxkeys@itemspresent{}\def\ltxkeys@nritems{-1}% \fi \cptexpandsecond\endgroup{% \cpt@csexit\ltxkeys@itemspresent \cpt@csexit\ltxkeys@nritems \ifx\ltxkeys@itemspresent\@empty\noexpand\@secondoftwo\else \noexpand\@firstoftwo\fi }% } \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\ltxkeys@itemspresent{}\cpt@cnta\z@pt \def\tsv@do##1{% \xifinsetFT{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{}{% \edef\ltxkeys@itemspresent {\cptliststack{}\ltxkeys@itemspresent\unexpanded{##1}}% \advance\cpt@cnta\@ne }% \ifnum\cpt@cnta>\numexpr#1-1\relax\loopbreak\fi }% \s@expandarg\tsv@@parse\ltxkeys@tempa \ifnum\cpt@cnta>\numexpr#1-1\relax \edef\ltxkeys@nritems{\the\cpt@cnta}% \else \def\ltxkeys@itemspresent{}\def\ltxkeys@nritems{-1}% \fi \cptexpandsecond\endgroup{% \cpt@csexit\ltxkeys@itemspresent \cpt@csexit\ltxkeys@nritems \ifx\ltxkeys@itemspresent\@empty\noexpand\@secondoftwo\else \noexpand\@firstoftwo\fi }% } \robust@def*\ltxkeys@ifinlistTF{% \cpt@testst{\cpt@testpnopt\ltxkeys@ifinlist{1}}% } \robust@def*\ltxkeys@ifinlist(#1)#2#3{% \begingroup \ifcpt@st\lowercase{\fi \edef\ltxkeys@tempa{\unexpanded{#2}}% \edef\ltxkeys@tempb{\unexpanded{#3}}% \ifcpt@st}\fi \def\ltxkeys@itemspresent{}\cpt@cnta\z@pt \s@expandarg\docommalist\ltxkeys@tempa{% \xifinsetFT{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{}{% \edef\ltxkeys@itemspresent {\cptliststack,\ltxkeys@itemspresent\unexpanded{##1}}% \advance\cpt@cnta\@ne }% \ifnum\cpt@cnta>\numexpr#1-1\relax\loopbreak\fi }% \ifnum\cpt@cnta>\numexpr#1-1\relax \edef\ltxkeys@nritems{\the\cpt@cnta}% \else \def\ltxkeys@itemspresent{}\def\ltxkeys@nritems{-1}% \fi \cptexpandsecond\endgroup{% \cpt@csexit\ltxkeys@itemspresent \cpt@csexit\ltxkeys@nritems \ifcsemptyTF\ltxkeys@itemspresent{\noexpand\@secondoftwo} {\noexpand\@firstoftwo}% }% } \robust@def*\ltxkeys@notinpkgclserr#1{% \ifinstylefileTF{}{% \ltxkeys@err{Command '\detokenize{#1}' issued outside style file}{The command '\detokenize{#1}' is available only in style files.}% }% } \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 \pushfunctions\ltxkeys@parse {\ifloopbreak,\ltxkeys@doo}\ltxkeys@csvdepth \ifdefTF\ltxkeys@do {\let\ltxkeys@doo\ltxkeys@do}{\cpt@notdeferr\ltxkeys@do}% \def\ltxkeys@parse@b{% \if@boolTF{loopbreak}{% \gobble@to@sentinel\ltxkeys@nil,% }{% \ltxkeys@parse@c.% }% }% \ifswitchTF{ltxkeys@nlz}{% \cpt@sttrue \usename{cpt@\if\ltxkeys@inkv kv\else csv\fi normalize}[,]\ltxkeys@arg }{}% \loopbreakfalse \expandafter\ltxkeys@parse@b\ltxkeys@arg,\ltxkeys@nil,% \popfunctions\ltxkeys@parse\ltxkeys@csvdepth \ifnum\ltxkeys@csvdepth=\z@pt\undefcs\ltxkeys@do\fi } \robust@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 }% } \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@testopt@h#1{% \cptexpandarg\ltxkeys@testopt@a{\noexpandcsn{ltxkeys@#1}}% } \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}}% }% } \new@def*\ltxkeys@currtriple{\ltxkeys@ttpref,\ltxkeys@tfam,\ltxkeys@tkey} \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 @}% }% } \new@def*\ltxkeys@badkeynamelist{} \robust@def*\ltxkeys@badkeynames#1{% \ifcsnullTF\ltxkeys@badkeynamelist{% \edef\ltxkeys@badkeynamelist{\detokenize{#1}}% \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@badkeynamelist }{% \cptexpandsecond{\cptfiltermergecsv[,]} {\noexpand\ltxkeys@badkeynamelist{\detokenize{#1}}}\nofilter }% } \robust@def*\ltxkeys@removebadkeynames#1{% \ifcsnullTF\ltxkeys@badkeynamelist{% \ltxkeys@info{Couldn't delete from empty \string\ltxkeys@badkeynamelist}% }{% \cptexpandsecond{\cptfilterremovecsv[,]} {\noexpand\ltxkeys@badkeynamelist{\detokenize{#1}}}\nofilter }% } \ltxkeys@badkeynames{.code,ordkey,cmdkey,choicekey,boolkey,% handledkeys,presetkeys,postsetkeys% } \robust@def*\ltxkeys@findbadkeyname#1{% \begingroup \edef\ltxkeys@tempa{\cpttrimspaces{#1}}% \oifinset@sp@TF,\ltxkeys@tempa\ltxkeys@badkeynamelist{% \ltxkeys@err{Bad key name '\ltxkeys@tempb'}\@ehc }{}% \endgroup } \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@verbose \s@expandarg\ltxkeys@findbadkeyname{#2}% \fi }% \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 \ltxkeys@vinfo{Key defined: \ltxkeys@currtriple}% } \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}% } \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}% } \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}% }% } \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@error{Biboolean keys '#2' not equal to 2}\@ehc }% \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}% }% } \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 \expandafter\cpt@csvnormalize \expandafter[\ltxkeys@keyparser]\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}{% \ltxkeys@warn{Something wrong with dependant keys}\@ehc \expandafter\gobble@to@sentinel\expandafter \ltxkeys@nil\ltxkeys@keyparser }{% \ltxkeys@trimspaces{##1}\key@type \def\striplaststar####1*\@empty####2\@nil{\edef\key@type{####1}}% \expandafter\striplaststar\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}{}{\ltxkeys@keyparser}% \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 }% }% } \robust@def*\ltxkeys@choicekey{% \ltxkeys@svtrue\ltxkeys@swfalse \ltxkeys@teststpl{\cpt@testcl{% \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}% }{% \ifinsetTF{/}{#4}{% \def\ltxkeys@tempa{\ltxkeys@executechclist}% }{% \def\ltxkeys@tempa{\@gobble}% }% }% \edef#1{% \csn@edef{#2}{\noexpand\unexpanded{####1}}% \cptmakecs{cpt@st\ifltxkeys@st true\else false\fi}% \cptmakecs{cpt@pl\ifltxkeys@pl true\else false\fi}% \ifcpt@cl \edef\noexpand\reserved@a{####1}% \else \edef\noexpand\reserved@a{\noexpand\unexpanded{####1}}% \fi \def\noexpand\reserved@b{\unexpanded{\ltxkeys@cc@b,[#3]}}% \unexpanded{\expandafter\reserved@b\expandafter{\reserved@a}}% {\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@tempd{##1}{##2}% }% \def\ltxkeys@tempc##1/##2/##3\ltxkeys@nil{% \ltxkeys@tempd{##1}{##2}% }% \def\ltxkeys@tempd##1##2{% \expandafter\ltxkeys@trimspaces\expandafter {\@gobble##1}\ltxkeys@tempa \ifcase#2\relax \cptaddtolist*[,]\ltxkeys@chclist\ltxkeys@tempa \or \cptexpandarg\lowercase{% \def\noexpand\ltxkeys@tempa{\expandcsonce\ltxkeys@tempa}% \def\noexpand\ltxkeys@tval{\expandcsonce\ltxkeys@tval}% }% \oifstrcmpTF\ltxkeys@tempa\ltxkeys@tval{% \edef\ltxkeys@chclist{\unexpanded{##2}}% \loopbreak }{}% \else \ltxkeys@err{Invalid number '#2' while in \string\ltxkeys@makechclist}\@ehc \fi }% \def\csv@do##1{% \ifinsetTF{/.code=}{##1}{% \ltxkeys@tempb.##1\ltxkeys@nil }{% \ltxkeys@tempc.##1//\ltxkeys@nil }% }% \expandafter\ifinsetTF\expandafter{\ltxkeys@keyparser}{#1}{% \expandafter\csv@@parse\expandafter[\ltxkeys@keyparser]{#1}% }{% \ifinsetTF{,}{#1}{% \csv@@parse[,]{#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@findpointer\savevalue{#1}#3\ltxkeys@svtrue\ltxkeys@svfalse \ltxkeys@findpointer\needvalue{#1}#3\ltxkeys@nvtrue\ltxkeys@nvfalse \ifdefTF\ltxkeys@fromgetkeynames{% \def#3{#1}% }{% \ltxkeys@trimspaces{#1}#3% }% } \robust@def*\ltxkeys@getkeynames#1{% \begingroup \def\ltxkeys@fromgetkeynames{}% \def\ltxkeys@keynames{}% \def\ltxkeys@do##1{% \ltxkeys@getkeyname##1=\ltxkeys@nil\ltxkeys@tempa \edef\ltxkeys@keynames{% \cptliststack,\ltxkeys@keynames\expandcsonce\ltxkeys@tempa }% }% \ifblankTF{#1}{}{\ltxkeys@kvparse{#1}}% \postgroupdef\ltxkeys@keynames\endgroup } \robust@def*\ltxkeys@getkeyvalue#1=#2\ltxkeys@nil#3{% \ifinsetTF{=\ltxkeys@nil}{#2\ltxkeys@nil}{% \ltxkeys@novalfalse \begingroup \def\ltxkeys@tempa##1=##2\ltxkeys@nil{\endgroup \s@expandarg\ltxkeys@trimspaces{\@gobble##1}#3% \let\CurrentVal#3% }% \ltxkeys@tempa.#2\ltxkeys@nil }{% \ltxkeys@novaltrue\def#3{}% }% } \robust@def*\ltxkeys@splitkeyval#1\ltxkeys@nil#2#3{% \ltxkeys@getkeyname#1=\ltxkeys@nil#2% \ltxkeys@getkeyvalue#1=\ltxkeys@nil#3% } \robust@def*\option@keys{% \ltxkeys@notinpkgclserr\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@notinpkgclserr\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{\usename{\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@handledkeys{% \ltxkeys@testopt@h{h@ndledkeys}% } \robust@def*\ltxkeys@removehandledkeys{% \ltxkeys@testopt@h{rem@vehandledkeys}% } \robust@def*\ltxkeys@undefhandledkeys{% \cpt@testcl{\ltxkeys@testopt@h{undefh@ndledkeys}}% } \robust@def*\ltxkeys@emptifyhandledkeys{% \cpt@testcl{\ltxkeys@testopt@h{emptifyh@ndledkeys}}% } \robust@def*\ltxkeys@h@ndledkeys#1{% \letcstocsn\ltxkeys@rsvda{\ltxkeys@hdr handledkeys}% \def\ltxkeys@do##1{% \ifcsndefTF{\ltxkeys@hdr##1}{% \def\ltxkeys@tempb{##1}% \ifdefTF\ltxkeys@rsvda{% \oifinset@sp@TF,\ltxkeys@tempb\ltxkeys@rsvda{}{% \edef\ltxkeys@rsvda{% \cptliststack,\ltxkeys@rsvda\unexpanded{##1}% }% }% }{% \let\ltxkeys@rsvda\ltxkeys@tempb }% }{% \ltxkeys@err{Key '##1' is undefined in family '\ltxkeys@tfam' \MsgBrk Only defined keys can be made handled keys.}\@ehc }% }% \ltxkeys@csvparse{#1}% \letcsntocs{\ltxkeys@hdr handledkeys}\ltxkeys@rsvda } \robust@def*\ltxkeys@rem@vehandledkeys#1{% \letcstocsn\ltxkeys@rsvda{\ltxkeys@hdr handledkeys}% \ifdefTF\ltxkeys@rsvda{% \def\ltxkeys@do##1{% \ifcsndefTF{\ltxkeys@hdr##1}{% \def\ltxkeys@tempb{##1}% \oifinset@sp@TF,\ltxkeys@tempb\ltxkeys@rsvda{% \let\cpt@fromrem\cpttrue\cpt@sttrue \cpt@removeoneelement[,]\ltxkeys@rsvda{##1}% }{% \ltxkeys@warn{Key '##1' with prefix '\ltxkeys@ttpref' in family \MsgBrk '\ltxkeys@tfam' is not a handled key: \MsgBrk It couldn't be deleted from handled keys list.}% }% }{% \ltxkeys@err{Key '##1' is undefined in family '\ltxkeys@tfam'}% {Key '##1' with prefix '\ltxkeys@ttpref' in family \MsgBrk '\ltxkeys@tfam' is not defined:\MsgBrk Can't be deleted from handled keys list.}% }% }% \ltxkeys@csvparse{#1}% }{% \ltxkeys@err{No handled keys for family '\ltxkeys@tfam'}% {No handled keys exist for prefix '\ltxkeys@ttpref' and \MsgBrk family '\ltxkeys@tfam'.}% }% \letcsntocs{\ltxkeys@hdr handledkeys}\ltxkeys@rsvda } \robust@def*\ltxkeys@undefh@ndledkeys{% \ifcsndefTF{\ltxkeys@hdr handledkeys}{% \usename{\ifcpt@cl g\fi undefcsn}{\ltxkeys@hdr handledkeys}% }{% \ltxkeys@err{No handled keys for prefix '\ltxkeys@ttpref' \MsgBrk and family '\ltxkeys@tfam': couldn't undefine}\@ehc }% } \robust@def*\ltxkeys@emptifyh@ndledkeys{% \ifcsndefTF{\ltxkeys@hdr handledkeys}{% \usename{\ifcpt@cl g\fi emptifycsn}{\ltxkeys@hdr handledkeys}% }{% \ltxkeys@err{No handled keys for prefix '\ltxkeys@ttpref' \MsgBrk and family '\ltxkeys@tfam': couldn't emptify}\@ehc }% } \robust@def*\ltxkeys@testoptionkey#1{% \ifcsndefFT{\ltxkeys@hdr#1option@keys}{}{% \cpt@choicefdfalse \def\ltxkeys@do##1{% \s@expandarg\ifstrcmpTF\ltxkeys@tkey{##1}{% \cpt@choicefdtrue\loopbreak }{}% }% \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\loopbreak }{}% }% \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@ifinlistTF(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 } \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{}% % We want \ltxkeys@definekeys to have a slightly different % syntax to \ltxkeys@declarekeys. So we use '=' here. But % the equality sign can always be replaced with '/' and % this won't cause any problems: \def\ltxkeys@tempa##1\ltxkeys@nil{% \expandafter\ltxkeys@splitc\reserved@a/##1//\ltxkeys@nil }% \def\ltxkeys@splita##1={% \def\reserved@a{##1}\ltxkeys@tempa.% }% \def\ltxkeys@splitb##1/{% \def\reserved@a{##1}\ltxkeys@tempa.% }% \def\ltxkeys@splitc##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 \oifblankTF{\@gobble##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}% } \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}{% \ltxkeys@warn{Something wrong in using \string\ltxkeys@declarekeys}\@ehc \expandafter\gobble@to@sentinel\expandafter\ltxkeys@nil\ltxkeys@keyparser }{% \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\ltxkeys@dependant)% {\unexpanded{##2}}% }% {sty*}{% \ltxkeys@stylekey*\ltxkeys@tempa [\expandcsonce\key@default](\expandcsonce\ltxkeys@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{\userinput\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\ltxkeys@dependant{}% }{% \ifinsetFT{>}{#1}{% \ltxkeys@err{Missing key type and name in dependant key ^^J\detokenize{#1}'}{No '>' in dependant key.}% \def\ltxkeys@dependant{}% }{% \def\ltxkeys@tempa##1>##2>##3>##4>##5\ltxkeys@nil{% \edef\ltxkeys@dependant{\unexpanded{##1/##2/##3/##4}}% }% \ltxkeys@tempa#1>>>>\ltxkeys@nil }% }% \postgroupdef\ltxkeys@dependant\endgroup } \robust@def*\ltxkeys@presetkeys{% \cpt@testcl{\ltxkeys@testopt@g{ppsetkeys}{pre}}% } \robust@def*\ltxkeys@removepresetkeys{% \cpt@testcl{\ltxkeys@testopt@g{removeppsetkeys}{pre}}% } \robust@def*\ltxkeys@undefpresetkeys{% \cpt@testcl{\ltxkeys@testopt@g{undefppsetkeys}{pre}}% } \robust@def*\ltxkeys@postsetkeys{% \cpt@testcl{\ltxkeys@testopt@g{ppsetkeys}{post}}% } \robust@def*\ltxkeys@removepostsetkeys{% \cpt@testcl{\ltxkeys@testopt@g{removeppsetkeys}{post}}% } \robust@def*\ltxkeys@undefpostsetkeys{% \cpt@testcl{\ltxkeys@testopt@g{undefppsetkeys}{post}}% } \robust@def*\ltxkeys@ppsetkeys#1#2{% \def\ltxkeys@rsvda{}\def\ltxkeys@rsvdb{}% \def\ltxkeys@do##1{% \ltxkeys@splitkeyval##1\ltxkeys@nil\ltxkeys@tkey\ltxkeys@tval \ifcsndefFT{\ltxkeys@hdr\ltxkeys@tkey}{% \ltxkeys@err{Key '\ltxkeys@currtriple' is undefined.}\@ehc }{% \ifcsndefTF{@\ltxkeys@hdr#1setkeys}{}{% \emptifycsn{@\ltxkeys@hdr#1setkeys}% }% \xifinsetTF{,\cptoxdetok\ltxkeys@tkey,} {,\cptsxdetok{\usename{@\ltxkeys@hdr#1setkeys},}}{% \ltxkeys@err{Double entry for key '\ltxkeys@currtriple' in\MsgBrk #1set key list}\@ehc }{% \edef\ltxkeys@rsvda{\cptliststack,\ltxkeys@rsvda \ltxkeys@tkey\ifcsemptyTF\ltxkeys@tval{} {=\expandcsonce\ltxkeys@tval}}% \edef\ltxkeys@rsvdb{\cptliststack,\ltxkeys@rsvdb \expandcsonce\ltxkeys@tkey}% }% }% }% \ltxkeys@kvparse{#2}% \ifcsemptyTF\ltxkeys@rsvda{}{% \ifcsndefTF{\ltxkeys@hdr#1setkeys}{% \cptpassexpanded{% \cptfiltermergekv\noexpandcsn{\ltxkeys@hdr#1setkeys}% {\expandcsonce\ltxkeys@rsvda}\noexpand\nofilter \cptfiltermergecsv\noexpandcsn{@\ltxkeys@hdr#1setkeys} {\ltxkeys@rsvdb}\noexpand\nofilter }% }{% \csn@edef{\ltxkeys@hdr#1setkeys}{\expandcsonce\ltxkeys@rsvda}% \csn@edef{@\ltxkeys@hdr#1setkeys}{\expandcsonce\ltxkeys@rsvdb}% }% \ifcpt@cl \globalizecsn{\ltxkeys@hdr#1setkeys}% \globalizecsn{@\ltxkeys@hdr#1setkeys}% \fi }% } \robust@def*\ltxkeys@removeppsetkeys#1#2{% \ifcsndefFT{\ltxkeys@hdr#1setkeys}{% \ltxkeys@err{No #1set keys defined for prefix '\ltxkeys@ttpref' and family '\ltxkeys@tfam'}\@ehc }{% \def\ltxkeys@rsvda{}\def\ltxkeys@rsvdb{}% \def\ltxkeys@do##1{% \ltxkeys@splitkeyval##1=\ltxkeys@nil\ltxkeys@tkey\ltxkeys@tval \ifcsndefFT{\ltxkeys@hdr\ltxkeys@tkey}{% \ltxkeys@err{Key '\ltxkeys@currtriple' is undefined}\@ehc }{% \xifinsetTF{,\cptoxdetok\ltxkeys@tkey=\cptoxdetok\ltxkeys@tval,}% {,\cptsxdetok{\usename{\ltxkeys@hdr#1setkeys}},}{% \edef\ltxkeys@rsvda{\cptliststack,\ltxkeys@rsvda \ltxkeys@tkey\ifcsemptyTF\ltxkeys@tval{} {=\expandcsonce\ltxkeys@tval}}% \edef\ltxkeys@rsvdb{\cptliststack,\ltxkeys@rsvdb \expandcsonce\ltxkeys@tkey}% }{% \ltxkeys@err{Key '\ltxkeys@currtriple' not a #1set key}\@ehc }% }% }% \ltxkeys@kvparse{#2}% \ifcsemptyTF\ltxkeys@rsvda{}{% \cptpassexpanded{% \cptfilterremovekv\noexpandcsn{\ltxkeys@hdr#1setkeys} {\expandcsonce\ltxkeys@rsvda}\noexpand\nofilter \cptfilterremovecsv\noexpandcsn{@\ltxkeys@hdr#1setkeys} {\ltxkeys@rsvdb}\noexpand\nofilter }% \ifcpt@cl \globalizecsn{\ltxkeys@hdr#1setkeys}% \globalizecsn{@\ltxkeys@hdr#1setkeys}% \fi }% }% } \robust@def*\ltxkeys@undefppsetkeys#1{% \ifcsndefFT{\ltxkeys@hdr#1setkeys}{% \ltxkeys@err{No #1set keys defined for prefix '\ltxkeys@ttpref' and family '\ltxkeys@tfam'}\@ehc }{% \usename{\ifcpt@cl g\fi undefcsn}{\ltxkeys@hdr#1setkeys}% \usename{\ifcpt@cl g\fi undefcsn}{@\ltxkeys@hdr#1setkeys}% }% } \robust@def*\ltxkeys@setmnkey#1{% \xifinsetTF{,}{\detokenize{#1}}{% \ltxkeys@err{\noexpand\ltxkeys@setmnkey doesn't accept key list}\@ehc }{% \cpt@testopt{\ltxkeys@s@tmnkey#1}{}% }% } \robust@def*\ltxkeys@s@tmnkey#1[#2]{% \begingroup \let\x\ltxkeys@tkey\let\y\noexpand \edef\z{\expandcstwice{\csname\ltxkeys@hdr#1\endcsname{}}}% \cptexpandsecond{\endgroup\ltxkeys@ifinlistTF(1)}{% {\y\ltxkeys@setmnkey{\x},\y\setmnkey{\x},\y\setaliaskey{\x}}% {\expandcsonce\z}% }{% \ltxkeys@err{\noexpand\ltxkeys@setmnkey or \noexpand\setmnkey or \noexpand\setaliaskey nested}\@ehc }{}% \cptexpandsecond\ltxkeys@setkeys{% [\ltxkeys@ttpref]{\ltxkeys@tfam}{% #1=\ifblankTF{#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 }{% \ifmacroTF{##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}}% }% }% }% } \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{% \def\ltxkeys@do####1{% \edef\ltxkeys@resa{% \cptliststack,\ltxkeys@resa \ifcsndefFT{##1@####1@initial@keyvals}{}{% \expandcsnonce{##1@####1@initial@keyvals}% }% }% }% \ltxkeys@csvparse{#2}% }% \ltxkeys@csvparse{#1}% \ltxkeys@getkeynames{#3}% \cptexpandsecond{\endgroup\ltxkeys@setkeys*+[#1]{#2}}% {[\ltxkeys@keynames]{\ltxkeys@resa}}% } \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]% % Don't use the star/plus forms of \ltxkeys@setkeys here, % otherwise we won't be able to catch undefined keys: \ifblankTF{#3}{}{\ltxkeys@setkeys[#1]{#2}{#3}}% } \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{% \begingroup \def\x{\ltxkeys@nil}% \xifinsetTF{\x\detokenize{#2}\x} {\x.\x,\x;\x:\x+\x-\x=\x*\x^\x_\x/\x|\x[\x(\x)\x]\x}{% \ltxkeys@err{Invalid key list '#2': Something is wrong}\@ehc }{}% \endgroup \ifnum\ltxkeys@keydepth=\z@pt \csn@def{\ltxkeys@hdr rmkeys}{}% \def\ltxkeys@undefinedkeys{}% \fi \ltxkeys@getkeynames{#2}% \let\ltxkeys@naa\ltxkeys@keynames \ifblankTF{#1}{}{% \edef\ltxkeys@naa{\cptliststack,\ltxkeys@naa\unexpanded{#1}}% }% \ltxkeys@usepresetkeys{pre}% \ltxkeys@setkeys@b{#1}{#2}% \ltxkeys@usepresetkeys{post}% \ltxkeys@exopfalse\ltxkeys@pxopfalse \ifnumcmpTF\ltxkeys@keydepth=\z@pt{% \emptifycsset{% \ltxkeys@keys,\ltxkeys@prefs,\ltxkeys@fams,\ltxkeys@nakeys,% \ltxkeys@naa,\ltxkeys@tpref,\ltxkeys@ttpref,\ltxkeys@tfam,% \ltxkeys@tkey,\ltxkeys@tval,\CurrentPref,\CurrentFam,% \CurrentKeyval,\CurrentKey,\CurrentVal,\ltxkeys@naa }% \ifcsemptyTF\ltxkeys@undefinedkeys{}\ltxkeys@logunknownkeys }{}% } \robust@def*\ltxkeys@usepresetkeys#1{% \ltxkeys@inpresettrue \begingroup \toks@{}% \ltxkeys@vinfo{Looking for #1-set keys}% \def\ltxkeys@do##1{% \ltxkeys@makepf{##1}% \def\ltxkeys@do####1{% \ltxkeys@makehdr{####1}% \ifcsndefFT{\ltxkeys@hdr#1setkeys}{}{% \cptexpanded{\toks@{\the\toks@\relax\ltxkeys@setkeys@b {\expandcsonce\ltxkeys@naa} {\expandcsnonce{\ltxkeys@hdr#1setkeys}}}}% }% }% \ltxkeys@csvloop*\ltxkeys@fams }% \ltxkeys@csvloop*\ltxkeys@prefs \oifblankTF{\the\toks@}{% \endgroup \ltxkeys@vinfo{No #1-set keys found}% }{% \ltxkeys@vinfo{P\@gobble#1-set keys found. Setting them now}% \expandafter\endgroup\the\toks@ \ltxkeys@vinfo{Finished setting #1-set keys}% }% \ltxkeys@inpresetfalse } \robust@def*\ltxkeys@setkeys@b#1#2{% \ifblankTF{#1}{% \def\ltxkeys@nakeys{}% }{% \edef\ltxkeys@nakeys{\cptcommanormalize{#1}}% }% \def\ltxkeys@do##1{% \edef\CurrentKeyval{\unexpanded{##1}}% \ltxkeys@getkeyvalue##1=\ltxkeys@nil\ltxkeys@tval \ltxkeys@setkeys@c##1=\ltxkeys@nil }% \ltxkeys@kvparse{#2}% } \robust@def*\ltxkeys@setkeys@c#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 \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@d }% }% } \robust@def*\ltxkeys@setkeys@d{% \ltxkeys@kffalse \if@boolTF{ltxkeys@inpreset}{% \ltxkeys@setkeys@e }{% \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@e }% \ltxkeys@csvloop*\ltxkeys@fams }% \ltxkeys@csvloop*\ltxkeys@prefs }{% \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@e \ifltxkeys@kf\loopbreak\fi }% \ltxkeys@csvloop*\ltxkeys@fams \ifltxkeys@kf\loopbreak\fi }% \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@e{% \ifcsndefFT{\ltxkeys@hdr\ltxkeys@tkey}{% \relax }{% \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 \ltxkeys@vinfo{% \ifltxkeys@inpreset Preset key\else Key\fi\@space executed: \ltxkeys@currtriple,\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 \ltxkeys@vinfo{% \ifltxkeys@inpreset Preset key\else Key\fi\@space executed: \ltxkeys@currtriple,\InnocentVal(default); on level '\the\ltxkeys@keydepth' }% }{}% \cpt@pushstate\ltxkeys@setkeys\ltxkeys@state\ltxkeys@keydepth \ifmacroTF{#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{% \ltxkeys@vinfo{Replacing pointers of key '\ltxkeys@tkey'}% \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 \ltxkeys@vinfo{Value '\InnocentVal' of key '\ltxkeys@tkey' inherited from key '\ltxkeys@tempb'}% \fi \else \ltxkeys@vinfo{No pointers found on key '\ltxkeys@tkey'}% \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@error{Dangerous back linking of pointers}{% Key pointer replacement terminated due \MsgBrk to possible back linking.}% }{% \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 \edef\ltxkeys@prefs{\cptcommanormalize{#1}}% \edef\ltxkeys@fams{\cptcommanormalize{#2}}% \edef\ltxkeys@keys{\cptcommanormalize{#3}}% \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}{% \ltxkeys@vwarn{Key '##1' undefined in families '\ltxkeys@tfam': \MsgBrk couldn't be disabled}% }{% \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}{% \loopbreak }{% \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\loopbreak }{}% }% \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 to stop or any character and 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@warn{Unknown option '\CurrentKey' with value '\InnocentVal' ignored.}% } \ltxkeys@declarecmdoption[KV][ltxkeys@]{keyparser}[{;}]{% \stripallouterbracesincs\ltxkeys@keyparser } \ltxkeys@declarecmdoption[KV][ltxkeys@]{keystacklimit}[4]{% \ifx\\#1\\% \ltxkeys@err{Invalid empty value for 'keystacklimit'}\@ehc \else \xdef\cpt@optionstacklimit{\number#1}% \fi } \ltxkeys@declarebooloption[KV][ltxkeys@]{verbose}[true]{} \ltxkeys@executeoptions[KV]{keyparser,keystacklimit}\relax \ltxkeys@processoptions*[KV]\relax \endinput