diff options
author | Karl Berry <karl@freefriends.org> | 2011-07-26 23:27:50 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2011-07-26 23:27:50 +0000 |
commit | 99f9db1a1a470ee103017fc3a72fcaf07e939512 (patch) | |
tree | 39333fee6b8143e38b7d8de97af05ccf9e65900c /Master/texmf-dist/tex/latex/catoptions/catoptions.sty | |
parent | 0339ee8be4b30971917d1b81561d1891e786c972 (diff) |
catoptions (13jul11)
git-svn-id: svn://tug.org/texlive/trunk@23244 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/catoptions/catoptions.sty')
-rw-r--r-- | Master/texmf-dist/tex/latex/catoptions/catoptions.sty | 3252 |
1 files changed, 1924 insertions, 1328 deletions
diff --git a/Master/texmf-dist/tex/latex/catoptions/catoptions.sty b/Master/texmf-dist/tex/latex/catoptions/catoptions.sty index 328c96e7345..ade4194d75b 100644 --- a/Master/texmf-dist/tex/latex/catoptions/catoptions.sty +++ b/Master/texmf-dist/tex/latex/catoptions/catoptions.sty @@ -1,5 +1,5 @@ %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% -% This is 'catoptions' package (Version 0.2b, March 2011) % +% This is 'catoptions' package (Version 0.2.4, July 2011) % % % % The catoptions package changes LaTeX package loading internals % % so that all subsequently loaded packages can rely on having % @@ -9,7 +9,7 @@ % syntax of LaTeX's legacy options parsing mechanism, but with % % improved robustness in terms of option value default, preservation % % of braces in option values, and parsing of expandable package % -% and class option values. Also, it contains some API. % +% and class option values. Also, the package contains some API. % % % % The catcode facilities of the package are an extension of the % % 'pcatcode' package by Michael J. Downes and David M. Jones. % @@ -20,7 +20,7 @@ % % % The LPPL maintenance status of this software is 'author-maintained'. % % % -% Copyright (c) 2010-2011 Ahmed Musa (a.musa@rocketmail.com). % +% Copyright (c) 2010-2011 Ahmed Musa (amusa22@gmail.com). % % % %+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% @@ -84,22 +84,29 @@ \catcode47=12 \catcode94=7 \catcode126=13 +\edef\cpt@hashchar{\string#} \m@ne=-1\z@=0pt\p@=1pt -\newcount\cpt@mone\cpt@mone\m@ne -\chardef\cpt@xii=12 +\@ifdefinable\m@one{\newcount\m@one\m@one\m@ne} +\@ifdefinable\z@pt{\newdimen\z@pt\z@pt\z@} \chardef\active=13 -\chardef\cpt@xcii=92 \NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesPackage{catoptions} - [2011/03/10 v0.2b Securing catcodes and parsing options (AM)] + [2011/07/07 v0.2.4 Securing catcodes and parsing options (AM)] \ifcase% - \ifx\eTeXversion\cpt@undefined\z@\else - \ifnum\eTeXversion<\tw@\z@\else\@ne\fi\fi + \ifx\eTeXversion\cpt@undefined\z@pt\else + \ifnum\eTeXversion<\tw@\z@pt\else\@ne\fi\fi \PackageError{catoptions}{eTeX not loaded or old version}% - {This package requires eTeX version 2 or later.}% + {This package requires eTeX version 2 or higher.}% \expandafter\endinput \fi +\ifx\pdfstrcmp\cpt@undefined + \PackageError{catoptions} + {You aren't using pdfTeX version 1.50.0} + {This package requires pdfTeX version 1.50.0}% +\fi \def\cptloggingall{\loggingall\tracingifs\@ne} +\newcommand*\showcsn{} +\protected\def\showcsn#1{\expandafter\show\csname#1\endcsname} \def\cptnormalcatcodes{% \endlinechar13 \catcode33=12\catcode34=12\catcode35=6\catcode36=3\catcode37=14 @@ -112,7 +119,7 @@ } \begingroup \let\s\string -\escapechar\m@ne +\escapechar\m@one \xdef\cpt@otherchars{% \s\!\s\"\s\#\s\$\s\%\s\&\s\'\s\(\s\)\s\*\s+\s\,\s\-\s\.\s\/\s\:% \s\;\s\<\s\=\s\>\s\?\s\[\s\\\s\]\s\^\s\_\s\`\s\{\s\|\s\}\s\~% @@ -125,18 +132,31 @@ \cpt@err{There is an unclosed \string\BeginOverlookWhiteSpace}\@ehc \fi - \chardef\cpt@spacecatcode=\number\catcode`\ % - \chardef\cpt@tabcatcode=\number\catcode`\^^I - \chardef\cpt@endlinechar=\number\endlinechar + \chardef\sav@spacecatcode=\number\catcode`\ % + \chardef\sav@tabcatcode=\number\catcode`\^^I + \chardef\sav@endlinechar=\number\endlinechar \catcode`\ =9\relax \catcode`\^^I=9\relax - \endlinechar\m@ne + \endlinechar\m@one } \newcommand*\EndOverlookWhiteSpace{% + \catcode`\ =\sav@spacecatcode + \catcode`\^^I=\sav@tabcatcode + \endlinechar\sav@endlinechar \popnumber\overlook@nr - \catcode`\ =\cpt@spacecatcode - \catcode`\^^I=\cpt@tabcatcode - \endlinechar\cpt@endlinechar +} +\newcommand*\BeginOverlookEndline{% + \pushnumber\overlookendline@nr + \ifnum\overlookendline@nr>\@ne + \cpt@err{There is an unclosed + \string\BeginOverlookEndline}\@ehc + \fi + \chardef\@sav@endlinechar=\number\endlinechar + \endlinechar\m@one +} +\newcommand*\EndOverlookEndline{% + \endlinechar\@sav@endlinechar + \popnumber\overlookendline@nr } \def\cpt@catcodestack{} \def\cptpushcatcodes{% @@ -177,9 +197,9 @@ }% \expandafter\endgroup\x } -\newcommand*\setup@safe@actives@edef{% +\newcommand*\setup@safeactives@edef{% \begingroup - \endlinechar\m@ne + \endlinechar\m@one \def\siso@do##1{\catcode`##1\string=\active}% \simpleexpandarg\siso@@loop\cpt@otherchars \gdef\safe@actives@edef##1##2{% @@ -188,15 +208,14 @@ \ifnum\catcode`####1\string=\active\edef####1{\string####1}\fi }% \simpleexpandarg\siso@@loop\cpt@otherchars - \cptpassexpanded{% - \endgroup\edef\noexpand##1{\noexpand\unexpanded{##2}}% - }% + \cptexpandsecond\endgroup + {\edef\noexpand##1{\noexpand\unexpanded{##2}}}% } \endgroup } \newcommand*\declarefutureletset[2][fl@]{% - \xdef\cpt@fletprefix{\xp@despace{#1}}% - \cptexpandargonce{\cpt@filtermergelists[,]\cpt@fletprefixes}% + \xdef\cpt@fletprefix{\cpttrimspaces{#1}}% + \cptexpandargonce{\cptfiltermergecsv[,]\cpt@fletprefixes}% \cpt@fletprefix\nofilter \ifblankTF{#2}{% \def\neededfutureletchars{}% @@ -226,7 +245,7 @@ \begingroup \edef\cpt@tempa{\noexpandcsn{\cpt@fletprefix#1}}% \edef\cpt@tempb{\noexpandcsn{if\cpt@fletprefix#1}}% - \if@sp@inlistTF,\cpt@tempa\cptfutureletmacros{}{% + \oifinset@sp@TF,\cpt@tempa\cptfutureletmacros{}{% \xdef\cptfutureletmacros{% \ifcsnullTF\cptfutureletmacros{}% {\expandcsonce\cptfutureletmacros,}% @@ -246,7 +265,7 @@ \fi \xdef\cpt@tempa{% \let\noexpand\cpt@tempa\noexpand\cpt@undefined - \cptglet\expandcsonce\cpt@tempa= % + \gletcs\expandcsonce\cpt@tempa= % }% \aftergroup\cpt@tempa \lowercase{% @@ -271,28 +290,28 @@ \gdef\cptfutureletmacros{}% \def\cpt@flet@b##1\@##2\@{% \ifxTF##1\end{}{% - \if@sp@inlistFT,{##1}\neededfutureletchars{}{% + \oifinset@sp@FT,{##1}\neededfutureletchars{}{% \cpt@flet@a{##1}{##2}% }% \cpt@flet@b }% }% - \def\comma@do##1{% + \def\csv@do##1{% \gundefcsn{##1\curropt}% \gundefcsn{if##1\curropt}% }% \def\cpt@fletundef##1\@##2\@{% \ifxTF##1\end{}{% \def\curropt{##1}% - \simpleexpandarg\comma@@loop\cpt@fletprefixes + \csv@@parse*[,]\cpt@fletprefixes \cpt@fletundef }% }% \def\cpt@fletdef##1\@##2\@{% \ifxTF##1\end{}{% - \if@sp@inlistFT,{##1}\neededfutureletchars{}{% + \oifinset@sp@FT,{##1}\neededfutureletchars{}{% \csn@xdef{if\cpt@fletprefix##1}####1{% - \noexpand\usecsn{@\noexpand\ifx + \noexpand\usename{@\noexpand\ifx \noexpandcsn{\cpt@fletprefix##1}% ####1\unexpanded{\@empty first\else second\fi oftwo}% }% @@ -316,48 +335,255 @@ } \endgroup -\newcommand*\ifcptcond[1]{% - \def\ifcptcond##1\fi##2##3{% - \romannumeral - ##1#1\expandafter\@firstoftwo\else +\newcommand\cptswap[2]{#2#1} +\newcommand\cptswapfirstbraced[2]{#2{#1}} +\newcommand\cptswapsecondbraced[2]{{#2}#1} +\cptswap{ }{\let\cptsptoken= } +\def\@space{ } +\newcommand\usename[1]{\csname#1\endcsname}% long! +\newcommand\usecsn[1]{% + \ifcsname#1\endcsname\expandafter\@iden\else + \expandafter\@gobble\fi{\usename{#1}}% +} +\newcommand\ifxTF[2]{% + \usename{@\ifx#1#2\@empty first\else second\fi oftwo}% +} +\newcommand\ifxFT[2]{\ifxTF{#1}{#2}\@secondoftwo\@firstoftwo} +\newcommand*\defifxTF[2]{% + \begingroup + \edef\cpt@tempa{\unexpanded{#1}}% + \expandafter\endgroup\ifx#2\cpt@tempa + \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi +} +\newcommand*\cptifcondTF[1]{% + \long\def\cptifcondTF##1\fi##2##3{% + \romannumeral##1#1\expandafter\@firstoftwo\else \expandafter\@secondoftwo\fi{0 ##2}{0 ##3}% }% } -\ifcptcond{ } -% \shell-def'ed macros don't have to be 'definable': -\@ifdefinable\shelldef{\protected\def\shelldef{\protected\def}} -\@ifdefinable\shelledef{\shelldef\shelledef{\protected\edef}} -% \shell-let macros must be 'definable': -\newcommand*\shelllet{} -\shelldef\shelllet#1#2{% - \ifcptcond\ifx\\#2\\\fi - {\@latex@error{Empty token for \string\shelllet}\@ehc}% - {\ifcptcond\expandafter\ifx\expandafter\\\@gobble#2\\\fi} - {\ifcptdefinable#1{\shelllet@a#1{#2}}}% - {\@latex@error{Multiple tokens '\detokenize{#2}'}\@ehc}% -} -\newcommand*\shelllet@a[2]{% - \aftercsname\newletcs{rsv@@\cptremovescape#1}{#2}% - \shelledef#1{\cptmakecs{rsv@@\cptremovescape#1}}% -} -\newcommand*\UseNormalCatcodes{} -\shelldef\UseNormalCatcodes{% - \ifcsnullTF\@currname{% - \cpt@warn{\noexpand\UseNormalCatcodes issued in - document: ignored}% - }{% - \let\UseNormalCatcodes\relax +\cptifcondTF{ } +\long\def\cptifcondFT#1\fi#2#3{\cptifcondTF#1\fi{#3}{#2}} +\newcommand*\ifcsnameTF[1]{% + \cptifcondTF\ifcat$\detokenize{#1}$\fi{% + \@secondoftwo + }{% + \usename{@\ifcsname#1\endcsname first\else second\fi oftwo}% + }% +} +\newcommand*\ifcsnameFT[1]{\ifcsnameTF{#1}\@secondoftwo\@firstoftwo} +\newcommand*\ifnamedefTF[1]{% + \ifcsnameTF{#1}{% + \usename{@\expandafter\ifx\csname#1\endcsname\relax + second\else first\fi oftwo}% + }{% + \@secondoftwo + }% +} +\newcommand*\kernel@ifdefinable[2]{% + \cptifcondTF\ifcat$\detokenize{#1}$\fi{% + \@latex@error{Empty command for \string\kernel@ifdefinable}\@ehc + }{% + \edef\reserved@a{\expandafter\@gobble\string#1}% + \begingroup + \ifnamedefTF\reserved@a{% + \endgroup\@notdefinable + }{% + \edef\reserved@b{\expandafter\@carcube\reserved@a xxx\@nil}% + \ifx\reserved@b\@qend + \toks@{\@notdefinable}% + \else + \ifx\reserved@a\@qrelax + \toks@{\@notdefinable}% + \else + \toks@{#2}% + \fi + \fi + \expandafter\endgroup\the\toks@ + }% + }% +} +\protected\def\cpt@oneorgobble\endgroup{% + \expandafter\endgroup\ifcpt@choicefd + \expandafter\@iden\else\expandafter\@gobble\fi +} +\protected\def\cpt@oneoftwo#1\endgroup{% + \let\@firstoftwo\relax + \let\@secondoftwo\relax + \edef\cpt@tempa{% + \ifnumcmpTF{#1}{1}{% + \if@boolTF{cpt@choicefd}\@firstoftwo\@secondoftwo + }{% + \ifnumcmpTF{#1}{2}{% + \if@boolTF{cpt@choicefd}\@secondoftwo\@firstoftwo + }{% + \cpt@err{Invalid number '#1'}\noexpand\@ehc + }% + }% + }% + \expandafter\endgroup\cpt@tempa +} +\protected\def\cpt@seeparameter#1#{% + \begingroup + \toks@{#1}% + \@expandtwoargs\in@ + {\detokenize{macro parameter character}}% + {\meaning\@let@token}% +} +\newif\ifcpt@kernelifnextchar\cpt@kernelifnextchartrue +\kernel@ifdefinable\CurrIfnextchar{% + \ifcpt@kernelifnextchar + \let\CurrIfnextchar\kernel@ifnextchar + \else + \let\CurrIfnextchar\ifnextcharTF + \fi +} +\protected\def\cpt@starorlong#1{% + \cpt@ifstar{\let\l@ngrel@x\relax#1}{\let\l@ngrel@x\long#1}% +} +\protected\def\cpt@ifstar#1{\CurrIfnextchar*{\@firstoftwo{#1}}} +\newcommand*\shelldef{} +\protected\def\shelldef{\cpt@starorlong\cpt@shelldef} +\protected\def\cpt@shelldef#1{% + \kernel@ifdefinable{#1}{\l@ngrel@x\protected\def#1}% +} +\shelldef*\cpt@notdeferr#1{% + \@latex@error{Command '\detokenize{#1}' isn't defined} + {I expected '\detokenize{#1}' to be defined.}% +} +\shelldef*\cpt@isdeferr#1{% + \@latex@error{Command '\detokenize{#1}' is already defined} + {I expected '\detokenize{#1}' to be undefined.}% +} +\shelldef*\cpt@notcserr#1{% + \@latex@error{Token '\detokenize{#1}' not a macro + \MsgBrk or is currently undefined} + {I expected '\detokenize{#1}' to be defined.}% +} +\shelldef*\cpt@iscserr#1{% + \@latex@error{Token '\detokenize{#1}' is a macro: + \MsgBrk not currently undefined} + {I didn't expect '\detokenize{#1}' to be defined.}% +} +\shelldef*\cpt@notescapederr#1{% + \@latex@error{Token '\detokenize{#1}' not escaped + \MsgBrk or is an active character}{I expected + the first token of\MsgBrk'\detokenize{#1}' to be + escape character.}% +} +\shelldef*\cpt@isescapederr#1{% + \@latex@error{Token '\detokenize{#1}' is escaped}{% + I didn't expect the first token of\MsgBrk + '\detokenize{#1}' to be escape character.}% +} +\shelldef*\cpt@notbracederr#1{% + \@latex@error{Token '\detokenize{#1}' isn't braced} + {I expected '\detokenize{#1}' to be braced.}% +} +\shelldef*\cpt@isbracederr#1{% + \@latex@error{Token '\detokenize{#1}' is braced} + {I didn't expect '\detokenize{#1}' to be braced.}% +} +\shelldef*\cpt@notonetokenerr#1{% + \@latex@error{'\detokenize{#1}' is not one token} + {I expected '\detokenize{#1}' to be one token.}% +} +\shelldef*\cpt@isonetokenerr#1{% + \@latex@error{'\detokenize{#1}' is one token} + {I didn't expect '\detokenize{#1}' to be one token.}% +} +\shelldef*\cpt@notblankerr#1{% + \@latex@error{'\detokenize{#1}' is not blank or empty} + {I expected '\detokenize{#1}' to be blank.}% +} +\shelldef*\cpt@isblankerr#1{% + \@latex@error + {Blank/empty token for command '\detokenize{#1}'} + {I didn't expect a blank token here.}% +} + +\begingroup +\catcode`\&=7 +\protected\gdef\cpt@getmacroprefix#1{% + \begingroup + \edef\cpt@tempa##1{\def##1####1\detokenize{macro}:####2&}% + \cpt@tempa\@ifmacro{% + \def\macroprefix{##1}% + \usename{@\ifblankTF{##2}{second}{first}oftwo}% + }% + \edef\cpt@tempb##1{##1\detokenize{macro}:&}% + \cpt@tempb{\expandafter\@ifmacro\meaning#1}{% + \@testtrue + }{% + \@testfalse\def\macroprefix{}% + }% + \cpteveryscan + \cptpassexpanded{% + \endgroup + \ifxTF\macroprefix\@empty{\@iden}{\noexpand\scantokens}% + {\def\noexpand\macroprefix{\macroprefix}\relax}% + }% +} +\gdef\cpt@getprefix#1>#2&{#1} +\protected\gdef\ifprotectedTF#1{% + \begingroup + \edef\cpt@tempa##1{\def##1####1\string\protected####2&}% + \cpt@tempa\cpt@tempa{% + \aftercsname\endgroup{@\ifblankTF{##2}{second}{first}oftwo}% + }% + \edef\cpt@tempb##1{% + ##1\expandafter\cpt@getprefix\meaning#1&\string\protected&% + }% + \cpt@tempb\cpt@tempa +} +\endgroup + +\shelldef*\shelllet#1{\cpt@ifeql{\cpt@shelllet{#1}}{\cpt@shelllet{#1}}} +\shelldef*\cpt@shelllet#1#2{% + \cptifcondTF\ifx\noboundary#2\noboundary\fi{% + \cpt@isblankerr\shelllet + }{% + \cptifcondTF\expandafter\ifx\expandafter + \noboundary\@gobble#2\noboundary\fi{% + \ifcsdefinable#1{% + \ifprotectedTF#2{\let#1=#2}{% + \ifcsndefinable{shell@\cptremovescape#1}{% + \letcsntocs{shell@\cptremovescape#1}=#2% + \protected\edef#1{\cptmakecs{shell@\cptremovescape#1}}% + }% + }% + }% + }{% + \cpt@notonetokenerr{#2}% + }% + }% +} +\shelldef\showruntime#1\runtime{% + \pdfresettimer#1% + \message{Run time: \the\pdfelapsedtime}% +} +\newcommand*\ifdocstartedTF{% + \ifdefTF\cpt@docstarted\@firstoftwo\@secondoftwo +} +\shelldef*\UseNormalCatcodes{% + \let\UseNormalCatcodes\relax + \ifdocstartedTF{}{% \cptpushcatcodes \cptnormalcatcodes - \AfterEndOfStyleFile{% - \cptpopcatcodes - \let\UseNormalCatcodes\rsv@UseNormalCatcodes + \ifxTF\@currname\@empty{% + \BeforeStartOfDocument{% + \cptpopcatcodes + }% + }{% + \AfterEndOfStyleFile{% + \cptpopcatcodes + \let\UseNormalCatcodes\rsv@UseNormalCatcodes + }% }% }% } -\newcommand*\rsv@UseNormalCatcodes{} -\global\let\rsv@UseNormalCatcodes\UseNormalCatcodes - +\kernel@ifdefinable\rsv@UseNormalCatcodes{% + \let\rsv@UseNormalCatcodes\UseNormalCatcodes +} \newcommand*\newcomment{% \begingroup \def\comment@envir{newcomment}% @@ -377,7 +603,7 @@ } \begingroup \catcode`\^^M=12 % -\endlinechar\m@ne% +\endlinechar\m@one% \gdef\cpt@commentloop#1^^M{% \def\comment@stuff{#1}% \ifx\comment@stuff\endnewcomment @@ -397,7 +623,6 @@ \next } \endgroup -%\traceon \begingroup \catcode`\{=12 \catcode`\}=12 @@ -410,22 +635,12 @@ !gdef!end@comment[\end{comment}] !endgroup -\newcommand\cptswap[2]{#2#1} -\newcommand\cptswapfirstbraced[2]{#2{#1}} -\newcommand\cptswapsecondbraced[2]{{#2}#1} -\cptswap{ }{\let\@sptoken= } -\def\@space{ } -\newcommand\usecsn[1]{\csname#1\endcsname}% long -\newcommand\gusecsn[1]{\global\csname#1\endcsname} -\newcommand\cptuse[1]{\ifcsndefFT{#1}{}{\usecsn{#1}}} \newcommand\uselivecs[1]{% - \ifdefTF{#1}{#1}{% - \cpt@err{Command 'string#1' undefined}\@ehc - }% + \ifdefTF{#1}{#1}{\cpt@notdeferr{#1}}% } \newcommand\uselivecsn[1]{% \ifcsndefTF{#1}{% - \usecsn{#1}% + \usename{#1}% }{% \let\relax\relax \cpt@err{Command '\@backslashchar#1' undefined}\@ehc @@ -437,50 +652,51 @@ \long\def\@thirdofthree#1#2#3{#3} \let\@iden\@firstofone \newcommand\cptalloftwo[2]{#1#2} -\newcommand*\newsentinel[1]{% - \@ifdefinable{#1}{\protected\edef#1{\string#1}}% -} -\newcommand*\ifsentinelTF[2]{% - \begingroup - \def#2{#2}% - \expandafter\endgroup - \ifx#1#2\expandafter\@firstoftwo\else - \expandafter\@secondoftwo\fi -} -\newcommand*\ifsentinelFT[2]{% - \ifsentinelTF{#1}{#2}\@secondoftwo\@firstoftwo -} -\newsentinel\cpt@nil +\kernel@ifdefinable\cpt@nil{\let\cpt@nil\relax} +\kernel@ifdefinable\cpt@relax{\let\cpt@relax\relax} +\def\cpt@nnil{\cpt@nil} +\newcommand*\cpt@rmstop{0 } \long\def\cpt@car#1#2\car@nil{#1} \long\def\cpt@cdr#1#2\cdr@nil{#2} \long\def\remove@to@nnil#1\@nnil{} \long\def\catch@to@nnil#1\@nnil{#1} \long\def\remove@to@dot#1.{} \long\def\catch@to@dot#1.{#1} -\newcommand*\remove@to@sentinel[2]{% +\long\def\remove@to@space#1 {} +\@namedef{@gobblespace} {} +\kernel@ifdefinable\remainder@do{\let\remainder@do\@gobble} +\shelldef*\gobble@to@sentinel#1#2{% \begingroup - \defpass\cpt@tempa##1#1#2{% - \endgroup\remainder@do{##1}% - }% + \defpass\cpt@tempa##1#1#2{\endgroup\remainder@do{##1}}% } \newcommand*\cptthreexp{\expandafter\expandafter\expandafter} \newcommand*\cptsevenxp{\expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter} \shelldef\cptlocalxp#1{\begingroup\cptthreexp\endgroup#1} -\shelldef\cptlocalxpxp{\cptlocalxp\expandafter} \newcommand*\cptzapspaces[1]{% \def\cptzapspaces##1{% - \romannumeral0\cpt@zapspaces.\@space##1#1\zap@nil + \romannumeral\cpt@zapspaces.##1#1\zap@nil }% } \cptzapspaces{ } \long\def\cpt@zapspaces#1 #2\zap@nil{% - \usecsn{@\ifx\\#2\\first\else second\fi oftwo}% - {\remove@to@dot#1}{% + \usename{@\ifx\noboundary#2\noboundary + first\else second\fi oftwo}{% + \expandafter\cpt@rmstop\remove@to@dot#1% + }{% \expandafter\cpt@zapspaces\expandafter .\remove@to@dot#1#2\zap@nil }% } +\newcommand*\cptsupergobble[1]{% + \romannumeral-`\q\expandafter\@gobble\romannumeral-`\q + \expandafter\cpt@sup@rgobble + \romannumeral\the\numexpr#1000{m\endcsname}% +} +\newcommand*\cpt@sup@rgobble[1]{% + \csname cpt@sup@rg@bble#1\cpt@sup@rgobble +} +\newcommand\cpt@sup@rg@bblem[1]{\endcsname} \newcommand*\cptdotimes[1]{% \ifblankTF{#1}{% \if@boolTF{cpt@useempty}{\cpt@dotimes{m}}\@gobble @@ -533,171 +749,198 @@ #2{\cpt@robustreverse{{#3}#1}}{\cpt@robustreverse{#3#1}}.% }% } -\newcommand*\ifpdfstrcmpTF[2]{% - \usecsn{@\ifnum\pdfstrcmp{\detokenize{#1}}% - {\detokenize{#2}}=\z@ first\else second\fi oftwo}% +\newcommand*\ifstrcmpTF[2]{% + \usename{@\ifnum\pdfstrcmp{\detokenize{#1}}% + {\detokenize{#2}}=0first\else second\fi oftwo}% } -\@ifdefinable\kernel@for{\let\kernel@for\@for} -\newcommand*\IfCommandsDefinable[1]{% - \@testopt{\cpt@ifcmdsdefinable#1}{}% +\shelldef*\ifcommandsdefinable#1{% + \@testopt{\cpt@ifcmdsdefinable#1}\relax } \def\cpt@ifcmdsdefinable#1[#2]{% - \kernel@for\cpt@tempa:=\noexpand#1\do{% - \edef\cpt@tempa{% - \unexpanded\expandafter{% - \ifnum0=0\expandafter\noexpand\cpt@tempa}\fi - }% - \expandafter\@ifdefinable\cpt@tempa{#2}% - }% -} -\IfCommandsDefinable{\normal@despace,\robust@despace,\xp@despace, - \despace@cs,\despacecontent,\robdespacecontent,\despacecsvlist, - \robdespacecsvlist,\newvariables}[\relax] -\def\cpt@tempa#1{% - \shelldef\normal@despace##1##2{% - \edef##2{% - \unexpanded\expandafter{\romannumeral-`\q - \cpt@normaldespace.##1\despace@nil#1\despace@nil}% + \begingroup + \@tempswafalse + \def\do##1,{% + \ifnot@nil{##1}{% + \edef\cpt@tempa{% + \unexpanded\expandafter{\romannumeral-`\q\noexpand##1}% + }% + \ifxTF\cpt@tempa\@empty\do{% + \edef\cpt@tempb{\expandafter\expandafter\expandafter + \@car\expandafter\string\cpt@tempa\@nil}% + \ifxTF\cpt@tempb\@backslashchar{% + \@tempswafalse + \expandafter\kernel@ifdefinable\cpt@tempa\@tempswatrue + }{% + \s@expandarg\cpt@notescapederr\cpt@tempa + }% + \usename{@\if@tempswa first\else second\fi oftwo}% + \do{\gobble@to@sentinel\@nil,}% + }% }% }% - \def\cpt@normaldespace##1#1\despace@nil{% - \cpt@norm@ldespace##1\despace@nil - }% - \def\cpt@norm@ldespace##1\despace@nil##2{% - \expandafter\noexpand\@gobble##1% - }% - \def\xp@despace##1{% - \cpt@xpdespace.##1\despace@nil#1\despace@nil - }% - \def\cpt@xpdespace##1#1\despace@nil{% - \cpt@xpd@space##1\despace@nil - }% - \def\cpt@xpd@space##1\despace@nil##2{% - \unexpanded\expandafter{% - \ifnum0=0\expandafter\noexpand\@gobble##1}\fi - }% + \do#1,\@nil,% + \cptifcondTF\if@tempswa\fi{\endgroup#2}\endgroup } -\cpt@tempa{ } -\shelldef\robust@despace#1#2{% - \edef#2{\unexpanded{#1}}% - \let\despace@tempa#2% - \normal@despace{#1}#2% - \ifxTF#2\despace@tempa{% - \undefcs\despace@tempa +\ifcommandsdefinable{\cpttrimspace,\cpttrimspaces}\relax +\def\cpttrimspaces#1{\cpt@trimspaces@a\relax{#1}} +\begingroup +\catcode`\&=7\catcode`\$=7 +\gdef\cpt@trimspaces@a#1#2{\cpt@trimspaces@b.#1$.#2& &} +\gdef\cpt@trimspaces@b#1$#2 &{\cpt@trimspaces@c#1$#2&} +\gdef\cpt@trimspaces@c#1$#2{% + \cpt@trimspaces@d\ifstrcmpTF{#2}{#1}{% + \unexpanded\expandafter{\@gobble#1}% }{% - \expandafter\robust@despace\expandafter{#2}#2% + \cpt@trimspaces@d\cpt@trimspaces@a{#2}{#2}% }% } -\shelldef\despace@cs{\cpt@testst\cpt@despacecs} -\def\cpt@despacecs#1{% - \usecsn{\ifcpt@st rob\fi despacecontent}{#1}% -} -\shelldef\despacecontent#1{% - \expandafter\normal@despace\expandafter{#1}#1% -} -\shelldef\robdespacecontent#1{% - \expandafter\robust@despace\expandafter{#1}#1% -} -\shelldef\despacecsvlist{% - \chardef\despace@type\z@ - \cpt@testopt\cpt@despacecsvlist{,}% +\gdef\cpt@trimspaces@d#1#2{% + \expandafter\cpt@trimspaces@e\expandafter#1\expandafter{% + \unexpanded\expandafter + {\romannumeral-`\q\expandafter\noexpand\@gobble#2}% + }% } -\shelldef\robdespacecsvlist{% - \chardef\despace@type\@ne - \cpt@testopt\cpt@despacecsvlist{,}% +\gdef\cpt@trimspaces@e#1#2#3{\expandafter#1\expandafter{\@gobble#3}{#2}} +\gdef\cpttrimspace#1{\cpt@trimspace@a.#1& &} +\gdef\cpt@trimspace@a#1 &{\cpt@trimspace@b#1&} +\gdef\cpt@trimspace@b#1{% + \unexpanded\expandafter + {\romannumeral-`\q\expandafter\noexpand\@gobble#1}% } -\def\cpt@despacecsvlist[#1]#2{% - \begingroup - \let\cpt@resb\@empty - \UseEmptyEntry - \ifnum\despace@type=\z@\let\do\normal@despace\else - \let\do\robust@despace\fi - \def\csv@do##1{% - \do{##1}\cpt@resa - \cptaddtolist*[#1]\cpt@resb\cpt@resa +\endgroup +\shelldef*\trim@@spaces#1#2{\edef#2{\cpttrimspaces{#1}}} +\shelldef*\trim@@space#1#2{\edef#2{\cpttrimspace{#1}}} +\shelldef*\despacecontent#1{% + \edef#1{\simpleexpandarg\cpttrimspaces{#1}}% +} +\shelldef*\cptdespacecsvlist{\cpt@teststopt\cpt@despacecsvlist,} +\shelldef*\cpt@despacecsvlist[#1]#2{% + \cpt@stchoose{cpt@st}{#2}\cpt@tempa\cpt@despacecsvlist + \ifcsnullTF\cpt@tempa{}{% + \def\cpt@rsvda{}% + \UseEmptyEntry + \def\csv@do##1{% + \edef\cpt@tempa{\cpttrimspaces{##1}}% + \cptaddtolist[#1]\cpt@rsvda\cpt@tempa + }% + \csv@@loop*[#1]\cpt@tempa + \if@boolFT{cpt@st}{}{\let#2=\cpt@rsvda}% }% - \csv@@loop*[#1]#2% - \let#2\cpt@resb - \exitgroupdef#2% - \undefcs\despace@type } -\outer\shelldef\newvariables#1{\@testopt{\cpt@newvariables{#1}}{}} -\def\cpt@newvariables#1[#2]#3{% +\ifcommandsdefinable{\newboxtype,\newboxcontent}\relax +\let\newboxtype=\hbox +\def\newboxcontent{} +% \newvariables{<type>}[<prf>]{<variables>}[<state/value>] +% Valid types are 'if, toks, dimen, count, box, tog'. +\shelldef*\newvariables#1{\@testopt{\cpt@newvariables{#1}}{}} +\shelldef*\cpt@newvariables#1[#2]#3{% \@testopt{\cpt@newv@riables{#1}{#2}{#3}}{}% } -\def\cpt@newv@riables#1#2#3[#4]{% - \def\cpt@resa##1{% +\shelldef*\cpt@newv@riables#1#2#3[#4]{% + \def\cpt@rsvda##1{% \ifx\noindent#4\noindent \def\cpt@tempc{##1}\else\def\cpt@tempc{#4}\fi }% - \edef\cpt@tempb{\ifpdfstrcmpTF{#1}{if}{if}{}}% - \kernel@for\cpt@tempa:=\noexpand#3\do{% - \edef\cpt@tempa{% - \expandafter\xp@despace\expandafter{\cpt@tempa}% - }% - \usecsn{@\ifcsname\cpt@tempb#2\cpt@tempa\endcsname - first\else second\fi oftwo}% - {% - \edef\reserved@a{\cpt@tempb#2\cpt@tempa}% - \@notdefinable - }{% - \ifpdfstrcmpTF{#1}{togsw}{% - \v@true - \ifcsndefTF{cpt@togsw@#2\cpt@tempa}{% - \cpt@err{Toggle switch '#2\cpt@tempa' already defined}\@ehc - }{% - \cpt@gettogswstate{#4}% - \letcsntocs{cpt@togsw@#2\cpt@tempa}\cpt@togswstate - }% - }{% - \v@false - \csname new#1\expandafter\endcsname\csname - \cpt@tempb#2\cpt@tempa\endcsname - }% - \ifpdfstrcmpTF{#1}{if}{% - \cpt@resa{false}% - \csname#2\cpt@tempa\cpt@tempc\endcsname + \edef\cpt@tempb{\ifstrcmpTF{#1}{if}{if}{}}% + \def\gobble@to@do##1\do{\do}% + \def\do##1,{% + \ifnot@nil{##1}{% + \edef\cpt@tempa{\cpttrimspace{##1}}% + \ifxTF\cpt@tempa\@empty\gobble@to@do\relax + \ifnamedefTF{\cpt@tempb#2\cpt@tempa}{% + \edef\reserved@a{\cpt@tempb#2\cpt@tempa}% + \ifstrcmpTF{#1}{tog}{}{\@notdefinable}% }{% - \ifpdfstrcmpTF{#1}{toks}{% - \cpt@resa{}% - \csname#2\cpt@tempa\endcsname\expandafter{\cpt@tempc}% + \ifstrcmpTF{#1}{tog}{% + \@tempswatrue + \ifnamedefTF{cpt@tog@#2\cpt@tempa}{% + \cpt@err{Toggle '#2\cpt@tempa' already defined}\@ehc + }{% + \lowercase{% + \ifstrcmpTF{#4}{true}{% + \let\cpt@togstate\@firstoftwo + }{% + \ifstrcmpTF{#4}{false}{% + \let\cpt@togstate\@secondoftwo + }{% + \ifx\noindent#4\noindent + \let\cpt@togstate\@secondoftwo + \else + \@latex@error{Invalid toggle value '#4'}\@ehc + \fi + }% + }% + }% + \expandafter\let\csname cpt@tog@#2\cpt@tempa\endcsname + \cpt@togstate + }% }{% - \ifpdfstrcmpTF{#1}{box}{% - \cpt@resa\z@ - \setbox\csname#2\cpt@tempa\endcsname\newboxtype - to\cpt@tempc{\newboxcontent}% + \@tempswafalse + \csname new#1\expandafter\endcsname\csname + \cpt@tempb#2\cpt@tempa\endcsname + \ifstrcmpTF{#1}{if}{% + \cpt@rsvda{false}% + \csname#2\cpt@tempa\cpt@tempc\endcsname }{% - \ifpdfstrcmpTF{#1}{count}{% - \cpt@resa\z@ - \csname#2\cpt@tempa\endcsname\cpt@tempc\relax + \ifstrcmpTF{#1}{toks}{% + \cpt@rsvda{}% + \csname#2\cpt@tempa\endcsname\expandafter{\cpt@tempc}% }{% - \ifpdfstrcmpTF{#1}{dimen}{% - \cpt@resa\z@ - \csname#2\cpt@tempa\endcsname\cpt@tempc\relax + \ifstrcmpTF{#1}{box}{% + \cpt@rsvda\z@pt + \setbox\csname#2\cpt@tempa\endcsname\newboxtype + to\cpt@tempc{\newboxcontent}% }{% - \ifv@\else - \cpt@err{Unknown variable type '#1'}\@ehc - \fi + \ifstrcmpTF{#1}{count}{% + \cpt@rsvda\z@pt + \csname#2\cpt@tempa\endcsname\cpt@tempc\relax + }{% + \ifstrcmpTF{#1}{dimen}{% + \cpt@rsvda\z@pt + \csname#2\cpt@tempa\endcsname\cpt@tempc\relax + }{% + \cpt@newvarerr{#1}% + }% + }% }% }% }% }% }% + \do }% }% + \do#3,\@nil,% + \let\gobble@to@do\cpt@undefined } -\IfCommandsDefinable{\newboxtype,\newboxcontent}\relax -\let\newboxtype\hbox -\def\newboxcontent{} -\newvariables{if}[cpt@]{st,pl,pm,verbose,usepox,optfd, - igopt,inpox,olddx,in,check,breakloop,choicefd,useempty, - normalize,despace,robdespace,twincall,bibool}[false] -\newvariables{count}[cpt@]{depth,optdepth,grouplevel,grouptype}[\z@] -\@ifdefinable\cptbreakloop{\let\cptbreakloop\cpt@breaklooptrue} +\def\cpt@newvarerr#1{% + \if@tempswa\else + \begingroup + \def\x##1{Maybe you meant '##1'.}% + \cpt@err{Unknown variable type '#1'}{% + \ifstrcmpTF{#1}{dim}{\x{dimen}}{% + \ifstrcmpTF{#1}{token}{\x{toks}}{% + \ifstrcmpTF{#1}{tok}{\x{toks}}{% + \ifstrcmpTF{#1}{toggle}{\x{tog}}{% + No variable of type '#1'. + }% + }% + }% + }% + }% + \endgroup + \fi +} +\newvariables{if}[cpt@]{st,pl,pm,cl,verbose,usepox,optfd, + igopt,inpox,olddx,in,check,breakloop,choicefd,useempty,swa, + lastitem +}[false] +\newvariables{tog}{biboolkeys}[false] +\newvariables{count}[cpt@]{optdepth,csvdepth, + sisodepth,foxdepth,grouplevel,grouptype,cnta}[\z@pt] +\kernel@ifdefinable\cptbreakloop{\let\cptbreakloop\cpt@breaklooptrue} \newcommand*\UseEmptyEntry{\global\cpt@useemptytrue} \newcommand*\DiscardEmptyEntry{\global\cpt@useemptyfalse} -\newcommand*\UseRobustDespace{\global\cpt@robdespacetrue} -\newcommand*\UseNormalDespace{\global\cpt@robdespacefalse} \newcommand*\MsgBrk{\MessageBreak} \newcommand*\cptgetcatcode[1]{% \number @@ -723,7 +966,7 @@ \ifx\noboundary#1\noboundary \expandafter\@gobble\else\expandafter\@iden\fi {\ifnum\escapechar>\@cclv\else - \ifnum\escapechar<\z@\else + \ifnum\escapechar<\z@pt\else \expandafter\expandafter \csname @gobble\ifnum\escapechar=\@xxxii @space\fi \cptthreexp\endcsname @@ -732,30 +975,30 @@ \string#1}% } \newcommand\ifnullTF[1]{% - \usecsn{@\ifnum\pdfstrcmp{}{\detokenize{#1}}% - =\z@ first\else second\fi oftwo}% + \usename{@\ifnum\pdfstrcmp{}{\detokenize{#1}}% + =\z@pt first\else second\fi oftwo}% } \newcommand\ifnullFT[1]{\ifnullTF{#1}\@secondoftwo\@firstoftwo} \newcommand\oifnullTF[1]{\expandafter\ifnullTF\expandafter{#1}} \newcommand\oifnullFT[1]{\expandafter\ifnullFT\expandafter{#1}} \newcommand\xifnullTF[1]{\cptexpandarg\ifnullTF{#1}} \newcommand\xifnullFT[1]{\cptexpandarg\ifnullFT{#1}} -\@ifdefinable\iftoksnullTF\relax -\def\iftoksnullTF#1#{% - \expandafter\ifnullTF\expandafter{\the#1}% -} \newcommand\ifblankTF[1]{% - \usecsn{@\ifnum\pdfstrcmp{}{\detokenize\expandafter - {\@gobble#1.}}=\z@ first\else second\fi oftwo}% + \usename{@\ifnum\pdfstrcmp{}{\detokenize\expandafter + {\@gobble#1.}}=\z@pt first\else second\fi oftwo}% } \newcommand\ifblankFT[1]{\ifblankTF{#1}\@secondoftwo\@firstoftwo} \newcommand\oifblankTF[1]{\expandafter\ifblankTF\expandafter{#1}} \newcommand\oifblankFT[1]{\expandafter\ifblankFT\expandafter{#1}} -\newcommand\xifblankTF[1]{\cptexpandarg\ifblankTF{#1}} -\newcommand\xifblankFT[1]{\cptexpandarg\ifblankFT{#1}} +% Expandable: +\newcommand\xifblankTF[1]{% + \usename{@\ifnum\pdfstrcmp{}{\@gobble#1.}=\z@pt + first\else second\fi oftwo}% +} +\newcommand\xifblankFT[1]{\xifblankTF{#1}\@secondoftwo\@firstoftwo} \newcommand*\ifdefTF[1]{% - \usecsn{@\ifx\\#1\\second\else first\fi oftwo}% - {\usecsn{@\ifx#1\cpt@undefined second\else + \usename{@\ifx\\#1\\second\else first\fi oftwo}% + {\usename{@\ifx#1\cpt@undefined second\else \ifx#1\relax second\else first\fi\fi oftwo}}% \@secondoftwo } @@ -777,32 +1020,97 @@ \newcommand*\oifcsndefFT[1]{\expandafter\ifcsndefFT\expandafter{#1}} \newcommand*\xifcsndefTF[1]{\cptexpandarg\ifcsndefTF{#1}} \newcommand*\xifcsndefFT[1]{\cptexpandarg\ifcsndefFT{#1}} -\newcommand*\ifcptdefinable[2]{% - \edef\reserved@a{\cptgobblescape#1}% - \ifdefTF{#1}\@notdefinable{% - \ifcsndefTF{end\reserved@a}\@notdefinable{#2}% +\shelldef*\ifcsdefinable#1#2{% + \ifblankTF{#1}{% + \cpt@err{Empty command for \string\ifcsdefinable}\@ehc + }{% + \edef\reserved@a{\cptgobblescape#1}% + \ifdefTF{#1}\@notdefinable{% + \ifcsndefTF{end\reserved@a}\@notdefinable{#2}% + }% + }% +} +\ifcsdefinable\@ifcsdefinable{\let\@ifcsdefinable=\ifcsdefinable} +\shelldef\rc@ifcsdefinable#1#2{\let\ifcsdefinable\@ifcsdefinable#2} +\shelldef*\ifcsndefinable#1{\cptlocalxp\aftercsname\ifcsdefinable{#1}} +\shelldef*\ifdefinableTF#1{% + \ifblankTF{#1}{% + \cpt@err{Empty command for \string\ifdefinableTF}\@ehc + \@secondoftwo + }{% + \ifdefTF{#1}\@secondoftwo{% + \ifcsndefTF{end\cptgobblescape#1}\@secondoftwo\@firstoftwo + }% }% } -\newcommand*\newletcs[2]{\ifcptdefinable{#1}{\let#1=#2}} -\newcommand*\newgletcs[2]{\ifcptdefinable{#1}{\global\let#1=#2}} -\newcommand*\cptglet{\global\let} -\newcommand\cpt@def@[3]{% - \ifcptdefinable#3{% +\shelldef\cpt@ifnextchar#1#2#3{% + \begingroup + \let\reserved@a=#1\toks@{\endgroup#2}\toks1{\endgroup#3}% + \global\futurelet\@let@token\cpt@ifnext +} +\shelldef*\cpt@ifnext{% + \ifx\@let@token\@sptoken + \toks2{\cpt@ifn@xt}% + \else + \ifx\@let@token\reserved@a + \toks2\expandafter{\the\toks@}% + \else + \toks2\expandafter{\the\toks1}% + \fi + \fi + \the\toks2 +} +\@namedef{cpt@ifn@xt} {\global\futurelet\@let@token\cpt@ifnext} +\shelldef\ifnextcharTF#1#2#3{% + \begingroup + \cpt@ifnextchar\relax + {\cpt@ifnextcharacter{#1}{#2}{#3}}% + {\cpt@ifnextcharacter{#1}{#2}{#3}}% +} +\long\def\cpt@ifnextcharacter#1#2#3{% + \ifcase + \ifcat\noexpand\@let@token\bgroup 1\fi + \ifcat\noexpand\@let@token\egroup 1\fi + 0\let\next\cpt@ifn@xtcharacter + \else + \def\next{\endgroup\cpt@ifnextchar}% + \fi + \next{#1}{#2}{#3}% +} +\long\def\cpt@ifn@xtcharacter#1#2#3#4{% + \escapechar92\relax + \edef\x{\cpt@ifn@xtch@racter{#1}\cpt@ifn@xtch@racter{#4}}% + \expandafter\endgroup\csname @\expandafter + \ifx\x first\else second\fi oftwo\endcsname + {#2}{#3}#4% +} +\long\def\cpt@ifn@xtch@racter#1{% + \expandafter\cpt@ifn@xtch@r@cter\string#1\relax\noindent{#1}% +} +\long\def\cpt@ifn@xtch@r@cter#1#2\noindent#3{% + \ifx\relax#2#1\else\noexpand#3\fi +} +\shelldef*\if@seeparameter#1#{% + \xifinsetTF{\detokenize{macro parameter character}}% + {\meaning\@let@token}% +} +\shelldef\cpt@def@#1#2#3{% + \ifcsdefinable#3{% \ifnullTF{#2}{}\protected - \cptthreexp\l@ngrel@x\usecsn{#1def}#3% - }% -} -\ifcptdefinable\robust@def\relax -\shelldef\robust@def{\@star@or@long{\cpt@def@{}{p}}} -\robust@def*\new@def{\@star@or@long{\cpt@def@{}{}}} -\robust@def*\new@gdef{\@star@or@long{\cpt@def@{g}{}}} -\robust@def*\robust@gdef{\@star@or@long{\cpt@def@{g}{p}}} -\robust@def*\new@edef{\@star@or@long{\cpt@def@{e}{}}} -\robust@def*\robust@edef{\@star@or@long{\cpt@def@{e}{p}}} -\robust@def*\new@xdef{\@star@or@long{\cpt@def@{x}{}}} -\robust@def*\robust@xdef{\@star@or@long{\cpt@def@{x}{p}}} -\robust@def*\renew@def{\@star@or@long{\cpt@redef@{}}} -\robust@def*\robust@redef{\@star@or@long{\cpt@redef@{p}}} + \cptthreexp\l@ngrel@x\usename{#1def}#3% + }% +} +\ifcsdefinable\robust@def\relax +\shelldef\robust@def{\cpt@starorlong{\cpt@def@{}{p}}} +\robust@def*\new@def{\cpt@starorlong{\cpt@def@{}{}}} +\robust@def*\new@gdef{\cpt@starorlong{\cpt@def@{g}{}}} +\robust@def*\robust@gdef{\cpt@starorlong{\cpt@def@{g}{p}}} +\robust@def*\new@edef{\cpt@starorlong{\cpt@def@{e}{}}} +\robust@def*\robust@edef{\cpt@starorlong{\cpt@def@{e}{p}}} +\robust@def*\new@xdef{\cpt@starorlong{\cpt@def@{x}{}}} +\robust@def*\robust@xdef{\cpt@starorlong{\cpt@def@{x}{p}}} +\robust@def*\renew@def{\cpt@starorlong{\cpt@redef@{}}} +\robust@def*\robust@redef{\cpt@starorlong{\cpt@redef@{p}}} \new@def*\cpt@redef@#1#2{% \ifdefFT#2{}{% \ifcpt@verbose @@ -811,17 +1119,53 @@ }% \ifstrcmpTF{#1}{p}\protected\relax\l@ngrel@x\def#2% } -\robust@def*\maybe@def#1{\cpt@teststpm{\cpt@maybe@def{#1}}} -\robust@def*\cpt@maybe@def#1{% +\robust@def\cpt@testopt#1#2{\CurrIfnextchar[{#1}{#1[{#2}]}} +\robust@def*\cpt@ifbrack#1#2{\CurrIfnextchar[{#1}{#2}} +\new@def*\cpt@xtestopt#1#2#3{% + \cpt@xifbrack#1\\[\\{#2#1}{#2[{#3}]{#1}}% +} +\new@def*\cpt@xifbrack#1[#2\\#3#{% + \usename{@\ifblankTF{#1#2}{first}{second}oftwo}% +} +\robust@def\cpt@testpnopt#1#2{\CurrIfnextchar({#1}{#1({#2})}} +\robust@def\cpt@ifplus#1{\CurrIfnextchar+{\@firstoftwo{#1}}} +\robust@def\cpt@ifclam#1{\CurrIfnextchar!{\@firstoftwo{#1}}} +\robust@def\cpt@ifprime#1{\CurrIfnextchar'{\@firstoftwo{#1}}} +\robust@def\cpt@ifeql#1{\CurrIfnextchar={\@firstoftwo{#1}}} +\robust@def\cpt@testst#1{\cpt@ifstar{\cpt@sttrue#1}{\cpt@stfalse#1}} +\robust@def\cpt@testpl#1{\cpt@ifplus{\cpt@pltrue#1}{\cpt@plfalse#1}} +\robust@def\cpt@testpm#1{\cpt@ifprime{\cpt@pmtrue#1}{\cpt@pmfalse#1}} +\robust@def\cpt@testcl#1{\cpt@ifclam{\cpt@cltrue#1}{\cpt@clfalse#1}} +\robust@def\cpt@teststpl#1{\cpt@testst{\cpt@testpl{#1}}} +\robust@def\cpt@teststpm#1{\cpt@testst{\cpt@testpm{#1}}} +\robust@def\cpt@teststopt#1#2{\cpt@testst{\cpt@testopt{#1}{#2}}} +\robust@def*\cptmaybedef{\cpt@teststpm\cpt@maybedef} +\robust@def*\cpt@maybedef#1{% \if@boolTF{cpt@st}\@firstoftwo{% \if@boolTF{cpt@pm}\@firstoftwo\@secondoftwo }\@gobble{\new@def#1}% } +\robust@def*\newletcs#1{% + \begingroup + \def\cpt@tempa{\relax}% + \cpt@ifeql{\cpt@newletcs{#1}}{\cpt@newletcs{#1}}% +} +\robust@def*\gnewletcs#1{% + \begingroup + \def\cpt@tempa{\global}% + \cpt@ifeql{\cpt@newletcs{#1}}{\cpt@newletcs{#1}}% +} +\robust@def*\cpt@newletcs#1{% + \ifcsdefinable{#1}{% + \expandafter\endgroup\cpt@tempa\let#1= % + }% +} +\robust@def*\gletcs{\global\let} \robust@def*\fulllet{\@testtrue\cpt@fulllet} \robust@def*\fullnewlet{\@testfalse\cpt@fulllet} \robust@def*\cpt@fulllet#1#2{% - \normal@despace{#1}\cpt@tempa - \normal@despace{#2}\cpt@tempb + \trim@@space{#1}\cpt@tempa + \trim@@space{#2}\cpt@tempb \cpt@fullleterr\cpt@tempa\cpt@tempb \if@test \cptthreexp\let\expandafter\cpt@tempa\cpt@tempb @@ -847,315 +1191,304 @@ \new@def*\cpt@fullleterr#1#2{% \simpleexpandarg\ifsingletokenTF{#1}{% \simpleexpandarg\ifsingletokenTF{#2}{}{% - \cpt@err{Multiple or blank argument '\expandcsonce{#2}'}\@ehc + \cpt@notonetokenerr{#2}% }% }{% - \cpt@err{Multiple or blank argument '\expandcsonce{#1}'}\@ehc + \cpt@notonetokenerr{#1}% }% } -\robust@def*\cptletcsset#1{% - \def\comma@do##1{% - \oifblankTF{\@gobble##1}{}{\fulllet##1}% +\robust@def*\cptletcsset#1#2{% + \def\csv@do##1{% + \oifblankTF{\@gobble##1}{}{\fulllet##1#2}% }% - \comma@@loop{#1}% + \csv@@parse[,]{#1}% } -\new@def*\ifcounterTF#1{% + +\begingroup +\catcode`\&=7 +\new@gdef*\ifcounterTF#1{% \ifstrcmpTF\count{#1}\@secondoftwo{% - \expandafter\cpt@ifcounter@a\meaning#1:\noboundary + \expandafter\cpt@ifcounter@a\meaning#1:&% }% } \edef\cpt@ifcounter@a#1#2{% - \def#1##1:##2\noboundary{#2##1\string\count\noboundary}% - \def#2##1\string\count##2\noboundary{\noexpand\ifblankTF{##1}}% + \gdef#1##1:##2&{#2##1\string\count&}% + \gdef#2##1\string\count##2&{\noexpand\ifblankTF{##1}}% } \cpt@ifcounter@a\cpt@ifcounter@a\cpt@ifcounter@b -% Can't be called \ifdimTF (=\ifdimcmpTF): -\new@def*\ifdimensionTF#1{% +\new@gdef*\ifdimenTF#1{% \ifstrcmpTF\dimen{#1}\@secondoftwo{% - \expandafter\cpt@ifdimen@a\meaning#1:\noboundary + \expandafter\cpt@ifdimen@a\meaning#1:&% }% } \edef\cpt@ifdimen@a#1#2{% - \def#1##1:##2\noboundary{#2##1\string\dimen\noboundary}% - \def#2##1\string\dimen##2\noboundary{\noexpand\ifblankTF{##1}}% + \gdef#1##1:##2&{#2##1\string\dimen&}% + \gdef#2##1\string\dimen##2&{\noexpand\ifblankTF{##1}}% } \cpt@ifdimen@a\cpt@ifdimen@a\cpt@ifdimen@b -\robust@def*\pushnumeric#1{% - \usecsn{push\ifcounterTF#1{count}{numb}er}#1% -} -\robust@def*\popnumeric#1{% - \usecsn{pop\ifcounterTF#1{count}{numb}er}#1% -} +\endgroup + \robust@def*\pushnumber#1{% - \ifdefTF{#1}{\edef#1{\the\numexpr#1+1}}{\chardef#1\@ne}% -} -\robust@def*\popnumber#1{% - \ifdefTF#1{% - \ifnumcmpTF#1=\z@{% - \let\relax\relax - \cpt@err{Number '\string#1' is already 0}\@ehc - }{% - \edef#1{\the\numexpr#1-1}% - }% - }{% - \let\relax\relax - \cpt@err{Number '\string#1' is undefined}\@ehc - }% -} -\robust@def*\pushcounter#1{% - \ifdefTF#1{% + \ifdefTF{#1}{% \ifcounterTF#1{% \global\advance#1\@ne }{% - \cpt@err{Number '\string#1' isn't a counter}\@ehc + \xdef#1{\the\numexpr#1+1}% }% }{% - \usecsn{newcount}#1% + \chardef#1=\@ne }% } -\robust@def*\popcounter#1{% - \ifdefTF#1{% - \ifnumcmpTF#1=\z@{% +\robust@def*\popnumber#1{% + \ifdefTF{#1}{% + \ifnumcmpTF#1=\z@pt{% \cpt@err{Counter or number '\string#1' is already 0}\@ehc }{% - \ifcounterTF#1{\global\advance#1\cpt@mone}{% - \cpt@err{Number '\string#1' isn't a counter}\@ehc + \ifcounterTF#1{% + \global\advance#1\m@one + }{% + \xdef#1{\the\numexpr#1-1}% }% }% }{% - \cpt@err{Counter '\string#1' is undefined}\@ehc + \cpt@err{Counter or number '\string#1' is undefined}\@ehc }% } -\new@def*\push@rnarg#1{% - \expandafter\cptremovescape\push@arg @\romannumeral#1% -} -\robust@def*\pushfunctions#1#2{% - \ifdefTF#2{% - \ifcounterTF#2{% - \global\advance#2\@ne +\robust@def*\pushfunctions#1#2#3{% + \ifdefTF{#3}{% + \ifcounterTF{#3}{% + \global\advance#3\@ne }{% - \xdef#2{\the\numexpr#2+1}% + \xdef#3{\the\numexpr#3+1}% }% }{% - \chardef#2\@ne + \chardef#3=\@ne }% - \def\push@do{% - \cptexpandsecondonce{\letcsntocs{\push@rnarg{#2}}}\push@arg + \begingroup + \edef\cpt@stack{\expandafter\@gobble\string#1@stack}% + \ifcsndefTF\cpt@stack{}{\csn@gdef\cpt@stack{}}% + \toks@{}\toks1{}\escapechar92 + \let\xp\expandcsonce + \def\push@do##1{% + \ifescapedTF{##1}{}{\cpt@notescapederr{##1}}% + \edef\cpt@tempa{\noexpandcsn + {\expandafter\@gobble\string##1@\romannumeral#3}}% + \cptpassexpanded{% + \toks@{\the\toks@\let\xp\cpt@tempa\noexpand##1}% + \toks1{\the\toks1\let\noexpand##1\xp\cpt@tempa + \undefcs\xp\cpt@tempa + }% + }% }% - \let\rsv@escapechar\escapechar\escapechar\cpt@xcii - \pushingloop{#1}% - \escapechar\rsv@escapechar + \push@@parse{#2}% + \csn@xdef\cpt@stack{\the\toks1{\expandcsnonce\cpt@stack}}% + \expandafter\endgroup\the\toks@ +} +\robust@def*\push@@parse#1{% + \cpt@stfalse\cpt@csvnormalize[,]{#1}% + \expandafter\cpt@pushparse\normalized@list,\@nil,% +} +\robust@def*\cpt@pushparse#1,{% + \ifnot@nil{#1}{\push@do{#1}\relax\cpt@pushparse}% } \robust@def*\popfunctions#1#2{% - \ifdefTF#2{% - \ifnum#2=\z@ + \ifdefTF{#2}{% + \ifnum#2=\z@pt \cpt@err{Number '\string#2' is currently '0'}\@ehc \fi }{% - \cpt@err{Pop function with unknown number \string#2?}\@ehc + \cpt@err{Pop function with unknown number \string#2}\@ehc }% - \def\push@do{% - \expandafter\letcstocsn\push@arg{\push@rnarg{#2}}% - \undefcsn{\push@rnarg{#2}}% + \edef\cpt@stack{\expandafter\@gobble\string#1@stack}% + \ifcsndefTF\cpt@stack{% + \edef\reserved@a{\expandcsnonce\cpt@stack}% + \def\reserved@b##1##{##1\csn@gdef\cpt@stack}% + \expandafter\reserved@b\reserved@a + }{% + \cpt@err{Unknown stack for function \string#1}\@ehc + \@gobble }% - \let\rsv@escapechar\escapechar\escapechar\cpt@xcii - \pushingloop{#1}% - \escapechar\rsv@escapechar - \ifcounterTF#2{% - \global\advance#2\cpt@mone + \ifcounterTF{#2}{% + \global\advance#2\m@one }{% \xdef#2{\the\numexpr#2-1}% }% } -% Why separate \pushcsvinternals from \pushfunctions? -% There is a reason: -\robust@def*\pushcsvinternals#1#2{% - \def\push@do{% - \cptexpandsecondonce{\letcsntocs{\push@rnarg{#2}}}\push@arg - }% - \pushingloop{#1}% -} -\robust@def*\popcsvinternals#1#2{% - \def\push@do{% - \expandafter\letcstocsn\push@arg{\push@rnarg{#2}}% - \undefcsn{\push@rnarg{#2}}% - }% - \pushingloop{#1}% +\robust@def*\push@onefunction#1#2{% + \global\advance#2\@ne + \letcsntocs{\cptremovescape#1@\romannumeral#2}#1% +} +\robust@def*\pop@onefunction#1#2{% + \letcstocsn#1{\cptremovescape#1@\romannumeral#2}% + \undefcsn{\cptremovescape#1@\romannumeral#2}% + \global\advance#2\m@one +} +\chardef\cpt@optionstacklimit4 +\robust@def*\cpt@pushstate#1#2#3{% + \ifnum#3>\cpt@optionstacklimit\relax + \let\reserved@a\cpt@optionstacklimit + \@latex@error{Current option/key state is being pushed + \MsgBrk beyond level '\reserved@a'. I suspect infinite + \MsgBrk re-entrance. Please set package option + \MsgBrk 'option-stack-limit' or 'key-stack-limit' + \MsgBrk to the required value in \noexpand\documentclass + }\@ehc + \fi + \expandafter\pushfunctions\expandafter#1\expandafter{#2}#3% } -\robust@def*\pushingloop#1{% - \def\comma@do##1{% - \normal@despace{##1}\push@arg - \push@do\relax +\robust@def*\cpt@popstate#1#2{\popfunctions#1#2} +\robust@def*\cpt@stchoose#1#2#3#4{% + \if@boolTF{#1}{% + \cptifmacroTF{#2}{% + \let#3=#2% + }{% + \cpt@err{Bad arguments to macro '\detokenize{#4}'. + \MsgBrk Token '\detokenize{#2}' not a macro + \MsgBrk but '\@backslashchar if#1' is true}\@ehc + }% + }{% + \edef#3{\unexpanded{#2}}% }% - \comma@@loop{#1}% } -\robust@def*\cpt@toodeep#1#2{% - \cpt@err{Command '\string#1' nested too deeply}% - {Sorry, but command '\string#1' can't be nested - \MsgBrk to depth(s) higher than #2.}% - \@gobble +\robust@def*\dofunclist{% + \let\csv@do\do + \csv@@parse } \robust@def*\csv@@loop{% - \cpt@normalizefalse - \chardef\csv@kv@type\z@ - \cpt@teststoptb\cpt@csvkvparse + \let\cpt@nmlz\cptfalse + \let\cpt@inkv\cptfalse + \cpt@teststopt\cpt@csvkvparse,% } \robust@def*\csv@@parse{% - \cpt@normalizetrue - \chardef\csv@kv@type\z@ - \cpt@teststoptb\cpt@csvkvparse + \let\cpt@nmlz\cpttrue + \let\cpt@inkv\cptfalse + \cpt@teststopt\cpt@csvkvparse,% +} +\robust@def*\kv@@loop{% + \let\cpt@nmlz\cptfalse + \let\cpt@inkv\cpttrue + \cpt@teststopt\cpt@csvkvparse,% } \robust@def*\kv@@parse{% - \cpt@normalizetrue - \chardef\csv@kv@type\@ne - \cpt@teststoptb\cpt@csvkvparse + \let\cpt@nmlz\cpttrue + \let\cpt@inkv\cpttrue + \cpt@teststopt\cpt@csvkvparse,% } -\newletcs\remainder@do\@gobble -\newsentinel\csv@nil -\newcount\csv@depth\csv@depth\cpt@mone +\robust@def*\cpt@csvstate{% + \csv@parse@a,\csv@parse@b,\csv@doo,\ifcpt@useempty,% + \ifcpt@breakloop,\remainder@do +} +\new@def*\cpt@csvnil{\cpt@csvnil} \newcommand\cpt@csvkvparse[2][,]{% - \if@boolTF{cpt@st}{\let\csv@arg#2}{\edef\csv@arg{\unexpanded{#2}}}% - \advance\csv@depth\@ne - \ifnumcmpFT\csv@depth>\z@{}{% - \pushcsvinternals{\csv@parse@a,\csv@parse@b,\csv@kv@do, - \ifcpt@useempty,\ifcpt@breakloop,\ifcpt@normalize, - \remainder@do}\csv@depth - }% - \letcstocsn\csv@kv@do{\ifnum\csv@kv@type=\z@ csv\else kv\fi @do}% - \ifdefTF\csv@kv@do{}{% + \cpt@stchoose{cpt@st}{#2}\cpt@csvarg\cpt@csvkvparse + \expandafter\pushfunctions\expandafter\cpt@csvkvparse + \expandafter{\cpt@csvstate}\cpt@csvdepth + \letcstocsn\csv@doo{\if\cpt@inkv kv\else csv\fi @do}% + \ifdefTF\csv@doo{}{% \cpt@err{'\string\csv@do' or '\string\kv@do' undefined}\@ehc }% - \long\def\csv@parse@a{% + \def\csv@parse@a{% \if@boolTF{cpt@breakloop}{% - \defpass\cpt@tempa####1\csv@nil#1{\remainder@do{####1}}% + \defpass\cpt@tempa####1\cpt@csvnil#1{\remainder@do{####1}}% }{% \csv@parse@b.% }% }% \long\def\csv@parse@b##1#1{% - \edef\csv@arg{\expandcsonce{\@gobble##1}}% - \ifsentinelTF\csv@arg\csv@nil{}{% - \ifcsnullTF\csv@arg{% - \if@boolFT{cpt@useempty}{}{\csv@kv@do{}\relax}% + \edef\cpt@csvarg{\expandcsonce{\@gobble##1}}% + \ifxTF\cpt@csvarg\cpt@csvnil{}{% + \ifxTF\@empty\cpt@csvarg{% + \if@boolFT{cpt@useempty}{}{\csv@doo{}\relax}% }{% - \expandafter\csv@kv@do\expandafter{\csv@arg}\relax + \expandafter\csv@doo\expandafter{\cpt@csvarg}\relax }% \csv@parse@a }% }% - \if@boolFT{cpt@normalize}{}{% - \ifcsnullTF\csv@arg{}{% + \ifpsiboolFT{cpt@nmlz}{}{% + \ifxTF\@empty\cpt@csvarg{}{% \cpt@sttrue - \usecsn{cpt@\ifnum\csv@kv@type=\@ne kv\else csv\fi normalize}% - [#1]\csv@arg + \usename{cpt@\ifpsiboolTF{cpt@inkv}{kv}{csv}normalize}% + [#1]\cpt@csvarg }% }% \cpt@breakloopfalse - \expandafter\csv@parse@a\csv@arg#1\csv@nil#1% - \ifnumcmpFT\csv@depth>\z@{% - \ifnum\csv@depth=\z@ - \global\let\remainder@do\@gobble - \gundefcs\csv@kv@do - \fi - }{% - \popcsvinternals{\csv@parse@a,\csv@parse@b,\csv@kv@do,\ifcpt@useempty, - \ifcpt@breakloop,\ifcpt@normalize,\remainder@do}\csv@depth - }% - \advance\csv@depth\cpt@mone -} -% Apart from \pushingloop and some simple jobs, \comma@@loop -% isn't necessary. \pushingloop can't use \csv@@loop, since -% \csv@@loop calls \pushingloop to push its internals: -\newsentinel\comma@nil -\robust@def*\comma@@loop#1{% - \pushnumber\comma@depth - \ifnum\comma@depth>\@ne\cpt@toodeep\comma@@loop1\fi - \cpt@commaloop#1,\comma@nil,% - \popnumber\comma@depth - \undefcs\comma@do -} -\robust@def*\cpt@commaloop#1,{% - \def\comma@arg{#1}% - \ifsentinelTF\comma@arg\comma@nil{}{% - \comma@do{#1}\relax\cpt@commaloop - }% + \expandafter\csv@parse@a\cpt@csvarg#1\cpt@csvnil#1% + \popfunctions\cpt@csvkvparse\cpt@csvdepth + \ifnum\cpt@csvdepth=\z@pt + \global\let\remainder@do\@gobble + \undefcs\csv@do\undefcs\kv@do + \fi } \robust@def*\tsv@@loop{% - \cpt@despacetrue\cpt@robdespacefalse + \let\tsv@type\cptfalse \cpt@testst\cpt@tsvparse@a } \robust@def*\tsv@@parse{% - \cpt@despacetrue\cpt@robdespacetrue + \let\tsv@type\cpttrue \cpt@testst\cpt@tsvparse@a } -\newsentinel\tsv@nil +\new@def*\cpt@tsvnil{\cpt@tsvnil} \robust@def\cpt@tsvparse@a#1{% - \if@boolTF{cpt@st}{\let\tsv@arg#1}{\edef\tsv@arg{\unexpanded{#1}}}% - \advance\csv@depth\@ne - \ifnumcmpFT\csv@depth>\z@{}{% - \pushcsvinternals{\tsv@do,\ifcpt@useempty,\ifcpt@breakloop,% - \ifcpt@despace,\ifcpt@robdespace,\remainder@do}\csv@depth - }% + \cpt@stchoose{cpt@st}{#1}\cpt@tsvarg\cpt@tsvparse@a + \pushfunctions\tsv@@parse{% + \tsv@doo,\ifcpt@useempty,\ifcpt@breakloop,% + \remainder@do,\tsv@type + }\cpt@csvdepth + \let\tsv@doo\tsv@do \cpt@breakloopfalse - \expandafter\cpt@tsvparse@b\tsv@arg\tsv@nil - \ifnumcmpFT\csv@depth>\z@{% - \ifnum\csv@depth=\z@ - \global\let\remainder@do\@gobble - \gundefcs\tsv@do - \fi - }{% - \popcsvinternals{\tsv@do,\ifcpt@useempty,\ifcpt@breakloop,% - \ifcpt@despace,\ifcpt@robdespace,\remainder@do}\csv@depth - }% - \advance\csv@depth\cpt@mone + \expandafter\cpt@tsvparse@b\cpt@tsvarg\cpt@tsvnil + \popfunctions\tsv@@parse\cpt@csvdepth + \ifnum\cpt@csvdepth=\z@pt + \global\let\remainder@do\@gobble + \undefcs\tsv@do + \fi } \robust@def*\cpt@tsvparse@b{% \if@boolTF{cpt@breakloop}{% - \defpass\cpt@tempa##1\tsv@nil{\remainder@do{##1}}% + \defpass\cpt@tempa##1\cpt@tsvnil{\remainder@do{##1}}% }{% \begingroup - \let\temp@bgroup\bgroup + \let\bgr@up\bgroup \let\bgroup\cpt@undefined - \futurelet\next\cpt@tsvparse@c + \cpt@ifnextchar\bgr@up\cpt@tsvparse@c\cpt@tsvparse@c }% } \robust@def\cpt@tsvparse@c#1{% - \cptpassexpanded{\endgroup\edef\noexpand\tsv@arg - {\noexpand\unexpanded{\ifxTF\next\temp@bgroup - {{\unexpanded{#1}}}{\unexpanded{#1}}}}}% - \if@boolFT{cpt@despace}{}{% - \usecsn{\ifcpt@robdespace rob\fi despacecontent}\tsv@arg - }% - \ifsentinelTF\tsv@arg\tsv@nil{}{% - \ifcsnullTF\tsv@arg{% - \ifcpt@useempty\tsv@do{}\relax\fi + \expandafter\endgroup\ifx\@let@token\bgr@up + \let\reserved@a\cpttrue\else\let\reserved@a\cptfalse\fi + \ifpsiboolTF{reserved@a}{% + \edef\cpt@tsvarg{{\unexpanded{#1}}}% + }{% + \edef\cpt@tsvarg{\usename{cpttrimspace\if\tsv@type s\fi}{#1}}% + }% + \ifxTF\cpt@tsvarg\cpt@tsvnil{}{% + \ifxTF\@empty\cpt@tsvarg{% + \ifcpt@useempty\tsv@doo{}\relax\fi }{% - \expandafter\tsv@do\expandafter{\tsv@arg}\relax + \expandafter\tsv@doo\expandafter{\cpt@tsvarg}\relax }% \cpt@tsvparse@b }% } -% Fast, but non-robust and non-nesting, tsv parser. -% \tsv@@parse does preserve outer braces but sometimes this -% isn't required, necessitating a call to a brace stripper. -% \siso@@loop strips outer braces in its arguments. -\newsentinel\siso@nil +\new@def*\siso@nil{\siso@nil} \robust@def*\siso@@loop#1{% - \pushnumber\siso@depth - \ifnum\siso@depth>\@ne\cpt@toodeep\siso@@loop1\fi + \push@onefunction\siso@doo\cpt@sisodepth + \ifdefTF\siso@do{}{\cpt@notdeferr\siso@do}% + \let\siso@doo\siso@do \cpt@sisoloop#1\siso@nil - \popnumber\siso@depth + \pop@onefunction\siso@doo\cpt@sisodepth + \undefcs\siso@do } \robust@def*\cpt@sisoloop#1{% - \def\siso@arg{#1}% - \ifsentinelTF\siso@arg\siso@nil{}{% - \siso@do{#1}\relax - \cpt@sisoloop + \edef\siso@arg{\unexpanded{#1}}% + \ifxTF\siso@arg\siso@nil{}{% + \siso@doo{#1}\relax\cpt@sisoloop }% } -\robust@def*\on@currlevel#1#2{% +\robust@def*\cpt@oncurrlevel#1#2{% \ifdefTF\curr@level{% - \ifnum\curr@level=\z@ + \ifnum\curr@level=\z@pt \cpt@err{'\string\curr@level' is zero}{% I can't do anything on zero current level.}% \fi @@ -1166,91 +1499,120 @@ {\noexpandcsn{\cptgobblescape#2@\romannumeral\curr@level}}% } \new@def*\cptliststack#1#2{% - \ifx#2\@empty\@empty\else\expandcsonce{#2}#1\fi + \ifdefFT{#2}{}{% + \ifxTF#2\@empty{}{\expandcsonce{#2}#1}% + }% } \new@def\cptafterfi#1\fi{\fi#1} \new@def\cptafterelsefi#1\else#2\fi{\fi#1} \new@def\cptafterfifi#1\fi#2\fi{\fi\fi#1} \robust@def*\emptify#1{\let#1\@empty} \robust@def*\gemptify#1{\global\let#1\@empty} -\robust@def*\genemptify{\cpt@teststpm\cpt@genemptify} +\robust@def*\genemptify{\cpt@teststcl\cpt@genemptify} \def\cpt@genemptify#1{% - \ifcpt@pm\global\fi\ifcpt@st\else\long\fi\def#1{}% + \ifcpt@cl\global\fi\ifcpt@st\else\long\fi\def#1{}% } \robust@def*\emptifycsn{\aftercsname\emptify} \robust@def*\gemptifycsn{\global\aftercsname\emptify} -\robust@def*\emptifycsset#1{% - \def\comma@do##1{% - \ifsingletokenFT{#1}{% - \cpt@err{Multiple tokens '\detokenize{##1}'}\@ehc +\robust@def*\emptifycsset{% + \cpt@testst{\cpt@testcl\cpt@emptifycsset}% +} +\robust@def*\cpt@emptifycsset#1{% + \let\ifempcl\ifcpt@cl + \cpt@stchoose{cpt@st}{#1}\cpt@rsvda\cpt@emptifycsset + \def\csv@do##1{% + \ifsingletokenFT{##1}{% + \cpt@notonetokenerr{##1}% }{% \ifescapedTF{##1}{% - \def##1{}% + \ifempcl\global\fi\def##1{}% }{% - \cpt@err{Can't emptify unescaped macro '\string##1'}\@ehc + \cpt@notescapederr{##1}% }% }% }% - \comma@@loop{#1}% + \csv@@parse*[,]\cpt@rsvda + \undefcs\ifempcl } -\robust@def*\cptonlypreamble{\cpt@testst\cpt@onlypreamble} -\robust@def*\cpt@onlypreamble#1{% - \let\ifv@\ifcpt@st - \begingroup - \def\cpt@resa{}% - \def\comma@do##1{% - \normal@despace{##1}\cpt@tempa - \ifcsnullTF\cpt@tempa{}{% - \simpleexpandarg\ifescapedFT\cpt@tempa{% - \cpt@err{'\expandcsonce\cpt@tempa' not a command}\@ehc +\AtEndOfPackage{% + \AfterStartOfDocument{% + \def\do#1{% + \ifcsnameTF{\cptgobblescape#1}{% + \gdef#1{\@latex@error{'\string#1' is a preamble command}% + {Move command '\string#1' to document preamble.}}% }{% - \simpleexpandarg\ifsingletokenTF\cpt@tempa{% - \xifinsetTF{,\expandcsonce\cpt@tempa,}% - {,\expandcsonce\cpt@resa,}{% - \cpt@warn{Command '\expandcsonce\cpt@tempa' multiply - \MsgBrk submitted to \string\cptonlypreamble: - ignored}% - }{% - \cptaddtolist*\cpt@resa\cpt@tempa - \ifv@ - \cptexpandarg\AtEndOfPackage - {\noexpand\@onlypreamble\expandcsonce\cpt@tempa}% - \else - \expandafter\@onlypreamble\cpt@tempa - \fi - }% + \cpt@warn{Undefined command '\unexpanded{#1}': + \MsgBrk appeared in \string\cptonlypreamble}% + }% + }% + \cpt@preamblecmdhook + \gundefcs\cpt@preamblecmdhook + \gletcs\do\noexpand + }% +} +\new@def*\cpt@preamblecmdhook{} +\robust@def*\cptonlypreamble#1{% + \begingroup + \def\csv@do##1{% + \ifescapedFT{##1}{% + \cpt@notescapederr{##1}% + }{% + \ifsingletokenTF{##1}{% + \xifinsetTF{\detokenize{\do##1}}% + {\cptoxdetok\cpt@preamblecmdhook}{% + \cpt@warn{Command '\unexpanded{##1}' multiply + \MsgBrk submitted to \string\cptonlypreamble: + ignored}% }{% - \cpt@err{Invalid multiple arguments - '\expandcsonce\cpt@tempa'}\@ehc + \xdef\cpt@preamblecmdhook{\cptliststack{}% + \cpt@preamblecmdhook\unexpanded{\do##1}% + }% }% + }{% + \cpt@notonetokenerr{##1}% }% }% }% - \comma@@loop{#1}% + \csv@@parse[,]{#1}% \endgroup } -\robust@def*\ifelementcountTF{% - \cpt@testopt\cpt@ifelementcount{,}% +\robust@def*\ifelemcountTF{% + \cpt@testst{\cpt@testopt\cpt@ifelemcount@a,}% +} +\robust@def*\cpt@ifelemcount@a[#1]{% + \cpt@testpnopt{\cpt@ifelemcount@b{#1}}=% } -\robust@def*\cpt@ifelementcount[#1]#2#3{% - \def\csv@do##1{\pushnumber\reserved@a}% - \chardef\reserved@a\z@ - \csv@@loop*[#1]{#2}% - \ifcptcond\ifnum\reserved@a>#3\fi +\robust@def*\cpt@ifelemcount@b#1(#2){% + \cpt@testopt{\cpt@ifelemcount@c{#1}{#2}}1% +} +\robust@def*\cpt@ifelemcount@c#1#2[#3]#4{% + \begingroup + \@tempcnta\z@pt + \edef\reserved@a{\ifcpt@st*\fi}% + \def\csv@do##1{% + \advance\@tempcnta\@ne + }% + \expandafter\csv@@loop\reserved@a[#1]{#4}% + \aftercsname\endgroup{@\ifnum\@tempcnta#2#3 % + first\else second\fi oftwo}% } \new@def*\ifcsnullTF#1{% - \@nameuse{@\expandafter\ifx\expandafter\noboundary - \@gobble#1.\noboundary second\else first\fi oftwo}% - {\@nameuse{@\ifx#1\@empty first\else second\fi oftwo}}% - \@secondoftwo + \cptifcondTF\expandafter\ifx\expandafter + \noboundary\@gobble#1.\noboundary\fi{% + \@secondoftwo + }{% + \cptifcondTF\expandafter\ifx\expandafter + \noboundary\@gobble#1\noboundary\fi{% + \ifxTF#1\@empty + }{% + \@secondoftwo + }% + }% } +\new@def*\ifcsemptyTF#1{\ifxTF#1\@empty} \new@def*\ifcsnullFT#1{\ifcsnullTF{#1}\@secondoftwo\@firstoftwo} \new@def*\oifcsnullTF#1{\expandafter\ifcsnullTF\expandafter{#1}} \new@def*\oifcsnullFT#1{\expandafter\ifcsnullFT\expandafter{#1}} -\new@def*\xifcsnullTF#1{% - \expandafter\ifcsnullTF\expandafter - {\romannumeral-`\q\cptfullexpand{#1}}% -} \new@def*\ifcsnnullTF#1{% \ifblankTF{#1}{% \@secondoftwo @@ -1274,44 +1636,27 @@ \ifcsnullTF{#1}\@secondoftwo\@firstoftwo }\@secondoftwo } -\new@def*\ifdefnotnullFT#1{% - \ifdefnotnullTF{#1}\@secondoftwo\@firstoftwo -} \new@def*\ifcsndefnotnullTF#1{% \ifcsndefTF{#1}{% \ifcsnnullTF{#1}\@secondoftwo\@firstoftwo }\@secondoftwo } -\new@def*\ifcsndefnotnullFT#1{% - \ifcsndefnotnullTF{#1}\@secondoftwo\@firstoftwo -} -% For private use only where #1 is surely one token: \new@def*\simpleexpandarg#1#2{\expandafter#1\expandafter{#2}} - +\newletcs\s@expandarg=\simpleexpandarg \new@def*\expandcsonce#1{\unexpanded\expandafter{#1}} -\new@def*\expandcsnonce#1{\cptthreexp\expandcsonce\usecsn{#1}} +\new@def*\expandcsnonce#1{\aftercsname\expandcsonce{#1}} \new@def*\expandcstwice#1{\unexpanded\cptthreexp{#1}} \new@def*\expandcsntwice#1{\aftercsname\expandcstwice{#1}} \new@def*\noexpandcsn#1{\expandcsonce{\csname#1\endcsname}} -\newletcs\cptmakecs\noexpandcsn +\newletcs\cptmakecs=\noexpandcsn \new@def*\cptoxdetok#1{\detokenize\expandafter{#1}} \new@def*\cpttxdetok#1{\detokenize\cptthreexp{#1}} \new@def*\cptsxdetok#1{\detokenize\cptsevenxp{#1}} \robust@def\cptpassexpanded#1{% \begingroup\protected@edef\x{\endgroup#1}\x } -\newletcs\cptexpanded\cptpassexpanded -\long\def\cptfullexpand#1{% - \romannumeral-`\q\cpt@fullexpand{#1}{}% -} -\long\def\cpt@fullexpand#1{% - \expandafter\cpt@fullexp@nd\romannumeral-`\q#1\exp@nil -} -\long\def\cpt@fullexp@nd#1#2\exp@nil#3{% - \ifblankTF{#2}{#3#1}{\cpt@fullexpand{#2}{#3#1}}% -} +\newletcs\cptexpanded=\cptpassexpanded \robust@def\cptpassunexpanded#1{\begingroup\long\def\x{\endgroup#1}\x} -\newletcs\cptpassasis\cptpassunexpanded \robust@def\defpass#1#2#{\afterassignment#1\long\def#1#2} \robust@def\edefpass#1#2#{\afterassignment#1\long\edef#1#2} \robust@def*\cptexpandarg#1#2{\cptpassexpanded{\unexpanded{#1}{#2}}} @@ -1361,16 +1706,22 @@ \robust@def*\cpt@SetStyleFileMessages[#1]#2#3#4{% \begingroup \def\cpt@tempa##1{\noexpandcsn{##1}}% - \shelldef\cpt@tempb{\global\protected\@namedef}% + \protected\def\cpt@tempb{\global\protected\@namedef}% \edef\cpt@tempc{\ifx\@currext\@pkgextension Package\else Class\fi}% \@tempswafalse - \kernel@for\cpt@resa:={#2,#3,#4}\do{% - \ifcsname#1\cpt@resa\endcsname - \@tempswatrue\let\cpt@resb\cpt@resa - \fi + \def\do##1,{% + \ifnot@nil{##1}{% + \if@tempswa\else + \ifcsname#1##1\endcsname + \edef\reserved@a{#1##1}\@tempswatrue + \fi + \fi + \do + }% }% + \do#2,#3,#4,\@nil,% \if@tempswa - \def\reserved@a{#1\cpt@resb}\@notdefinable + \@notdefinable \else \cptpassexpanded{% \cpt@tempb{#1#2}####1{\cpt@tempa{\cpt@tempc Info}% @@ -1385,12 +1736,12 @@ \interactionmode\thr@@ } \SetStyleFileMessages[cpt@]{info}{warn}{err} -\robust@def*\cpt@begingroup{% +\robust@def*\cptbegingroup{% \begingroup \cpt@grouplevel\currentgrouplevel \cpt@grouptype\currentgrouptype } -\robust@def*\cpt@endgroup{% +\robust@def*\cptendgroup{% \ifnum\cpt@grouptype=\currentgrouptype \ifnum\cpt@grouplevel=\currentgrouplevel\else \cpt@err{There is a group level mismatch}\@ehc @@ -1406,16 +1757,17 @@ \ifcsndefTF{if#1}{% \if@boolTF{#1}% }{% - \cpt@err{Boolean '\usecsn{#1}' undefined}\@ehc + \cpt@err{Boolean '\@backslashchar#1' undefined}\@ehc }% } \new@def*\ifboolFT#1{\ifboolTF{#1}\@secondoftwo\@firstoftwo} \new@def*\ifbooleanTF#1#{\ifboolTF{#1}} \new@def*\if@boolTF#1{% - \usecsn{@\usecsn{if#1}first\else second\fi oftwo}% + \usename{@\usename{if#1}first\else second\fi oftwo}% } \new@def*\if@boolFT#1{\if@boolTF{#1}\@secondoftwo\@firstoftwo} \new@def\cptiterate#1\repeat{\cpt@iterate\@gobble{#1}} +\newletcs\cptloop=\cptiterate \new@def\cpt@iterate\@gobble#1{% #1\relax\expandafter\cpt@iterate\fi\@gobble{#1}% } @@ -1454,15 +1806,15 @@ \expandafter\@gobbletwo\fi{#1}{#2}% } \new@def*\ifnumcmpTF#1#{% - \usecsn{@\ifnum\numexpr\cpt@numlt\cpt@numgt\cpt@numeq#1% + \usename{@\ifnum\numexpr\cpt@numlt\cpt@numgt\cpt@numeq#1% \remove@to@nnil<=>\@nnil first\else second\fi oftwo}% } -\new@def*\ifnumcmpFT#1#{\usecsn{@\ifnumcmpTF#1{second}{first}oftwo}} +\new@def*\ifnumcmpFT#1#{\usename{@\ifnumcmpTF#1{second}{first}oftwo}} \new@def*\ifdimcmpTF#1#{% - \usecsn{@\ifdim\dimexpr\cpt@dimlt\cpt@dimgt\cpt@dimeq#1% + \usename{@\ifdim\dimexpr\cpt@dimlt\cpt@dimgt\cpt@dimeq#1% \remove@to@nnil<=>\@nnil first\else second\fi oftwo}% } -\new@def*\ifdimcmpFT#1#{\usecsn{@\ifdimcmpTF#1{second}{first}oftwo}} +\new@def*\ifdimcmpFT#1#{\usename{@\ifdimcmpTF#1{second}{first}oftwo}} \robust@def*\cpt@defcheck#1#2\cpt@nil{% \new@def*#1##1\cpt@nil{% \begingroup @@ -1472,10 +1824,7 @@ \cpt@tempa##1#2\cpt@nil }% } -\def\siso@do#1{\cpt@defcheck#1\cpt@nil}% -\siso@@loop{% - {\cpt@checkeq=}{\cpt@checkgt>}{\cpt@checklt<}{\cpt@checkhyp-}% -} +\cpt@defcheck\cpt@checkeq=\cpt@nil \robust@def*\cpt@defsplit@at#1#2\cpt@nil{% \new@def*#1##1\cpt@nil{% \begingroup @@ -1489,160 +1838,197 @@ }% }% } -\def\siso@do#1{\cpt@defsplit@at#1\cpt@nil}% -\siso@@loop{% - {\cpt@split@ateq=}{\cpt@split@atgt>}% - {\cpt@split@atlt<}{\cpt@split@athyp-}% -} +\cpt@defsplit@at\cpt@split@ateq=\cpt@nil \robust@def\DefSuffixChecker#1#2#3{% \def#1##1##2##3{% \begingroup \toks@{}% - \def\xwm@tempa{% + \def\cpt@tempa{% \ifsingleTF{##2}{% \ifsingleTF{##3}{\toks@{##1##2##3}}{\toks@{##1##2{##3}}}% }{% \ifsingleTF{##3}{\toks@{##1{##2}##3}}{\toks@{##1{##2}{##3}}}% }% }% - \defpass\xwm@tempb{% - \ifstrcmpTF{##2}{#2}{\xwm@tempa}{% + \defpass\cpt@tempb{% + \ifstrcmpTF{##2}{#2}{\cpt@tempa}{% \ifstrcmpTF{##2}{#3}{% - \ifstrcmpTF{##3}{#2}{\toks@{##1##3##2}}{\xwm@tempa}% - }{\xwm@tempa}% + \ifstrcmpTF{##3}{#2}{\toks@{##1##3##2}}{\cpt@tempa}% + }{\cpt@tempa}% }% }% \expandafter\endgroup\the\toks@ }% } \new@def*\ifnumoddTF#1#{% - \usecsn{@\ifodd#1\@empty first\else second\fi oftwo}% + \usename{@\ifodd#1\@empty first\else second\fi oftwo}% +} +\new@def*\ifnumoddFT#1#{% + \usename{@\ifnumoddTF#1{second}{first}oftwo}% } -\new@def*\ifnumoddFT#1#{\usecsn{@\ifnumoddTF#1{second}{first}oftwo}} \newletcs\ifnumevenTF\ifnumoddFT \robust@def*\cptnumdef#1#2{\edef#1{\the\numexpr#2}} \robust@def*\cptdimdef#1#2{\edef#1{\the\dimexpr#2}} \robust@def*\cptnumadd#1#2{\edef#1{\the\numexpr#1+#2}} \robust@def*\cptdimadd#1#2{\edef#1{\the\dimexpr#1+#2}} -\new@edef*\@leftbracechar{\expandafter\@car\string{\@nil\iffalse}\fi} -\new@def\cptstrcmp#1#2{% - \ifcptcond\ifnum\pdfstrcmp{#1}{#2}=\z@\fi +\robust@def*\csnnumdef#1#2{\csn@edef{#1}{\the\numexpr#2}} +\robust@def*\csndimdef#1#2{\csn@edef{#1}{\the\dimexpr#2}} +\robust@def*\csnnumadd#1#2{\csn@edef{#1}{\the\numexpr#1+#2}} +\robust@def*\csndimadd#1#2{\csn@edef{#1}{\the\dimexpr#1+#2}} +\new@edef*\cpt@leftbracechar{% + \expandafter\@car\string{\@nil\iffalse}\fi } -\new@def\ifstrcmpTF#1#2{% - \cptstrcmp{\detokenize{#1}}{\detokenize{#2}}% +\new@edef*\cpt@rightbracechar{% + \iffalse{\fi\expandafter\@car\string}\@nil +} +\new@def\cptstrcmp#1#2{% + \usename{@\ifnum\pdfstrcmp{#1}{#2}=0 first\else second\fi oftwo}% } \new@def\ifstrcmpFT#1#2{\ifstrcmpTF{#1}{#2}\@secondoftwo\@firstoftwo} -\robust@def\oifstrcmpTF#1#2{\cptexpandtwoargsonce\ifstrcmpTF{#1}{#2}} -\robust@def\oif@sp@strcmpTF#1#2{% +\new@def\oifstrcmpTF#1#2{% + \cptstrcmp{\expandcsonce{#1}}{\expandcsonce{#2}}% +} +\robust@def\oifstrcmp@sp@TF#1#2{% \ifsingletokenTF{#1}{% \ifsingletokenTF{#2}{% - \ifnum\pdfstrcmp{\expandcsonce{#1}}{\expandcsonce{#2}}=\z@ - \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + \oifstrcmpTF{#1}{#2}% }{% - \cpt@err{'\detokenize{#2}' not a single token}\@ehc + \cpt@notonetokenerr{#2}% }% }{% - \cpt@err{'\detokenize{#1}' not a single token}\@ehc + \cpt@notonetokenerr{#1}% }% } -\robust@def\oifstrcmpFT#1#2{\cptexpandtwoargsonce\ifstrcmpFT{#1}{#2}} -\robust@def\xifstrcmpTF#1#2{\cptexpandtwoargs\ifstrcmpTF{#1}{#2}} -\robust@def\xifstrcmpFT#1#2{\cptexpandtwoargs\ifstrcmpFT{#1}{#2}} -\robust@def\ifstreqTF#1#2{% - \begingroup - \robust@despace{#1}\cpt@tempa - \robust@despace{#2}\cpt@tempb - \aftercsname\endgroup{@\ifnum\pdfstrcmp - {\cptoxdetok\cpt@tempa}{\cptoxdetok\cpt@tempb}% - =\z@ first\else second\fi oftwo}% +\robust@def\oifstrcmpFT#1#2{% + \oifstrcmpTF{#1}{#2}\@secondoftwo\@firstoftwo +} +\new@def\xifstrcmpTF#1#2{\cptstrcmp{#1}{#2}} +\new@def\xifstrcmpFT#1#2{\cptstrcmp{#1}{#2}\@secondoftwo\@firstoftwo} +\new@def\ifstreqTF#1#2{% + \expandafter\cptswapfirstbraced\expandafter + {\romannumeral-`\q\cpttrimspaces{#1}} + {\expandafter\ifstrcmpTF\expandafter + {\romannumeral-`\q\cpttrimspaces{#2}}} } + \robust@def\ifstreqFT#1#2{\ifstreqTF{#1}{#2}\@secondoftwo\@firstoftwo} \robust@def\oifstreqTF#1#2{\cptexpandtwoargsonce\ifstreqTF{#1}{#2}} \robust@def\oifstreqFT#1#2{\cptexpandtwoargsonce\ifstreqFT{#1}{#2}} \robust@def\xifstreqTF#1#2{\cptexpandtwoargs\ifstreqTF{#1}{#2}} \robust@def\xifstreqFT#1#2{\cptexpandtwoargs\ifstreqFT{#1}{#2}} -\long\def\ifbracedTF#1{% - \cptstrcmp{\detokenize\expandafter{\@gobble#1.}}{}\@secondoftwo{% - \cptstrcmp{\detokenize\expandafter{\@gobble#1}}{}{% - \cptstrcmp{\expandafter\cpt@car\detokenize{#1}\car@nil}\@leftbracechar - \@firstoftwo\@secondoftwo + +% Ulrich Diez 06/02/2011: +\new@def*\ifbracedTF#1#2#3{% + \romannumeral + \ifblankTF{#1}{% + 0 #3% + }{% + \ifnullTF{#1}{% + 0 #3% }{% - \@secondoftwo + \expandafter\@secondoftwo\expandafter + {\expandafter{\string#1.}\expandafter\@firstoftwo + \expandafter{\iffalse}\fi0 #2}{0 #3}% }% }% } -\newcommand\ifbracedFT[1]{\ifbracedTF{#1}\@secondoftwo\@firstoftwo} -\long\def\ifleftbracedTF#1{% - \cptstrcmp{\detokenize\expandafter{\@gobble#1.}}{}\@secondoftwo{% - \cptstrcmp{\expandafter\cpt@car\detokenize{#1}\car@nil}\@leftbracechar - \@firstoftwo\@secondoftwo +%%-- + +\new@def*\ifbracedFT#1{\ifbracedTF{#1}\@secondoftwo\@firstoftwo} +\new@def*\ifleftbracedTF#1{% + \ifblankTF{#1}{% + \@secondoftwo + }{% + \@nameuse{@\if\expandafter\@car\detokenize{#1}\@nil + \expandafter\@car\string{\@nil\ifnum0=`}\fi + first\else second\fi oftwo}% }% } -\new@def\ifxTF#1#2{% - \usecsn{@\ifx#1#2\@empty first\else second\fi oftwo}% -} -\new@def\ifxFT#1#2{\ifxTF{#1}{#2}\@secondoftwo\@firstoftwo} \new@def*\ifdefeqTF#1#2{% \ifdefTF{#1}{% \ifdefTF{#2}{% - \usecsn{@\ifx#1#2first\else second\fi of oftwo}% + \usename{@\ifx#1#2first\else second\fi of oftwo}% }\@secondoftwo }\@secondoftwo } \new@def\ifdefeqFT#1#2{\ifdefeqTF{#1}{#2}\@secondoftwo\@firstoftwo} -\new@def\ifcateqTF#1#{% - \usecsn{@\ifcat#1first\else second\fi oftwo}% -} +\new@def\ifcateqTF#1#{\usename{@\ifcat#1first\else second\fi oftwo}} \new@def\ifcharcmpTF#1#2{% \ifsingletokenTF{#1}{% \ifsingletokenTF{#2}{% - \usecsn{@\if\detokenize\expandafter{\romannumeral\expandafter + \usename{@\if\detokenize\expandafter{\romannumeral\expandafter \cptswap\expandafter{\romannumeral-`\q#2}{-`\q#1}}% first\else second\fi oftwo}% }{% - \cpt@err{More than one token in '\detokenize{#2}'}\@ehc - \@secondoftwo + \cpt@notonetokenerr{#2}\@secondoftwo }% }{% - \cpt@err{More than one token in '\detokenize{#1}'}\@ehc - \@secondoftwo + \cpt@notonetokenerr{#1}\@secondoftwo }% } -\new@def\ifcharcmpFT#1#2{\ifcharcmpTF{#1}{#2}\@secondoftwo\@firstoftwo} \new@def\ifexpandableTF#1#2#3{% \romannumeral\ifleftbracedTF{#1}\@secondoftwo{% \ifblankTF{#1}\@secondoftwo{\expandafter\ifx\noexpand#1#1% \expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi}}% {0 #2}{0 #3}% } -\new@def*\iffirstisspaceTF#1{% - \long\def\iffirstisspaceTF##1##2##3{% - \romannumeral\usecsn{@\ifblankTF{##1}{second}% - {\cpt@iffirstisspace.##1#1\@nnil}oftwo}{0#1##2}{0#1##3}% +\newcommand*\ifleadspaceTF[1]{% + \long\def\ifleadspaceTF##1##2##3{% + \romannumeral\@nameuse{@\ifnullTF{##1}{second}% + {\cpt@ifleadspace.##1#1\@nnil}oftwo}{0#1##2}{0#1##3}% }% } -\iffirstisspaceTF{ } -\new@def\cpt@iffirstisspace#1 {% - \expandafter\ifblankTF\expandafter{\@gobble#1}{first}{second}% +\ifleadspaceTF{ } +\long\def\cpt@ifleadspace#1 {% + \expandafter\ifnullTF\expandafter{\@gobble#1}{first}{second}% \remove@to@nnil } +\newcommand\iftrailspaceTF[1]{% + \long\def\iftrailspaceTF##1{% + \romannumeral-`\q + \csname @\expandafter\@firstofone\expandafter{% + \romannumeral\expandafter + \cpt@iftrailspace\expandafter{\remove@to@space.##1#1}% + }% + }% +} +\iftrailspaceTF{ } +\newcommand\cpt@iftrailspace[1]{% + \ifnullTF{#1}{% + \expandafter\@secondoftwo\@firstoftwo + }{% + \ifleadspaceTF{#1}{% + \expandafter\ifnullTF\expandafter{\@gobblespace#1}{% + \expandafter\@firstoftwo\@firstoftwo + }{% + \@secondoftwo + }% + }{% + \@secondoftwo + }% + }{% + {0 first}{0 second}oftwo\endcsname + }{% + \expandafter\cpt@iftrailspace\expandafter{\remove@to@space.#1}% + }% +} \new@def\ifsingletokenTF#1#2#3{% - \romannumeral-`\q\ifblankTF{#1}\@secondoftwo{% + \romannumeral\ifblankTF{#1}\@secondoftwo{% \ifbracedTF{#1}\@secondoftwo{% - \iffirstisspaceTF{#1}{% + \ifleadspaceTF{#1}{% \expandafter\ifblankTF\expandafter{\@gobblespace#1}% }{% \expandafter\ifblankTF\expandafter{\@gobble#1}% }% \@firstoftwo\@secondoftwo }% - }{#2}{#3}% + }{0 #2}{0 #3}% } -\newletcs\ifsingleTF\ifsingletokenTF +\newletcs\ifsingleTF=\ifsingletokenTF \robust@def*\ifsingletokenFT#1{% \ifsingletokenTF{#1}\@secondoftwo\@firstoftwo } -\new@def\if@sp@singletokenTF#1#2#3{% +\new@def\ifsingletoken@sp@TF#1#2#3{% \romannumeral-`\q\ifblankTF{#1}\@secondoftwo{% \ifbracedTF{#1}\@secondoftwo{% \expandafter\ifblankTF\expandafter{\@gobble#1}% @@ -1650,24 +2036,56 @@ }% }{#2}{#3}% } -\robust@def*\cpt@listparser@err#1{% - \@latex@error{Invalid list parser '#1'}\@ehc +\robust@def*\ifsingledigitTF#1{% + \begingroup + \def\cpt@tempa##1#1##2##3\@@nil{% + \endgroup + \csname @\ifx##20first\else second\fi oftwo\endcsname + }% + \cpt@tempa00 01 02 03 04 05 06 07 08 09 0#1\relax\@@nil } +\new@def*\cpt@parserlist{,;:/|*><=-+"'} \robust@def*\cpt@checklistparser#1#2{% - \ifsingletokenTF{#1}{% - \xifinsetTF{\cptoxdetok{#1}}{\detokenize{,;:/+-|*&}}{% - #2% + \cptifmacroTF{#1}{% + \cpt@err{Parser '\detokenize{#1}' is a macro}\@ehc + }{% + \ifsingletokenTF{#1}{% + \xifinsetTF{\detokenize{#1}}\cpt@parserlist{% + #2% Don't put \relax here! + }{% + \cpt@listparsererr{#1}% + }% }{% - \cpt@listparser@err{#1}% + \cpt@listparsererr{#1}% }% - }{% - \cpt@listparser@err{#1}% }% } -\robust@def\exitgroupdef#1{% - \cptpassexpanded{\endgroup\edef - \noexpand#1{\noexpand\unexpanded{\expandcsonce#1}}}% + +\robust@def*\cpt@checklistparser@b#1{% + \expandafter\ifx\expandafter\\\@gobble#1.\\% + \cpt@listparsererr{#1}% + \else + \def\cpt@tempa##1##2\cpt@nil{% + \ifx##2\relax + \xifinsetTF{\detokenize{#1}}\cpt@parserlist{}{% + \cpt@listparsererr{#1}% + }% + \else + \cpt@listparsererr{#1}% + \fi + }% + \expandafter\cpt@tempa\string#1\relax\cpt@nil + \fi +} + +\robust@def*\postgroupdef#1\endgroup{% + \cptpassexpanded{\endgroup\cpt@csexit{#1}}% +} +\robust@def*\cptpassacross#1#2{% + \cptpassexpanded{\unexpanded{#2}\cpt@csexit#1}% } +\new@def*\cpt@csexit#1{\edef\noexpand#1{\ox@unexpanded{#1}}} +\new@def*\ox@unexpanded#1{\noexpand\unexpanded{\expandcsonce{#1}}} \robust@def*\cptaftergroup#1{% \advance\@tempcnta\@ne \csn@xdef{cpt@aftergroup@\romannumeral\@tempcnta}{% @@ -1683,12 +2101,12 @@ \gundefcsn{cpt@afterassignment@\romannumeral\@tempcnta}% \unexpanded\ifblankTF{#1}{}\expandafter{#1}% }% - \aftercsname{\endgroup\afterassignment}{% - cpt@afterassignment@\romannumeral\@tempcnta}% + \aftercsname{\endgroup\afterassignment} + {cpt@afterassignment@\romannumeral\@tempcnta}% } \robust@def*\cptexpandmacro#1#2{% \ifsingletokenTF{#1}{% - \ifcptmacroTF{#1}{% + \cptifmacroTF{#1}{% \ifexpandableTF{#1}{% \simpleexpandarg\cptexpandmacro{#1}#2% }{% @@ -1701,57 +2119,47 @@ \edef#2{\unexpanded{#1}}% }% } -% Donald Arseneau's \@ifnextchar: -\robust@def\cpt@ifnextchar#1#2#3{% - \begingroup - \@ifnextchar\relax - {\cpt@ifnextchar@a{#1}{#2}{#3}}% - {\cpt@ifnextchar@a{#1}{#2}{#3}}% -} -\robust@def\cpt@ifnextchar@a#1#2#3{% - \ifcase - \ifcat\noexpand\@let@token\bgroup 1\fi - \ifcat\noexpand\@let@token\egroup 1\fi - 0\let\next\cpt@ifnextchar@b - \else - \def\next{\endgroup\@ifnextchar}% - \fi - \expandafter\next\expandafter{\string#1}{#2}{#3}% -} -\robust@def\cpt@ifnextchar@b#1#2#3#4{% - \escapechar92\relax - \edef\cpt@tempa{\cpt@ifnextchar@c{#1}\cpt@ifnextchar@c{#4}}% - \expandafter\endgroup\csname\expandafter @\expandafter - \ifx\cpt@tempa first\else second\fi oftwo\endcsname - {#2}{#3}#4% +\new@def*\cptexpandcs#1{% + \ifsingletokenTF{#1}{% + \cptifmacroTF{#1}{% + \ifexpandableTF{#1}{% + \simpleexpandarg\cptexpandcs{#1}% + }{% + \noexpand#1% + }% + }{% + \noexpand#1% + }% + }{% + \unexpanded{#1}% + }% } -\new@def\cpt@ifnextchar@c#1{% - \expandafter\cpt@ifnextchar@d\string#1\relax\noindent{#1}% +\begingroup +\catcode`\&=7 +\new@gdef*\cptfullexpand#1{% + \romannumeral\cpt@fullexpand{#1}{}% } -\new@def\cpt@ifnextchar@d#1#2\noindent#3{% - \ifx\relax#2#1\else\noexpand#3\fi +\new@gdef*\cpt@fullexpand#1{% + \expandafter\cpt@f@llexp@nd\romannumeral\cpt@f@llexpand#1&% } -\robust@def\cpt@testopt#1#2{\cpt@ifnextchar[{#1}{#1[{#2}]}} -\robust@def*\cpt@ifbrack#1#2{\cpt@ifnextchar[{#1}{#2}} -\new@def*\cpt@xtestopt#1#2#3{% - \cpt@xifbrack#1\noboundary[\noboundary{#2#1}{#2[{#3}]{#1}}% +\new@gdef*\cpt@f@llexpand#1{% + \cptifmacroTF{#1}{% + \ifexpandableTF{#1}{% + \expandafter\cpt@f@llexpand\expandafter{#1}% + }{% + 0 #1% + }% + }{% + 0 #1% + }% } -\new@def*\cpt@xifbrack#1[#2\noboundary#3#{% - \usecsn{@\ifblankTF{#1#2}{first}{second}oftwo}% +\new@gdef*\cpt@f@llexp@nd#1#2{% + \ifblankTF{#2}{0 #3#1}{\cpt@fullexpand{#2}{#3#1}}% } -\robust@def\cpt@testpnopt#1#2{\cpt@ifnextchar({#1}{#1({#2})}} -\robust@def\cpt@ifstar#1{\cpt@ifnextchar*{\@firstoftwo{#1}}} -\robust@def\cpt@ifplus#1{\cpt@ifnextchar+{\@firstoftwo{#1}}} -\robust@def\cpt@ifprime#1{\cpt@ifnextchar'{\@firstoftwo{#1}}} -\robust@def\cpt@testst#1{\cpt@ifstar{\cpt@sttrue#1}{\cpt@stfalse#1}} -\robust@def\cpt@testpl#1{\cpt@ifplus{\cpt@pltrue#1}{\cpt@plfalse#1}} -\robust@def\cpt@teststpl#1{\cpt@testst{\cpt@testpl{#1}}} -\robust@def\cpt@testpm#1{\cpt@ifprime{\cpt@pmtrue#1}{\cpt@pmfalse#1}} -\robust@def\cpt@teststpm#1{\cpt@testst{\cpt@testpm{#1}}} -\robust@def\cpt@teststopta#1{\cpt@testst{\cpt@testopt{#1}{}}} -\robust@def\cpt@teststoptb#1{\cpt@testst{\cpt@testopt{#1}{,}}} -\robust@def\cpt@teststoptc#1#2{\cpt@testst{\cpt@testopt{#1}{#2}}} -\new@def*\ifstreqcase#1{\cpt@xtestopt{#1}\cpt@ifstreqcase{}} +\endgroup + +% [<default act>]{<teststr>}{<{str1}{act1}{str2}{act2}...>} +\new@def*\IfStrEqCase#1{\cpt@xtestopt{#1}\cpt@ifstreqcase{}} \new@def\cpt@ifstreqcase[#1]#2#3{% \expandafter\cptswapfirstbraced\expandafter{#2}% {\cpt@ifstreqc@se#3\cpt@mil\cpt@mil\cpt@nil}{#1}% @@ -1763,83 +2171,82 @@ }% }% } -\new@def*\ifstrincase#1{\cpt@xtestopt{#1}\cpt@ifstrincase{}} +\def\cptcheckchoice#1#2#3{% + \expandafter\cptswapfirstbraced\expandafter + {\romannumeral-`\q\cpttrimspace{#1}} + {\cpt@checkchoice#2,\cpt@mil\cpt@mil,\cpt@nil}{#3}% +} +\new@def\cpt@checkchoice#1#2,#3\cpt@nil#4#5{% + \ifblankTF{#3}{\unexpanded{#5}}{% + \xifstrcmpTF{\cpttrimspace{#1}}{\unexpanded{#4}}{% + \unexpanded{#2}% + }{% + \cpt@checkchoice#3\cpt@nil{#4}{#5}% + }% + }% +} +\new@def*\IfStrPresentCase#1{\cpt@xtestopt{#1}\cpt@ifstrincase{}} \new@def\cpt@ifstrincase[#1]#2#3{% \expandafter\cptswapfirstbraced\expandafter{#2}% {\cpt@ifstrinc@se#3\cpt@mil\cpt@mil\cpt@nil}{#1}% } \new@def\cpt@ifstrinc@se#1#2#3\cpt@nil#4#5{% - \ifblankTF{#3}{#5}{% - \ifinsetTF{#1}{#4}{#2}{% + \ifblankTF{#3}{#5\relax}{% + \ifinsetTF{#1}{#4}{#2\relax}{% \cpt@ifstrinc@se#3\cpt@nil{#4}{#5}% }% }% } -% LaTeX kernel's \in@ (which is used frequently elsewhere) -% is not reliable in cases like \in@{cc}{abc}. So we provide -% a modified form of it here: -\robust@def\cptinset#1#2{% - \begingroup - \def\in@@##1#1##2##3\in@@{\endgroup - \ifx##2\cptinset\cpt@infalse\else\cpt@intrue\fi - }% - \in@@#2{\in@@}#1\cptinset\in@@ +\robust@def\cpt@in#1#2{% + \long\def\in@@##1#1{}% + \ifcat$\detokenize\expandafter{\in@@#2{}{}#1}$% + \cpt@infalse\else\cpt@intrue\fi } -\newletcs\cpt@in\cptinset \robust@def\ifinsetTF#1#2{% - \cptinset{#1}{#2}% - \@nameuse{@\ifcpt@in first\else second\fi oftwo}% + \cpt@in{#1}{#2}% + \csname @\ifcpt@in first\else second\fi oftwo\endcsname } \robust@def\ifinsetFT#1#2{\ifinsetTF{#1}{#2}\@secondoftwo\@firstoftwo} -\robust@def\oifinsetTF#1#2{% - \begingroup - \edef\cpt@tempa{{\expandcsonce{#1}}{\expandcsonce{#2}}}% - \expandafter\endgroup\expandafter\ifinsetTF\cpt@tempa -} +\robust@def\oifinsetTF#1#2{\cptexpandtwoargsonce\ifinsetTF{#1}{#2}} \robust@def\oifinsetFT#1#2{\oifinsetTF{#1}{#2}\@secondoftwo\@firstoftwo} -\robust@def\xifinsetTF#1#2{% - \begingroup - \protected@edef\cpt@tempa{{#1}{#2}}% - \expandafter\endgroup\expandafter\ifinsetTF\cpt@tempa -} +\robust@def\xifinsetTF#1#2{\cptexpandtwoargs\ifinsetTF{#1}{#2}} \robust@def\xifinsetFT#1#2{\xifinsetTF{#1}{#2}\@secondoftwo\@firstoftwo} -\robust@def\if@sp@inlistTF#1#2#3{% - \xifinsetTF{\detokenize{#1}\cptoxdetok{#2}\detokenize{#1}}% - {\detokenize{#1}\cptoxdetok{#3}\detokenize{#1}}% -} -\robust@def\if@sp@inlistFT#1#2#3{% - \if@sp@inlistTF{#1}{#2}{#3}\@secondoftwo\@firstoftwo +\robust@def\oifinset@sp@TF#1#2#3{% + \begingroup + \edef\x{\detokenize{#1}}% + \edef\x{{\x\cptoxdetok{#2}\x}{\x\cptoxdetok{#3}\x}}% + \expandafter\endgroup\expandafter\ifinsetTF\x } -\robust@def*\cptaddtotoks#1{% - \long\shelldef\cptaddtotoks##1##2{% - \toks##1\oifblankTF{\the\toks##1}{{##2}}% - {\expandafter{\the\toks##1#1##2}}% - }% +\robust@def\oifinset@sp@FT#1#2#3{% + \oifinset@sp@TF{#1}{#2}{#3}\@secondoftwo\@firstoftwo } -\cptaddtotoks{ } -\robust@def*\cptaddtolist{\cpt@teststoptb{\cpt@addtolist\expandcsonce{e}}} -\robust@def*\cptgaddtolist{\cpt@teststoptb{\cpt@addtolist\expandcsonce{x}}} -\robust@def*\cptxaddtolist{\cpt@teststoptb{\cpt@addtolist\@firstofone{e}}} -\robust@def*\cptgxaddtolist{\cpt@teststoptb{\cpt@addtolist\@firstofone{x}}} +\robust@def*\cptaddtolist{\cpt@teststopt{\cpt@addtolist\expandcsonce{e}},} +\robust@def*\cptgaddtolist{\cpt@teststopt{\cpt@addtolist\expandcsonce{x}},} +\robust@def*\cptxaddtolist{\cpt@teststopt{\cpt@addtolist\@firstofone{e}},} +\robust@def*\cptgxaddtolist{\cpt@teststopt{\cpt@addtolist\@firstofone{x}},} \robust@def\cpt@addtolist#1#2[#3]#4#5{% \ifcpt@check\cpt@checklistparser{#3}\relax\fi \begingroup - \def\cpt@tempa{\endgroup + \toks@{\endgroup \ifdefTF#4{% \if@boolTF{cpt@st}{% - \usecsn{protected@#2def}#4{\cptliststack#3#4#1{#5}}% + \usename{protected@#2def}#4{\cptliststack#3#4#1{#5}}% }{% - \usecsn{#2def}#4{\cptliststack#3#4\unexpanded{#5}}% + \usename{#2def}#4{\cptliststack#3#4#1{#5}}% }% }{% \if@boolTF{cpt@st}{% - \usecsn{protected@#2def}#4{#1{#5}}% + \usename{protected@#2def}#4{#1{#5}}% }{% - \usecsn{#2def}#4{\unexpanded{#5}}% + \usename{#2def}#4{#1{#5}}% }% }% }% - \ifblankTF{#5}{\ifcpt@useempty\cpt@tempa\else\endgroup\fi}\cpt@tempa + \ifblankTF{#5}{% + \ifcpt@useempty\the\toks@\else\endgroup\fi + }{% + \the\toks@ + }% } \robust@def*\cptfilterremoveelements{% \cpt@testopt\cpt@filterremoveelements{,}% @@ -1860,7 +2267,6 @@ \def\csv@do##1{% \edef\cpt@tempa{\unexpanded{##1}}% \cpt@usefilter\cpt@tempa\cpt@tempb - % no \if@sp@inlistTF here: \expandafter\xifinsetTF\cpt@tempd\cpt@tempb{}{% \cptaddtolist[#1]\cpt@tempc{##1}% }% @@ -1871,7 +2277,7 @@ }% }% \let#2\cpt@tempc - \exitgroupdef#2% + \postgroupdef#2\endgroup } \robust@def*\cptdeclarefilter#1{% \edef\cpt@usefilter##1##2{% @@ -1884,26 +2290,32 @@ }% }% } -\newletcs\everymergeitem\@iden -\robust@def*\cptfiltermergelists{\cpt@testopt\cpt@filtermergelists{,}} -\robust@def*\cpt@filtermergelists[#1]#2#3#4{% +\newletcs\everymergeitem=\@iden +\robust@def*\cptfiltermergecsv{% \begingroup + \let\temp@parse\csv@@parse + \cpt@testopt\cpt@filtermergelists{,}% +} +\robust@def*\cptfiltermergekv{% + \begingroup + \let\temp@parse\kv@@parse + \cpt@testopt\cpt@filtermergelists{,}% +} +\robust@def*\cpt@filtermergelists[#1]#2#3#4{% + \edef\temp@do + {\cptmakecs{\ifxTF\temp@parse\csv@@parse{csv}{kv}@do}}% \cptdeclarefilter{#4}% \ifdefTF{#2}{}{\def#2{}}% - \ifblankTF{#3}{% - \def\cpt@update{}% - }{% - \edef\cpt@update{\unexpanded{#3}}% - }% + \ifblankTF{#3}{\def\cpt@update{}} + {\edef\cpt@update{\unexpanded{#3}}}% \def\cpt@add##1{% - \edef#2{\cptliststack#1#2% - \everymergeitem{\expandcsonce{##1}}}% + \edef#2{\cptliststack#1#2\everymergeitem{\expandcsonce{##1}}}% }% - \def\csv@do##1{% + \expandafter\def\temp@do##1{% \cpt@choicefdfalse \edef\cpt@merge@a{\unexpanded{##1}}% \cpt@usefilter\cpt@merge@a\cpt@merge@b - \def\csv@do####1{% + \expandafter\def\temp@do####1{% \edef\cpt@merge@c{\unexpanded{####1}}% \cpt@usefilter\cpt@merge@c\cpt@merge@d \cptscantokens\cpt@merge@b @@ -1914,17 +2326,17 @@ \cpt@add\cpt@merge@c \fi }% - \cptexpandargonce{\def#2{}\csv@@parse[#1]}#2% + \cptexpandargonce{\def#2{}\temp@parse[#1]}#2% \if@boolTF{cpt@choicefd}{}{\cpt@add\cpt@merge@a}% }% \ifcsnullTF#2{% \edef#2{\expandcsonce\cpt@update}% }{% \ifcsnullTF\cpt@update{}{% - \csv@@parse*[#1]\cpt@update + \temp@parse*[#1]\cpt@update }% }% - \exitgroupdef#2% + \postgroupdef#2\endgroup \let\everymergeitem\@firstofone } \robust@def*\preservebracedefQ#1#2{% @@ -1952,20 +2364,43 @@ }% }% } -\@namedef{@gobblespace} {} \robust@def*\csn@newif#1{% \ifstrcmpTF{#1}{x}{% \cpt@err{Redefining '\cptmakecs{ifx}'?}\@ehc }{% - \usecsn{newif\cptthreexp}\usecsn{if#1}% + \usename{newif\cptthreexp}\usename{if#1}% + }% +} +\robust@def*\csn@def{\aftercsname\def} +\robust@def*\csn@gdef{\aftercsname\gdef} +\robust@def*\csn@edef{\aftercsname\edef} +\robust@def*\csn@xdef{\aftercsname\xdef} +\new@def*\cpt@csnd@f#1{\l@ngrel@x\aftercsname\aftercsname{#1def}} +\robust@def*\csndef{\cpt@starorlong{\cpt@csnd@f{}}} +\robust@def*\csnpdef{\cpt@starorlong{\protected\cpt@csnd@f{}}} +\robust@def*\csngdef{\cpt@starorlong{\cpt@csnd@f{g}}} +\robust@def*\csnpgdef{\cpt@starorlong{\protected\cpt@csnd@f{g}}} +\robust@def*\csnedef{\cpt@starorlong{\cpt@csnd@f{e}}} +\robust@def*\csnpedef{\cpt@starorlong{\protected\cpt@csnd@f{e}}} +\robust@def*\csnxdef{\cpt@starorlong{\cpt@csnd@f{x}}} +\robust@def*\csnpxdef{\cpt@starorlong{\protected\cpt@csnd@f{x}}} +\robust@def*\newcsndef{\cpt@newcsn{}} +\robust@def*\newcsngdef{\cpt@newcsn{g}} +\robust@def*\newcsnedef{\cpt@newcsn{e}} +\robust@def*\newcsnxdef{\cpt@newcsn{x}} +\robust@def*\cpt@newcsn#1{\cpt@starorlong{\cpt@n@wcsn{#1def}}} +\robust@def*\cpt@n@wcsn#1#2{% + \begingroup + \edef\reserved@a{\noexpandcsn{#2}}% + \expandafter\ifdefTF\reserved@a{% + \@notdefinable\endgroup + }{% + \edef\reserved@b{\endgroup\l@ngrel@x\noexpandcsn{#1}}% + \expandafter\reserved@b\reserved@a }% } -\robust@def*\csn@def#1{\cptthreexp\def\usecsn{#1}} -\robust@def*\csn@gdef#1{\cptthreexp\gdef\usecsn{#1}} -\robust@def*\csn@edef#1{\cptthreexp\edef\usecsn{#1}} -\robust@def*\csn@xdef#1{\cptthreexp\xdef\usecsn{#1}} -\robust@def*\letcsntocs#1{\cptthreexp\let\usecsn{#1}} -\robust@def*\gletcsntocs#1{\global\cptthreexp\let\usecsn{#1}} +\robust@def*\letcsntocs#1{\cptthreexp\let\usename{#1}} +\robust@def*\gletcsntocs#1{\global\cptthreexp\let\usename{#1}} \robust@def*\letcstocsn#1#2{% \begingroup\expandafter\endgroup\expandafter \let\expandafter#1\csname#2\endcsname @@ -1990,7 +2425,7 @@ \new@def\xaftercsname#1#2{% \cptsevenxp\cptswap\cptthreexp{\csname#2\endcsname}{#1}% } -\robust@def*\globalize#1{\cptglet#1#1} +\robust@def*\globalize#1{\gletcs#1#1} \robust@def*\globalizecsn#1{% \begingroup\expandafter\endgroup\expandafter \global\expandafter\let\csname#1\expandafter\endcsname @@ -2000,26 +2435,27 @@ \robust@def*\gundefcs{\global\undefcs} \robust@def*\undefcsn#1{\aftercsname\undefcs{#1}} \robust@def*\gundefcsn{\global\undefcsn} -\robust@def*\undefcsset{\cpt@testst\cpt@undefcsset} +\robust@def*\undefcsset{% + \cpt@testst{\cpt@testcl\cpt@undefcsset}% +} \robust@def*\cpt@undefcsset#1{% - \ifcpt@st\let\cpt@tempa#1\else\def\cpt@tempa{#1}\fi - \def\comma@do##1{% - \normal@despace{##1}\cpt@tempa - \simpleexpandarg\ifescapedTF\cpt@tempa{% - \expandafter\undefcs\cpt@tempa + \let\ifundefcl\ifcpt@cl + \cpt@stchoose{cpt@st}{#1}\cpt@rsvda\cpt@undefcsset + \def\csv@do##1{% + \ifescapedTF{##1}{% + \ifundefcl\global\fi\undefcs##1% }{% - \cpt@err{I can't find escape in token - '\cptoxdetok\cpt@tempa':\MsgBrk - Maybe it's an active character}\@ehc + \cpt@notescapederr{##1}% }% }% - \simpleexpandarg\comma@@loop\cpt@tempa + \csv@@parse*[,]\cpt@rsvda + \undefcs\ifundefcl } \robust@def*\cpttrimparser{\cpt@testopt\cpt@trimparser{,}} \robust@def\cpt@trimparser[#1]#2{% \begingroup \edef\cpt@tempd{\detokenize{#1}}% - \let\trimpr@nil\cpt@nil + \let\trimpr@nil\relax \def\cpt@trimb{% \xifinsetFT{\cpt@tempd\trimpr@nil}{\cptoxdetok{#2}\trimpr@nil}{}{% \cptexpandsecond @@ -2042,13 +2478,13 @@ \cpt@trimb }% }% - \exitgroupdef#2% + \postgroupdef#2\endgroup } \robust@def*\stripouterbraces{\cpt@testopt\cpt@stripouterbraces\@ne} \robust@def\cpt@stripouterbraces[#1]{% \begingroup - \def\after@def##1##2##3{\exitgroupdef{##3}}% - \@tempcnta\z@ + \def\after@def##1##2##3{\postgroupdef##3\endgroup}% + \@tempcnta\z@pt \catcode`\{=1 \catcode`\}=2 \catcode`\#=6 @@ -2060,24 +2496,23 @@ \cpt@str@pouterbr@ces#2\strip@nil#3#1% } \robust@def\cpt@str@pouterbr@ces#1\strip@nil#2#3{% - \defcmpifx{#1}#2% - \expandafter\after@def - \else + \defifxTF{#1}#2{% + \after@def + }{% \ifnum\@tempcnta>#3\relax - \cptthreexp\after@def + \expandafter\after@def \else - \cptthreexp\cpt@str@pouterbraces + \expandafter\cpt@str@pouterbraces \fi - \fi + }% {#3}{#1}{#2}% } \robust@def\stripallouterbraces#1#2{% \edef#2{\unexpanded\cptthreexp{\cpt@stripallouterbraces{#1}}}% } -\robust@def\stripallouterbraces@incs#1{% +\robust@def\stripallouterbracesincs#1{% \expandafter\stripallouterbraces\expandafter{#1}#1% } -%% Based on a solution by Ulrich Diez: \robust@def\cpt@stripallouterbraces#1{% \romannumeral\ifbracedTF{#1}{% \expandafter\ifnullTF\expandafter{\@gobble#1}{% @@ -2085,22 +2520,6 @@ }{0 #1}% }{0 #1}% } -%% - -\robust@def\defcmpifx#1#2{% - \begingroup - \edef\cpt@tempa{\unexpanded{#1}}% - \expandafter\endgroup\ifx#2\cpt@tempa -} -\robust@def\defcmpifxTF#1#2{% - \begingroup - \edef\cpt@tempa{\unexpanded{#1}}% - \ifxTF#2\cpt@tempa - {\endgroup\@firstoftwo}{\endgroup\@secondoftwo}% -} -\robust@def\defcmpifxFT#1#2{% - \defcmpifxTF{#1}{#2}\@secondoftwo\@firstoftwo -} \robust@def\cpt@starafter#1#2{% \begingroup \def\cpt@tempa{#1}% @@ -2112,7 +2531,7 @@ \ifxTF\@sptoken\next{% \afterassignment\cpt@tempc\let\next= % }{% - \cptpassexpanded{\endgroup + \cptexpandsecond\endgroup{% \ifxTF*\next{\expandcsonce\cpt@tempb}% {\expandcsonce\cpt@tempa}% }% @@ -2121,53 +2540,64 @@ \robust@def*\cptbracearg{\cpt@testopt\cpt@bracearg\@ne} \robust@def\cpt@bracearg[#1]#2#3{% \begingroup - \@tempcnta\z@ + \@tempcnta\z@pt \loop \edef#3{\unexpanded{{#2}}}% \advance\@tempcnta\@ne \ifnum\@tempcnta<#1\relax \repeat - \exitgroupdef#3% + \postgroupdef#3\endgroup } -\new@edef*\ifcptmacroTF#1{% - \unexpanded{\expandafter\cpt@ifmacro\meaning}% - #1\detokenize{macro}:\cpt@nil +\edef\cptifmacroTF#1{% + \noexpand\ifblankTF{#1}{% + \noexpand\@secondoftwo + }{% + \noexpand\ifleftbracedTF{#1}{% + \noexpand\@secondoftwo + }{% + \unexpanded{\expandafter\cpt@ifmacro\meaning}% + #1\detokenize{macro}:\cpt@nil + }% + }% } -\new@def*\ifcptmacroFT#1{\ifcptmacroTF{#1}\@secondoftwo\@firstoftwo} +\new@def*\cptifmacroFT#1{\cptifmacroTF{#1}\@secondoftwo\@firstoftwo} \edef\cpt@ifmacro{% \def\noexpand\cpt@ifmacro##1\detokenize{macro}:##2\cpt@nil } +\cpt@ifmacro{\usename{@\ifblankTF{#2}{second}{first}oftwo}} + \robust@def*\csnmeaning#1{\aftercsname\meaning{#1}} -\cpt@ifmacro{\usecsn{@\ifblankTF{#2}{second}{first}oftwo}} -\robust@def*\cpt@nomacroerr#1{% - \cpt@err{Argument '\detokenize{#1}' isn't a macro}\@ehc -} \robust@def*\ifescapedTF#1{% - \begingroup\escapechar92\relax + \begingroup + \escapechar92\relax \edef\cpt@tempa{\expandafter\cpt@car\string#1x\car@nil}% - \cptthreexp\endgroup\usecsn{@\ifx\cpt@tempa + \cptthreexp\endgroup + \usename{@\ifx\cpt@tempa \@backslashchar first\else second\fi oftwo}% } \robust@def*\ifescapedFT#1{\ifescapedTF{#1}\@secondoftwo\@firstoftwo} -\ifcptdefinable\robustaliascount\relax +\ifcsdefinable\maxrobustalias{\chardef\maxrobustalias20} \newcommand*\cptrobustify[1]{% - \def\comma@do##1{% - \normal@despace{##1}\cpt@tempa - \simpleexpandarg\ifescapedTF\cpt@tempa{% - \oifdefTF\cpt@tempa{% - \cptexpandsecondonce{\aftercsname\newletcs - {rsv@\expandafter\cptremovescape\cpt@tempa}}\cpt@tempa - \expandafter\protected\expandafter\edef\cpt@tempa - {\noexpandcsn{rsv@\expandafter\cptremovescape\cpt@tempa}}% + \def\csv@do##1{% + \ifescapedTF{##1}{% + \ifdefTF{##1}{% \pushnumber\robustaliascount + \ifnum\robustaliascount<\maxrobustalias\relax + \aftercsname\newletcs{rsv@\cptremovescape##1}##1% + \protected\edef##1{\cptmakecs{rsv@\cptremovescape##1}}% + \else + \cpt@err{Maximum number '\number\maxrobustalias' of + command aliases exceeded:\MsgBrk + You can set \noexpand\maxrobustalias higher}\@ehc + \fi }{% - \cpt@err{Command '\string\cpt@tempa' undefined}\@ehc + \cpt@notdeferr{##1}% }% }{% - \cpt@err{String '\detokenize{\cpt@tempa}' not escaped}\@ehc + \cpt@notescapederr{##1}% }% }% - \comma@@loop{#1}% + \csv@@parse[,]{#1}% } \robust@def*\leftaddtocs{% \let\cpt@def\edef\let\swap\cptswap\cpt@addtocs @@ -2185,127 +2615,168 @@ \robust@def*\grightaddtocsn{\aftercsname\grightaddtocs} \robust@def*\leftaddtocsn{\aftercsname\leftaddtocs} \robust@def*\gleftaddtocsn{\aftercsname\gleftaddtocs} -\robust@def*\cpteveryscantokens{% +\robust@def\cpt@addtocs#1#2{% + \ifsingletokenTF{#1}{% + \ifescapedTF{#1}{% + \ifdefTF#1{% + \cpt@getmacroprefix{#1}% + \macroprefix\cpt@def + #1{\swap{\expandcsonce{#1}}{\unexpanded{#2}}}% + }{% + \cpt@def#1{\unexpanded{#2}}% + }% + }{% + \cpt@notescapederr{#1}% + }% + }{% + \cpt@notonetokenerr{#1}% + }% + \undefcs\cpt@def\undefcs\swap +} +\robust@def*\cpteveryscan{% \everyeof{\noexpand}% - \endlinechar\m@ne + \endlinechar\m@one \makeatletter \catcode`\ =10 - \catcode`\\\z@ + \catcode`\\\z@pt \catcode`\{\@ne \catcode`\}\tw@ } -% #1 must be a non-parametered macro: \robust@def*\cptscantokens#1{% \begingroup \edef#1{\long\def\string#1{\cptoxdetok{#1}}}% - \cpteveryscantokens + \cpteveryscan \scantokens\expandafter{#1}\relax - \exitgroupdef#1% + \postgroupdef#1\endgroup } -\robust@def\cpt@addtocs#1#2{% - \cpt@getmacroprefix{#1}% - \ifdefTF#1{% - \macroprefix\cpt@def#1{\swap{\expandcsonce{#1}}{\unexpanded{#2}}}% +\robust@def*\cpt@lowercasecs#1{% + \cptifmacroTF{#1}{% + \cptexpandarg\lowercase{\def\noexpand#1{#1}}% }{% - \macroprefix\cpt@def#1{\unexpanded{#2}}% + \cpt@notcserr{#1}% }% - \undefcs\cpt@def\undefcs\swap } -\robust@def*\cpt@getmacroprefix#1{% - \begingroup - \edef\cpt@tempa##1{\def##1####1\detokenize{macro}:####2\noboundary}% - \cpt@tempa\@ifmacro{% - \def\macroprefix{##1}% - \usecsn{@\ifblankTF{##2}{second}{first}oftwo}% - }% - \edef\cpt@tempb##1{##1\detokenize{macro}:\noboundary}% - \cpt@tempb{\expandafter\@ifmacro\meaning#1}{% - \@testtrue - }{% - \@testfalse\def\macroprefix{}% - }% - \cpteveryscantokens - \cptpassexpanded{% - \endgroup\noexpand\scantokens - {\def\noexpand\macroprefix{\macroprefix}\relax}% +\robust@def*\providecount#1{% + \ifdefTF{#1}{% + \ifcounterTF{#1}{}{% + \cpt@warn{Command '\noexpand#1' is already + \MsgBrk defined but not a counter}% + }% + }{\newcount#1}% +} +\robust@def*\providedimen#1{% + \ifdefTF{#1}{% + \ifdimenTF{#1}{}{% + \cpt@warn{Command '\noexpand#1' is already + \MsgBrk defined but not a dimension}% + }% + }{\newdimen#1}% +} +\robust@def*\providetog#1{% + \ifcsndefTF{cpt@tog@#1}{}{% + \letcsntocs{cpt@tog@#1}\@secondoftwo }% } -\robust@def*\cpt@gettogswstate#1{% - \lowercase{% - \ifinsetTF{,#1,}{,true,on,}{% - \let\cpt@togswstate\@firstoftwo +\robust@def*\cpt@gettogstate#1{% + \cptexpandarg\lowercase{\def\noexpand\reserved@a{#1}}% + \xifstrcmpTF\reserved@a{true}{% + \let\cpt@togstate\@firstoftwo + }{% + \xifstrcmpTF\reserved@a{false}{% + \let\cpt@togstate\@secondoftwo }{% - \ifinsetTF{,#1,}{,false,off,}{% - \let\cpt@togswstate\@secondoftwo - }{% - \@latex@error{Invalid toggle switch value '#1'}% - {Valid toggle switch values are 'true' and 'false'.}% - }% + \cpt@err{Invalid toggle switch value '#1'}% + {Valid toggle values are 'true' and 'false'.}% }% }% } -\robust@def*\cpt@undeftogswerr#1{% +\robust@def*\cpt@undeftogerr#1{% \cpt@err{Toggle switch '#1' undefined}\@ehc } -\robust@def*\settogswtrue#1{% - \ifcsndefTF{cpt@togsw@#1}{% - \letcsntocs{cpt@togsw@#1}\@firstoftwo - }{\cpt@undeftogswerr{#1}}% -} -\robust@def*\settogswfalse#1{% - \ifcsndefTF{cpt@togsw@#1}{% - \letcsntocs{cpt@togsw@#1}\@secondoftwo - }{\cpt@undeftogswerr{#1}}% +\robust@def*\settogtrue#1{% + \ifcsndefTF{cpt@tog@#1}{% + \letcsntocs{cpt@tog@#1}\@firstoftwo + }{% + \cpt@undeftogerr{#1}% + }% } -\new@def*\iftogswTF#1{% - \ifcsndefTF{cpt@togsw@#1}% - {\usecsn{cpt@togsw@#1}}% - {\cpt@undeftogswerr{#1}\@gobbletwo}% +\newletcs\togtrue=\settogtrue +\robust@def*\settogfalse#1{% + \ifcsndefTF{cpt@tog@#1}{% + \letcsntocs{cpt@tog@#1}\@secondoftwo + }{% + \cpt@undeftogerr{#1}% + }% } -\new@def*\iftogswFT#1{\iftogswTF{#1}\@secondoftwo\@firstoftwo} -\robust@def*\settogsw#1#2{% - \ifcsndefTF{cpt@togsw@#1}{% - \cpt@gettogswstate{#2}% - \letcsntocs{cpt@togsw@#1}\cpt@togswstate - }{\cpt@undeftogswerr{#1}}% +\newletcs\togfalse=\settogfalse +\robust@def*\settog#1#2{% + \ifcsndefTF{cpt@tog@#1}{% + \cpt@gettogstate{#2}% + \letcsntocs{cpt@tog@#1}\cpt@togstate + }{% + \cpt@undeftogerr{#1}% + }% } -\robust@def*\killtogsw#1{% - \ifcsndefTF{cpt@togsw@#1}{% - \letcsntocs{cpt@togsw@#1}\cpt@undefined +\robust@def*\undeftog#1{% + \ifcsndefTF{cpt@tog@#1}{% + \letcsntocs{cpt@tog@#1}\cpt@undefined }{% - \cpt@info{Toggle switch '#1' not defined: not killed}% + \cpt@info{Toggle switch '#1' not defined}% + }% +} +\new@def*\iftogTF#1{% + \ifcsndefTF{cpt@tog@#1}{\usename{cpt@tog@#1}}% + {\cpt@undeftogerr{#1}\@gobbletwo}% +} +\new@def*\iftogFT#1{\iftogTF{#1}\@secondoftwo\@firstoftwo} + +\new@def*\cpttrue{00} +\new@def*\cptfalse{01} +\def\reserved@a#1{% + \new@def*\cptnegate##1{% + 0\ifcase##11#1\or\expandafter1\else\expandafter0\fi + }% + \new@def*\cptbothtrue##1##2{% + 0\ifcase##1##2#1\expandafter0\else\expandafter1\fi + }% + \new@def*\cptonetrue##1##2{% + 0\ifnum##1##2<101#1\expandafter0\else\expandafter1\fi }% } +\reserved@a{ } +\new@def*\ifpsiboolTF#1{\cptifcondTF\if\usename{#1}\fi} +\new@def*\ifpsiboolFT#1{\cptifcondFT\if\usename{#1}\fi} +\new@def*\thebool@normal#1{\ifboolTF{#1}{true}{false}} +\new@def*\thebool@reverse#1{\ifboolTF{#1}{false}{true}} \robust@def*\BeforeStartOfDocument{% - \grightaddtocs\cpt@beforestartdoc@hook + \grightaddtocs\cpt@beforestartdoc } -\new@def*\cpt@beforestartdoc@hook{} +\new@def*\cpt@beforestartdoc{} \gleftaddtocs\document{% \endgroup \let\BeforeStartOfDocument\@firstofone - \cpt@beforestartdoc@hook + \cpt@beforestartdoc \let\BeforeStartOfDocument\@notprerr - \gundefcs\cpt@beforestartdoc@hook + \gundefcs\cpt@beforestartdoc + \def\cpt@docstarted{}% \begingroup } \robust@def*\AfterStartOfDocument{% - \grightaddtocs\cpt@afterstartdoc@hook + \grightaddtocs\cpt@afterstartdoc } -\new@def*\cpt@afterstartdoc@hook{} +\new@def*\cpt@afterstartdoc{} \grightaddtocs\document{% \let\AfterStartOfDocument\@firstofone - \cpt@afterstartdoc@hook + \cpt@afterstartdoc \let\AfterStartOfDocument\@notprerr - \gundefcs\cpt@afterstartdoc@hook + \gundefcs\cpt@afterstartdoc \ignorespaces } \gleftaddtocs\@popfilename{% - \usecsn{% - @\ifcsname\@currname.\@currext-cpt@hook\endcsname - iden\else gobble\fi + \ifcsnameFT{\@currname.\@currext-cpt@hook}{}{% + \usename{\@currname.\@currext-cpt@hook}% + \gundefcsn{\@currname.\@currext-cpt@hook}% }% - {\usecsn{\@currname.\@currext-cpt@hook}}% - \gundefcsn{\@currname.\@currext-cpt@hook}% } \robust@def*\ifpackagewithTF{\cpt@ifoptions\@pkgextension} \robust@def*\ifclasswithTF{\cpt@ifoptions\@clsextension} @@ -2314,10 +2785,10 @@ } \robust@def*\cpt@ifopti@ns#1#2{% \cpt@stfalse\cpt@kvnormalize[,]{#1}% - \let\temp@optlist\cpt@normalizedlist + \let\temp@optlist\normalized@list \cpt@choicefdtrue \def\kv@do##1{% - \if@sp@inlistTF,{##1}\temp@optlist + \oifinset@sp@TF,{##1}\temp@optlist {}{\cpt@choicefdfalse\cptbreakloop}% }% \kv@@parse{#2}% @@ -2327,9 +2798,9 @@ \robust@def*\ifpackageafterTF{\cpt@ifpkgafter\@pkgextension} \robust@def*\ifclassafterTF{\cpt@ifpkgafter\@clsextension} \robust@def*\cpt@ifpkgafter#1#2#3{% - \usecsn{@if#1loaded}{#2}{}{% + \usename{@if#1loaded}{#2}{}{% \AfterStartOfDocument{% - \usecsn{@if#1loaded}{#2}{% + \usename{@if#1loaded}{#2}{% \cpt@warn{\@cls@pkg '#2' was loaded afterwards}% #3\relax }{}% @@ -2338,37 +2809,74 @@ } \robust@def*\cptloadpackages{% \begingroup - \toks@{}% - \begingroup - \catcode`\;=12\catcode`\|=12 - \endlinechar\m@ne - \expandafter\endgroup\cpt@loadpackages + \endlinechar=-1 + \cpt@testopt{\expandafter\endgroup\cpt@loadpackages}{|;}% } -\robust@def\cpt@loadpackages#1{% - \cpt@useemptyfalse - \def\csv@do##1{% - \cpt@lo@dpackages##1|||\cpt@nil - }% - \csv@@parse[;]{#1}% - \expandafter\endgroup\the\toks@ -} -\robust@def\cpt@lo@dpackages#1|#2|#3|#4\cpt@nil{% - \stripallouterbraces{#2}\cpt@tempb - \cpt@sttrue\cpt@kvnormalize[,]\cpt@tempb - \@ifpackageloaded{#1}{% - \edef\cpt@tempa{\cpt@optionlist{#1.\@pkgextension}}% - \ifx\cpt@tempa\cpt@tempb\else - \cpt@err{Option clash for package #1.\@pkgextension}\@ehc - \expandafter\@gobbletwo +\robust@def\cpt@loadpackages[#1]#2{% + \begingroup + \toks@{}% + \def\cpt@tempa##1##2\cpt@nil{% + \ifx\noboundary##2\noboundary + \cpt@err{No outer parser or something wrong + \MsgBrk while in \string\cptloadpackages}\@ehc + \expandafter\@gobble + \else + \ifinsetFT{,}{##1##2}{}{% + \cpt@err{Parser can't be comma (,) in + \string\cptloadpackages}\@ehc + \expandafter\@gobble + }% \fi - }{% - \cptexpanded{% - \cptaddtotoks0{% - \ifcsnullTF\@currname{\noexpand\usepackage}{% - \noexpand\RequirePackage}[\cpt@tempb]{#1}[#3]% + \def\cpt@lo@dpackages####1##1####2##1####3##1####4\cpt@nil{% + \ifx\noboundary####1\noboundary + \cpt@err{No package name while in \string\cptloadpackages}\@ehc + \expandafter\@gobble + \fi + \ifblankTF{####2}{% + \def\cpt@rsvda{}% + }{% + \stripallouterbraces{####2}\cpt@rsvda + }% + \@ifpackageloaded{####1}{% + \edef\cpt@rsvdb{\detokenize\expandafter + {\romannumeral-`\q\cpt@optionlist{####1.\@pkgextension}}}% + \@tempswafalse + \ifcsnullTF\cpt@rsvda{% + \ifcsnullTF\cpt@rsvdb{}\@tempswatrue + }{% + \ifcsnullTF\cpt@rsvdb{% + \@tempswatrue + }{% + \def\kv@do########1{% + \xifinsetTF{,\detokenize{########1},}{,\cpt@rsvdb,}{}{% + \@tempswatrue\cptbreakloop + }% + }% + \kv@@parse*[,]\cpt@rsvda + }% + }% + \if@tempswa + \cpt@err{Option clash for package ####1.\@pkgextension}\@ehc + \expandafter\@gobble + \fi + }{% + \cptexpanded{% + \toks@{\the\toks@ + \ifxTF\documentclass\@twoclasseserror + {\noexpand\usepackage}{\noexpand\RequirePackage}% + [\expandcsonce\cpt@rsvda]{####1}[####3]% + }% + }% }% }% + \def\csv@do####1{% + \cpt@lo@dpackages####1##1##1##1##1\cpt@nil + }% + \cpt@useemptyfalse + \csv@@parse[##2]{#2}% }% + \cpt@tempa#1\cpt@nil + \expandafter\endgroup\the\toks@ } \robust@def*\AfterEndOfStyleFile{% \begingroup @@ -2378,11 +2886,13 @@ }% \ifcsnullTF\@currname\endgroup\cpt@tempa } -\edef\cpt@hashchar{\string#} +\robust@def*\ifinstylefileTF{% + \ifcsemptyTF\@currname\@secondoftwo\@firstoftwo +} \robust@def*\cpt@pushhash{% \begingroup \@makeother{\#}% - \endlinechar\m@ne + \endlinechar\m@one \cpt@pop@hash } \robust@def\cpt@push@hash#1#2{% @@ -2403,12 +2913,12 @@ \toks@\expandafter{\detokenize{#1}}% }% \edef#2{\the\toks@}% - \exitgroupdef#2% + \postgroupdef#2\endgroup } \robust@def*\cpt@pophash{% \begingroup \@makeother{\#}% - \endlinechar\m@ne + \endlinechar\m@one \cpt@push@hash } \robust@def\cpt@pop@hash#1#2{% @@ -2428,140 +2938,140 @@ \toks@\expandafter{\detokenize{#1}}% }% \edef#2{\the\toks@}% - \exitgroupdef#2% -} -\cptonlypreamble{% - \cptloadpackages,\ifpackagewithTF,\ifclasswithTF,\cpt@ifoptions, - \cptpushcatcodes,\cptpopcatcodes,\UseNormalCatcodes, - \rsv@UseNormalCatcodes,\StyleFilePurpose,\StyleFileInfo, - \AfterEndOfStyleFile,\StyleFileRCSInfo,\SetStyleFileMessages, - \XDeclareOption,\XDeclareOptions,\XDeclareCommandOption, - \XDeclareCommandOptions,\XDeclareBooleanOption,\XDeclareBooleanOptions, - \XDeclareBiBooleanOptions,\XProcessOptions,\XExecuteOptions, - \cpt@processedoptions,\cpt@optionlist,\cpt@findoption@a, - \cpt@findoption@b,\cpt@processoptions,\cpt@xprocessoptions, - \cpt@yprocessoptions,\cpt@pr@cessoptions,\BeforeStartOfDocument, - \AfterStartOfDocument,\XInvalidOptionHandler,\XDeclareInvalidOption, - \XDeclareInvalidOptions,\XUnknownOptionHandler,\ExternalOptions + \postgroupdef#2\endgroup } -\robust@def*\csv@@normalize{\cpt@teststoptb\cpt@csvnormalize} +\robust@def*\csv@@normalize{\cpt@teststopt\cpt@csvnormalize,} \robust@def\cpt@csvnormalize[#1]#2{% - \chardef\normalize@listtype\z@ - \csv@kv@normalize{#1}{#2}\cpt@normalizedlist + \let\cpt@inkv\cptfalse + \cpt@normalize{#1}{#2}% } -\robust@def*\kv@@normalize{\cpt@teststoptb\cpt@kvnormalize} +\robust@def*\kv@@normalize{\cpt@teststopt\cpt@kvnormalize,} \robust@def\cpt@kvnormalize[#1]#2{% - \chardef\normalize@listtype\@ne - \csv@kv@normalize{#1}{#2}\cpt@normalizedlist + \let\cpt@inkv\cpttrue + \cpt@normalize{#1}{#2}% } -\robust@def\csv@kv@normalize#1#2#3{% - \let\ifcpt@normst\ifcpt@st - \cpt@checklistparser{#1}\relax +\ifcsdefinable\normalized@list\relax +\robust@def\cpt@normalize#1#2{% \begingroup - \expandafter\setup@parser@normalize\string#1% - \ifcpt@normst - \toks@\expandafter{\expandafter#1#2#1}% - \else - \toks@{#1#2#1}% + \let\ifnmlzst\ifcpt@st + \cpt@stchoose{cpt@st}{#2}\reserved@e\cpt@normalize + \ifx\reserved@e\@empty + \def\normalized@list{}% + \def\cpt@relax##1\cpt@relax{\endgroup}% \fi - \normalize@activeparser - \expandafter\normalize@spaceletter\string#1% - \expandafter\normalize@letterspace\string#1% - \expandafter\normalize@doubleletter\string#1% - \ifnumcmpFT\normalize@listtype=\@ne{}{% - \normalize@activeequal - \expandafter\normalize@spaceletter\string=% - \expandafter\normalize@letterspace\string=% - \expandafter\normalize@doubleletter\string=% + \cpt@relax + \cpt@checklistparser@b{#1}% + \expandafter\setup@parser@nmlz\string#1% + \toks@\expandafter{\expandafter#1\reserved@e#1}% + \nmlz@activeparser + \expandafter\nmlz@spaceletter\string#1% + \expandafter\nmlz@letterspace\string#1% + \expandafter\nmlz@doubleletter\string#1% + \ifpsiboolFT{cpt@inkv}{}{% + \nmlz@activeequal + \nmlz@spaceletter=% + \nmlz@letterspace=% + \nmlz@doubleletter=% \cpt@commaequalerr }% - \edef#3{\the\toks@}% - \expandafter\cpttrimparser\expandafter[\string#1]#3% - \exitgroupdef#3% - \ifcpt@normst\let#2#3\undefcs#3\fi - \undefcs\ifcpt@normst + \def\reserved@a##1{% + \@nameuse{@\if\string#1\noexpand##1first\else + second\fi oftwo}\reserved@a{0 ##1}% + }% + \edef\normalized@list{% + \expandcsonce{\romannumeral\expandafter\reserved@a\the\toks@}% + }% + \cptexpandsecond\endgroup{% + \if@boolTF{nmlzst}{% + \edef\noexpand#2{\ox@unexpanded\normalized@list}% + \undefcs\noexpand\normalized@list + }{% + \cpt@csexit\normalized@list + }% + }% + \cpt@relax } -\def\setup@parser@normalize#1{% +\def\setup@parser@nmlz#1{% \begingroup - \uccode`\~\string=`#1% + \uccode`\~=`#1% \uppercase{\endgroup - \def\normalize@activeparser{% - \def\cpt@tempa####1~####2\cpt@nil{% - \toks@\expandafter{\the\toks@####1}% - \ifblankTF{####2}{}{\cpt@tempa#1####2\cpt@nil}% + \def\nmlz@activeparser{% + \def\cpt@tempa####1~####2\nmlz@nil{% + \ifblankTF{####2}{% + \toks@{####1}% + }{% + \cpt@tempa####1#1####2\nmlz@nil + }% }% - \toks@\expandafter{\expandafter}% - \expandafter\cpt@tempa\the\toks@~\cpt@nil + \toks@\expandafter{\expandafter}\expandafter + \cpt@tempa\the\toks@~\nmlz@nil }% }% } \begingroup -\catcode`\=\string=12 +\catcode`\==12 \uccode`\~=`\=% \uppercase{\endgroup - \def\normalize@activeequal{% - \def\cpt@tempa##1~##2\cpt@nil{% - \expandafter\ifblankTF\expandafter{\the\toks@}{% + \def\nmlz@activeequal{% + \def\cpt@tempa##1~##2\nmlz@nil{% + \ifblankTF{##2}{% \toks@{##1}% }{% - \toks@\expandafter{\the\toks@=##1}% + \cpt@tempa##1=##2\nmlz@nil }% - \ifblankTF{##2}{}{\cpt@tempa##2\cpt@nil}% }% \toks@\expandafter{\expandafter}\expandafter - \cpt@tempa\the\toks@~\cpt@nil + \cpt@tempa\the\toks@~\nmlz@nil }% } -\def\normalize@doubleletter#1{% - \def\cpt@tempa##1#1#1##2\cpt@nil{% +\def\nmlz@doubleletter#1{% + \def\cpt@tempa##1#1#1##2\nmlz@nil{% \ifblankTF{##2}{% \toks@{##1}% }{% - \toks@{##1#1##2}% - \expandafter\cpt@tempa\the\toks@\cpt@nil + \cpt@tempa##1#1##2\nmlz@nil }% }% - \expandafter\cpt@tempa\the\toks@#1#1\cpt@nil + \expandafter\cpt@tempa\the\toks@#1#1\nmlz@nil } \defpass\cpt@tempa#1{% - \def\normalize@spaceletter##1{% - \def\cpt@tempa####1#1##1####2\cpt@nil{% + \def\nmlz@spaceletter##1{% + \def\cpt@tempa####1#1##1####2\nmlz@nil{% \ifblankTF{####2}{% \toks@{####1}% }{% - \toks@{####1##1####2}% - \expandafter\cpt@tempa\the\toks@\cpt@nil + \cpt@tempa####1##1####2\nmlz@nil }% }% - \expandafter\cpt@tempa\the\toks@#1##1\cpt@nil + \expandafter\cpt@tempa\the\toks@#1##1\nmlz@nil }% - \def\normalize@letterspace##1{% - \def\cpt@tempa####1##1#1####2\cpt@nil{% + \def\nmlz@letterspace##1{% + \def\cpt@tempa####1##1#1####2\nmlz@nil{% \ifblankTF{####2}{% \toks@{####1}% }{% - \toks@{####1##1####2}% - \expandafter\cpt@tempa\the\toks@\cpt@nil + \cpt@tempa####1##1####2\nmlz@nil }% }% - \expandafter\cpt@tempa\the\toks@##1#1\cpt@nil + \expandafter\cpt@tempa\the\toks@##1#1\nmlz@nil }% }{ } \robust@def*\cpt@commaequalerr{% - \def\cpt@tempa##1,=##2\cpt@nil{% + \def\cpt@tempa##1,=##2\nmlz@nil{% \ifblankTF{##2}{}{% \cpt@err{There is 'comma' next to 'equal' (,=) in \MsgBrk your key-value list}\@ehc }% }% - \expandafter\cpt@tempa\the\toks@,=\cpt@nil + \expandafter\cpt@tempa\the\toks@,=\nmlz@nil } \let\cpt@documentclass\cpt@undefined \robust@def*\cpt@getdocumentclass{% \def\csv@do##1{% \filename@parse{##1}% \ifx\filename@ext\@clsextension - \ifcsndefFT{opt@\filename@area\filename@base.\filename@ext}{}{% + \ifcsndefFT{opt@\filename@area\filename@base.% + \filename@ext}{}{% \xdef\cpt@documentclass{% \filename@area\filename@base.\filename@ext }% @@ -2575,7 +3085,7 @@ \string\documentclass: \MsgBrk no problem}% }% } -\cptpassasis{% +\cptpassunexpanded{% \ifxTF\@filelist\relax{}{% \ifxTF\@filelist\@gobble{}{% \ifxTF\@filelist\@empty\relax\cpt@getdocumentclass @@ -2592,32 +3102,37 @@ }% \let\cpt@classoptionslist\@classoptionslist \def\@fileswith@ptions##1[##2]##3{% - \ifstreqTF{##3}{xkeyval}{% - \let\@classoptionslist\cpt@classoptionslist - }{% - \ifstreqFT{##3}{kvoptions}{}{% - \let\@classoptionslist\cpt@classoptionslist - }% + \cpt@stfalse\cpt@csvnormalize[,]{##3}% + \cpt@choicefdfalse + \def\csv@do####1{% + \xifinsetTF{,####1,}{,\normalized@list,}{% + \cpt@choicefdtrue + }{}% }% + \csv@@loop[,]{xkeyval,kvoptions,ltxkeys}% + \ifcpt@choicefd + \let\@classoptionslist\cpt@classoptionslist + \fi \cpt@ifbrack{\@fileswith@pti@ns##1[##2]##3}% {\@fileswith@pti@ns##1[##2]##3[]}% }% - \def\comma@do##1{% + \def\csv@do##1{% \ifinsetTF{=}{##1}{}{% \cptgaddtolist\@classoptionslist{##1}% }% }% - \cptexpandargonce{\emptify\@classoptionslist\comma@@loop}% - \@classoptionslist + \expandafter\def\expandafter\@classoptionslist\expandafter + {\expandafter}\expandafter\csv@@loop\expandafter + {\@classoptionslist}% }% } \robust@def*\cpt@testfam#1{% - \cpt@ifnextchar<{#1}{#1<\@currname.\@currext>}% + \CurrIfnextchar<{#1}{#1<\@currname.\@currext>}% } \robust@redef\@pass@ptions#1#2#3{% \begingroup \ifsingletokenTF{#2}{% - \ifcptmacroTF{#2}{% + \cptifmacroTF{#2}{% \let\@expand\expandcsonce }{% \let\@expand\unexpanded @@ -2627,7 +3142,7 @@ }% \ifcsndefTF{opt@#3.#1}{% \ifblankTF{#2}{}{% - \cptexpandarg{\cptexpandsecond{\cpt@filtermergelists[,]}% + \cptexpandarg{\cptexpandsecond{\cptfiltermergekv[,]}% {\cptmakecs{opt@#3.#1}}}{\@expand{#2}}{}% }% }{% @@ -2637,13 +3152,13 @@ \endgroup } \robust@redef*\OptionNotUsed{% - \ifx\@currext\@clsextension - \cptexpandargonce{\cpt@filtermergelists[,]% + \ifxTF\@currext\@clsextension{% + \cptexpandargonce{\cptfiltermergekv[,]% \@unusedoptionlist}\CurrentOption\nofilter - \fi + }{}% } \robust@redef*\@use@ption{% - \if@sp@inlistFT,\CurrentOption\@unusedoptionlist{}{% + \oifinset@sp@FT,\CurrentOption\@unusedoptionlist{}{% \cptexpandargonce{\cpt@filterremoveelements[,]% \@unusedoptionlist}\CurrentOption\nofilter }% @@ -2681,45 +3196,39 @@ \ifblankFT{#1}{}{% \cpt@err{Blank argument to command \string\RecoverAtRequirePackage}\@ehc - \@gobble }% \begingroup - \edef\cpt@tempb{\expandcsnonce{\@currname.\@currext-h@@k}}% - \def\comma@do##1{% + \def\csv@do##1{% \ifescapedTF{##1}{% - \ifdefTF#1{}{% - \cpt@err{Undefined argument to command\MsgBrk - \string\RecoverAtRequirePackage}\@ehc + \ifdefTF{##1}{}{% + \cpt@notdeferr{##1}% + \@gobble }% }{% - \cpt@err{Non-escaped argument to command\MsgBrk - \string\RecoverAtRequirePackage}\@ehc + \cpt@notescapederr{##1}% \@gobble }% - \cptthreexp\ifcptdefinable\usecsn{rsv@\cptremovescape##1}{% - \gletcsntocs{rsv@\cptremovescape##1}##1% + \ifcsndefinable{atpush@\cptremovescape##1}{% + \gletcsntocs{atpush@\cptremovescape##1}##1% }% \edef\cpt@tempa{% - \cptglet\unexpanded{##1}=\noexpandcsn{rsv@\cptremovescape##1}% - }% - \xifinsetTF{\cptoxdetok\cpt@tempa}{\cptoxdetok\cpt@tempb}{}{% - \expandafter\AtEndOfPackage\expandafter{\cpt@tempa}% + \gletcs\unexpanded{##1}=\noexpandcsn{atpush@\cptremovescape##1}% }% - \xifinsetTF{\cptoxdetok\cpt@tempa}{\cptoxdetok\RequirePackage}{}{% - \xdef\RequirePackage{% - \expandcsonce\cpt@tempa\expandcsonce\RequirePackage + \xifinsetTF{\cptoxdetok\cpt@tempa}{\cptoxdetok\@pushfilename}{}{% + \xdef\@pushfilename{% + \expandcsonce\cpt@tempa\expandcsonce\@pushfilename }% }% }% - \comma@@loop{#1}% + \csv@@parse[,]{#1}% \endgroup } \robust@def*\cpt@badoptionerr#1{% \expandafter\ifescapedTF\expandafter{#1}{% - \cpt@err{Bad option name '\expandcsonce{#1}'}\@ehc + \cpt@escapederr{#1}% }{% - \expandafter\ifcptmacroFT\expandafter{#1}{}{% - \cpt@err{Bad option name '\expandcsonce{#1}'}\@ehc + \expandafter\cptifmacroFT\expandafter{#1}{}{% + \cpt@err{Macro as option name '\expandcsonce{#1}'}\@ehc }% }% } @@ -2730,8 +3239,8 @@ {\cpt@testfam\cpt@declareoption}% } \robust@def*\cpt@declareoption<#1>#2{% - \normal@despace{#1}\cpt@currfam - \normal@despace{#2}\cpt@curropt + \trim@@space{#1}\cpt@currfam + \trim@@space{#2}\cpt@curropt \cpt@badoptionerr\cpt@curropt \cptexpandarg\cpt@testopt {\cpt@d@clareoption{\cpt@currfam}{\cpt@curropt}}{}% @@ -2739,7 +3248,13 @@ \robust@def\cpt@d@clareoption#1#2[#3]#4{% \cpt@d@cl@reoption{#1}{#2}{#3}% \if@boolTF{cpt@olddx}{% - \long\csn@xdef{#1@ds@#2}{\unexpanded{#4}}% + \xifstrcmpTF{\@currname.\@currext}{xcolor.sty}{% + \long\csn@xdef{#1@ds@#2}{% + \unexpanded{\edef\XC@@opt{\XC@@opt#2,}#4}% + }% + }{% + \long\csn@xdef{#1@ds@#2}{\unexpanded{#4}}% + }% }{% \begingroup \long\def\cpt@tempa##1{\endgroup @@ -2762,32 +3277,30 @@ \cpt@testopt{\cpt@d@clareoptions{#1}{#2}}{}% } \robust@def\cpt@d@clareoptions#1#2[#3]#4{% - \edef\curr@fam{\xp@despace{#1}}% + \trim@@space{#1}\cpt@currfam \def\csv@do##1{% \cpt@badoptionerr{##1}% - \simpleexpandarg\cpt@d@clareoption\curr@fam{##1}[#3]{#4}% + \s@expandarg\cpt@d@clareoption\cpt@currfam{##1}[#3]{#4}% }% \csv@@parse[,]{#2}% - \undefcs\curr@fam } \robust@def*\XInvalidOptionHandler{% \cpt@testfam\cpt@invalidoptionhandler } \robust@def*\cpt@invalidoptionhandler<#1>#2{% - \def\comma@do##1{% - \normal@despace{##1}\cpt@currfam - \ifcsndefTF{\cpt@currfam @invalidoptionerr}{% + \def\cpt@currfams{#1}% + \def\csv@do##1{% + \ifcsndefTF{##1@invalidoptionerr}{% \cpt@err{Invalid option handler already defined - \MsgBrk for family '\cpt@currfam'}{% - Second invalid option handler for family - '\cpt@currfam'? + \MsgBrk for family '##1'}{% + Second invalid option handler for family '##1'? }% }{% - \csn@gdef{\cpt@currfam @invalidoptionerr}####1{#2####1}% + \csn@gdef{##1@invalidoptionerr}####1{#2####1}% }% }% - \comma@@loop{#1}% + \csv@@parse*[,]\cpt@currfams } \robust@def*\XDeclareInvalidOptions{% \let\@fileswith@pti@ns\@badrequireerror @@ -2800,13 +3313,13 @@ } \newletcs\XDeclareInvalidOption\XDeclareInvalidOptions \robust@def*\cpt@declarenulloptions<#1>#2{% - \def\csv@do##1{% - \cpt@d@clarenulloptions{##1}{#2}% - }% - \csv@@parse[,]{#1}% + \def\cpt@currfams{#1}% + \def\cpt@curropts{#2}% + \def\csv@do##1{\cpt@d@clarenulloptions{##1}}% + \csv@@parse*[,]\cpt@currfams \cpt@olddxfalse } -\robust@def*\cpt@d@clarenulloptions#1#2{% +\robust@def*\cpt@d@clarenulloptions#1{% \def\csv@do##1{% \ifcsndefTF{#1@ds@##1}{% \cpt@err{Option '##1' of family '#1' @@ -2832,83 +3345,84 @@ }% }% }% - \csv@@parse[,]{#2}% + \csv@@parse*[,]\cpt@curropts } \robust@def*\XDeclareCommandOption{% \let\@fileswith@pti@ns\@badrequireerror - \chardef\cmdoption\@ne + \let\cmdoption\cpttrue \cpt@testfam\cpt@declarecmdoption } \robust@def*\XDeclareCommandOptions{% \let\@fileswith@pti@ns\@badrequireerror - \chardef\cmdoption\@ne + \let\cmdoption\cpttrue \cpt@testfam\cpt@declarecmdoptions } \robust@def*\XDeclareBooleanOption{% \let\@fileswith@pti@ns\@badrequireerror - \chardef\cmdoption\z@ + \let\cmdoption\cptfalse \cpt@testfam\cpt@declarecmdoption } +\robust@def*\XDeclareBooleanOptions{% + \let\@fileswith@pti@ns\@badrequireerror + \let\cmdoption\cptfalse + \cpt@testfam\cpt@declarecmdoptions +} \robust@def*\cpt@declarecmdoption<#1>#2{% - \normal@despace{#1}\cpt@currfam - \normal@despace{#2}\cpt@curropt + \trim@@space{#1}\cpt@currfam + \trim@@space{#2}\cpt@curropt \cpt@badoptionerr\cpt@curropt \cptexpandarg\cpt@testopt {\cpt@d@clarecmdoption{\cpt@currfam}{\cpt@curropt}}{}% } \robust@def\cpt@d@clarecmdoption#1#2[#3]{% \cptexpandarg{\cpt@testpnopt{\cpt@d@cl@recmdoption - {#1}{#2}{#3}}}{\ifnum\cmdoption=\@ne cmd\fi\@currname @}% + {#1}{#2}{#3}}}{\if\cmdoption cmd\fi\@currname @}% } \robust@def\cpt@d@cl@recmdoption#1#2#3(#4)#5{% \cpt@d@cl@reoption{#1}{#2}{#3}% - \ifnum\cmdoption=\@ne - \def\cpt@resa{\csn@def{#4#2}{####1}}% + \if\cmdoption + \def\cpt@rsvda{\csn@def{#4#2}{####1}}% \else \csn@newif{#4#2}% - \def\cpt@resa{% + \def\cpt@rsvda{% \ifinsetTF{,####1,}{,true,false,}{}{% \@latex@error{Invalid value for option '#2'}\@ehc }% - \cptuse{#4#2####1}% + \usename{#4#2####1}% }% \fi - \long\def\cpt@resb##1{% + \long\def\cpt@rsvdb##1{% \long\csn@gdef{#1@ds@#2}####1{##1\relax}% }% - \expandafter\cpt@resb\expandafter{\cpt@resa#5}% -} -\robust@def*\XDeclareBooleanOptions{% - \let\@fileswith@pti@ns\@badrequireerror - \chardef\cmdoption\z@ - \cpt@testfam\cpt@declarecmdoptions + \expandafter\cpt@rsvdb\expandafter{\cpt@rsvda#5}% } \robust@def*\cpt@declarecmdoptions<#1>#2{% \cpt@testopt{\cpt@d@clarecmdoptions{#1}{#2}}{}% } \robust@def\cpt@d@clarecmdoptions#1#2[#3]{% \cptexpandarg{\cpt@testpnopt{\cpt@d@cl@recmdoptions - {#1}{#2}{#3}}}{\ifnum\cmdoption=\@ne cmd\fi\@currname @}% + {#1}{#2}{#3}}}{\if\cmdoption cmd\fi\@currname @}% } \robust@def\cpt@d@cl@recmdoptions#1#2#3(#4)#5{% - \edef\curr@fam{\xp@despace{#1}}% + \trim@@spaces{#1}\cpt@currfam \def\csv@do##1{% \cpt@badoptionerr{##1}% - \simpleexpandarg\cpt@d@cl@recmdoption\curr@fam{##1}{#3}(#4){#5}% + \simpleexpandarg\cpt@d@cl@recmdoption\cpt@currfam{##1}{#3}(#4){#5}% }% \csv@@parse[,]{#2}% - \undefcs\curr@fam } \robust@def*\XDeclareBiBooleanOptions{% \let\@fileswith@pti@ns\@badrequireerror - \chardef\cmdoption\z@ + \let\cmdoption\cptfalse \cpt@testfam\cpt@declarebibooloptions } \robust@def*\cpt@declarebibooloptions<#1>#2{% \begingroup - \@tempcnta\z@ - \def\comma@do##1{\advance\@tempcnta\@ne}% - \comma@@loop{#2}% + \@tempcnta\z@pt + \def\csv@do##1{% + \advance\@tempcnta\@ne + }% + \csv@@loop[,]{#2}% \ifnum\@tempcnta>\tw@ \cpt@err{Biboolean options '#2' more than 2}\@ehc \aftergroup\@gobble @@ -2926,47 +3440,30 @@ {#1}{#2}{#3}}}{\@currname @}% } \robust@def\cpt@d@cl@rebibooloptions#1#2#3(#4)#5#6{% - \edef\curr@fam{\xp@despace{#1}}% - \def\curr@opts{#2}% - \cpt@sttrue\cpt@csvnormalize[,]\curr@opts - \begingroup - \def\cpt@tempa##1,##2\cpt@nil{% - \def\cpt@tempa####1{% - \endgroup - \cpt@newv@riables{togsw}{####1@}{##1,##2}[false]% - \cpt@d@cl@recmdoption{####1}{##1}{#3}(#4){% - #5\relax - \settogswtrue{####1@##2}% - \iftogswTF{####1@##1}{}{% - \cpt@bibooltrue - \ifboolTF{#4##1}{% - \XExecuteOptions<####1>{##2=false}% - }{% - \XExecuteOptions<####1>{##2=true}% - }% - }% - \settogswfalse{####1@##2}% - \cpt@biboolfalse - }% - \cpt@d@cl@recmdoption{####1}{##2}{#3}(#4){% - #6\relax - \settogswtrue{####1@##1}% - \iftogswTF{####1@##2}{}{% - \cpt@bibooltrue - \ifboolTF{#4##2}{% - \XExecuteOptions<####1>{##1=false}% - }{% - \XExecuteOptions<####1>{##1=true}% - }% - }% - \settogswfalse{####1@##1}% - \cpt@biboolfalse - }% + \edef\cpt@currfam{\cpttrimspaces{#1}}% + \def\cpt@curropts{#2}% + \cpt@sttrue\cpt@csvnormalize[,]\cpt@curropts + \def\cpt@tempa##1,##2\cpt@nil##3{% + \cpt@newv@riables{tog}{##3@}{##1,##2}[false]% + \def\cpt@tempa####1####2{% + \cpt@d@cl@rebib@oloptions{##1}{##2}{#3}{#4}{##3}{####1}% + \cpt@d@cl@rebib@oloptions{##2}{##1}{#3}{#4}{##3}{####2}% + }% + }% + \cptexpandsecond\cpt@tempa{\cpt@curropts\cpt@nil{\cpt@currfam}}% + \cpt@tempa{#5}{#6}% +} +\robust@def\cpt@d@cl@rebib@oloptions#1#2#3#4#5#6{% + \cpt@d@cl@recmdoption{#5}{#1}{#3}(#4){% + #6\relax + \iftogTF{#5@#1}{}{% + \settogtrue{#5@#2}% + \settogtrue{biboolkeys}% + \cptexpandarg{\XExecuteOptions<#5>}{#2=\thebool@reverse{#4#1}}% + \settogfalse{biboolkeys}% + \settogfalse{#5@#2}% }% - \expandafter\cpt@tempa\expandafter{\curr@fam}% }% - \expandafter\cpt@tempa\curr@opts\cpt@nil - \undefcs\curr@opts\undefcs\curr@fam } \robust@def\cpt@d@cl@reoption#1#2#3{% \ifcsndefTF{#1@declaredoptions}{% @@ -2986,26 +3483,27 @@ } \robust@def*\XDisableOptions{% \cpt@testst{% - \let\ifv@\ifcpt@st + \let\ifcpt@swa\ifcpt@st \cpt@testfam\cpt@disableoption }% } \robust@def*\cpt@disableoption<#1>#2{% + \def\cpt@currfams{#1}% + \def\cpt@curropts{#2}% \def\csv@do##1{% - \cpt@dis@bleoption{##1}{#2}% + \cpt@dis@bleoption{##1}% }% - \csv@@parse[,]{#1}% - \undefcs\ifv@ + \csv@@parse*[,]\cpt@currfams } -\robust@def*\cpt@dis@bleoption#1#2{% +\robust@def*\cpt@dis@bleoption#1{% \def\csv@do##1{% \ifcsndefFT{#1@ds@##1}{% \cpt@info{Option '##1' of family '#1'\MsgBrk is undeclared: not disabled} }{% \cptpassexpanded{% - \ifv@\noexpand\AtBeginDocument{\fi - \cpt@filtermergelists[,]% + \ifcpt@swa\noexpand\AtBeginDocument{\fi + \cptfiltermergekv[,]% \noexpandcsn{#1@disabledoptions}{##1}% \noexpand\nofilter \noexpand\undefcsn{#1@ds@##1@default}% @@ -3020,21 +3518,21 @@ or \string\usepackage }% }% - \ifv@}\fi + \ifcpt@swa}\fi }% }% }% - \csv@@parse[,]{#2}% + \csv@@parse*[,]\cpt@curropts } \robust@def*\XLogDisabledOptions{% - \cpt@ifnextchar<\cpt@disabledoptionlist + \CurrIfnextchar<\cpt@disabledoptionlist \cpt@dis@bledoptionlist } \robust@def*\cpt@disabledoptionlist<#1>{% \cpt@dis@bledoptionlist{#1}% } \robust@def*\cpt@dis@bledoptionlist#1{% - \def\cpt@disablea##1{% + \def\cpt@disable@a##1{% \ifcsndefTF{##1@disabledoptions}{% \cpt@info{Disabled options of family '##1': ^^J\expandcsnonce{##1@disabledoptions}}% @@ -3042,11 +3540,11 @@ \cpt@info{No disabled options in family '##1' \MsgBrk at this point\ifcsnullTF\@currname{} {:\@space You can try the command - \MsgBrk\noexpand\XLogDisabledOptions again after + \MsgBrk\noexpand\XLogDisabledOptions again, after \MsgBrk begin document}}% }% }% - \def\cpt@disableb##1##2{% + \def\cpt@disable@b##1##2{% \cpt@err{Command \noexpand\XLogDisabledOptions issued \MsgBrk in document but family name contains \MsgBrk ##1 extension \string##2, @@ -3054,70 +3552,68 @@ }% \def\csv@do##1{% \ifcsnullFT\@currname{% - \cpt@disablea{##1}% + \cpt@disable@a{##1}% }{% \ifinsetTF\@pkgextension{##1}{% - \cpt@disableb{package}\@pkgextension + \cpt@disable@b{package}\@pkgextension }{% \ifinsetTF\@clsextension{##1}{% - \cpt@disableb{class}\@clsextension + \cpt@disable@b{class}\@clsextension }{% - \cpt@disablea{##1}% + \cpt@disable@a{##1}% }% }% }% }% \ifblankTF{#1}{}{\csv@@parse{#1}}% - \undefcsset{\cpt@disablea,\cpt@disableb}% + \undefcs\cpt@disable@a\undefcs\cpt@disable@b } \robust@def*\ifoptdisabledTF{% - \v@true - \cpt@testfam\cpt@ifoptdisabled + \cpt@swatrue\cpt@testfam\cpt@ifoptdisabled } \robust@def*\ifoptdisabledFT{% - \v@false - \cpt@testfam\cpt@ifoptdisabled + \cpt@swafalse\cpt@testfam\cpt@ifoptdisabled } \robust@def*\cpt@ifoptdisabled<#1>#2{% + \def\cpt@currfams{#1}% \cpt@choicefdfalse \def\csv@do##1{% \cpt@ifoptdis@bled{##1}{#2}% }% - \csv@@parse[,]{#1}% - \if@boolTF{v@}\if@boolTF\if@boolFT{cpt@choicefd}% + \csv@@parse*[,]\cpt@currfams + \if@boolTF{cpt@swa}\if@boolTF\if@boolFT{cpt@choicefd}% } \robust@def*\cpt@ifoptdis@bled#1#2{% \ifcsndefFT{#1@disabledoptions}{}{% - \xifinsetFT{#2}{\expandcsnonce{#1@disabledoptions}}{}{% + \xifinsetFT{,#2,}{,\expandcsnonce{#1@disabledoptions},}{}{% \cptbreakloop\cpt@choicefdtrue }% }% } \robust@def*\ifoptdefTF{% - \v@true - \cpt@testfam\cpt@ifoptdef + \cpt@swatrue\cpt@testfam\cpt@ifoptdef } \robust@def*\ifoptdefFT{% - \v@false - \cpt@testfam\cpt@ifoptdef + \cpt@swafalse\cpt@testfam\cpt@ifoptdef } \robust@def*\cpt@ifoptdef<#1>#2{% + \def\cpt@currfams{#1}% \cpt@choicefdfalse \def\csv@do##1{% \cpt@ifoptd@f{##1}{#2}% }% - \csv@@parse[,]{#1}% - \if@boolTF{v@}\if@boolTF\if@boolFT{cpt@choicefd}% + \csv@@parse*[,]\cpt@currfams + \if@boolTF{cpt@swa}\if@boolTF\if@boolFT{cpt@choicefd}% } \robust@def*\cpt@ifoptd@f#1#2{% \ifcsndefFT{#1@ds@#2}{}{% - \cptbreakloop\cpt@choicefdtrue + \cpt@choicefdtrue\cptbreakloop }% } \new@def*\cpt@getdeclaredoptions#1{% \ifcsndefFT{#1@declaredoptions}{}{% \ifcsnnullTF{#1@declaredoptions}{}{% - \detokenize\cptsevenxp{\usecsn{#1@declaredoptions}}% + \detokenize\cptsevenxp{\usename{#1@declaredoptions}}% }% }% } @@ -3128,23 +3624,25 @@ \cpt@testopt{\cpt@unkn@wnoptionhandler#1}{}% } \robust@def*\cpt@unkn@wnoptionhandler#1[#2]#3{% - \edef\unknown@ds{% - \unexpanded{\csn@def{\cpt@tempa @default@ds}##1##2##3{#3}}% + \def\cpt@currfams{#1}% + \edef\reserved@e##1{% + \csn@def{##1@default@ds}####1####2####3{\unexpanded{#3}}% }% \def\csv@do##1{% \ifcsndefFT{##1@default@ds}{}{% - \cpt@warn{Unknown option handler for family - \MsgBrk '##1' replaced}% + \ifcpt@verbose + \cpt@warn{Unknown option handler for family + \MsgBrk '##1' replaced}% + \fi }% - \def\cpt@tempa{##1}\unknown@ds + \reserved@e{##1}% \csn@def{##1@default@na}{#2}% }% - \csv@@parse[,]{#1}% - \undefcs\unknown@ds + \csv@@parse*[,]\cpt@currfams } \robust@def*\cpt@define@default@ds<#1>#2{% \csn@def{#1@default@ds}##1##2##3{#2}% - \shelldef\cpt@define@default@ds<##1>##2{% + \protected\def\cpt@define@default@ds<##1>##2{% \cpt@err{'\string\XDeclareOption*' multiply defined in \MsgBrk\@cls@pkg\space'\@currname'}{Multiple star variant of \noexpand\XDeclareOption in @@ -3153,7 +3651,7 @@ } \RecoverAtRequirePackage\cpt@define@default@ds \new@def*\cpt@optionlist#1{% - \ifcsndefFT{opt@#1}{}{\unexpanded\cptsevenxp{\usecsn{opt@#1}}}% + \ifcsndefFT{opt@#1}{}{\unexpanded\cptsevenxp{\usename{opt@#1}}}% } \newletcs\cpt@processedoptions\@empty \robust@def*\XProcessOptions{% @@ -3168,7 +3666,7 @@ \expandcsonce\cpt@classoptionslist\fi }% \edef\@curroptions{\cpt@optionlist{\@currname.\@currext}}% - \ifcsnullTF\@curroptions\@empty + \ifcsnullTF\@curroptions{} {\cpt@sttrue\cpt@kvnormalize[,]\@curroptions}% \cpt@testst{\cpt@testfam\cpt@processoptions}% } @@ -3180,18 +3678,18 @@ }% } \robust@def*\cpt@yprocessoptions#1[#2]{% - \edef\cpt@currna{\unexpanded{#2}}% - \ifcsnullTF\cpt@currna{} - {\cpt@sttrue\cpt@csvnormalize[,]\cpt@currna}% + \def\cpt@currfams{#1}% + \def\cpt@currna{#2}% + \cpt@sttrue\cpt@csvnormalize[,]\cpt@currna \def\csv@do##1{% \cpt@ypr@cessoptions{##1}% }% - \csv@@parse[,]{#1}% - \cpt@pr@cessoptions{#1}% + \csv@@parse*[,]\cpt@currfams + \cpt@pr@cessoptions \cpt@pr@cessopti@ns } \robust@def*\cpt@ypr@cessoptions#1{% - \edef\cpt@currfam{\unexpanded{#1}}% + \def\cpt@currfam{#1}% \def\kv@do##1{% \edef\CurrentOption{\unexpanded{##1}}% \ifcsnullTF\CurrentOption{}{% @@ -3201,7 +3699,7 @@ \ifcsnullTF\cpt@currna{% \cpt@igoptfalse }{% - \if@sp@inlistTF,\cpt@curropt\cpt@currna{% + \oifinset@sp@TF,\cpt@curropt\cpt@currna{% \cpt@igopttrue }{% \cpt@igoptfalse @@ -3212,21 +3710,22 @@ }% }% }% - \ifcsnullTF\cpt@classoptions{}{% + \ifxTF\cpt@classoptions\@empty{}{% \ifcsnnullTF{#1@declaredoptions}{}{% - \cptexpandsecond{\kv@@parse*}{\noexpandcsn{#1@declaredoptions}}% + \aftercsname{\kv@@parse*}{#1@declaredoptions}% }% }% } \robust@def*\cpt@xprocessoptions#1[#2]{% - \edef\cpt@currna{\unexpanded{#2}}% - \ifcsnullTF\cpt@currna{} - {\cpt@sttrue\cpt@csvnormalize[,]\cpt@currna}% + \def\cpt@currfams{#1}% + \cpt@sttrue\cpt@csvnormalize[,]\cpt@currfams + \def\cpt@currna{#2}% + \csv@@normalize*[,]\cpt@currna \def\csv@do##1{% \cpt@xpr@cessoptions{##1}% }% - \csv@@parse[,]{#1}% - \cpt@pr@cessoptions{#1}% + \csv@@parse*[,]\cpt@currfams + \cpt@pr@cessoptions \cpt@pr@cessopti@ns } \robust@def*\cpt@xpr@cessoptions#1{% @@ -3236,12 +3735,12 @@ \edef\CurrentOption{\unexpanded{##1}}% \ifcsnullTF\CurrentOption{}{% \cpt@findoption@b - \if@sp@inlistFT,\cpt@curropt\DeclaredOptions{}{% + \oifinset@sp@FT,\cpt@curropt\DeclaredOptions{}{% \ifcsndefFT{#1@ds@\cpt@curropt}{}{% \ifcsnullTF\cpt@currna{% \cpt@igoptfalse }{% - \if@sp@inlistTF,\cpt@curropt\cpt@currna{% + \oifinset@sp@TF,\cpt@curropt\cpt@currna{% \cpt@igopttrue }{% \cpt@igoptfalse @@ -3252,10 +3751,10 @@ }% }% }% - \ifcsnullTF\cpt@classoptions{}{\kv@@parse*\cpt@classoptions}% + \ifcsnullTF\cpt@classoptions{} + {\kv@@parse*[,]\cpt@classoptions}% } -\robust@def*\cpt@pr@cessoptions#1{% - \def\cpt@fams{#1}% +\robust@def*\cpt@pr@cessoptions{% \def\kv@do##1{% \edef\CurrentOption{\unexpanded{##1}}% \ifcsnullTF\CurrentOption{}{% @@ -3266,7 +3765,7 @@ \ifcsnullTF\cpt@currna{% \cpt@igoptfalse }{% - \if@sp@inlistTF,\cpt@curropt\cpt@currna{% + \oifinset@sp@TF,\cpt@curropt\cpt@currna{% \cpt@igopttrue }{% \cpt@igoptfalse @@ -3274,64 +3773,94 @@ }% \cpt@useoption }{% - \if@sp@inlistTF,\cpt@curropt\ExternalOptions{}{% + \oifinset@sp@TF,\cpt@curropt\XExternalOptions{% + \ifindefaultdsTF{\PassOptionsToClass}{% + \cpt@use@default@ds + }{% + \ifindefaultdsFT{\PassOptionsToPackage}{}{% + \cpt@use@default@ds + }% + }% + }{% \cpt@addto@undef@opts \cpt@use@default@ds }% }% }% - \ifcsnullTF\cpt@fams{}{\csv@@loop*[,]\cpt@fams}% + \csv@@loop*[,]\cpt@currfams }% }% \ifcsnullTF\@curroptions{}{\kv@@parse*[,]\@curroptions}% } \robust@def*\cpt@pr@cessopti@ns{% \let\CurrentOption\@empty - \ifx\cpt@documentclass\cpt@undefined\else - \let\cpt@processedoptions\@empty\fi \undefcs\cpt@classoptions \let\@fileswith@pti@ns\@@fileswith@pti@ns \cpt@olddxfalse \AtEndOfPackage{\let\@unprocessedoptions\relax}% } +\robust@def*\ifindefaultdsTF{% + \begingroup + \def\reserved@e{\@firstoftwo\@secondoftwo}% + \cpt@ifin@default@ds +} +\robust@def*\ifindefaultdsFT{% + \begingroup + \def\reserved@e{\@secondoftwo\@firstoftwo}% + \cpt@ifin@default@ds +} +\robust@def*\cpt@ifin@default@ds#1{% + \let\xp\expandcsonce + \edef\cpt@ds@a{% + {\xp\cpt@currfam}{\xp\cpt@curropt}{\xp\cpt@currval}% + }% + \edef\cpt@ds@b{\cptmakecs{\cpt@currfam @default@ds}}% + \edef\cpt@ds@c{% + \unexpanded\cptsevenxp{\expandafter\cpt@ds@b\cpt@ds@a}% + }% + \cptexpanded{% + \endgroup + \cpt@csexit\cpt@ds@a\cpt@csexit\cpt@ds@b\cpt@csexit\cpt@ds@c + \ifinsetTF{\detokenize{#1}}{\cptoxdetok\cpt@ds@c}% + \xp\reserved@e + }% +} \robust@def*\cpt@use@default@ds{% \begingroup - \let\@xp\expandcsonce + \let\xp\expandcsonce \ifcsndefTF{\cpt@currfam @default@na}{}{% \csn@def{\cpt@currfam @default@na}{}% }% \toks@{\default@ds}% \ifcsndefFT{\cpt@currfam @default@ds}{}{% \edef\cpt@tempa{\expandcsnonce{\cpt@currfam @default@na}}% - \if@sp@inlistTF,\cpt@curropt\cpt@tempa{}{% - \edef\cpt@tempa{% - {\@xp\cpt@currfam}{\@xp\cpt@curropt}{\@xp\cpt@currval}% - }% - \edef\cpt@tempb{\cptmakecs{\cpt@currfam @default@ds}}% - \edef\cpt@tempc{% - \unexpanded\cptsevenxp{\expandafter\cpt@tempb\cpt@tempa}% - }% - \xifinsetFT{\detokenize{define/.code=}}{\cptoxdetok\cpt@tempc}{% - \toks@\cptthreexp{\expandafter\cpt@tempb\cpt@tempa}% + \oifinset@sp@TF,\cpt@curropt\cpt@tempa{}{% + \ifindefaultdsFT{define/.code=}{% + \toks@\expandafter{\cpt@ds@c}% }{% - \cptexpandmacro\cpt@currval\curr@val - \despacecontent\curr@val - \def\cpt@tempb{\XDeclareBooleanOption}% - \let\cmd\@empty - \oifstrcmpTF{true}\curr@val{}{% - \oifstrcmpTF{false}\curr@val{}{% - \def\cpt@tempb{\XDeclareCommandOption}% - \def\cmd{cmd}% + \ifindefaultdsFT{/.end}{% + \cpt@err{I can't find '/.end' in^^J'\cptoxdetok\cpt@ds@c}\@ehc + }{% + \cptexpandmacro\cpt@currval\curr@val + \despacecontent\curr@val + \def\cpt@tempb{\XDeclareBooleanOption}% + \let\cmd\@empty + \oifstrcmpTF{true}\curr@val{}{% + \oifstrcmpTF{false}\curr@val{}{% + \def\cpt@tempb{\XDeclareCommandOption}% + \def\cmd{cmd}% + }% }% + \def\cpt@tempa##1define/.code=##2/.end##3\cpt@nil{% + \cptexpanded{\toks@{% + \unexpanded{##1##3}% + \cpt@tempb<\cpt@currfam>{\cpt@curropt}[\xp\curr@val]% + (\cmd\@currname @){\unexpanded{##2}}% + \XExecuteOptions<\cpt@currfam>{\cpt@curropt=\xp\curr@val}% + }}% + }% + \expandafter\cpt@tempa\cpt@ds@c\cpt@nil }% - \def\cpt@tempa##1define/.code=##2\cpt@nil{% - \cptexpanded{\toks@{% - \cpt@tempb<\cpt@currfam>{\cpt@curropt}[\@xp\curr@val]% - (\cmd\@currname @){\unexpanded{##2}}% - \XExecuteOptions<\cpt@currfam>{\cpt@curropt=\@xp\curr@val}% - }}% - }% - \expandafter\cpt@tempa\cpt@tempc\cpt@nil }% }% }% @@ -3345,20 +3874,25 @@ \cpt@testopt{\cpt@ex@cuteoptions{#1}{#2}}{}% } \robust@def*\cpt@ex@cuteoptions#1#2[#3]{% - \edef\cpt@currna{\unexpanded{#3}}% + \def\cpt@currna{#3}% \ifcsnullTF\cpt@currna{}{% \cpt@sttrue\cpt@csvnormalize[,]\cpt@currna }% + \edef\cpt@curroptvals{\unexpanded{#2}}% + \ifcsnullTF\cpt@curroptvals{}{% + \cpt@sttrue\cpt@kvnormalize[,]\cpt@curroptvals + }% \def\csv@do##1{% - \cpt@ex@cuteopti@ns{##1}{#2}% + \cpt@ex@cuteopti@ns{##1}% }% \csv@@parse[,]{#1}% \cpt@olddxfalse - \undefcsset{\ExecutedOptions,\exec@warnlist}% + \undefcs\ExecutedOptions + \undefcs\cpt@execwarnlist } -\robust@def*\cpt@ex@cuteopti@ns#1#2{% +\robust@def*\cpt@ex@cuteopti@ns#1{% \def\cpt@currfam{#1}% - \ifnum\cpt@optdepth=\z@ + \ifnum\cpt@optdepth=\z@pt \csn@def{\cpt@currfam @executedoptions}{}% \csn@def{\cpt@currfam @exec@warnlist}{}% \fi @@ -3370,19 +3904,21 @@ \edef\ExecutedOptions{% \expandcsnonce{\cpt@currfam @executedoptions}% }% - \edef\exec@warnlist{% + \edef\cpt@execwarnlist{% \expandcsnonce{\cpt@currfam @exec@warnlist}% }% - \if@sp@inlistTF,\cpt@curropt\cpt@currna{}{% + \oifinset@sp@TF,\cpt@curropt\cpt@currna{}{% \cpt@igoptfalse - \if@sp@inlistTF,\cpt@curropt\DeclaredOptions{% - \if@sp@inlistTF,\cpt@curropt\ExecutedOptions{% - \if@sp@inlistTF,\cpt@curropt\exec@warnlist{}{% - \ifcpt@bibool\else - \cpt@warn{Option '\cpt@curropt' of family - '\cpt@currfam'\MsgBrk multiply submitted to - \string\XExecuteOptions:\MsgBrk re-executed}% - \fi + \oifinset@sp@TF,\cpt@curropt\DeclaredOptions{% + \oifinset@sp@TF,\cpt@curropt\ExecutedOptions{% + \oifinset@sp@TF,\cpt@curropt\cpt@execwarnlist{}{% + \iftogTF{biboolkeys}{}{% + \ifcpt@verbose + \cpt@info{Option '\cpt@curropt' of family + '\cpt@currfam'\MsgBrk multiply submitted to + \string\XExecuteOptions:\MsgBrk re-executed}% + \fi + }% \aftercsname{\cptgaddtolist*} {\cpt@currfam @exec@warnlist}\cpt@curropt }% @@ -3397,20 +3933,30 @@ }% }% }% - \kv@@parse{#2}% + \kv@@loop*[,]\cpt@curroptvals +} +\robust@def*\XExecuteAliasOption#1{% + \cpt@testopt{\cpt@executealiasoption#1}{}% +} +\robust@def*\cpt@executealiasoption#1[#2]{% + \edef\reserved@a{\ifblankTF{#2} + {\expandcsonce\cpt@currval}{\unexpanded{#2}}}% + \cpt@inpoxfalse + \cptexpandsecond\cpt@executeoptions + {<\cpt@currfam>{#1=\expandcsonce\reserved@a}}\relax } \robust@def\cpt@findoption@a{% \cpt@optfdfalse - \def\csv@do##1{% + \def\kv@do##1{% \ifblankTF{##1}{}{% \xifinsetTF{=}{\detokenize{##1}}{% - \cpt@splitoption##1=\split@nil + \cpt@splitoption##1=\opt@split@nil }{% \edef\cpt@curropt{\unexpanded{##1}}% \let\cpt@currval\@empty }% \ifx\cpt@curropt\CurrentOption - \cpt@optfdtrue\cpt@breaklooptrue + \cpt@optfdtrue\cptbreakloop \edef\OptionFound{\unexpanded{##1}}% \else \let\cpt@curropt\@empty @@ -3418,32 +3964,36 @@ \fi }% }% - \csv@@parse*[,]\cpt@classoptions + \kv@@loop*[,]\cpt@classoptions } \robust@def\cpt@findoption@b{% \let\OptionFound\CurrentOption \xifinsetTF{=}{\cptoxdetok\CurrentOption}{% - \expandafter\cpt@splitoption\CurrentOption=\split@nil + \expandafter\cpt@splitoption\CurrentOption=\opt@split@nil + \let\CurrentOption\cpt@curropt }{% \let\cpt@curropt\CurrentOption \let\cpt@currval\@empty }% } -\robust@def\cpt@splitoption#1=#2\split@nil{% - \normal@despace{#1}\cpt@curropt - \ifinsetTF{=\split@nil}{#2\split@nil}{% +\robust@def\cpt@splitoption#1=#2\opt@split@nil{% + \def\cpt@curropt{#1}% + \ifinsetTF{=\opt@split@nil}{#2\opt@split@nil}{% \begingroup - \defpass\cpt@tempa##1=##2\split@nil{\endgroup - \simpleexpandarg\normal@despace{\@gobble##1}\cpt@currval + \defpass\cpt@tempa##1=##2\opt@split@nil{\endgroup + \edef\cpt@currval{\unexpanded\expandafter{\@gobble##1}}% }% - .#2\split@nil + .#2\opt@split@nil }{% - \normal@despace{#2}\cpt@currval + \edef\cpt@currval{\unexpanded{#2}}% }% } \robust@def*\cpt@useoption{% \if@boolFT{cpt@inpox}{}{% - \if@sp@inlistTF,\CurrentOption\cpt@processedoptions{}{% + \oifinset@sp@TF,\OptionFound\cpt@processedoptions{}{% + \cptgaddtolist*\cpt@processedoptions\OptionFound + }% + \oifinset@sp@TF,\CurrentOption\cpt@processedoptions{}{% \cptgaddtolist*\cpt@processedoptions\CurrentOption }% \ifcsnullTF\OptionFound{}{\cpt@removecurroption\OptionFound}% @@ -3454,7 +4004,7 @@ \if@boolTF{cpt@igopt}{}{% \ifcsndefFT{\cpt@currfam @ds@\cpt@curropt}{}{% \if@boolTF{cpt@olddx}{% - \cptuse{\cpt@currfam @ds@\cpt@curropt}% + \usename{\cpt@currfam @ds@\cpt@curropt}% }{% \ifcsnullTF\cpt@currval{% \cptthreexp\cpt@usedefault @@ -3468,44 +4018,47 @@ }% } \robust@def*\cpt@useoption@a{% - \cpt@pushoptionstate - \cptexpandargonce{\cptuse{\cpt@currfam @ds@\cpt@curropt}}% + \cpt@pushstate\XExecuteOptions\cpt@optionstate\cpt@optdepth + \cptexpandargonce{\usename{\cpt@currfam @ds@\cpt@curropt}}% \cpt@currval\relax - \cpt@popoptionstate -} -\new@def*\ExternalOptions{% - 10pt,11pt,12pt,14pt,17pt,20pt,25pt,30pt,36pt,48pt,60pt,% - a0paper,a1paper,a2paper,a3paper,a4paper,a6paper,% - b0paper,b1paper,b2paper,b3paper,b4paper,b5paper,b6paper,% - letterpaper,legalpaper,executivepaper,landscape,oneside,% - twoside,draft,final,titlepage,notitlepage,onecolumn,% - twocolumn,leqno,fleqn,openbib,openright,openleft,openany,% - article,ms,showtrims,oldfontcommands,extrafontsizes,noetex% -} + \cpt@popstate\XExecuteOptions\cpt@optdepth +} +% Only 'article', 'report', 'memoir' options have been added +% to \XExternalOptions. Other external options (eg, those of +% script and KOMA-Script classes) haven't been added. +\BeginOverlookWhiteSpace +\newcommand*\XExternalOptions{% + 10pt,11pt,12pt,14pt,17pt,20pt,25pt,30pt,36pt,48pt,60pt, + a0paper,a1paper,a2paper,a3paper,a4paper,a6paper, + b0paper,b1paper,b2paper,b3paper,b4paper,b5paper,b6paper, + letterpaper,legalpaper,executivepaper,landscape,oneside, + twoside,draft,final,titlepage,notitlepage,onecolumn, + twocolumn,leqno,fleqn,openbib,openright,openleft,openany, + article,ms,showtrims,oldfontcommands,extrafontsizes,noetex +} +\EndOverlookWhiteSpace \robust@def*\AddToExternalOptions#1{% - \cpt@filtermergelists[,]\ExternalOptions{#1}\nofilter + \cptfiltermergecsv[,]\XExternalOptions{#1}\nofilter } \robust@def*\RemoveFromExternalOptions#1{% - \cpt@filterremoveelements[,]\ExternalOptions{#1}\nofilter + \cpt@filterremoveelements[,]\XExternalOptions{#1}\nofilter } \robust@def*\cpt@addto@undecl@opts{% \edef\everymergeitem##1{\@space##1}% - \cptexpandarg{\cpt@filtermergelists[;]\cpt@undeclaredopts}% + \cptexpandarg{\cptfiltermergekv[;]\cpt@undeclaredopts}% {\cpt@currfam,\cpt@curropt,\cpt@currval}\nofilter } \robust@def*\cpt@addto@undef@opts{% \edef\everymergeitem##1{\@space##1}% - \if@sp@inlistTF,\cpt@curropt\ExternalOptions{}{% - \cptexpandarg{\cpt@filtermergelists[;]\cpt@undefinedopts}% + \oifinset@sp@TF,\cpt@curropt\XExternalOptions{}{% + \cptexpandarg{\cptfiltermergekv[;]\cpt@undefinedopts}% {\cpt@currfam,\cpt@curropt,\cpt@currval}\nofilter }% } \AfterStartOfDocument{\AtEndDocument{% \ifdefFT\cpt@undeclaredopts{}{% \ifcsnullTF\cpt@undeclaredopts{}{% - \edef\cpt@undeclaredopts{% - \simpleexpandarg\xp@despace\cpt@undeclaredopts - }% + \despacecontent\cpt@undeclaredopts \cpt@warn{% Undeclared options found in \string\XExecuteOptions \MsgBrk (family,option,value): @@ -3515,22 +4068,20 @@ }% \ifdefFT\cpt@undefinedopts{}{% \ifcsnullTF\cpt@undefinedopts{}{% - \edef\cpt@undefinedopts{% - \simpleexpandarg\xp@despace\cpt@undefinedopts - }% + \despacecontent\cpt@undefinedopts \cpt@warn{% Undefined options (family,option,value): - ^^J\expandcsonce\cpt@undefinedopts - \MsgBrk Default action taken in each case + \MsgBrk\expandcsonce\cpt@undefinedopts + \MsgBrk Default action already taken in each case }% }% }% }} \robust@def*\cpt@usedefault#1#2\cpt@nil{% - \ifcptmacroTF{#1}{% + \cptifmacroTF{#1}{% \edef\cpt@tempa{\cptremovescape#1}% }{% - \cpt@nomacroerr{#1}% + \cpt@notcserr{#1}% }% \edef\cpt@tempb{\cpt@currfam @ds@\cpt@curropt}% \@onelevel@sanitize\cpt@tempb @@ -3539,59 +4090,54 @@ \csn@def{\cpt@currfam @ds@\cpt@curropt}##1{% \toks@{\def\cpt@currval{##1}}% }% - \cptuse{\cpt@currfam @ds@\cpt@curropt @default}% + \usename{\cpt@currfam @ds@\cpt@curropt @default}% \expandafter\endgroup\the\toks@ \cpt@useoption@a }{% \cpt@warn{Non-standard default function for option '\expandcsonce\cpt@curropt':\MsgBrk Executed anyway}% - \cpt@pushoptionstate - \cptuse{\cpt@currfam @ds@\cpt@curropt @default}\relax - \cpt@popoptionstate + \cpt@pushstate\XExecuteOptions\cpt@optionstate\cpt@optdepth + \usename{\cpt@currfam @ds@\cpt@curropt @default}\relax + \cpt@popstate\XExecuteOptions\cpt@optdepth }% } \robust@def*\cpt@optionstate{% - \cpt@currfam,\cpt@currna,\cpt@curropt,\cpt@currval,% - \CurrentOption,\OptionFound,\ifcpt@inpox,\ifcpt@optfd,% - \ifcpt@igopt,\DeclaredOptions -} -\robust@def*\cpt@pushoptionstate{% - \simpleexpandarg\pushfunctions\cpt@optionstate\cpt@optdepth -} -\robust@def*\cpt@popoptionstate{% - \simpleexpandarg\popfunctions\cpt@optionstate\cpt@optdepth + \cpt@currfams,\cpt@curroptvals,\cpt@currfam,\cpt@currna, + \cpt@curropt,\cpt@currval,\CurrentOption,\OptionFound, + \ifcpt@inpox,\ifcpt@optfd,\ifcpt@igopt,\DeclaredOptions, + \ExecutedOptions } \robust@def*\cpt@removecurroption#1{% \cptexpandargonce{\cpt@filterremoveelements[,]% \@unusedoptionlist}{#1}\nofilter } -\robust@def*\CleanupUnusedOptionlist#1{% - \ifcptmacroTF{#1}{}{\cpt@nomacroerr{#1}}% +\robust@def*\cpt@cleanup#1{% + \cptifmacroTF{#1}{}{\cpt@notcserr{#1}}% \BeforeStartOfDocument{% \ifdefFT#1{}{% \ifcsnullTF#1{}{% \ifcsnullTF\@unusedoptionlist{}{% - \def\comma@do##1{% - \normal@despace{##1}\cpt@tempa - \if@sp@inlistFT,\cpt@tempa\@unusedoptionlist{}{% - \cpt@removecurroption\cpt@tempa + \def\csv@do##1{% + \xifinsetTF{,\detokenize{##1},}% + {,\cptoxdetok\@unusedoptionlist,}{% + \cpt@removecurroption{##1}% }% }% - \simpleexpandarg\comma@@loop#1% + \csv@@parse*[,]#1% }% }% }% \globalize\@unusedoptionlist - \emptify#1% + \def#1{}% }% } -\CleanupUnusedOptionlist\cpt@processedoptions +\cpt@cleanup\cpt@processedoptions \cptpassunexpanded{% \begingroup \def\cpt@tempa{\endgroup - \newgletcs\kernel@DeclareOption\DeclareOption - \newgletcs\kernel@ProcessOptions\ProcessOptions - \newgletcs\kernel@ExecuteOptions\ExecuteOptions + \gnewletcs\kernel@DeclareOption\DeclareOption + \gnewletcs\kernel@ProcessOptions\ProcessOptions + \gnewletcs\kernel@ExecuteOptions\ExecuteOptions \gdef\DeclareOption{\cpt@olddxtrue\XDeclareOption}% \gdef\ProcessOptions{\cpt@olddxtrue\XProcessOptions}% \gdef\ExecuteOptions{\cpt@olddxtrue\XExecuteOptions}% @@ -3601,9 +4147,9 @@ \let\documentclass\@twoclasseserror \if@compatibility\else \def\usepackage{% - \cptglet\DeclareOption\kernel@DeclareOption - \cptglet\ProcessOptions\kernel@ProcessOptions - \cptglet\ExecuteOptions\kernel@ExecuteOptions + \gletcs\DeclareOption\kernel@DeclareOption + \gletcs\ProcessOptions\kernel@ProcessOptions + \gletcs\ExecuteOptions\kernel@ExecuteOptions \cpt@olddxfalse \RequirePackage }% @@ -3616,8 +4162,38 @@ \ifx\cpt@documentclass\cpt@undefined \expandafter\cpt@tempa\else\expandafter\endgroup\fi } -\XDeclareBooleanOption{verbose}[true](cpt@){} +\cptonlypreamble{% + \cptonlypreamble, + \cptloadpackages,\ifpackagewithTF,\ifclasswithTF,\cpt@ifoptions, + \cptpushcatcodes,\cptpopcatcodes,\UseNormalCatcodes, + \rsv@UseNormalCatcodes,\StyleFilePurpose,\StyleFileInfo, + \AfterEndOfStyleFile,\StyleFileRCSInfo,\SetStyleFileMessages, + \XDeclareOption,\XDeclareOptions,\XDeclareCommandOption, + \XDeclareCommandOptions,\XDeclareBooleanOption, + \XDeclareBooleanOptions,\XDeclareBiBooleanOptions, + \XProcessOptions,\XExecuteOptions,\XExecuteAliasOption, + \cpt@processedoptions,\cpt@optionlist,\cpt@findoption@a, + \cpt@findoption@b,\cpt@processoptions,\cpt@xprocessoptions, + \cpt@yprocessoptions,\cpt@pr@cessoptions,\BeforeStartOfDocument, + \AfterStartOfDocument,\XInvalidOptionHandler,\XDeclareInvalidOption, + \XDeclareInvalidOptions,\XUnknownOptionHandler,\XExternalOptions +} +\XDeclareBiBooleanOptions{verbose,silent}[true](cpt@){}{} \XDeclareBiBooleanOptions{draft,final}[true](cpt@){}{} +\XDeclareCommandOption{optionstacklimit}[4](cpt@){} +\XDeclareCommandOption{option-stack-limit}[4](cpt@){% + \XExecuteAliasOption{optionstacklimit}% +} +\XDeclareCommandOption{key-stack-limit}[4](cpt@){% + \XExecuteAliasOption{optionstacklimit}% +} +\XDeclareBooleanOption{kernelifnextchar}[true](cpt@){% + \ifcpt@kernelifnextchar + \let\CurrIfnextchar\kernel@ifnextchar + \else + \let\CurrIfnextchar\ifnextcharTF + \fi +} \XDeclareBooleanOption{usepox}[true](cpt@){% \ifcpt@usepox \AtEndOfPackage{% @@ -3629,15 +4205,35 @@ } \XDisableOptions*{draft,final} \XDeclareOption*{\cpt@warn{Unknown option '\CurrentOption' ignored}} -\XExecuteOptions{verbose=false,usepox=true} +\XExecuteOptions{verbose=false,usepox=true,optionstacklimit=4}\relax \XProcessOptions*\relax +\robust@def*\@ltx@warn{\@latex@warning@no@line} +\robust@def*\@ltx@info{\@latex@info@no@line} +\robust@def*\@ltx@err{\@latex@error} +\robust@def\gen@nil#1\fi#2\gen@do#3\gen@nil{\fi#1#2} +\robust@def*\cpt@fox{\cpt@teststopt\cpt@f@x,} +\robust@def*\cpt@f@x[#1]#2#3{% + \advance\cpt@foxdepth\@ne + \ifnum\cpt@foxdepth>\@ne + \cpt@err{\noexpand\cpt@fox nesting}\@ehc + \fi + \cpt@stchoose{cpt@st}{#2}\cpt@rsvda\cpt@fox + \cpt@sttrue\cpt@csvnormalize[#1]\cpt@rsvda + \cpt@lastitemfalse\chardef\foxnr\z@pt + \def\gen@do##1#1##2\gen@nil{% + \ifcat$\detokenize\expandafter{\@gobble##2.}$\gen@nil + \cpt@lastitemtrue\fi + \edef\foxnr{\the\numexpr\foxnr+1}% + #3{##1}% + \gen@do##2\gen@nil + }% + \expandafter\gen@do\cpt@rsvda#1\gen@nil + \advance\cpt@foxdepth\m@one +} + \cptpopcatcodes \cptrestorecatcodes \declarefutureletset[fl@]{lbracket,star,rquote} -\shelllet\@ltx@warn\@latex@warning@no@line -\shelllet\@ltx@info\@latex@info@no@line -\shelllet\@ltx@err\@latex@error - \endinput %% End of file catoptions.sty %% |