diff options
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/latex/catoptions/catoptions-guide.pdf | bin | 447426 -> 452170 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/catoptions/catoptions-guide.tex | 138 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg | 59 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/catoptions/catoptions.sty | 1564 |
4 files changed, 1079 insertions, 682 deletions
diff --git a/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.pdf b/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.pdf Binary files differindex 0952cd13491..cb85c28fa4b 100644 --- a/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.pdf +++ b/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.pdf diff --git a/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.tex b/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.tex index 41002076fdb..5037a01e1bb 100644 --- a/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.tex +++ b/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.tex @@ -21,14 +21,12 @@ \begin{frontmatter} \title{The \texttt{\color{blue}catoptions} Package\titleref{t1,t2}} \titlenotes[t1,t2]{% - The package is available at \iftogTF{pdf}{\url{\@titleurl}} - {\url{\@shorttitleurl}}.\sep + The package is available at \url{\titleurltext}.\sep This manual doesn't, as yet, explain all the currently available features and commands of the \pkg'{catoptions}. This manual continues to evolve, but many of the available functions will appear in the user guide of the forthcoming \pkg'{ltxtools}. } -\version{0.2.5} +\version{0.2.6} \titleurl{http://www.ctan.org/tex-archive/macros/latex/contrib/catoptions/} -\shorttitleurl{http://www.ctan.org/} \author{Ahmed Musa \Email{amusa22@gmail.com}\\Preston, Lancashire, UK} \def\abstractname{\textsf{Summary}} @@ -43,7 +41,7 @@ \xwmcolorbox[textalign=justified, outerframecolor=blue, innerframecolor=orange, width=.985\hsize]{% This work (\ie, all the files in the \pkg'{catoptions} bundle) may be distributed and/or modified under the conditions of the \lppl, either version~1.3 of this license or any later version. - The \lppl maintenance status of this software is _{author-maintained}. This software is provided _{as it is}, without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. + The \lppl maintenance status of this software is \quoted{author-maintained}. This software is provided \quoted{as it is}, without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. \endgraf \centerline{\makered{\CopyrightYear}}\vspace{-.8\baselineskip}\relax } @@ -60,6 +58,16 @@ \lletter{M}{y motivation} for turning to the \pkgg'{pcatcode} was to save myself the trouble of declaring category codes at the beginning of my packages. After spending some time on the \pkgg'{pcatcode}, I discovered I had learnt enough to make changes and additions to some of its macros and functionality. After completing the catcode stuff in the \pkg'{catoptions}, I wanted to pass options to the package. If the package is to be loaded on top of other packages, as intended, then its options parsing scheme should be independent of other packages. But realizing the trouble with passing expandable option values to packages and classes via the \latex kernel's scheme, I decided to implement modifications to the kernel's options parser. Apart from the problem of premature expansion of options and values by the \latex kernel, outer curly braces in option values are lost during parsing. Indeed, the kernel's option parsing scheme doesn't recognize option values indicated with the equality sign. +\docsection(sec:packageloading){Loading the package} + +\deffnote{1}{% + The user interfaces of \ffx'{\XDeclareOption, \XExecuteOptions, \XProcessOptions} are similar to those of \hhx'{\DeclareOption, \ExecuteOptions, \ProcessOptions} but they aren't the same. See \amref{sec:options-parse}. +} +The \pkg'{catoptions} can be loaded in class and style files and in documents (before or after \hx{\documentclass}) with the options described in \amref{sec:pkg-options}. If the package is loaded before \hx{\documentclass}, it will, by default, use the options parser of the package in place of \latex's options parsing scheme (namely, the more robust commands \ffx'{\XDeclareOption, \XExecuteOptions, \XProcessOptions} in place of \latex's native commands \hhx'{\DeclareOption, \ExecuteOptions, \ProcessOptions})\usefnote{1}. In that case, the legacy commands \hhx'{\DeclareOption, \ExecuteOptions, \ProcessOptions} are aliased to \ffx'{\XDeclareOption, \XExecuteOptions, \XProcessOptions}, respectively. The latter set of commands do immediately recognize that they have to deal with option functions that are based on the kernel's syntax and semantics. This allows expandable options and option values (together with options with spaces in their names) to be passed via \hx{\documentclass}---if \pkg{catoptions} is loaded before \hx{\documentclass}. This also implies that existing packages can use the options parsing scheme of \pkg'{catoptions} without modifying the packages. + +However, if after loading \pkg'{catoptions} before \hx{\documentclass} the user still wants to use the legacy commands \hhx'{\DeclareOption, \ExecuteOptions, \ProcessOptions}, the package option \fx{usepox} (see \amref{sec:pkg-options}) can be toggled to \texttt{false}. In this case, option values can't be passed via \hx{\documentclass}. More precisely, option values passed via \hx{\documentclass} are stripped off internally by \pkg{catoptions} so that they may be processed by \hx{\ProcessOptions}. + + \docsection(sec:pkg-options)<Package options>{Package options} \lletter{T}{he} \pkg'{catoptions} has the options shown in \amref{tab:pkgoptions}. The boolean option \fxim{verbose} instructs the package to enter information onto the log file when some events happen (\eg, when commands are redefined by means of, say, the command \fx{\robust@redef}, which has the same syntax with \tex's legacy \hx{\def}; and when an option from the same family is multiply submitted to, say, \fx{\XExecuteOptions}). This option may be used in the future to provide debugging features for the package. @@ -81,16 +89,13 @@ \endlastfoot \fx{verbose} & \hx{false} & The global boolean switch that determines if information should be logged for some tasks in the package.\\\hline \fx{usepox} & \hx{true} & The boolean switch that determines if the options parser of \pkgg{catoptions} should be used for all options processing of packages loaded after \hx{\documentclass} even if those packages are based on \usecsn{latex2e}'s native options processing scheme.\\\hline -\fx{kernelifnextchar} & \hx{true} & The boolean option that determines if the package uses \fxim{\ifnextcharTF} or \hxi{\kernel@ifnextchar}; the former is based on an idea of Donald Arseneau, which allows even active characters to appear \quoted{as the next character}, but it is costlier than the latter.\\\hline \end{tabularx} -If the \pkg'{catoptions} is loaded before \hx{documentclass}, it will invariably use the options processing mechanism of the package (namely, the more robust commands \ffx'{\XDeclareOption, \XExecuteOptions, \XProcessOptions} in place of \latex's native commands \hhx'{\DeclareOption, \ExecuteOptions, \ProcessOptions})\footnote{The user interfaces of \ffx'{\XDeclareOption, \XExecuteOptions, \XProcessOptions} are similar to those of \hhx'{\DeclareOption, \ExecuteOptions, \ProcessOptions} but they aren't the same. See \amref{sec:options-parse}.}. In that case, the legacy commands \hhx'{\DeclareOption, \ExecuteOptions, \ProcessOptions} are aliased to \ffx'{\XDeclareOption, \XExecuteOptions, \XProcessOptions}, respectively. The latter set of commands do immediately recognize that they have to deal with option functions that are based on the kernel's semantics. This allows expandable options and option values (together with options with spaces in their names) to be passed via \hx{\documentclass}---if \pkg{catoptions} is loaded before \hx{\documentclass}. This also implies that existing packages can use the options parsing scheme of \pkg'{catoptions} without modifying the packages. +As noted in \amref{sec:packageloading}, if the \pkg'{catoptions} is loaded before \hx{\documentclass} it will invariably use the options processing mechanism of the package. In that case (of the package being loaded before \hx{\documentclass}), the option \fxim{usepox} directs the package to use the \pkg{catoptions}'s options processing scheme for all the packages loaded after \hx{\documentclass}, instead of \latex's native options parsing procedures. This allows \pkg{catoptions}'s options parsing scheme to be used for existing packages loaded after \hx{\documentclass} without modifying the packages. -The option \fxim{usepox} directs the package to use the \pkg{catoptions}'s options processing scheme for all the packages loaded after \hx{\documentclass}, instead of \latex's native options parsing procedures. This allows \pkg{catoptions}'s options parsing scheme to be used for existing packages loaded after \hx{\documentclass} without modifying the packages. +Assuming that the options \quotedtt{textstyle} and \quotedtt{name} belong to an existing package (say, \quotedtt{mypackage}) to be loaded later, then the following example demonstrates one feature of the \pkg'{catoptions}, in the case in which the package is loaded before \hx{\documentclass}: -Assuming that the options \quotedtt{textstyle} and \quotedtt{name} belong to an existing package (say, \quotedtt{mypackage}) to be loaded later, then the following example demonstrates one feature of the \pkg'{catoptions}: - -\start{example}[] +\start{example}[Loading catoptions before \documentclass] \RequirePackage[verbose, usepox]{catoptions} \documentclass[textstyle=\ttfamily,name={Mr X\"avier Sanchez},a4paper, draft,10pt]{article} @@ -98,6 +103,8 @@ Assuming that the options \quotedtt{textstyle} and \quotedtt{name} belong to an \finish{example} \fxim*{\RequirePackage,\usepackage,\documentclass} +If the \pkg'{catoptions} wasn't loaded before \hx{\documentclass} then the above example would fail, because \latex's option parser can't handle options with values (much less values with expandable tokens). + \docsection(sec:saving-catcodes){Saving and restituting category codes} @@ -114,11 +121,13 @@ There are the following user commands for saving and returning category codes of \fxim*{\UseNormalCatcodes,\cptpushcatcodes,\cptpopcatcodes, \cptnormalcatcodes,\cptfutureletsetup,\GetCurrentCatcodeSubset} -The command \fx{\cptnormalcatcodes} simply resets the category codes of all \otherchars together with those of the space character and \fx{\^^I} and \fx{\^^J} to their standard values. The command \fx{\cptpushcatcodes} pushes the current category codes for restitution later with \fx{\cptpopcatcodes}. The command \fx{\UseNormalCatcodes} works only in packages and does more than one thing: it calls \ffx'{\cptpushcatcodes, \cptnormalcatcodes,\cptfutureletsetup} in that order. At the end of the package, it automatically issues \fx{\cptpopcatcodes} to recover all the category codes earlier pushed. The command \fx{\UseNormalCatcodes} can conveniently be issued at the start of the package and the developer can be assured of access to the standard category codes of all \otherchars together with those of the space character and \fx{\^^I} and \fx{\^^J}. It should be called only once in a package: subsequent calls will have no effect. +The command \fx{\cptnormalcatcodes} simply resets the category codes of all \otherchars together with those of the space character and \fx{\^^I} and \fx{\^^J} to their standard values. The \hx{\endlinechar} is also reset to its normal value by this command. The command \fx{\cptpushcatcodes} pushes the current category codes for restitution later with \fx{\cptpopcatcodes}. + +The command \fx{\UseNormalCatcodes} works only in packages and does more than one thing: it calls \fx{\cptpushcatcodes} (to save the prevailing category codes) and then \fx{\cptnormalcatcodes} (to enforce the standard category codes). At the end of the class file or package, it automatically issues \fx{\cptpopcatcodes} to recover all the category codes earlier pushed. The command \fx{\UseNormalCatcodes} can conveniently be issued at the start of the package and the developer can be assured of access to the standard category codes of all \otherchars together with those of the space character and \fx{\^^I} and \fx{\^^J}. It should be called only once in a package: subsequent calls within the same package will have no effect. After issuing the command \fx{\GetCurrentCatcodeSubset}, you can do -\start{example}[] +\start{example}[\currentcatcodesubset] \show\currentcatcodesubset \finish{example} \fxim*{\currentcatcodesubset} @@ -130,22 +139,37 @@ to see the current catcode setup. The command \fx{\cptfutureletsetup} is describ \NeedsTeXFormat{LaTeX2e}[1995/12/01] \RequirePackage[verbose, usepox]{catoptions} \UseNormalCatcodes +|com(At the end of `mypackage' all the category codes pushed by) +|com(\UseNormalCatcodes will automatically be popped.) \finish{example} \dummyfxi*{\UseNormalCatcodes} -\docsection(sec:future-letting){Future-letting of \headq{other} characters} +\docsection(sec:future-letting){Future-letting of \headqtd{other} characters} The command \fx{\cptfutureletsetup} defines canonical control sequences to represent the following characters: -\start'{example}[Futurelet characters] -space|R(|textvisiblespace) exclam|R(!) dblquote|R(") hash|R(#) dollar|R($) ampersand|R(|ampersand) -lrquote|R(') lparen|R(|() rparen|R(|)) star|R(*) plus|R(+) comma|R(,) hyphen|R(-) period|R(.) -slash|R(/) colon|R(:) semicolon|R(;) less|R(<) equal|R(=) greater|R(>) question|R(?) lbracket|R([) -rbracket|R(]) hat|R(^) underscore|R(_) lquote|R(`) lbrace|R({) vert|R(|rv) rbrace|R(}) tilde|R(~) -bslash|R(\) -\finish{example} -\dummyfxim*{\cptfutureletsetup} +$$\vbox{% + \def\newvrule{% + \ifnum\@tempcnta<\@vpt + \global\@tempcnta\numexpr\@tempcnta+1\relax + \textcolor{blue}{\vrule}% + \fi + }% + \noindent\everycr{\noalign{\global\@tempcnta\z@}}% + \@tempcnta\z@\tabskip=1em + \halign{% + &\strut#\hfil&\hfil\textcolor{red}{\tt#}\hskip.25em\newvrule\cr + space&\textvisiblespace& exclam&!&dblquote&"&hash&\#& dollar&\$& + ampersand&\&\cr + lquote&`& rquote&'& lparen&(& rparen&)& star&$*$& plus&+\cr + comma&,& hyphen&-&period&.&slash&/& colon&:& semicolon&;\cr + less&<&greater&>&equal&=& question&?& lbracket&[& rbracket&]\cr + hat&\char`\^& underscore&\char`\_& bslash&\char`\\& + lbrace&\char`\{& rbrace&\char`\}& vert&|\cr + tilde&\char`~\cr + }% +}$$ However, for efficiency reasons, the canonical control sequences will be defined for only the characters (or their names) appearing in the user-supplied list \fx{\declarefutureletset}, whose syntax is @@ -171,10 +195,10 @@ For instance, with the choices we have the following commands on hand for testing after \fx{\futurelet}: -\start+{newmacro}[Futurelet commands] +\start+{example}[Futurelet commands] \fl@space \fl@star \fl@lbracket \iffl@space \iffl@star \iffl@lbracket -\finish{newmacro} +\finish{example} \aidx*{Futurelet commands} If any of the commands emanating from concatenating \ang{stub} with the name of the character is already defined, an error message is flagged. It should be noted that these commands are available only after issuing the command \fx{\cptfutureletsetup}, which isn't called automatically anywhere by the \pkg'{catoptions}. Normally, at \hx{\AtBeginDocument} the \pkg'{catoptions} calls the command \fx{\cptrestorecatcodes}, without calling \fx{\cptfutureletsetup}. Calling \ffx'{\declarefutureletset, \cptfutureletsetup} is the user's duty. @@ -212,7 +236,7 @@ where \quotedtt{all} means that control sequences should be defined for all the This will yield control sequences that may never be needed. While such a facility does exist, using it will be inefficient despite the large capacities of many modern \tex engines. -The use syntaxes for the commands \fnl{{stub}{char}} and \fnl{{if}{stub}{char}} are as follows: +The use syntaxes for the commands \fnl*'\bs{stub,char} and \fnl*'{\bs if}{stub,char} are as follows: \start{example}[Futurelet characters] \futurelet\next\cmd |textbf(|R(*)) @@ -285,20 +309,24 @@ The \unstform of the macro \fx{\XDeclareOption} declares an option that can be u \start{example}[\XDeclareOption] \ProvidesPackage{mypackage}[\StyleFileInfo] -\newif\ifmybool +\cptnewbool{mybool} \XDeclareOption{mybool}[true]{\@nameuse{mybool#1}} \XDeclareOption{leftmargin}[.5\hsize]{\setlength\leftmargin{#1}}|xwmlabel(mac:leftmargin) \finish{example} -The options \ffx'{mybool,leftmargin} could then be called via any of the following statements: +\deffnote{2}{% + The commands \ffx'{\XDeclareBooleanOption, \XDeclareBooleanOptions, \XDeclareBiBooleanOptions} allow the user to define new boolean options without the need to first initialize the booleans with \hx{\newif} or \fx{\cptnewbool} as seen here. +} + +The user would have noticed the use \fx{\cptnewbool} in the above example\usefnote{2}. The options \ffx'{mybool,leftmargin} could then be called via any of the following statements: \start{example}[\XDeclareOption] |com(Inside class or package files:) -\RequirePackage[mybool=true,leftmargin=20\p@]{mypackage} +\RequirePackage[mybool=true,leftmargin=20pt]{mypackage} |com(Inside document file:) -\usepackage[mybool=false,leftmargin=20\p@]{mypackage} +\usepackage[mybool=false,leftmargin=20pt]{mypackage} |com(Via document class:) -\documentclass[mybool,leftmargin=20\p@]{myclass} +\documentclass[mybool,leftmargin=20pt]{myclass} \finish{example} The \stform of the macro \fx{\XDeclareOption} can be used to process unknown options. It is similar to \latex's \hx{\DeclareOption}\RedStar, but it has additional features. You can deploy \hx{\CurrentOption} within the \ang{fn} of this macro to access the option name and value for which the option is unknown. These values (possibly including an option) could, for example, be passed on to another class or package or could be used as an extra class or package option that, for instance, specifies a style that should be loaded. Moreover, you can use \fx{#1}, \fx{#2} and \fx{#3} within \ang{fn} to refer to the current family, current option (without its value), and current value, respectively. @@ -310,7 +338,11 @@ The \stform of the macro \fx{\XDeclareOption} can be used to process unknown opt \finish{newmacro} \fxim*{\XUnknownOptionHandler} -The command \fx{\XUnknownOptionHandler} can be used in place of \xdecs to specify default action(s) for options undefined in any family in \ang{fams}\footnote{Declaring a default handler for each unknown option is, of course, inefficient. We have therefore provided provisions for declaring such handers for only families of options.}. \ang{handler} refers to the default function that should be executed if undeclared options are called from families \ang{fams} by the user. \hx{\CurrentOption} can be deployed within \ang{handler} to access the option name (coupled with its current value) for which the option name is unknown. As mentioned above in the case of \xdecs, you can use \fx{#1}, \fx{#2} and \fx{#3} within \ang{handler} to access the current family, current option (uncoupled from its current value), and current value, respectively. \ang{na} is the list of options for which \ang{handler} shouldn't apply; for these options, the kernel's unknown option handler (\ie, \hx{\default@ds}) would apply. +\deffnote{3}{% + Declaring a default handler for each unknown option is, of course, inefficient. + We have, therefore, provided provisions for declaring such handers for only families of options. +} +The command \fx{\XUnknownOptionHandler} can be used in place of \xdecs to specify default action(s) for options undefined in any family in \ang{fams}\usefnote{3}. \ang{handler} refers to the default function that should be executed if undeclared options are called from families \ang{fams} by the user. \hx{\CurrentOption} can be deployed within \ang{handler} to access the option name (coupled with its current value) for which the option name is unknown. As mentioned above in the case of \xdecs, you can use \fx{#1}, \fx{#2} and \fx{#3} within \ang{handler} to access the current family, current option (uncoupled from its current value), and current value, respectively. \ang{na} is the list of options for which \ang{handler} shouldn't apply; for these options, the kernel's unknown option handler (\ie, \hx{\default@ds}) would apply. If the \ang{handler} contains the special literal form \fx{define/.code=} as in @@ -417,7 +449,7 @@ The command \fx{\XInvalidOptionHandler} defines, for each family \ang{fam} in \a \finish{newmacro} \fxim*{\XDeclareCommandOption} -The command \fx{\XDeclareCommandOption} will, apart from declaring the option \ang{opt}, also create a macro \fnl{{pref}{opt}} to hold the user-supplied value of the option. The macro so created can be used in \ang{fn} or in any other place. The default value of the optional \ang{pref} is \quotedFx{\@currname @} prefixed with the letters \fx{cmd}. +The command \fx{\XDeclareCommandOption} will, apart from declaring the option \ang{opt}, also create a macro \fnl*'\bs{pref,opt} to hold the user-supplied value of the option. The macro so created can be used in \ang{fn} or in any other place. The default value of the optional \ang{pref} is \quotedFx{\@currname @} prefixed with the letters \fx{cmd}. \start{newmacro}[\XDeclareCommandOptions] \XDeclareCommandOptions<|nang(fam)>{|nang(opts)}[|nang(default)]|(|nang(pref)|){|nang(fn)} @@ -432,7 +464,7 @@ The command \fx{\XDeclareCommandOptions} is similar to \fx{\XDeclareCommandOptio \finish{newmacro} \fxim*{\XDeclareBooleanOption} -The command \fx{\XDeclareBooleanOption} will, apart from declaring the option \ang{opt}, also create a boolean \fnl{{if}{pref}{opt}}. It will automatically toggle this boolean (to \hx{true} or \hx{false}) when the option is set and the input is valid, depending on the user-supplied value of the option. The macros so created can be used in \ang{fn} or in any other place. The default value of the optional \ang{pref} is \quotedFx{\@currname @} with no additional prefix. Only \hx{true} or \hx{false} may be submitted as the value of a boolean option. +The command \fx{\XDeclareBooleanOption} will, apart from declaring the option \ang{opt}, also create a boolean \fnl*'{\bs if}{pref,opt}. It will automatically toggle this boolean (to \hx{true} or \hx{false}) when the option is set and the input is valid, depending on the user-supplied value of the option. The macros so created can be used in \ang{fn} or in any other place. The default value of the optional \ang{pref} is \quotedFx{\@currname @} with no additional prefix. Only \hx{true} or \hx{false} may be submitted as the value of a boolean option. \start{newmacro}[\XDeclareBooleanOptions] \XDeclareBooleanOptions<|nang(fam)>{|nang(opts)}[|nang(default)]|(|nang(pref)|){|nang(fn)} @@ -463,7 +495,10 @@ In the parlance of the \pkg'{catoptions,ltxtools}, a switch can assume only one \finish{newmacro} \fxim*{\ifswitchTF,\ifswitchFT} -Note that here \ang{switch} has no escape character, unless it evaluates to a switch name. So, after defining \fx{\def\swa{00}} we could then do \fx{\ifswitchTF{swa}{true}{false}}. It is somewhat risky to introduce new switches with \hx{\def} or \hx{\let}\footnote{Because of the need to do, \eg, \fx{\let\swa\cpttrue} and \hx{\if}\unskip\fx{\swa} for any given switch \fx{\swa}, switches, unlike toggles, don't have their own separate name space and it is all too easy to redefine an existing switch.}. It is advisable to use \fx{\newswitch} instead. It has the syntax +\deffnote{4}{% + Because of the need to do, \eg, \fx{\let\swa\cpttrue} and \hx{\if}\unskip\fx{\swa} for any given switch \fx{\swa}, switches, unlike toggles, don't have their own separate namespace and it is all too easy to redefine an existing switch. +} +Note that here \ang{switch} has no escape character, unless it evaluates to a switch name. So, after defining \fx{\def\swa{00}} we could then do \fx{\ifswitchTF{swa}{true}{false}}. It is somewhat risky to introduce new switches with \hx{\def} or \hx{\let}\usefnote{4}. It is advisable to always use \fx{\newswitch} instead. It has the syntax \start{newmacro}[\newswitch] \newswitch{|nang(switch)}[|nang(state)] @@ -484,7 +519,7 @@ It is possible to toggle the state of a switch by simply using the commands: \finish{newmacro} \fxim*{\setswitchtrue,\setswitchfalse} -The command \fx{\XDeclareSwitchOption} will, apart from declaring the option \ang{opt}, also create a switch \fnl{{pref}{opt}}. It will automatically toggle this switch to \hx{true} (equivalent to \fx{00}) or \hx{false} (equivalent to \fx{01}) when the option is set and the input is valid, depending on the user-supplied value of the option. The macros so created can be used in \ang{fn} or in any other place. The default value of the optional \ang{pref} is again \quotedFx{\@currname @} with no additional prefix. Only \hx{true} or \hx{false} may be submitted as the value of a switch option. +The command \fx{\XDeclareSwitchOption} will, apart from declaring the option \ang{opt}, also create a switch \fnl*'\bs{pref,opt}. It will automatically toggle this switch to \hx{true} (equivalent to \fx{00}) or \hx{false} (equivalent to \fx{01}) when the option is set and the input is valid, depending on the user-supplied value of the option. The macros so created can be used in \ang{fn} or in any other place. The default value of the optional \ang{pref} is again \quotedFx{\@currname @} with no additional prefix. Only \hx{true} or \hx{false} may be submitted as the value of a switch option. \start{newmacro}[\XDeclareSwitchOptions] \XDeclareSwitchOptions<|nang(fam)>{|nang(opts)}[|nang(default)]|(|nang(pref)|){|nang(fn)} @@ -697,8 +732,8 @@ Here are some points to note about these list processors: \item Since \ffx'{\csv@@loop,\kv@@loop} don't call the normalizer, they preserve outer/surrounding spaces in the entries. Empty entries in \ang{list} or \ang{listcmd} will be processed by \ffx'{\csv@@loop,\kv@@loop} if the boolean \fx{cpt@useempty} is true. You may thus issue the command \fx{\UseEmptyEntry} or \fx{\DiscardEmptyEntry}, which are based on the boolean \fx{cpt@useempty}, before commencing the iteration. If empty entries are important to the task at hand, then issuing \fx{\UseEmptyEntry} or \fx{\DiscardEmptyEntry} prior to the commencement of the loop is recommended, because a previous call to either \fx{\csv@@loop} or \fx{\kv@@loop} (perhaps by another package) could have set \fx{cpt@useempty} to a state that is no longer valid or desired. \item The commands \ffx'{\csv@@loop,\csv@@parse,\kv@@loop,\kv@@parse} will execute at least once for empty \ang{list} or \ang{listcmd}. \item The commands \ffx'{\csv@@loop,\csv@@parse,\kv@@loop,\kv@@parse} can be nested to any level and can be mixed. -\item In the commands \ffx'{\csv@@loop,\csv@@parse,\kv@@loop,\kv@@parse}, it is always possible to break out of the loop prematurely at any level of nesting, simply by issuing the command \fx{\loopbreak} (see the example below). Breaking an inner loop doesn't affect the continuation of the outer loop, and vice versa; that is, loop breaks are nesting level-dependent. -\item The user can insert \fx{\csvbreak} as an element in \ang{list} for any of the commands \ffx'{\csv@@loop, \csv@@parse, \kv@@loop, \kv@@parse, \dofunclist} with the hope of automatically breaking out of the list processing prematurely (\ie, before the list is exhausted). The tokens \ffx'{\listbreak, \breaklist} are not defined or used by the \pkg'{catoptions}, to avoid name clashes with other packages. The \pkg'{catoptions} instead uses \fx{\csvbreak}, which is an unexpandable token; if it were to be expandable, then experience has shown that a chaotic infinite loop could arise in an expansion context. Breaking out of the loop prematurely on the current nesting level doesn't affect the continuation of the loop on the other levels. +\item In the commands \ffx'{\csv@@loop,\csv@@parse,\kv@@loop,\kv@@parse}, it is always possible to break out of the loop prematurely at any level of nesting, simply by issuing the command \fx{\loopbreak} (see the example below). Breaking an inner loop doesn't affect the continuation of the outer loop, and vice versa; that is, loop breaks are nest-level-dependent. +\item The user can insert \fx{\csvbreak} as an element in \ang{list} for any of the commands \ffx'{\csv@@loop, \csv@@parse, \kv@@loop, \kv@@parse, \dofunclist} with the hope of automatically breaking out of the list processing prematurely (\ie, before the list is exhausted). The tokens \ffx'{\listbreak, \breaklist} are not defined or used by the \pkg'{catoptions}, to avoid name clashes with other packages. The \pkg'{catoptions} instead uses \fx{\csvbreak}, which is an unexpandable token; if it were to be expandable, then experience has shown that a chaotic infinite loop could arise in an expansion context. Breaking out of the loop prematurely on the current nest level doesn't affect the continuation of the loop on the other levels. \end{enum} \start{example}[\csv@@parse] @@ -788,22 +823,22 @@ Empty entries in \ang{list} will be ignored by the normalizer called by \fx{\dof |com(Let us load many packages compactly here. This is just an example of) |com(|fx(\dofunclist); you can instead use the more appropriate command) |com(|fx(\cptloadpackages) to load packages (see |amref(mac:loadpkg)):) -\def\do#1#2[#3]{% +\def\do#1.#2[#3]{% \@ifpackageloaded{#1}{% \@ifpackagelater{#1}{#2}{}{% \cpt@warn{Older version of package `#1' loaded earlier}% }% }{% - \usepackage[#3]{#1}[#2]% + \cptexpandsecond\usepackage{[\cpttrimspaces{#3}]}{#1}[#2]% }% } |com(The default parser |(,|) is implied below:) \dofunclist{% - {yfonts}{2003/01/08}[], - {pifont}{2005/04/12}[], - {helvet}{2005/04/12}[scaled=0.9], - {zref}{2008/10/01}[user,lastpage], - {xcolor}{2007/01/21}[table,hyperref] + yfonts.2003/01/08[], + pifont.2005/04/12[], + helvet.2005/04/12[scaled=0.9], + zref.2008/10/01[|R({)user,lastpage|R(})], + xcolor.2007/01/21[|R({)table,hyperref|R(})] } |com(An example of nested loops follows. Here outer braces in the) @@ -822,7 +857,7 @@ Empty entries in \ang{list} will be ignored by the normalizer called by \fx{\dof \dofunclist[,]{a,{b},c,d,e} \finish{example} -While \fx{\dofunclist} allows the user to define and call multi-parametered \fx{\do} functions, outer curly braces in the \emph{individual} arguments of \fx{\do} may, in some rare cases, be lost in parsing (but only if the number of arguments exceeds one). This possibility depends on how the parameters and arguments of the user-supplied command \fx{\do} are arranged. If preserving braces is essential to the user's need, then he/she might consider using the more robust commands \ffx'{\csv@@loop, \csv@@parse, \kv@@loop, \kv@@parse}. It is possible to robustly build a multi-parametered callback in the user-defined commands \ffx'{\csv@do,\kv@do} required by \ffx'{\csv@@loop, \csv@@parse, \kv@@loop, \kv@@parse}. Admittedly, only experienced \texnicians may be able to do that. +While \fx{\dofunclist} allows the user to define and call multi-parametered \fx{\do} functions, outer curly braces in the \emph{individual} arguments of \fx{\do} may, in some rare cases, be lost in parsing (but only if the number of arguments exceeds one). This possibility depends on how the parameters and arguments of the user-supplied command \fx{\do} are arranged. If preserving braces is essential to the user's need, then he/she might consider using the more robust commands \ffx'{\csv@@loop, \csv@@parse, \kv@@loop, \kv@@parse}. It is possible to robustly build a multi-parametered callback in the user-defined commands \ffx'{\csv@do,\kv@do} required by \ffx'{\csv@@loop, \csv@@parse, \kv@@loop, \kv@@parse}. In fact, this is what \fx{\dofunclist} does internally. Admittedly, only experienced \texnicians may be able to do that. \docsubsection(sec:indris){Looking ahead in csv lists} @@ -839,11 +874,11 @@ Imagine an instance in which, while processing a csv list, you need not only the The \fx{\indrisloop} command can be used to iterate over a \ang{parser}-separated \ang{list} or \ang{listcmd} and execute the user-supplied one-parameter command \ang{fn} for every item in the list, passing the item as an argument and preserving outer braces. -The \fx{\indrisloop} iterator is of particular interest. The loop provides the macros \ffx'{\indrisdepth, \currindris, \currindris@i, \nextindris, \nextindris@i, \indrisnr, \iflastindris, \ifloopbreak}, which mean, respectively, the current nesting depth/level, the current item on the current level, the current item on an arbitrary level \quotedfx{i}, the next item on the current level, the next item on an arbitrary level \quotedfx{i}, the numerical order of the current item on the current level, the boolean that indicates that the last item of the list has been reached on the current level of nesting, and the boolean that can be used to break the loop prematurely (before the list is exhausted) on any level. +The \fx{\indrisloop} iterator is of particular interest. The loop provides the macros \ffx'{\indrisdepth, \currindris, \currindris@i, \nextindris, \nextindris@i, \indrisnr, \iflastindris, \ifloopbreak}, which mean, respectively, the current nested depth/level, the current item on the current level, the current item on an arbitrary level \quotedfx{i}, the next item on the current level, the next item on an arbitrary level \quotedfx{i}, the numerical order of the current item on the current level, the boolean that indicates that the last item of the list has been reached on the current level of nesting, and the boolean that can be used to break the loop prematurely (before the list is exhausted) on any level. You can do \fx{\iflastindris...\fi} on any level. On any given level, it is possible to break out of the current loop by simply issuing \fx{\loopbreak}. This would not affect the progress of the loops on other levels. When \fx{\iflastindris} is true on a given level \quotedfx{i}, then \ffx'{\nextindris,\nextindris@i} are empty on that level, but not necessarily the macros \ffx'{\currindris,\currindris@i}. -The following provides a simple application of \fx{\indrisloop}, which I posted on \href{https://groups.google.com/forum/#!forum/comp.text.tex}{comp.text.tex} in July~2011. +The following provides a simple application of \fx{\indrisloop}, which I posted on \comptexttex in July~2011 in response to a posted question. \start{example}[\indrisloop] \makeatletter @@ -894,7 +929,7 @@ The following provides a simple application of \fx{\indrisloop}, which I posted \finish{example} %\bigskip -\docsection(sec:tsvparse)<Iterating tokenwise>{Parsing \headq{tsv} lists} +\docsection(sec:tsvparse)<Iterating tokenwise>{Parsing \headqtd{tsv} lists} \start+{newmacro}[\tsv@@parse,\tsv@@loop] \tsv@@loop{|nang(list)} @@ -934,6 +969,9 @@ In the commands \ffx'{\tsv@loop,\tsv@@parse}, it is always possible to break out The following change history highlights significant changes that affect user utilities and interfaces; mutations of technical nature are not documented in this section. The numbers on the right-hand side of the following lists are section numbers; the \stsign means the subject features in the package but is not reflected anywhere in this user guide. \begin{versionhist} + \begin{version}{0.2.6}{2011/09/10} + \item Bug fix in the command \fx{\UseNormalCatcodes} \vsecref{sec:saving-catcodes} + \end{version} \begin{version}{0.2.5}{2011/07/20} \item Enlarged the command \fxi{\newvariables} to include \hx{\newwrite} and \fx{\newswitch} \vsecref* \end{version} @@ -945,7 +983,7 @@ The following change history highlights significant changes that affect user uti \end{version} \begin{version}{0.2b}{2011/04/02} - \item The following commands have been introduced \vsecref{sec:options-parse} + \item The following commands were introduced \vsecref{sec:options-parse} \start{veritem} \XDeclareInvalidOptions \XUnknownOptionHandler \XDisableOptions \XLogDisabledOptions \ifoptdisabledTF \ifoptdefTF @@ -954,7 +992,7 @@ The following change history highlights significant changes that affect user uti \begin{version}{0.2a}{2011/02/15} \item For efficiency reasons, canonical control sequences for futurelet characters are no longer defined automatically. The user is now responsible for specifying the canonical control sequences that should be defined \vsecref{sec:future-letting} - \item The following plural-form commands have been introduced \vsecref{sec:options-parse} + \item The following plural-form commands were introduced \vsecref{sec:options-parse} \start{veritem} \XDeclareOptions \XDeclareCommandOptions \XDeclareBooleanOptions \XDeclareBiBooleanOptions diff --git a/Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg b/Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg index 9103717cd8d..5a7153b4ca9 100644 --- a/Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg +++ b/Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg @@ -1,5 +1,5 @@ \ProvidesFile{catoptions-guide.cfg}% - [2011/07/30 v0.2.5 Configuration file for catoptions-guide.tex (AM)] + [2011/09/10 v0.2.6 Configuration file for catoptions-guide.tex (AM)] \cptloadpackages{% xwatermark|printwatermark; @@ -10,44 +10,41 @@ \keepXColumns \fancypagenos[% - show-on-page-one = false, - show-page-numbers = true, - show-headrule = true, - show-footrule = false, - y-position = -.45\paperheight, - x-position = 0, + showonpageone = false, + showpagenumbers = true, + showheadrule = true, + showfootrule = false, + yposition = -.45\paperheight, + xposition = 0, scale = 1, angle = 0, - left-header = {The \textcolor{maccolor}{catoptions} package}, - style = {\textsc{Page~\thepage~of~\pageref{xwmlastpage}}}, + left-header = The \textcolor{macrocolor}{catoptions} package, + style = \textsc{Page~\thepage~of~\pageref{xwmlastpage}}, right-header = \tcl{black}{\today} ] \amltxoptions{% - geometry-options = {left=3cm,right=3cm,top=2.5cm,% - bottom=2.5cm,includeheadfoot}, - review-document = false, - parindent = false, - toc = false, - front-page-style = empty, - pre-title-skip = 0ex, - post-title-skip = 1ex, - pre-suptitle-skip = 15ex, - post-suptitle-skip = 0ex, - pre-subtitle-skip = 0ex, - post-subtitle-skip = -\baselineskip, - load-natbib = {numbers,sort&compress}, - command-color = xmagenta1, - style-color = xgreen1, - special-color = teal, - section-heading-color = blue + geometryoptions = {left=3cm,right=3cm,top=2.5cm,% + bottom=2.5cm,includeheadfoot}, + reviewdocument = false, + parindent = false, + toc = false, + frontpagestyle = empty, + pretitleskip = 0ex, + posttitleskip = 1ex, + presuptitleskip = 15ex, + postsuptitleskip = 0ex, + presubtitleskip = 0ex, + postsubtitleskip = -\baselineskip, + loadnatbib = {numbers,sort&compress}, + cmdcolor = xmagenta1, + stylecolor = xgreen1, + speccolor = teal, + sectionheadcolor = blue } -\AfterStartOfDocument{\MakeQuoteCommand*_} \def\otherchars{\quoted{other} characters\sspace} \ltsnewletcs*\sectionbreak\medbreak -\ltsnewletcs\mccolor\makemaccolor -\ltsnewletcs\pucolor\makepurple -\AtBeginDocument{\redef*\thefootnote{\fnsymbol{footnote}}} +\AtBeginDocument{\renewdef*\thefootnote{\fnsymbol{footnote}}} \newwatermark [page=1,fontfamily=phv,fontsize=11pt,fontseries=m,textalign=center, @@ -71,7 +68,7 @@ by the kernel. Theoretically speaking, the \pkgg'{pcatcode} itself has to guard against the kind of catcode problems that it is intended to circumvent. If you would like a - nice little \tex\unskip nician's exercise, try your hand, before looking at the code of the + nice little \texnician's exercise, try your hand, before looking at the code of the \pkgg'{pcatcode}, at the task that I set for myself: find the minimal set of catcode assumptions that one has to make before attempting to establish normalcy, where normalcy is defined as the state at the end of the \latex kernel, just before the last diff --git a/Master/texmf-dist/tex/latex/catoptions/catoptions.sty b/Master/texmf-dist/tex/latex/catoptions/catoptions.sty index 9cda3633ae1..3c4e5f6c5f2 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.2.5, July 2011) % +% This is 'catoptions' package (Version 0.2.6, September 2011) % % % % The catoptions package changes LaTeX package loading internals % % so that all subsequently loaded packages can rely on having % @@ -85,14 +85,13 @@ \catcode94=7 \catcode126=13 \edef\cpt@hashchar{\string#} -% Just in case: \m@ne=-1\z@=0pt\p@=1pt \@ifdefinable\m@one{\newcount\m@one\m@one\m@ne} \@ifdefinable\z@pt{\newdimen\z@pt\z@pt\z@} \chardef\active=13 -\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\NeedsTeXFormat{LaTeX2e}[2005/12/01] \ProvidesPackage{catoptions} - [2011/07/30 v0.2.5 Securing catcodes and parsing options (AM)] + [2011/09/10 v0.2.6 Securing catcodes and parsing options (AM)] \ifcase% \ifx\eTeXversion\cpt@undefined\z@pt\else \ifnum\eTeXversion<\tw@\z@pt\else\@ne\fi\fi @@ -108,9 +107,10 @@ \newcommand*\MsgBrk{\MessageBreak} \def\cptloggingall{\loggingall\tracingifs\@ne} -\newcommand*\showcsn{} -\protected\def\showcsn#1{\expandafter\show\csname#1\endcsname} -\def\cptnormalcatcodes{% +\@ifdefinable\showcsn{% + \protected\def\showcsn#1#{\expandafter\show\csname#1\endcsname}% +} +\newcommand*\cptnormalcatcodes{% \endlinechar13 \catcode33=12\catcode34=12\catcode35=6\catcode36=3\catcode37=14 \catcode38=4\catcode39=12\catcode40=12\catcode41=12\catcode42=12 @@ -129,40 +129,47 @@ } \endgroup +\def\cpt@spcatcodestack{} +\def\cpt@sppushcatcodes{% + \edef\cpt@spcatcodestack{% + \catcode\number`\ =\the\catcode`\ % + \catcode\number`\^^I=\the\catcode`\^^I + \catcode\number\endlinechar=\the\catcode`\ + \endlinechar=\the\endlinechar + {\cpt@spcatcodestack}% + }% +} \newcommand*\BeginOverlookWhiteSpace{% - \pushnumber\overlook@nr - \ifnum\overlook@nr>\@ne + \pushnumber\cpt@overlooknr + \ifnum\cpt@overlooknr>\@ne \cpt@err{There is an unclosed \string\BeginOverlookWhiteSpace}\@ehc \fi - \chardef\sav@spacecatcode=\number\catcode`\ % - \chardef\sav@tabcatcode=\number\catcode`\^^I - \chardef\sav@endlinechar=\number\endlinechar + \cpt@sppushcatcodes \catcode`\ =9\relax \catcode`\^^I=9\relax \endlinechar\m@one } \newcommand*\EndOverlookWhiteSpace{% - \catcode`\ =\sav@spacecatcode - \catcode`\^^I=\sav@tabcatcode - \endlinechar\sav@endlinechar - \popnumber\overlook@nr + \def\reserved@a##1##{##1\xdef\cpt@spcatcodestack}% + \expandafter\reserved@a\cpt@spcatcodestack + \undefcs\cpt@overlooknr } \newcommand*\BeginOverlookEndline{% - \pushnumber\overlookendline@nr - \ifnum\overlookendline@nr>\@ne + \pushnumber\cpt@overlookendlinenr + \ifnum\cpt@overlookendlinenr>\@ne \cpt@err{There is an unclosed \string\BeginOverlookEndline}\@ehc \fi - \chardef\@sav@endlinechar=\number\endlinechar + \chardef\cpt@savendlinechar=\number\endlinechar \endlinechar\m@one } \newcommand*\EndOverlookEndline{% - \endlinechar\@sav@endlinechar - \popnumber\overlookendline@nr + \endlinechar\cpt@savendlinechar + \undefcs\cpt@overlookendlinenr } -\def\cpt@catcodestack{} -\def\cptpushcatcodes{% +\newcommand*\cpt@catcodestack{} +\newcommand*\cptpushcatcodes{% \begingroup \def\x##1{% \ifx##1\@nnil\else @@ -178,7 +185,7 @@ } \cptpushcatcodes \cptnormalcatcodes -\def\cptpopcatcodes{% +\newcommand*\cptpopcatcodes{% \begingroup \def\x##1##{\endgroup##1\xdef\cpt@catcodestack}% \expandafter\x\cpt@catcodestack @@ -200,12 +207,12 @@ }% \expandafter\endgroup\x } -\newcommand*\setup@safeactives@edef{% +\newcommand*\cpt@setupsafeactivesedef{% \begingroup \endlinechar\m@one \def\siso@do##1{\catcode`##1\string=\active}% \simpleexpandarg\siso@@loop\cpt@otherchars - \gdef\safe@actives@edef##1##2{% + \gdef\cptsafeactivesedef##1##2{% \begingroup \def\siso@do####1{% \ifnum\catcode`####1\string=\active\edef####1{\string####1}\fi @@ -338,14 +345,12 @@ } \endgroup -\@ifdefinable\CurrIfnextchar\relax \long\protected\def\cpt@ifnextchar#1#2#3{% \begingroup \let\reserved@a=#1% \toks@{\endgroup#2}\toks1{\endgroup#3}% \global\futurelet\@let@token\cpt@ifnext } -\let\CurrIfnextchar\cpt@ifnextchar \protected\def\cpt@ifnext{% \ifx\@let@token\@sptoken \toks2{\cpt@ifn@xt}% @@ -359,7 +364,7 @@ \the\toks2 } \@namedef{cpt@ifn@xt} {\global\futurelet\@let@token\cpt@ifnext} -\long\protected\def\ifnextcharTF#1#2#3{% +\newcommand\ifnextcharTF[3]{% \begingroup \cpt@ifnextchar\relax {\cpt@ifnextcharacter{#1}{#2}{#3}}% @@ -388,11 +393,21 @@ \long\def\cpt@ifn@xtch@r@cter#1#2\noboundary#3{% \ifx\relax#2#1\else\noexpand#3\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{\ifnextcharTF*{\@firstoftwo{#1}}} \newcommand\cptswap[2]{#2#1} \newcommand\cptswapfirstbraced[2]{#2{#1}} \newcommand\cptswapsecondbraced[2]{{#2}#1} \cptswap{ }{\let\cptsptoken= } \def\@space{ } +\@ifdefinable\ifsecondisnilTF\relax +\def\ifsecondisnilTF#1#2\cpt@nil{\ifxTF#2\cpt@nnil} +\newcommand\iflacus[1]{% + \ifcat$\detokenize\expandafter{\@gobble#1.}$% + \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi +} \newcommand\aftercsname[2]{% \expandafter\cptswap\expandafter{\csname#2\endcsname}{#1}% } @@ -402,21 +417,19 @@ \expandafter\expandafter\expandafter{\csname#2\endcsname}{#1}% } \newcommand\cptremovescape[1]{% - \ifx\noboundary#1\noboundary - \expandafter\@gobble\else\expandafter\@iden\fi - {\expandafter\@gobble\string#1}% + \iflacus{#1}{}{\expandafter\@gobble\string#1}% } \newcommand\cptgobblescape[1]{% - \ifx\noboundary#1\noboundary - \expandafter\@gobble\else\expandafter\@iden\fi - {\ifnum\escapechar>\@cclv\else - \ifnum\escapechar<\z@pt\else - \expandafter\expandafter - \csname @gobble\ifnum\escapechar=\@xxxii @space\fi - \cptthreexp\endcsname + \iflacus{#1}{}{% + \ifnum\escapechar>\@cclv\else + \ifnum\escapechar<\z@pt\else + \expandafter\expandafter + \csname @gobble\ifnum\escapechar=\@xxxii @space\fi + \cptthreexp\endcsname + \fi \fi - \fi - \string#1}% + \string#1% + }% } \@ifdefinable\defpass\relax \@ifdefinable\edefpass\relax @@ -427,6 +440,18 @@ \ifcsname#1\endcsname\expandafter\@iden\else \expandafter\@gobble\fi{\usename{#1}}% } +\newcommand\uselivecs[1]{% + \ifdefTF{#1}{#1}{\cpt@notdeferr{#1}}% +} +\newcommand\uselivecsn[1]{% + \ifcsndefTF{#1}{% + \usename{#1}% + }{% + \let\relax\relax + \cpt@err{Command '\@backslashchar#1' undefined}\@ehc + }% +} +\@ifdefinable\usedefname{\let\usedefname\uselivecsn} \newcommand\ifxTF[2]{% \usename{@\ifx#1#2\@empty first\else second\fi oftwo}% } @@ -447,9 +472,7 @@ \ifcondTF{ } \long\def\ifcondFT#1\fi#2#3{\ifcondTF#1\fi{#3}{#2}} \newcommand*\ifcsnameTF[1]{% - \ifcondTF\ifcat$\detokenize{#1}$\fi{% - \@secondoftwo - }{% + \iflacus{#1}\@secondoftwo{% \usename{@\ifcsname#1\endcsname first\else second\fi oftwo}% }% } @@ -464,9 +487,9 @@ } \protected\def\cpt@notdefinable{% \@latex@error - {Command \@backslashchar\reserved@a\@space already exists}% - {Command \@backslashchar\reserved@a\@space already defined, - \MsgBrk or name \@backslashchar\@qend... illegal.} + {Command '\@backslashchar\reserved@a' already exists}% + {Command '\@backslashchar\reserved@a' already defined, + \MsgBrk or name '\@backslashchar\@qend\reserved@a' illegal.} } \newcommand*\if@@definable[2]{% \edef\reserved@a{\cptremovescape{#1}}% @@ -487,11 +510,12 @@ \expandafter\endgroup\the\toks@ }% } -\protected\def\cpt@oneorgobble\endgroup{% +\@ifdefinable\ifchoicefoundTF\relax +\protected\def\ifchoicefoundTF\endgroup{% \expandafter\endgroup\ifcpt@choicefd - \expandafter\@iden + \expandafter\@firstoftwo \else - \expandafter\@gobble + \expandafter\@secondoftwo \fi } \protected\def\cpt@oneoftwo#1\endgroup{% @@ -500,16 +524,16 @@ \cptpassexpanded{% \endgroup \ifcase#1\relax - \if@boolTF{cpt@choicefd}\@firstoftwo\@secondoftwo + \ifboolTF{cpt@choicefd}\@firstoftwo\@secondoftwo \or - \if@boolTF{cpt@choicefd}\@secondoftwo\@firstoftwo + \ifboolTF{cpt@choicefd}\@secondoftwo\@firstoftwo \else \cpt@err{Invalid number '#1'}\noexpand\@ehc \fi }% } -\if@@definable\if@@seeparameter\relax -\protected\def\if@@seeparameter#1#{% +\if@@definable\cpt@ifseeparameter\relax +\protected\def\cpt@ifseeparameter#1#{% \xifinsetTF {\detokenize{macro parameter character}} {\meaning\@let@token}% @@ -522,13 +546,7 @@ \expandafter\if@@definable\csname#1\endcsname {\expandafter\newcount\csname#1\endcsname}% } -\newcommand\iflacus[1]{% - \ifcat$\detokenize\expandafter{\@gobble#1.}$% - \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi -} -% \cptcommanormalize and \docommalist are cheap but are restricted -% to comma lists only. Also, they aren't meant for parsing key-val -% lists. See \kv@@normalize and \kv@@parse: + \begingroup \uccode`\~=`\,% \uppercase{\endgroup @@ -568,42 +586,61 @@ }% }% } -\newcommand*\cpt@ppcmds[3]{% - \global\advance#3\@ne - \begingroup - \toks@{}\toks1{}% - \def\cpt@tempa##1{\cptremovescape##1@\romannumeral#3\endcsname}% - \def\push@do##1,{% - \ifnot@nil{##1}{% - \toks@\expandafter\expandafter\expandafter - {\expandafter\the\expandafter\toks@\expandafter - \let\csname\cpt@tempa{##1}##1}% - \toks1\expandafter\expandafter\expandafter - {\expandafter\the\expandafter\toks1\expandafter - \let\expandafter##1\csname\cpt@tempa{##1}}% - \push@do +\newcommand*\cpt@ppcmds[4]{% + \ifcase0\ifnum#1=1 1 \else\ifnum#1=-1 1 \fi\fi + \cpt@err{Invalid stack direction '#1'}\@ehc + \fi + \ifcondTF\ifnum#1=1\fi{% + \edef\reserved@a##1##{##1\gdef\expandafter\noexpand + \csname\cptremovescape#2@stack\endcsname}% + \expandafter\expandafter\expandafter\reserved@a + \csname\cptremovescape#2@stack\endcsname + }{% + \global\advance#4\@ne + \begingroup + \toks@{}\toks1{}\toks2{}% + \def\cpt@tempa##1{\cptremovescape##1@\romannumeral#4\endcsname}% + \def\do##1,{% + \ifnot@nil{##1}{% + \toks@\expandafter\expandafter\expandafter + {\expandafter\the\expandafter\toks@\expandafter + \let\csname\cpt@tempa{##1}##1}% + \toks1\expandafter\expandafter\expandafter + {\expandafter\the\expandafter\toks1\expandafter + \let\expandafter##1\csname\cpt@tempa{##1}}% + \toks2\expandafter\expandafter\expandafter + {\expandafter\the\expandafter\toks2\expandafter + \let\csname\cpt@tempa{##1}\cpt@undefined}% + \do + }% }% - }% - \edef\reserved@a{\cptcommanormalize{#2}}% - \expandafter\push@do\reserved@a,\@nil,% - \expandafter\xdef\csname\cptremovescape#1@stack\endcsname{% - \the\toks1\global\advance#3\m@one - \@ifundefined{\cptremovescape#1@stack}{{}}{% - {\unexpanded\expandafter\expandafter\expandafter - {\csname\cptremovescape#1@stack\endcsname}}% + \edef\reserved@a{\cptcommanormalize{#3}}% + \expandafter\do\reserved@a,\@nil,% + \expandafter\xdef\csname\cptremovescape#2@stack\endcsname{% + \the\toks1\relax\the\toks2\global\advance#4\m@one + \@ifundefined{\cptremovescape#2@stack}{{}}{% + {\unexpanded\expandafter\expandafter\expandafter + {\csname\cptremovescape#2@stack\endcsname}}% + }% }% + \expandafter\endgroup\the\toks@ }% - \expandafter\endgroup\the\toks@ } +\newcommand*\cpt@pushcmds[3]{\cpt@ppcmds\m@one#1{#2}#3} +\newcommand*\cpt@popcmds[1]{\cpt@ppcmds1#1\relax\relax} \cptnewcount{cpt@csvdepth} \cptnewbool{loopbreak} \if@@definable\loopbreak{\let\loopbreak\loopbreaktrue} \newcommand*\cpt@commanil{\cpt@commanil} -\newcommand*\docommalist[2]{% - \cpt@ppcmds\docommalist{\ifloopbreak,\cpt@commaact}\cpt@csvdepth +\newcommand*\docommalist{\cpt@ifstar\cpt@docommalist\cpt@doc@mmalist} +\newcommand*\cpt@docommalist[1]{% + \expandafter\cpt@doc@mmalist\expandafter{#1}% +} +\newcommand*\cpt@doc@mmalist[2]{% + \cpt@pushcmds\docommalist{\ifloopbreak,\cpt@commaact}\cpt@csvdepth \def\cpt@commaact##1{#2}% \def\cpt@commado##1,{% - \@nameuse{@\@nameuse{ifloopbreak}first\else second\fi oftwo}{% + \@nameuse{@\ifloopbreak first\else second\fi oftwo}{% \def\reserved@a####1\cpt@commanil,{}\reserved@a }{% \edef\reserved@a{\unexpanded\expandafter{\@gobble##1}}% @@ -616,14 +653,9 @@ \loopbreakfalse \edef\reserved@a{\cptcommanormalize{#1}}% \expandafter\cpt@commado\expandafter.\reserved@a,\cpt@commanil,% - \def\reserved@a##1##{##1\gdef\docommalist@stack}% - \expandafter\reserved@a\docommalist@stack + \cpt@popcmds\docommalist } \docommalist{st,pl,pm,cl}{\cptnewbool{cpt@#1}} -\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*\cpt@cmdsuffixcheck{\@iden} \AtEndOfPackage{\DefSuffixChecker\cpt@cmdsuffixcheck{*}{!}} \if@@definable\shelldef{% @@ -635,7 +667,7 @@ }% } \protected\def\cpt@shelldef{% - \CurrIfnextchar + \ifnextcharTF !{\@firstoftwo{\cpt@cltrue\cpt@shelld@f}} {\cpt@clfalse\cpt@shelld@f}% } @@ -674,8 +706,8 @@ } \shelldef*\cpt@isescapederr#1{% \@latex@error{Token '\detokenize{#1}' is escaped}{% - I didn't expect the first token of '\detokenize{#1}' - \MsgBrk to be escape character.}% + I didn't expect the first character of '\detokenize{#1}' + \MsgBrk to be the escape character.}% } \shelldef*\cpt@notbracederr#1{% \@latex@error{Token '\detokenize{#1}' isn't braced} @@ -700,7 +732,7 @@ \shelldef*\cpt@isblankerr#1{% \@latex@error {Blank/empty token for command '\detokenize{#1}'} - {I didn't expect a blank token here.}% + {I didn't expect a blank argument/token here.}% } \shelldef*\cpt@notexpandableerr#1{% \@latex@error{'\detokenize{#1}' is not expandable @@ -750,11 +782,10 @@ \shelldef*\shelllet#1{\cpt@ifeql{\cpt@shelllet{#1}}{\cpt@shelllet{#1}}} \shelldef*\cpt@shelllet#1#2{% - \ifcondTF\ifx\noboundary#2\noboundary\fi{% + \iflacus{#2}{% \cpt@isblankerr\shelllet }{% - \ifcondTF\expandafter\ifx\expandafter - \noboundary\@gobble#2\noboundary\fi{% + \expandafter\iflacus\expandafter{\@gobble#2}{% \ifcsdefinable#1{% \ifprotectedTF#2{\let#1=#2}{% \ifcsndefinable{shell@\cptremovescape#1}{% @@ -776,24 +807,29 @@ \ifdefTF\cpt@docstarted\@firstoftwo\@secondoftwo } \shelldef*\UseNormalCatcodes{% + \ifdocstartedTF{% + \cpt@err{\noexpand\UseNormalCatcodes is a + preamble command}\@ehc + }{}% + \xdef\@pushfilename{% + \gletcs\UseNormalCatcodes\UseNorm@lCatcodes + \expandcsonce\@pushfilename + }% \let\UseNormalCatcodes\relax - \ifdocstartedTF{}{% - \cptpushcatcodes - \cptnormalcatcodes - \ifxTF\@currname\@empty{% - \BeforeStartOfDocument{% - \cptpopcatcodes - }% - }{% - \AfterEndOfStyleFile{% - \cptpopcatcodes - \let\UseNormalCatcodes\rsv@UseNormalCatcodes - }% + \cptpushcatcodes + \cptnormalcatcodes + \ifxTF\@currname\@empty{% + \BeforeStartOfDocument{% + \cptpopcatcodes + }% + }{% + \AfterEndOfStyleFile{% + \cptpopcatcodes }% }% } -\if@@definable\rsv@UseNormalCatcodes{% - \let\rsv@UseNormalCatcodes\UseNormalCatcodes +\if@@definable\UseNorm@lCatcodes{% + \global\let\UseNorm@lCatcodes\UseNormalCatcodes } \newcommand*\newcomment{% \begingroup @@ -846,17 +882,6 @@ !gdef!end@comment[\end{comment}] !endgroup -\newcommand\uselivecs[1]{% - \ifdefTF{#1}{#1}{\cpt@notdeferr{#1}}% -} -\newcommand\uselivecsn[1]{% - \ifcsndefTF{#1}{% - \usename{#1}% - }{% - \let\relax\relax - \cpt@err{Command '\@backslashchar#1' undefined}\@ehc - }% -} \long\def\@gobblethree#1#2#3{} \long\def\@firstofthree#1#2#3{#1} \long\def\@secondofthree#1#2#3{#2} @@ -865,26 +890,29 @@ \newcommand\cptalloftwo[2]{#1#2} \if@@definable\cpt@nil{\let\cpt@nil\relax} \def\cpt@nnil{\cpt@nil} -\if@@definable\cpt@relax{\let\cpt@relax\relax} \newcommand*\cptrmstop{0 } \if@@definable\cptrm{\let\cptrm\romannumeral} \long\def\cpt@car#1#2\car@nil{#1} \long\def\cpt@cdr#1#2\cdr@nil{#2} +\if@@definable\cpt@relax{\let\cpt@relax\relax} +\if@@definable\gobble@to@relax\relax +\long\def\gobble@to@relax#1\cpt@relax{} +\def\cpt@defrelax\fi{% + \fi\defpass\cpt@relax##1\cpt@relax{\endgroup}% +} \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} -\defpass\reserved@a#1{% - \long\def\remove@to@space##1#1{}% - \def\@gobblespace#1{}% -}{ } +\long\def\remove@to@space#1 {} +\@namedef{@gobblespace} {} \protected\def\ifnot@nil#1{% - \edef\reserved@g{\unexpanded{#1}}% - \ifxTF\reserved@g\@nnil\@gobble\@iden + \edef\reserved@a{\unexpanded{#1}}% + \ifxTF\reserved@a\@nnil\@gobble\@iden } \newcommand*\ifsentinelTF[1]{% - \edef\reserved@g{\unexpanded{#1}}% - \ifxTF\reserved@g\currsentinel + \edef\reserved@a{\unexpanded{#1}}% + \ifxTF\reserved@a\currsentinel } \if@@definable\csvbreak{\let\csvbreak\relax} \newcommand*\cpt@csvbreak{\csvbreak} @@ -893,8 +921,8 @@ \if@@definable\tsvbreak{\let\tsvbreak\relax} \newcommand*\cpt@tsvbreak{\tsvbreak} \newcommand*\ifcsvbreakTF[1]{% - \edef\reserved@g{\unexpanded{#1}}% - \ifxTF\reserved@g\cpt@csvbreak + \edef\reserved@a{\unexpanded{#1}}% + \ifxTF\reserved@a\cpt@csvbreak } \if@@definable\cptdoremainder{\let\cptdoremainder\@gobble} \shelldef*\gobble@to@sentinel#1#2{% @@ -911,10 +939,10 @@ } \cptzapspaces{ } \long\def\cpt@zapspaces#1 #2\zap@nil{% - \usename{@\ifx\noboundary#2\noboundary first\else second\fi oftwo}{% - \expandafter\cptrmstop\remove@to@dot#1% + \iflacus{#2}{% + \expandafter\cptrmstop\@gobble#1% }{% - \expandafter\cpt@zapspaces\expandafter.\remove@to@dot#1#2\zap@nil + \expandafter\cpt@zapspaces\expandafter.\@gobble#1#2\zap@nil }% } \newcommand*\cptsupergobble[1]{% @@ -928,7 +956,7 @@ \newcommand\cpt@superg@bblem[1]{\endcsname} \newcommand*\cptdotimes[1]{% \ifblankTF{#1}{% - \if@boolTF{cpt@useempty}{\cpt@dotimes{m}}\@gobble + \ifboolTF{cpt@useempty}{\cpt@dotimes{m}}\@gobble }{% \expandafter\cpt@dotimes\expandafter {\romannumeral\number#1000}% @@ -961,7 +989,7 @@ \newcommand*\normal@reverse[1]{\cpt@normalreverse{}#1\@nnil} \long\def\cpt@normalreverse#1#2{% \ifxTF#2\@nnil{% - \if@boolTF{@test}\@iden\unexpanded{#1}% + \ifboolTF{@test}\@iden\unexpanded{#1}% }{% \cpt@normalreverse{#2#1}% }% @@ -973,7 +1001,7 @@ } \long\def\cpt@r@bustreverse#1#2.#3{% \ifxTF#3\@nnil{% - \if@boolTF{@test}\@iden\unexpanded{#1}% + \ifboolTF{@test}\@iden\unexpanded{#1}% }{% #2{\cpt@robustreverse{{#3}#1}}{\cpt@robustreverse{#3#1}}.% }% @@ -1005,36 +1033,40 @@ \ifcondTF\if@tempswa\fi{\endgroup#2}\endgroup } \ifcommandsdefinable{\cpttrimspace,\cpttrimspaces}\relax -\def\cpttrimspaces#1{\cpt@trimspaces@a\relax{#1}} +\long\def\cpttrimspaces#1{\cpt@trimspaces@a\relax{#1}} +\long\def\cpt@trimspaces@strcmp#1#2{% + \csname @\ifnum\pdfstrcmp{\detokenize{#1}}% + {\detokenize{#2}}=0first\else second\fi oftwo\endcsname +} \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}{% +\long\gdef\cpt@trimspaces@a#1#2{\cpt@trimspaces@b.#1$.#2& &} +\long\gdef\cpt@trimspaces@b#1$#2 &{\cpt@trimspaces@c#1$#2&} +\long\gdef\cpt@trimspaces@c#1$#2{% + \cpt@trimspaces@d\cpt@trimspaces@strcmp{#2}{#1}{% \unexpanded\expandafter{\@gobble#1}% }{% \cpt@trimspaces@d\cpt@trimspaces@a{#2}{#2}% }% } -\gdef\cpt@trimspaces@d#1#2{% +\long\gdef\cpt@trimspaces@d#1#2{% \expandafter\cpt@trimspaces@e\expandafter#1\expandafter{% \unexpanded\expandafter {\romannumeral-`\q\expandafter\noexpand\@gobble#2}% }% } -\gdef\cpt@trimspaces@e#1#2#3{% +\long\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{% +\long\gdef\cpttrimspace#1{\cpt@trimspace@a.#1& &} +\long\gdef\cpt@trimspace@a#1 &{\cpt@trimspace@b#1&} +\long\gdef\cpt@trimspace@b#1{% \unexpanded\expandafter {\romannumeral-`\q\expandafter\noexpand\@gobble#1}% } \endgroup -\shelldef*\trim@@spaces#1#2{\edef#2{\cpttrimspaces{#1}}} -\shelldef*\trim@@space#1#2{\edef#2{\cpttrimspace{#1}}} +\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}}% @@ -1050,12 +1082,9 @@ \cptaddtolist[#1]\cpt@rsvda\cpt@tempa }% \csv@@loop*[#1]\cpt@tempa - \if@boolFT{cpt@st}{}{\let#2=\cpt@rsvda}% + \ifdefboolFT{cpt@st}{}{\let#2=\cpt@rsvda}% }% } -% \newvariables{<type>}[<prf>]{<variables>}[<state/value>] -% Valid <types> are 'if, toks, box, dimen, count, tog, switch'. -% Boxes can be defined but not initialized by this command. \shelldef*\newvariables#1{\@testopt{\cpt@newvariables{#1}}{}} \if@@definable\newvariable{\let\newvariable\newvariables} \shelldef*\cpt@newvariables#1[#2]#3{% @@ -1063,15 +1092,11 @@ } \shelldef*\cpt@newv@riables#1#2#3[#4]{% \def\cpt@rsvda##1{% - \ifx\noboundary#4\noboundary - \def\cpt@tempc{##1}\else\def\cpt@tempc{#4}\fi + \iflacus{#4}{\def\cpt@tempc{##1}}{\def\cpt@tempc{#4}}% }% \edef\cpt@tempb{\ifstrcmpTF{#1}{if}{if}{}}% \docommalist{#3}{% - \iflacus{##1}{% - \def\cpt@relax####1\cpt@relax{\let\cpt@relax\relax}% - }{}% - \cpt@relax + \iflacus{##1}\gobble@to@relax\relax \ifnamedefTF{\cpt@tempb#2##1}{% \edef\reserved@a{\cpt@tempb#2##1}% \ifstrcmpTF{#1}{tog}{}{\cpt@notdefinable}% @@ -1088,11 +1113,11 @@ \ifstrcmpTF{#4}{false}{% \let\cpt@togstate\@secondoftwo }{% - \ifx\noboundary#4\noboundary + \iflacus{#4}{% \let\cpt@togstate\@secondoftwo - \else + }{% \@latex@error{Invalid toggle value '#4'}\@ehc - \fi + }% }% }% }% @@ -1109,11 +1134,11 @@ \ifstrcmpTF{#4}{false}{% \def\reserved@a{01}% }{% - \ifx\noboundary#4\noboundary + \iflacus{#4}{% \def\reserved@a{01}% - \else + }{% \@latex@error{Invalid switch value '#4'}\@ehc - \fi + }% }% }% }% @@ -1130,7 +1155,8 @@ \cpt@rsvda{}% \csname#2##1\endcsname\expandafter{\cpt@tempc}% }{% - % It is dangerous to initialize boxes here: + % It is dangerous to initialize boxes. + % Horizontal and vertical boxes aren't compatible: \ifstrcmpTF{#1}{box}{}{% \ifstrcmpTF{#1}{count}{% \cpt@rsvda\z@pt @@ -1179,8 +1205,8 @@ \endgroup \fi } -\newvariables{if}[cpt@]{verbose,usepox,optfd, - igopt,inpox,olddx,in,check,choicefd,useempty,swa, +\newvariables{if}[cpt@]{verbose,usepox,optfd,% + igopt,inpox,olddx,in,check,choicefd,useempty,swa% }[false] \newvariables{tog}{biboolopts}[false] \newvariables{count}[cpt@]{optdepth,grouplevel,grouptype,cnta}[\z@pt] @@ -1201,6 +1227,37 @@ \ifcat\noexpand#1\noexpand~13\else -1\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi } +\newcommand*\cptcountspacesincs{% + \begingroup + \catcode\endlinechar=12 + \cpt@countspacesincs +} +\def\cpt@countspacesincs#1{% + \lccode`\ `\^^S\relax + \catcode\endlinechar=9 + \scantokens{\cpt@c@untspacesincs{#1}{ignoring}}% + \catcode\endlinechar=10 + \scantokens{\cpt@c@untspacesincs{#1}{counting}}% + \endgroup +} +\def\cpt@c@untspacesincs#1#2{% + \@tempcnta\z@pt + \toks@{##1}% + \lowercase{% + \toks1\expandafter{\detokenize{ }}% + \expandafter\def\expandafter\cpt@tempa\the + \expandafter\toks@\the\toks1##2\@nil{% + \ifblankTF{##2}{}{% + \advance\@tempcnta\@ne + \cpt@tempa##2\@nil + }% + }% + \expandafter\cpt@tempa\detokenize{#1 }\@nil + }% + \typeout{^^J\unexpanded{#1}}% + \typeout{Number of spaces, + #2 end-of-line characters: \the\@tempcnta.}% +} \newcommand\ifnullTF[1]{% \usename{@\ifnum\pdfstrcmp{}{\detokenize{#1}}% =\z@pt first\else second\fi oftwo}% @@ -1223,10 +1280,10 @@ } \newcommand\xifblankFT[1]{\xifblankTF{#1}\@secondoftwo\@firstoftwo} \newcommand*\ifdefTF[1]{% - \usename{@\ifx\noboundary#1\noboundary second\else first\fi oftwo}% - {\usename{@\ifx#1\cpt@undefined second\else - \ifx#1\relax second\else first\fi\fi oftwo}}% - \@secondoftwo + \ifblankTF{#1}\@secondoftwo{% + \usename{@\ifx#1\cpt@undefined second\else + \ifx#1\relax second\else first\fi\fi oftwo}% + }% } \newcommand*\ifdefFT[1]{\ifdefTF{#1}\@secondoftwo\@firstoftwo} \newcommand*\oifdefTF[1]{\expandafter\ifdefTF\expandafter{#1}} @@ -1234,12 +1291,15 @@ \newcommand*\xifdefTF[1]{\cptexpandarg\ifdefTF{#1}} \newcommand*\xifdefFT[1]{\cptexpandarg\ifdefFT{#1}} \newcommand*\ifcsndefTF[1]{% - \ifcsname#1\endcsname - \expandafter\@firstofone - \else - \cptthreexp\@secondoftwo\expandafter\@gobble - \fi - {\aftercsname\ifdefTF{#1}}% + \ifblankTF{#1}\@gobble{% + \ifcsname#1\endcsname + \expandafter\@firstofone + \else + \cptthreexp\@secondoftwo\expandafter\@gobble + \fi + }{% + \aftercsname\ifdefTF{#1}% + }% } \newcommand*\ifcsndefFT[1]{\ifcsndefTF{#1}\@secondoftwo\@firstoftwo} \newcommand*\oifcsndefTF[1]{\expandafter\ifcsndefTF\expandafter{#1}} @@ -1322,23 +1382,23 @@ \ifcpt@st\else\long\fi #1\def\reserved@b } -\robust@def*\@ltx@warn{\@latex@warning@no@line} -\robust@def*\@ltx@info{\@latex@info@no@line} -\robust@def*\@ltx@err{\@latex@error} -\robust@def\cpt@testopt#1#2{\CurrIfnextchar[{#1}{#1[{#2}]}} -\robust@def*\cpt@ifbrack#1#2{\CurrIfnextchar[{#1}{#2}} +\robust@def*\ltx@warn{\@latex@warning@no@line} +\robust@def*\ltx@info{\@latex@info@no@line} +\robust@def*\ltx@err{\@latex@error} +\robust@def\cpt@testopt#1#2{\ifnextcharTF[{#1}{#1[{#2}]}} +\robust@def*\cpt@ifbrack#1#2{\ifnextcharTF[{#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@testltopt#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@testpnopt#1#2{\ifnextcharTF({#1}{#1({#2})}} +\robust@def\cpt@testltopt#1#2{\ifnextcharTF<{#1}{#1<{#2}>}} +\robust@def\cpt@ifplus#1{\ifnextcharTF+{\@firstoftwo{#1}}} +\robust@def\cpt@ifclam#1{\ifnextcharTF!{\@firstoftwo{#1}}} +\robust@def\cpt@ifprime#1{\ifnextcharTF'{\@firstoftwo{#1}}} +\robust@def\cpt@ifeql#1{\ifnextcharTF={\@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}} @@ -1346,11 +1406,10 @@ \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}}} -% */' -> don't define, otherwise attempt to define: \robust@def*\cptmaybedef{\cpt@teststpm\cpt@maybedef} \robust@def*\cpt@maybedef#1{% - \if@boolTF{cpt@st}\@firstoftwo{% - \if@boolTF{cpt@pm}\@firstoftwo\@secondoftwo + \ifboolTF{cpt@st}\@firstoftwo{% + \ifboolTF{cpt@pm}\@firstoftwo\@secondoftwo }{% \@gobble }{% @@ -1379,11 +1438,8 @@ \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 - \else - \cptthreexp\newletcs\expandafter\cpt@tempa\cpt@tempb - \fi + \csname\if@test let\else newletcs\fi + \cptthreexp\endcsname\expandafter\cpt@tempa\cpt@tempb \oifdefFT\cpt@tempb{}{% \ifcsndefTF{\expandafter\string\cpt@tempb}{% \letcsntocsn{\expandafter\string\cpt@tempa} @@ -1427,7 +1483,6 @@ \gdef#2##1\string\count##2&{\noexpand\ifblankTF{##1}}% } \cpt@ifcounter@a\cpt@ifcounter@a\cpt@ifcounter@b -% Similar to \ifcounterTF. Don't call this \ifdimTF: \new@gdef*\ifdimenTF#1{% \ifstrcmpTF\dimen{#1}\@secondoftwo{% \expandafter\cpt@ifdimen@a\meaning#1:&% @@ -1441,47 +1496,45 @@ \endgroup \robust@def*\pushnumber#1{% - \ifdefTF{#1}{% - \ifcounterTF#1{% - \global\advance#1\@ne + \ifsingletokenTF{#1}{% + \ifdefTF{#1}{% + \ifcounterTF#1{% + \global\advance#1\@ne + }{% + \xdef#1{\the\numexpr#1+1}% + }% }{% - \xdef#1{\the\numexpr#1+1}% + \chardef#1=\@ne }% }{% - \chardef#1=\@ne + \cpt@notonetokenerr{#1}% }% } \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\m@one + \ifsingletokenTF{#1}{% + \ifdefTF{#1}{% + \ifnumcmpTF#1=\z@pt{% + \cpt@err{Counter or number '\string#1' is already 0}\@ehc }{% - \xdef#1{\the\numexpr#1-1}% + \ifcounterTF#1{% + \global\advance#1\m@one + }{% + \xdef#1{\the\numexpr#1-1}% + }% }% + }{% + \cpt@err{Counter or number '\string#1' is undefined}\@ehc }% }{% - \cpt@err{Counter or number '\string#1' is undefined}\@ehc + \cpt@notonetokenerr{#1}% }% } \robust@def*\pushfunctions#1#2#3{% - \ifdefTF{#3}{% - \ifcounterTF{#3}{% - \global\advance#3\@ne - }{% - \xdef#3{\the\numexpr#3+1}% - }% - }{% - \chardef#3=\@ne - }% + \pushnumber{#3}% \begingroup \edef\cpt@stack{\cptremovescape{#1}@stack}% \ifcsndefTF\cpt@stack{}{\csn@gdef\cpt@stack{}}% \toks@{}\toks1{}\escapechar92\relax - % Using \csv@@loop or \csv@@parse here will bomb out, - % because \pushfunctions is called within those loops: \let\xp\expandcsonce \def\push@do##1{% \ifescapedTF{##1}{}{\cpt@notescapederr{##1}}% @@ -1489,8 +1542,7 @@ \cptpassexpanded{% \toks@{\the\toks@\let\xp\cpt@tempa\noexpand##1}% \toks1{\the\toks1\let\noexpand##1\xp\cpt@tempa - \undefcs\xp\cpt@tempa - }% + \undefcs\xp\cpt@tempa}% }% }% \cptpushparse{#2}% @@ -1522,29 +1574,25 @@ \cpt@err{Unknown stack for function \string#1}\@ehc \@gobble }% - \ifcounterTF{#2}{% - \global\advance#2\m@one - }{% - \xdef#2{\the\numexpr#2-1}% - }% + \popnumber{#2}% } -\chardef\cpt@optionstacklimit4 +\chardef\cpt@optionstacklimit=4 \robust@def*\cpt@pushstate#1#2#3{% \ifnum#3>\cpt@optionstacklimit\relax - \let\reserved@a\cpt@optionstacklimit + \let\x\cpt@optionstacklimit \@latex@error{Current option/key state is being pushed - \MsgBrk beyond level '\reserved@a'. I suspect infinite + \MsgBrk beyond level '\x'. I suspect infinite \MsgBrk re-entrance. If this isn't the case, please \MsgBrk set package option 'option-stack-limit' or 'key-stack-limit' to the required value in \MsgBrk\noexpand\documentclass }\@ehc \fi - \expandafter\pushfunctions\expandafter#1\expandafter{#2}#3% + \expandafter\pushfunctions\expandafter#1\expandafter{#2}{#3}% } -\robust@def*\cpt@popstate#1#2{\popfunctions#1#2} +\robust@def*\cpt@popstate#1#2{\popfunctions{#1}{#2}} \robust@def*\cpt@stchoose#1#2#3#4{% - \if@boolTF{#1}{% + \ifboolTF{#1}{% \ifmacroTF{#2}{% \let#3=#2% }{% @@ -1582,9 +1630,6 @@ \gletcs#1\cpt@tempa \endgroup } -% \dofunclist[<parser>]{<list>} -% \dofunclist*[<parser>]{<listcmd>} -% This expects \do, which can be multi-parametered. \robust@def*\dofunclist{% \pushnumber\dofunclistnr \begingroup @@ -1599,23 +1644,23 @@ \csv@@parse } \robust@def*\csv@@loop{% - \let\cpt@nmlz\cptfalse - \let\cpt@inkv\cptfalse + \let\cpt@nmlz\cptswfalse + \let\cpt@inkv\cptswfalse \cpt@teststopt\cpt@csvkvparse,% } \robust@def*\csv@@parse{% - \let\cpt@nmlz\cpttrue - \let\cpt@inkv\cptfalse + \let\cpt@nmlz\cptswtrue + \let\cpt@inkv\cptswfalse \cpt@teststopt\cpt@csvkvparse,% } \robust@def*\kv@@loop{% - \let\cpt@nmlz\cptfalse - \let\cpt@inkv\cpttrue + \let\cpt@nmlz\cptswfalse + \let\cpt@inkv\cptswtrue \cpt@teststopt\cpt@csvkvparse,% } \robust@def*\kv@@parse{% - \let\cpt@nmlz\cpttrue - \let\cpt@inkv\cpttrue + \let\cpt@nmlz\cptswtrue + \let\cpt@inkv\cptswtrue \cpt@teststopt\cpt@csvkvparse,% } \new@def*\cpt@csvnil{\cpt@csvnil} @@ -1629,7 +1674,7 @@ \cpt@err{'\string\csv@do' or '\string\kv@do' undefined}\@ehc }% \def\cpt@csvdo@a{% - \if@boolTF{loopbreak}{% + \ifboolTF{loopbreak}{% \gobble@to@sentinel\cpt@csvnil#1% }{% \cpt@csvdo.% @@ -1642,7 +1687,7 @@ \loopbreaktrue }{% \ifcsemptyTF\cpt@csvarg{% - \if@boolFT{cpt@useempty}{}{\sav@csv@do{}\relax}% + \ifdefboolFT{cpt@useempty}{}{\sav@csv@do{}\relax}% }{% \expandafter\sav@csv@do\expandafter{\cpt@csvarg}\relax }% @@ -1650,10 +1695,10 @@ \cpt@csvdo@a }% }% - \ifswitchFT{cpt@nmlz}{}{% + \ifdefswitchFT{cpt@nmlz}{}{% \ifcsemptyTF\cpt@csvarg{}{% \cpt@sttrue - \usename{cpt@\ifswitchTF{cpt@inkv}{kv}{csv}normalize}% + \usename{cpt@\ifdefswitchTF{cpt@inkv}{kv}{csv}normalize}% [#1]\cpt@csvarg }% }% @@ -1665,13 +1710,56 @@ \undefcsset{\csv@do,\kv@do,\dofunclistnr}% \fi } -%% Robust, multi-level, general-purpose tsv processor: +\robust@def\indris@nil#1\fi#2\indris@do#3\indris@nil{\fi#1#2} +\newvariables{if}{lastindris}[false] +\robust@def*\indrisloop{\cpt@teststopt\cpt@indrisloop{,}} +\robust@def*\cpt@indrisloop[#1]#2#3{% + \pushfunctions\cpt@indrisloop + {\indris@do,\indrisnr,\iflastindris,% + \ifloopbreak,\user@do,\getnextindris}\indrisdepth + \cpt@stchoose{cpt@st}{#2}\cpt@rsvda\indrisloop + \cpt@sttrue\cpt@csvnormalize[#1]\cpt@rsvda + \lastindrisfalse\loopbreakfalse + \chardef\indrisnr\z@pt + \ifsingletokenTF{#3}{% + \ifmacroTF{#3}{}{\cpt@notcserr{#3}}% + }{% + \cpt@notonetokenerr{#3}% + }% + \let\user@do#3% + \def\getnextindris##1#1##2\indris@nil{% + \edef\nextindris{\unexpanded\expandafter{\@gobble##1}}% + \letcsntocs{nextindris@\cptrm\indrisdepth}\nextindris + }% + \def\indris@do##1#1##2\indris@nil{% + \edef\currindris{\unexpanded\expandafter{\@gobble##1}}% + \letcsntocs{currindris@\cptrm\indrisdepth}\currindris + \ifcat$\detokenize\expandafter{\@gobble##2.}$\indris@nil + \lastindristrue\fi + \ifboolTF{lastindris}{% + \def\nextindris{}% + \csn@def{nextindris@\cptrm\indrisdepth}{}% + }{% + \ifcsvbreakTF{##1}\loopbreak\relax + \ifboolTF{loopbreak}{% + \defpass\reserved@a####1\indris@nil{\cptdoremainder{####1}}% + }{% + \getnextindris.##2\indris@nil + }% + }% + \pushnumber\indrisnr + \expandafter\user@do\expandafter{\@gobble##1}% + \indris@do.##2\indris@nil + }% + \expandafter\indris@do\expandafter.\cpt@rsvda#1\indris@nil + \popfunctions\cpt@indrisloop\indrisdepth +} \robust@def*\tsv@@loop{% - \let\tsv@inparse\cptfalse + \let\tsv@inparse\cptswfalse \cpt@testst\cpt@tsvparse@a } \robust@def*\tsv@@parse{% - \let\tsv@inparse\cpttrue + \let\tsv@inparse\cptswtrue \cpt@testst\cpt@tsvparse@a } \new@def*\cpt@tsvnil{\cpt@tsvnil} @@ -1692,13 +1780,12 @@ \fi } \robust@def*\cpt@tsvparse@b{% - \if@boolTF{loopbreak}{% + \ifboolTF{loopbreak}{% \gobble@to@sentinel\cpt@tsvnil{}% }{% \begingroup \let\bgr@up\bgroup \let\bgroup\cpt@undefined - % Don't use \CurrIfnextchar here: \cpt@ifnextchar\bgr@up\cpt@tsvparse@c\cpt@tsvparse@c }% } @@ -1725,21 +1812,27 @@ } % \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, but can +% \siso@@loop strips outer braces in its arguments and +% doesn't trim leading and trailing spaces, but can % be nested to any level: \new@def*\cpt@sisonil{\cpt@sisonil} \robust@def*\siso@@loop#1{% - \pushfunctions\siso@@loop{\siso@doo}\cpt@sisodepth + \pushfunctions\siso@@loop{\sav@siso@do,\ifloopbreak}\cpt@sisodepth \ifdefTF\siso@do{}{\cpt@notdeferr\siso@do}% - \let\siso@doo\siso@do + \let\sav@siso@do\siso@do + \loopbreakfalse \cpt@sisoloop#1\cpt@sisonil \popfunctions\siso@@loop\cpt@sisodepth - \undefcs\siso@do + \ifnum\cpt@sisodepth=\z@pt\undefcs\siso@do\fi } \robust@def*\cpt@sisoloop#1{% - \edef\reserved@g{\unexpanded{#1}}% - \ifxTF\reserved@g\cpt@sisonil{}{% - \siso@doo{#1}\relax\cpt@sisoloop + \edef\siso@arg{\unexpanded{#1}}% + \ifxTF\siso@arg\cpt@sisonil{}{% + \ifboolTF{loopbreak}{% + \gobble@to@sentinel\cpt@sisonil{}% + }{% + \sav@siso@do{#1}\relax\cpt@sisoloop + }% }% } \robust@def*\cpt@oncurrlevel#1#2{% @@ -1754,10 +1847,16 @@ \cptexpandsecond{#1} {\noexpandcsn{\cptgobblescape#2@\romannumeral\curr@level}}% } -\new@def*\cptliststack#1#2{% - \ifdefFT{#2} - {} - {\ifxTF#2\@empty{}{\expandcsonce{#2}#1}}% +\new@def*\csliststack#1#2{% + \ifdefFT{#2}{}{% + \ifxTF#2\@empty{}{\expandcsonce{#2}#1}% + }% +} +\new@def*\csnliststack#1#2{% + \expandafter\ifdefFT\csname#2\endcsname{}{% + \expandafter\ifxTF\csname#2\endcsname\@empty{}% + {\expandafter\expandcsonce\csname#2\endcsname#1}% + }% } \new@def\cptafterfi#1\fi{\fi#1} \new@def\cptafterelsefi#1\else#2\fi{\fi#1} @@ -1820,7 +1919,7 @@ \MsgBrk submitted to \string\cptonlypreamble: ignored}% }{% - \xdef\cpt@preamblecmdhook{\cptliststack{}% + \xdef\cpt@preamblecmdhook{\csliststack{}% \cpt@preamblecmdhook\unexpanded{\do##1}% }% }% @@ -1832,6 +1931,7 @@ \csv@@parse[,]{#1}% \endgroup } +\new@def*\cpt@newlinespaces{^^J\@spaces\@spaces} \robust@def*\cptelementcount{\cpt@teststopt\cpt@elemcount,} \robust@def*\cpt@elemcount[#1]#2{% \begingroup @@ -1843,10 +1943,8 @@ \expandafter\csv@@loop\reserved@a[#1]{#2}% \postgroupdef\cpt@elemnr\endgroup } -% Eg, \ifelemcountTF[;](>)[2]{a;b;c}{T}{F}; -% * -> #4 is a macro \robust@def*\ifelemcountTF{% - \cpt@testst{\cpt@testopt\cpt@ifelemcount@a,}% + \cpt@teststopt\cpt@ifelemcount@a,% } \robust@def*\cpt@ifelemcount@a[#1]{% \cpt@testpnopt{\cpt@ifelemcount@b{#1}}=% @@ -1874,9 +1972,9 @@ \def\csv@do##1{% \xifinsetTF{\detokenize{#1##1#1}} {\parser\cptoxdetok\cpt@currstack\parser}{% - \xdef\duplicates{\cptliststack#1\duplicates\unexpanded{##1}}% + \xdef\duplicates{\csliststack#1\duplicates\unexpanded{##1}}% }{% - \edef\cpt@currstack{\cptliststack#1\cpt@currstack\unexpanded{##1}}% + \edef\cpt@currstack{\csliststack#1\cpt@currstack\unexpanded{##1}}% }% }% \expandafter\csv@@parse\reserved@a[#1]{#2}% @@ -1884,13 +1982,8 @@ {\endgroup\@firstoftwo}{\endgroup\@secondoftwo}% } \new@def*\ifcsnullTF#1{% - % Don't use \ifxTF here: - \ifcondTF\expandafter\ifx\expandafter - \noboundary\@gobble#1.\noboundary\fi{% - \@secondoftwo - }{% - \ifcondTF\expandafter\ifx\expandafter - \noboundary\@gobble#1\noboundary\fi{% + \ifblankTF{#1}\@secondoftwo{% + \expandafter\ifblankTF\expandafter{\@gobble#1}{% \ifxTF#1\@empty }{% \@secondoftwo @@ -1928,13 +2021,10 @@ \ifcsnnullTF{#1}\@secondoftwo\@firstoftwo }\@secondoftwo } -% For private use only where #1 is surely a single token. -% For reasons of efficiency, we don't want to confirm -% here if #1 is actually a single token: +%% For private use only: \new@def*\simpleexpandarg#1#2{\expandafter#1\expandafter{#2}} \newletcs\s@expandarg=\simpleexpandarg %%-- - \new@def*\expandcsonce#1{\unexpanded\expandafter{#1}} \new@def*\expandcsnonce#1{\aftercsname\expandcsonce{#1}} \new@def*\expandcstwice#1{\unexpanded\cptthreexp{#1}} @@ -2043,21 +2133,33 @@ \fi \endgroup } -\new@def*\ifboolTF#1{% - \ifcsndefTF{if#1}{% - \if@boolTF{#1}% +\new@def*\ifdefboolTF#1{% + \ifblankTF{#1}{% + \cpt@err{Empty boolean}\@ehc }{% - \cpt@err{Boolean '\@backslashchar#1' undefined}\@ehc + \ifcsndefTF{if#1}{% + \ifboolTF{#1}% + }{% + \cpt@err{Boolean '\@backslashchar#1' undefined}\@ehc + }% }% } -\new@def*\ifboolFT#1{\ifboolTF{#1}\@secondoftwo\@firstoftwo} -\new@def*\ifbooleanTF#1{% - \ifboolTF{#1}{\endgroup\@firstoftwo}{\endgroup\@secondoftwo}% -} -\new@def*\if@boolTF#1{% +\new@def*\ifdefboolFT#1{\ifdefboolTF{#1}\@secondoftwo\@firstoftwo} +\new@def*\ifboolTF#1{% \usename{@\usename{if#1}first\else second\fi oftwo}% } -\new@def*\if@boolFT#1{\if@boolTF{#1}\@secondoftwo\@firstoftwo} +\new@def*\ifboolFT#1{\ifboolTF{#1}\@secondoftwo\@firstoftwo} +\new@def*\ifbooleanTF#1#{% + \ifsingletokenTF{#1}{% + \ifescapedTF{#1}{% + \ifdefboolTF{\cptremovescape#1}\@firstoftwo\@secondoftwo + }{% + \cpt@notescapederr + }% + }{% + \cpt@notonetokenerr{#1}% + }% +} \new@def\cptiterate#1\repeat{\cpt@iterate\@gobble{#1}} \newletcs\cptloop=\cptiterate \new@def\cpt@iterate\@gobble#1{% @@ -2102,6 +2204,9 @@ \remove@to@nnil<=>\@nnil first\else second\fi oftwo}% } \new@def*\ifnumcmpFT#1#{\usename{@\ifnumcmpTF#1{second}{first}oftwo}} +\new@def*\ifnumtestTF#1#2#3{% + \usename{@\ifnum\numexpr#1#2\numexpr#3 first\else second\fi oftwo}% +} \new@def*\ifdimcmpTF#1#{% \usename{@\ifdim\dimexpr\cpt@dimlt\cpt@dimgt\cpt@dimeq#1% \remove@to@nnil<=>\@nnil first\else second\fi oftwo}% @@ -2175,14 +2280,49 @@ \usename{@\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}} -\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}} +\robust@def*\cptnumexpr{\cpt@testcl{\cpt@numexpr{num}}} +\robust@def*\cptdimexpr{\cpt@testcl{\cpt@numexpr{dim}}} +\robust@def*\cptglueexpr{\cpt@testcl{\cpt@numexpr{glue}}} +\robust@def*\cptmuexpr{\cpt@testcl{\cpt@numexpr{mu}}} +\new@def*\cpt@numexpr#1#2#3{% + \ifsingletokenTF{#2}{}{\cpt@notonetokenerr{#2}}% + \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}% + \ifdefTF{#2}{% + \ifcpt@cl\global\fi#2=\usename{#1expr}#3\relax\relax + }{% + \def\reserved@a##1#1##2##3\@nil{% + \usename{new##2}#2\relax + }% + \reserved@a num{count}dim{dimen}glue{skip}mu{muskip}\@nil + \ifcpt@cl\global\fi#2=\usename{#1expr}#3\relax\relax + }% +} +\robust@def*\cptnumdef{\cpt@testcl{\cpt@numdef{num}}} +\robust@def*\cptdimdef{\cpt@testcl{\cpt@numdef{dim}}} +\robust@def*\cptgluedef{\cpt@testcl{\cpt@numdef{glue}}} +\robust@def*\cptmudef{\cpt@testcl{\cpt@numdef{mu}}} +\new@def*\cpt@numdef#1#2#3{% + \ifsingletokenTF{#2}{}{\cpt@notonetokenerr{#2}}% + \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}% + \ifcpt@cl\global\fi\edef#2{\the\usename{#1expr}#3}% +} +\robust@def*\cptnumadd{\cpt@testcl{\cpt@numadd{num}}} +\robust@def*\cptdimadd{\cpt@testcl{\cpt@numadd{dim}}} +\robust@def*\cptglueadd{\cpt@testcl{\cpt@numadd{glue}}} +\robust@def*\cptmuadd{\cpt@testcl{\cpt@numadd{mu}}} +\new@def*\cpt@numadd#1#2#3{% + \ifsingletokenTF{#2}{}{\cpt@notonetokenerr{#2}}% + \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}% + \ifdefTF{#2}{% + \ifcpt@cl\global\fi\edef#2{\the\usename{#1expr}#2+#3}% + }{% + \ifcpt@cl\global\fi\edef#2{\the\usename{#1expr}#3}% + }% +} +\robust@def*\csnnumdef{\cpt@testcl{\aftercsname{\cpt@numdef{num}}}} +\robust@def*\csndimdef{\cpt@testcl{\aftercsname{\cpt@numdef{dim}}}} +\robust@def*\csnnumadd{\cpt@testcl{\aftercsname{\cpt@numadd{num}}}} +\robust@def*\csndimadd{\cpt@testcl{\aftercsname{\cpt@numadd{dim}}}} \new@edef*\cpt@leftbracechar{% \expandafter\@car\string{\@nil\iffalse}\fi } @@ -2230,15 +2370,31 @@ {\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}} +\newcommand\ifbracedTF[3]{% + \romannumeral + \ifcase + \iffalse{{{\fi\expandafter\expandafter\expandafter + \@gobble\expandafter\expandafter\expandafter + {\expandafter\expandafter\expandafter{\expandafter + \iffalse\expandafter}\expandafter}\expandafter\fi + \string#1}\m@ne}\@ne}\z@ + \expandafter\@secondoftwo + \or + \expandafter\@secondoftwo + \else + \expandafter\@firstoftwo + \fi + {0 #2}{0 #3}% +} +\new@def*\ifbracedFT#1{\ifbracedTF{#1}\@secondoftwo\@firstoftwo} % Ulrich Diez 06/02/2011: -\new@def*\ifbracedTF#1#2#3{% +\new@def*\ud@ifbracedTF#1#2#3{% \romannumeral \ifblankTF{#1}{% 0 #3% @@ -2254,13 +2410,12 @@ } %%-- -\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 + \@nameuse{@\if\expandafter\cpt@car\detokenize{#1}\car@nil + \expandafter\cpt@car\string{\car@nil\ifnum0=`}\fi first\else second\fi oftwo}% }% } @@ -2347,7 +2502,6 @@ \robust@def*\ifsingletokenFT#1{% \ifsingletokenTF{#1}\@secondoftwo\@firstoftwo } -% Don't test for \ifleadspaceTF: \new@def\ifsingletoken@sp@TF#1#2#3{% \romannumeral\ifblankTF{#1}{% \@secondoftwo @@ -2377,7 +2531,7 @@ }{% \ifsingletokenTF{#1}{% \xifinsetTF{\detokenize{#1}}\cpt@parserlist{% - #2% + #2% Don't put \relax here! }{% \cpt@listparsererr{#1}% }% @@ -2386,11 +2540,11 @@ }% }% } -\robust@def*\cpt@checklistparser@b#1{% +\robust@def*\cpt@ch@cklistparser#1{% \ifblankTF{#1}{% \cpt@listparsererr{#1}% }{% - \expandafter\ifsecondis@nnil\string#1\cpt@nnil\cpt@nil{% + \expandafter\ifsecondisnilTF\string#1\cpt@nnil\cpt@nil{% \xifinsetTF{\detokenize{#1}}\cpt@parserlist{}{% \cpt@listparsererr{#1}% }% @@ -2402,7 +2556,6 @@ \robust@def*\cpt@listparsererr#1{% \cpt@err{Invalid list parser '\detokenize{#1}'}\@ehc } -\new@def*\ifsecondis@nnil#1#2\cpt@nil{\ifxTF#2\cpt@nnil} \robust@def*\postgroupdef#1\endgroup{% \cptpassexpanded{\endgroup\cpt@csexit{#1}}% } @@ -2459,7 +2612,6 @@ \unexpanded{#1}% }% } - \begingroup \catcode`\&=7 \new@gdef*\cptfullexpand#1{% @@ -2484,7 +2636,6 @@ } \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}% @@ -2511,8 +2662,6 @@ }% }% } -% Test if <str1>, etc, is in <teststr> -% [<default act>]{<teststr>}{<{str1}{act1}{str2}{act2}...>} \new@def*\IfStrPresentCase#1{\cpt@xtestopt{#1}\cpt@ifstrincase{}} \new@def\cpt@ifstrincase[#1]#2#3{% \expandafter\cptswapfirstbraced\expandafter{#2}% @@ -2532,7 +2681,7 @@ } \robust@def\ifinsetTF#1#2{% \cpt@in{#1}{#2}% - \csname @\ifcpt@in first\else second\fi oftwo\endcsname + \usename{@\ifcpt@in first\else second\fi oftwo}% } \robust@def\ifinsetFT#1#2{\ifinsetTF{#1}{#2}\@secondoftwo\@firstoftwo} \robust@def\oifinsetTF#1#2{\cptexpandtwoargsonce\ifinsetTF{#1}{#2}} @@ -2557,13 +2706,13 @@ \begingroup \toks@{\endgroup \ifdefTF#4{% - \if@boolTF{cpt@st}{% - \usename{protected@#2def}#4{\cptliststack#3#4#1{#5}}% + \ifboolTF{cpt@st}{% + \usename{protected@#2def}#4{\csliststack#3#4#1{#5}}% }{% - \usename{#2def}#4{\cptliststack#3#4#1{#5}}% + \usename{#2def}#4{\csliststack#3#4#1{#5}}% }% }{% - \if@boolTF{cpt@st}{% + \ifboolTF{cpt@st}{% \usename{protected@#2def}#4{#1{#5}}% }{% \usename{#2def}#4{#1{#5}}% @@ -2578,13 +2727,13 @@ } \robust@def*\cptfilterremovecsv{% \begingroup - \let\cpt@inkv\cptfalse + \let\cpt@inkv\cptswfalse \let\temp@parse\csv@@parse \cpt@testopt\cpt@filterremoveelements{,}% } \robust@def*\cptfilterremovekv{% \begingroup - \let\cpt@inkv\cpttrue + \let\cpt@inkv\cptswtrue \let\temp@parse\kv@@parse \cpt@testopt\cpt@filterremoveelements{,}% } @@ -2651,7 +2800,7 @@ \edef\cpt@update{\unexpanded{#3}}% }% \def\cpt@add##1{% - \edef#2{\cptliststack#1#2\everymergeitem{\expandcsonce{##1}}}% + \edef#2{\csliststack#1#2\everymergeitem{\expandcsonce{##1}}}% }% \expandafter\def\temp@do##1{% \cpt@choicefdfalse @@ -2669,7 +2818,7 @@ \fi }% \cptexpandargonce{\def#2{}\temp@parse[#1]}#2% - \if@boolTF{cpt@choicefd}{}{\cpt@add\cpt@merge@a}% + \ifboolTF{cpt@choicefd}{}{\cpt@add\cpt@merge@a}% }% \ifcsnullTF#2{% \edef#2{\expandcsonce\cpt@update}% @@ -2694,14 +2843,12 @@ }% \xifinsetTF{\detokenize{#1##1#1}}{\pser\cptoxdetok{#2}\pser}{% \expandafter\cpt@remove@b\expandafter#1#2#1\remove@nil - \if@boolTF{removest}{% + \ifboolTF{removest}{% \expandafter\cpt@remove@a\expandafter{\cpt@remove@c}% }{}% }{}% }% - \ifswitchTF{cpt@fromrem}{% - % We're coming from \cptremoveelements, #3 has been - % trimmed and #2 has already been normalized: + \ifdefswitchTF{cpt@fromrem}{% \edef\cpt@remove@c{\unexpanded{#3}}% }{% \cpt@sttrue\cpt@csvnormalize[#1]#2% @@ -2709,7 +2856,7 @@ }% \let\cpt@remove@d#2% \expandafter\cpt@remove@a\expandafter{\cpt@remove@c}% - \ifswitchTF{cpt@fromrem}{}{% + \ifdefswitchTF{cpt@fromrem}{}{% \ifx\cpt@remove@d#2\ifcpt@verbose \cpt@warn{The list in \noexpand#2 not updated: \MsgBrk perhaps something was wrong}% @@ -2721,7 +2868,7 @@ \robust@def\cpt@removeelements[#1]#2#3{% \begingroup \edef\cpt@resa{\ifcpt@st*\fi}% - \let\cpt@fromrem\cpttrue + \let\cpt@fromrem\cptswtrue \cpt@sttrue\cpt@csvnormalize[#1]#2% \long\def\csv@do##1{% \expandafter\cptremoveoneelement\cpt@resa[#1]#2{##1}% @@ -2741,14 +2888,12 @@ }% \xifinsetTF{\detokenize{#1##1#1}}{\pser\cptoxdetok#2\pser}{% \expandafter\cpt@replace@b\expandafter#1#2#1\rep@nil - \if@boolTF{replst}{% + \ifboolTF{replst}{% \expandafter\cpt@replace@a\expandafter{\cpt@replace@c}% }{}% }{}% }% - \ifswitchTF{cpt@fromrepl}{% - % We're coming from \cptreplaceelements, #3 has been - % trimmed and #2 has already been normalized: + \ifdefswitchTF{cpt@fromrepl}{% \edef\cpt@replace@c{\unexpanded{#3}}% }{% \cpt@sttrue\cpt@csvnormalize[#1]#2% @@ -2756,7 +2901,7 @@ }% \let\cpt@replace@d#2% \expandafter\cpt@replace@a\expandafter{\cpt@replace@c}% - \ifswitchTF{cpt@fromrepl}{}{% + \ifdefswitchTF{cpt@fromrepl}{}{% \ifx\cpt@replace@d#2\ifcpt@verbose \cpt@warn{The list in \noexpand#2 not updated: \MsgBrk something was wrong}% @@ -2782,7 +2927,7 @@ }% }% }% - \let\cpt@fromrepl\cpttrue + \let\cpt@fromrepl\cptswtrue \cptexpandsecond\cpt@replace@d{% \expandcsonce\cpt@replace@a#1\noboundary \expandcsonce\cpt@replace@b#1\noboundary @@ -2814,7 +2959,7 @@ }% }% } -\robust@def*\csn@newif#1{% +\robust@def*\csnnewif#1{% \ifstrcmpTF{#1}{x}{% \cpt@err{Redefining '\cptmakecs{ifx}'?}\@ehc }{% @@ -2825,21 +2970,32 @@ \robust@def*\csn@gdef{\aftercsname\gdef} \robust@def*\csn@edef{\aftercsname\edef} \robust@def*\csn@xdef{\aftercsname\xdef} -\new@def*\cpt@csnd@f#1#2#3{% - \ifcsndefTF{#3}{% - \def\reserved@a{#3}\cpt@notdefinable - }{% - #1\l@ngrel@x\aftercsname\aftercsname{#2def}{#3}% - }% +\robust@def*\csndef{\cpt@starorlong{\cpt@csndef{}{}{}}} +\robust@def*\csnpdef{\cpt@starorlong{\cpt@csndef{}{p}{}}} +\robust@def*\csngdef{\cpt@starorlong{\cpt@csndef{}{}{g}}} +\robust@def*\csnpgdef{\cpt@starorlong{\cpt@csndef{}{p}{g}}} +\robust@def*\csnedef{\cpt@starorlong{\cpt@csndef{}{}{e}}} +\robust@def*\csnpedef{\cpt@starorlong{\cpt@csndef{}{p}{e}}} +\robust@def*\csnxdef{\cpt@starorlong{\cpt@csndef{}{}{x}}} +\robust@def*\csnpxdef{\cpt@starorlong{\cpt@csndef{}{p}{x}}} +\robust@def*\newcsndef{\cpt@starorlong{\cpt@csndef{n}{}{}}} +\robust@def*\newcsnpdef{\cpt@starorlong{\cpt@csndef{n}{p}{}}} +\robust@def*\newcsngdef{\cpt@starorlong{\cpt@csndef{n}{}{g}}} +\robust@def*\newcsnpgdef{\cpt@starorlong{\cpt@csndef{n}{p}{g}}} +\robust@def*\newcsnedef{\cpt@starorlong{\cpt@csndef{n}{}{e}}} +\robust@def*\newcsnpedef{\cpt@starorlong{\cpt@csndef{n}{p}{e}}} +\robust@def*\newcsnxdef{\cpt@starorlong{\cpt@csndef{n}{}{x}}} +\robust@def*\newcsnpxdef{\cpt@starorlong{\cpt@csndef{n}{p}{x}}} +\new@def*\cpt@csndef#1#2#3#4{% + \if#1n\relax + \ifcsndefTF{#4}{% + \def\reserved@a{#4}\cpt@notdefinable + }{}% + \fi + \if#2p\relax\let\reserved@a\protected\else + \let\reserved@a\relax\fi + \reserved@a\l@ngrel@x\aftercsname\aftercsname{#3def}{#4}% } -\robust@def*\csndef{\cpt@starorlong{\cpt@csnd@f{}{}}} -\robust@def*\csnpdef{\cpt@starorlong{\cpt@csnd@f\protected{}}} -\robust@def*\csngdef{\cpt@starorlong{\cpt@csnd@f{}{g}}} -\robust@def*\csnpgdef{\cpt@starorlong{\cpt@csnd@f\protected{g}}} -\robust@def*\csnedef{\cpt@starorlong{\cpt@csnd@f{}{e}}} -\robust@def*\csnpedef{\cpt@starorlong{\cpt@csnd@f\protected{e}}} -\robust@def*\csnxdef{\cpt@starorlong{\cpt@csnd@f{}{x}}} -\robust@def*\csnpxdef{\cpt@starorlong{\cpt@csnd@f\protected{x}}} \robust@def*\letcsntocs#1{\cptthreexp\let\usename{#1}} \robust@def*\gletcsntocs#1{\global\cptthreexp\let\usename{#1}} \robust@def*\letcstocsn#1#2{% @@ -2873,7 +3029,8 @@ \robust@def*\undefcsset{\cpt@testst{\cpt@testcl\cpt@undefcsset}} \robust@def*\cpt@undefcsset#1{% \cpt@stchoose{cpt@st}{#1}\cpt@rsvda\undefcsset - \cpt@sttrue\cpt@csvnormalize[,]\cpt@rsvda + \edef\cpt@rsvda + {\expandafter\cptcommanormalize\expandafter{\cpt@rsvda}}% \def\do##1,{% \ifnot@nil{##1}{% \ifsingletoken@sp@TF{##1}{% @@ -2891,13 +3048,12 @@ \expandafter\do\cpt@rsvda,\@nil,% } \robust@def*\cpttrimleadparsers#1#2{% - \ifcat$\detokenize\expandafter{\@gobble#1.}$% + \ifblankTF{#1}{% \cpt@err{Empty parser in \string\cpttrimleadparsers}\@ehc - \fi + }{}% \begingroup \ifcat$\detokenize\expandafter\expandafter\expandafter {\expandafter\@gobble#2.}$\cpt@defrelax\fi - \cpt@relax \def\reserved@e##1#1{% \edef\reserved@a{\unexpanded\expandafter{\@gobble##1}}% \ifx\reserved@a\@empty @@ -2912,23 +3068,39 @@ \expandafter\reserved@e\expandafter.#2#1\noboundary \postgroupdef#2\endgroup\cpt@relax } -\robust@def*\cpttrimparsers{\cpt@testopt\cpt@trimparsers{,}} -\robust@def\cpt@trimparsers[#1]#2{% +\robust@def\cpttrimtrailparsers#1#2{% \begingroup - \def\cpt@trima##1{% - \xifinsetTF{##1\batchmode}{\cptoxdetok{#2}\batchmode}{% - \def\reserved@a####1##1\batchmode{% + \def\cpt@trima{% + \xifinsetTF{\detokenize{#1}\noboundary} + {\cptoxdetok{#2}\noboundary}{% + \def\reserved@a####1#1\noboundary{% \edef#2{\expandcsonce{\@gobble####1}}% - \cpt@trima{##1}% + \cpt@trima }% - \expandafter\reserved@a\expandafter.#2\batchmode - }{% - \cpttrimleadparsers{##1}#2% - }% + \expandafter\reserved@a\expandafter.#2\noboundary + }{}% }% - \s@expandarg\cpt@trima{\detokenize{#1}}% + \cpt@trima \postgroupdef#2\endgroup } +\robust@def*\cpttrimparsers{\cpt@testopt\cpt@trimparsers{,}} +\robust@def*\cpt@trimparsers[#1]#2{% + \ifsingletokenTF{#1}{% + \cpttrimleadparsers{#1}#2% + \cpttrimtrailparsers{#1}#2% + }{% + \cpt@notonetokenerr{#1}% + }% +} +\robust@def\cpt@stripsuffix#1#2{% + \ifblankTF{#2}{% + \cpt@err{Blank test token for \string\cpt@stripsuffix}\@ehc + }{% + \edef\reserved@a{% + \ifblankTF{#1}{}{\ifstrcmpTF{#1}{#2}{}{\unexpanded{#1}}}% + }% + }% +} \robust@def*\stripouterbraces{\cpt@testopt\cpt@stripouterbraces\@ne} \robust@def\cpt@stripouterbraces[#1]{% \begingroup @@ -2998,8 +3170,6 @@ \repeat \postgroupdef#3\endgroup } - -% Expandable: \edef\ifmacroTF#1{% \noexpand\ifblankTF{#1}{% \noexpand\@secondoftwo @@ -3029,10 +3199,6 @@ {@\ifx\x\@backslashchar first\else second\fi oftwo}% } \robust@def*\ifescapedFT#1{\ifescapedTF{#1}\@secondoftwo\@firstoftwo} -% \robustaliascount counts the number of 'robustified' commands. -% It may be used to set a threshold for the no. of allowable -% aliases. Only non-parametered macros may be aliased in the -% following way! \ifcsdefinable\maxrobustalias{\chardef\maxrobustalias20} \newcommand*\cptrobustify[1]{% \def\csv@do##1{% @@ -3216,16 +3382,16 @@ }% } \new@def*\iftogFT#1{\iftogTF{#1}\@secondoftwo\@firstoftwo} -\new@def*\cpttrue{00} -\new@def*\cptfalse{01} +\new@def*\cptswtrue{00} +\new@def*\cptswfalse{01} \def\reserved@a#1{% - \new@def*\cptnegate##1{% + \new@def*\negatesw##1{% 0\ifcase##11#1\or\expandafter1\else\expandafter0\fi }% - \new@def*\cptbothtrue##1##2{% + \new@def*\bothswtrue##1##2{% 0\ifcase##1##2#1\expandafter0\else\expandafter1\fi }% - \new@def*\cptonetrue##1##2{% + \new@def*\oneswtrue##1##2{% 0\ifnum##1##2<101#1\expandafter0\else\expandafter1\fi }% } @@ -3236,21 +3402,20 @@ \cpt@err{Command \noexpand\newswitch doesn't accept list} {Please submit only one switch to \string\newswitch.}% }{}% - \xifinsetTF{,#1,}{,if,x,switch,tog,bool,}{% + \xifinsetTF{,#1,}{,if,x,switch,tog,togg,bool,test,}{% \cpt@err{Invalid switch name '#1'}\@ehc }{}% \ifcsndefinable{#1}\relax \cpt@getswitchstate{#2}% - \letcsntocsn{#1}{cpt\cpt@switchstate}% + \letcsntocsn{#1}{cptsw\cpt@switchstate}% } \robust@def*\cpt@getswitchstate#1{% - \lowercase{% - \xifinsetTF{,#1,}{,true,false,}{% - \edef\cpt@switchstate{#1}% - }{% - \cpt@err{Invalid switch value '#1'} - {Valid switch values are 'true' and 'false'.}% - }% + \lowercase{\edef\cpt@tempa{\cpttrimspaces{#1}}}% + \xifinsetTF{,\cpt@tempa,}{,true,false,}{% + \let\cpt@switchstate\cpt@tempa + }{% + \cpt@err{Invalid switch value '#1'} + {Valid switch values are 'true' and 'false'.}% }% } \robust@def*\cpt@noswitcherr#1{% @@ -3259,14 +3424,14 @@ \robust@def*\setswitch#1#2{% \ifcsndefTF{#1}{% \cpt@getswitchstate{#2}% - \letcsntocsn{#1}{cpt\cpt@switchstate}% + \letcsntocsn{#1}{cptsw\cpt@switchstate}% }{% \cpt@noswitcherr{#1}% }% } \robust@def*\setswitchtrue#1{% \ifcsndefTF{#1}{% - \letcsntocs{#1}\cpttrue + \letcsntocs{#1}\cptswtrue }{% \cpt@noswitcherr{#1}% }% @@ -3274,13 +3439,13 @@ \newletcs\switchtrue\setswitchtrue \robust@def*\setswitchfalse#1{% \ifcsndefTF{#1}{% - \letcsntocs{#1}\cptfalse + \letcsntocs{#1}\cptswfalse }{% \cpt@noswitcherr{#1}% }% } \newletcs\switchfalse\setswitchfalse -\new@def*\ifswitchTF#1{% +\new@def*\ifdefswitchTF#1{% \ifcsndefFT{#1}{% \cpt@err{Switch '#1' is not defined}\@ehc \@gobbletwo @@ -3288,10 +3453,134 @@ \ifcondTF\if\usename{#1}\fi }% } -\new@def*\if@switchTF#1{\ifcondTF\if\usename{#1}\fi} +\new@def*\ifdefswitchFT#1{\ifdefswitchTF{#1}\@secondoftwo\@firstoftwo} +\new@def*\ifswitchTF#1{\ifcondTF\if\usename{#1}\fi} \new@def*\ifswitchFT#1{\ifswitchTF{#1}\@secondoftwo\@firstoftwo} -\new@def*\thebool@normal#1{\ifboolTF{#1}{true}{false}} -\new@def*\thebool@reverse#1{\ifboolTF{#1}{false}{true}} +\new@def*\thebool@normal#1{\ifdefboolTF{#1}{true}{false}} +\new@def*\thebool@reverse#1{\ifdefboolTF{#1}{false}{true}} +\newvariables{count}[cpt@]{exprcnt}[0] +\robust@def*\ifexprTF#1{% + \begingroup + \let\cpt@expr@neg\cptswfalse + \cpt@exprcnt\z@pt + \cpt@expr@beg + \cpt@expr@bgroup#1(\expr@nil + \cpt@expr@end + \cpt@expr@eval +} +\def\cpt@expr@beg{% + \begingroup + \let\cpt@expr@neg\cptswfalse + \cpt@exprcnt\z@pt +} +\def\cpt@expr@end{% + \cpt@expr@eval\cpt@expr@true\cpt@expr@false +} +\def\cpt@expr@eval{% + \aftercsname\endgroup + {@\ifnum\cpt@exprcnt<\z@pt second\else first\fi oftwo}% +} +\def\cpt@expr@true{% + \advance\cpt@exprcnt\if\cpt@expr@neg\m@one\else\z@pt\fi + \let\cpt@expr@neg\cptswfalse +} +\def\cpt@expr@false{% + \advance\cpt@exprcnt\if\cpt@expr@neg\z@pt\else\m@one\fi + \let\cpt@expr@neg\cptswfalse +} +\long\def\cpt@expr@bgroup#1(#2\expr@nil{% + \cpt@expr@egroup#1)\expr@nil + \ifblankTF{#2}{}{% + \cpt@expr@beg + \cpt@expr@bgroup#2\expr@nil + }% +} +\long\def\cpt@expr@egroup#1)#2\expr@nil{% + \cpt@expr@and#1and\expr@nil + \ifblankTF{#2}{}{% + \cpt@expr@end + \cpt@expr@egroup#2\expr@nil + }% +} +\long\def\cpt@expr@and#1and#2\expr@nil{% + \cpt@expr@or#1or\expr@nil + \ifblankTF{#2}{}{% + \cpt@exprcnt\ifnum\cpt@exprcnt<\z@pt\m@one\else\z@pt\fi + \cpt@expr@and#2\expr@nil + }% +} +\long\def\cpt@expr@or#1or#2\expr@nil{% + \cpt@expr@not#1not\expr@nil + \ifblankTF{#2}{}{% + \cpt@exprcnt\ifnum\cpt@exprcnt<\z@pt\z@pt\else\@ne\fi + \cpt@expr@or#2\expr@nil + }% +} +\long\def\cpt@expr@not#1not#2\expr@nil{% + \cpt@expr@tog#1tog\expr@nil + \ifblankTF{#2}{}{% + \let\cpt@expr@neg\cptswtrue + \cpt@expr@not#2\expr@nil + }% +} +\long\def\cpt@expr@tog#1tog#2\expr@nil{% + \cpt@expr@bool#1bool\expr@nil + \ifblankTF{#2}{}{\cpt@expr@tog@a#2\expr@nil}% +} +\long\def\cpt@expr@tog@a#1#2\expr@nil{% + \edef\reserved@a{\cpttrimspaces{#1}}% + \ifcsndefTF{cpt@tog@\reserved@a}{% + \usename{cpt@tog@\reserved@a}\cpt@expr@true\cpt@expr@false + }{% + \cpt@err{Invalid test expression: + \MsgBrk toggle '\reserved@a' is undefined}\@ehc + \cpt@expr@false + }% + \cpt@expr@tog#2\expr@nil +} +\long\def\cpt@expr@bool#1bool#2\expr@nil{% + \cpt@expr@switch#1switch\expr@nil + \ifblankTF{#2}{}{\cpt@expr@bool@a#2\expr@nil}% +} +\long\def\cpt@expr@bool@a#1#2\expr@nil{% + \edef\reserved@a{\cpttrimspaces{#1}}% + \ifcsndefTF{if\reserved@a}{% + \ifboolTF\reserved@a\cpt@expr@true\cpt@expr@false + }{% + \cpt@err{Invalid test expression: + \MsgBrk boolean '\reserved@a' is undefined}\@ehc + \cpt@expr@false + }% + \cpt@expr@bool#2\expr@nil +} +\long\def\cpt@expr@switch#1switch#2\expr@nil{% + \cpt@expr@test#1test\expr@nil + \ifblankTF{#2}{}{\cpt@expr@switch@a#2\expr@nil}% +} +\long\def\cpt@expr@switch@a#1#2\expr@nil{% + \edef\reserved@a{\cpttrimspaces{#1}}% + \ifcsndefTF\reserved@a{% + \ifswitchTF\reserved@a\cpt@expr@true\cpt@expr@false + }{% + \cpt@err{Invalid test expression: + \MsgBrk switch '\reserved@a' is undefined}\@ehc + \cpt@expr@false + }% + \cpt@expr@switch#2\expr@nil +} +\long\def\cpt@expr@test#1test#2\expr@nil{% + \ifblankTF{#1}{}{% + \cpt@err{Invalid piece in test expression: + \MsgBrk'\detokenize{#1}'}\@ehc + }% + \ifblankTF{#2}{}{% + \cpt@expr@test@a#2\expr@nil + }% +} +\long\def\cpt@expr@test@a#1#2\expr@nil{% + \ignorespaces#1\cpt@expr@true\cpt@expr@false + \cpt@expr@test#2\expr@nil +} \new@def*\cpt@beforeprocessoptions{} \new@def*\cpt@afterprocessoptions{} \robust@def*\BeforeProcessOptions{% @@ -3330,26 +3619,22 @@ \gundefcsn{\@currname.\@currext-cpt@hook}% }% } -\robust@def*\ifpackagewithoptionsTF{% - \begingroup\cpt@ifoptions\@pkgextension -} -\robust@def*\ifclasswithoptionsTF{% - \begingroup\cpt@ifoptions\@clsextension -} +\robust@def*\ifpackagewithoptionsTF{\cpt@ifoptions\@pkgextension} +\robust@def*\ifclasswithoptionsTF{\cpt@ifoptions\@clsextension} \robust@def*\cpt@ifoptions#1#2{% \cptexpandarg\cpt@ifopti@ns{\cpt@optionlist{#2.#1}}% } \robust@def*\cpt@ifopti@ns#1#2{% - \cpt@stfalse\cpt@kvnormalize[,]{#1}% - \let\temp@optlist\normalized@list + \begingroup + \edef\temp@optlist{\unexpanded{#1}}% + \cpt@sttrue\cpt@kvnormalize[,]\temp@optlist \cpt@choicefdtrue \def\kv@do##1{% \oifinset@sp@TF,{##1}\temp@optlist - {} - {\cpt@choicefdfalse\loopbreak}% + {}{\cpt@choicefdfalse\loopbreak}% }% \kv@@parse{#2}% - \if@boolTF{cpt@choicefd} + \ifboolTF{cpt@choicefd} {\endgroup\@firstoftwo}{\endgroup\@secondoftwo}% } \robust@def*\ifpackageloadedlaterTF{\cpt@ifpkgloadedlater\@pkgextension} @@ -3376,22 +3661,22 @@ \begingroup \toks@{}% \def\cpt@tempa##1##2\cpt@nil{% - \ifx\noboundary##2\noboundary + \ifblankTF{##2}{% \cpt@err{No outer parser or something wrong \MsgBrk while in \string\cptloadpackages}\@ehc - \expandafter\@gobble - \else + \@gobble + }{% \ifinsetFT{,}{##1##2}{}{% \cpt@err{Parser can't be comma (,) in \string\cptloadpackages}\@ehc \expandafter\@gobble }% - \fi + }% \def\cpt@lo@dpackages####1##1####2##1####3##1####4\cpt@nil{% - \ifx\noboundary####1\noboundary + \ifblankTF{####1}{% \cpt@err{No package name while in \string\cptloadpackages}\@ehc - \expandafter\@gobble - \fi + \@gobble + }{}% \ifblankTF{####2}{% \def\cpt@rsvda{}% }{% @@ -3444,7 +3729,11 @@ \expandafter\grightaddtocs \csname\@currname.\@currext-cpt@hook\endcsname }% - \ifcsnullTF\@currname\endgroup\cpt@tempa + \ifcsnullTF\@currname{% + \endgroup\@gobble + }{% + \cpt@tempa + }% } \robust@def*\ifinstylefileTF{% \ifcsemptyTF\@currname\@secondoftwo\@firstoftwo @@ -3502,12 +3791,12 @@ } \robust@def*\csv@@normalize{\cpt@teststopt\cpt@csvnormalize,} \robust@def\cpt@csvnormalize[#1]#2{% - \let\cpt@inkv\cptfalse + \let\cpt@inkv\cptswfalse \cpt@normalizelist{#1}{#2}% } \robust@def*\kv@@normalize{\cpt@teststopt\cpt@kvnormalize,} \robust@def\cpt@kvnormalize[#1]#2{% - \let\cpt@inkv\cpttrue + \let\cpt@inkv\cptswtrue \cpt@normalizelist{#1}{#2}% } \ifcsdefinable\normalized@list\relax @@ -3516,18 +3805,16 @@ \let\ifnmlzst\ifcpt@st \cpt@stchoose{cpt@st}{#2}\reserved@e\cpt@normalizelist \ifx\reserved@e\@empty - \def\normalized@list{}% - \def\cpt@relax##1\cpt@relax{\endgroup\let\cpt@relax\relax}% + \def\normalized@list{}\cpt@defrelax \fi - \cpt@relax - \cpt@checklistparser@b{#1}% + \cpt@ch@cklistparser{#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% - \ifswitchFT{cpt@inkv}{}{% + \ifdefswitchFT{cpt@inkv}{}{% \nmlz@activeequal \nmlz@spaceletter=% \nmlz@letterspace=% @@ -3537,7 +3824,7 @@ \edef\normalized@list{\the\toks@}% \cpttrimleadparsers#1\normalized@list \cptexpandsecond\endgroup{% - \if@boolTF{nmlzst}{% + \ifboolTF{nmlzst}{% \edef\noexpand#2{\ox@unexpanded\normalized@list}% \undefcs\noexpand\normalized@list }{% @@ -3636,8 +3923,10 @@ }% \csv@@parse*\@filelist \ifdefTF\cpt@documentclass{}{% - \@latex@info@no@line{'catoptions' package loaded before - \string\documentclass: \MsgBrk no problem}% + \ifcpt@verbose + \@latex@info@no@line{'catoptions' package loaded before + \string\documentclass: \MsgBrk no problem}% + \fi }% } \cptpassunexpanded{% @@ -3647,7 +3936,6 @@ }% }% \ifxTF\cpt@documentclass\cpt@undefined{% - \let\cpt@documentclass\@empty \let\cpt@classoptionslist\@empty }{% \ifxTF\@classoptionslist\relax{}{% @@ -3657,11 +3945,12 @@ }% \let\cpt@classoptionslist\@classoptionslist \def\@fileswith@ptions##1[##2]##3{% - \cpt@stfalse\cpt@csvnormalize[,]{##3}% + \edef\cpt@tempa{\cptcommanormalize{##3}}% \cpt@choicefdfalse \def\do####1,{% \ifnot@nil{####1}{% - \xifinsetFT{,####1,}{,\normalized@list,}{}\cpt@choicefdtrue + \xifinsetFT{,####1,}{,\cpt@tempa,} + {}\cpt@choicefdtrue \do }% }% @@ -3683,90 +3972,28 @@ }% } \robust@def*\cpt@testfam#1{% - \CurrIfnextchar<{#1}{#1<\@currname.\@currext>}% -} -\robust@redef\@pass@ptions#1#2#3{% - \begingroup - \ifsingletokenTF{#2}{% - \ifmacroTF{#2}{% - \let\@expand\expandcsonce - }{% - \let\@expand\unexpanded - }% - }{% - \let\@expand\unexpanded - }% - \ifcsndefTF{opt@#3.#1}{% - \ifblankTF{#2}{}{% - \cptexpandarg{\cptexpandsecond{\cptfiltermergekv[,]}% - {\cptmakecs{opt@#3.#1}}}{\@expand{#2}}{}% - }% - }{% - \csn@edef{opt@#3.#1}{\@expand{#2}}% - }% - \globalizecsn{opt@#3.#1}% - \endgroup -} -\robust@redef*\OptionNotUsed{% - \ifxTF\@currext\@clsextension{% - \cptexpandargonce{\cptfiltermergekv[,]% - \@unusedoptionlist}\CurrentOption\nofilter - }{}% -} -\robust@redef*\@use@ption{% - \oifinset@sp@FT,\CurrentOption\@unusedoptionlist{}{% - \cptexpandargonce{\cptfilterremovekv[,]% - \@unusedoptionlist}\CurrentOption\nofilter - }% - \csname ds@\CurrentOption\endcsname -} -\robust@redef*\@fileswith@pti@ns#1[#2]#3[#4]{% - \begingroup - \edef\fileopts{\unexpanded{#2}}% - \ifcsnullTF\fileopts{}{\cpt@sttrue\cpt@kvnormalize[,]\fileopts}% - \def\fileswithopts##1##2{% - \noexpand\@onefilewithoptions{##1}% - [\expandcsonce\fileopts]\unexpanded{[#4]##2}% - }% - \def\file@withopts##1{\cptpassexpanded{\toks@{##1}}}% - \toks@{}% - \ifxTF#1\@clsextension{% - \ifx\@classoptionslist\relax - \xdef\@classoptionslist{\expandcsonce\fileopts}% - \file@withopts{\fileswithopts{#3}{#1\@documentclasshook}}% - \else - \file@withopts{\fileswithopts{#3}{#1}}% - \fi - }{% - \edef\cpt@tempa{\cptzapspaces{#3}}% - \DiscardEmptyEntry - \def\csv@do##1{% - \file@withopts{\the\toks@\fileswithopts{##1}\@pkgextension}% - }% - \csv@@loop*\cpt@tempa - }% - \expandafter\endgroup\the\toks@ + \ifnextcharTF<{#1}{#1<\@currname.\@currext>}% } -\let\@@fileswith@pti@ns\@fileswith@pti@ns \robust@def*\RecoverAtRequirePackage#1{% \ifblankFT{#1}{}{% \cpt@isblankerr\RecoverAtRequirePackage }% \begingroup - \def\csv@do##1{% + \docommalist{#1}{% \ifescapedTF{##1}{% \ifdefTF{##1}{}{% - \cpt@notdeferr{##1}\@gobble + \cpt@notdeferr{##1}% + \@gobble }% }{% \cpt@notescapederr{##1}% \@gobble }% - \ifcsndefinable{atpush@\cptremovescape##1}{% - \gletcsntocs{atpush@\cptremovescape##1}##1% + \ifcsndefinable{cpt@atpush@\cptremovescape##1}{% + \gletcsntocs{cpt@atpush@\cptremovescape##1}##1% }% \edef\cpt@tempa{% - \gletcs\unexpanded{##1}=\noexpandcsn{atpush@\cptremovescape##1}% + \gletcs\unexpanded{##1}=\noexpandcsn{cpt@atpush@\cptremovescape##1}% }% \xifinsetTF{\cptoxdetok\cpt@tempa}{\cptoxdetok\@pushfilename}{}{% \xdef\@pushfilename{% @@ -3774,7 +4001,6 @@ }% }% }% - \csv@@parse[,]{#1}% \endgroup } \robust@def*\cpt@badoptionerr#1{% @@ -3801,18 +4027,18 @@ } \robust@def\cpt@d@clareoption#1#2[#3]#4{% \cpt@d@cl@reoption{#1}{#2}{#3}% - \if@boolTF{cpt@olddx}{% + \ifboolTF{cpt@olddx}{% \xifstrcmpTF{\@currname.\@currext}{xcolor.sty}{% - \long\csn@xdef{#1@ds@#2}{% + \csn@xdef{#1@ds@#2}{% \unexpanded{\edef\XC@@opt{\XC@@opt#2,}#4}% }% }{% - \long\csn@xdef{#1@ds@#2}{\unexpanded{#4}}% + \csn@xdef{#1@ds@#2}{\unexpanded{#4}}% }% }{% \begingroup \long\def\cpt@tempa##1{\endgroup - \long\csn@gdef{#1@ds@#2}####1{##1}% + \csn@gdef{#1@ds@#2}####1{##1}% }% \cpt@tempa{#4}% }% @@ -3890,10 +4116,10 @@ \MsgBrk is invalid or null}{% Invalid option '##1' of family '#1'.}% }% - \if@boolTF{cpt@olddx}{% - \long\csn@xdef{#1@ds@##1}{\cpt@temp@err}% + \ifboolTF{cpt@olddx}{% + \csn@xdef{#1@ds@##1}{\cpt@temp@err}% }{% - \long\csn@xdef{#1@ds@##1}####1{\cpt@temp@err}% + \csn@xdef{#1@ds@##1}####1{\cpt@temp@err}% }% \endgroup }% @@ -3903,25 +4129,25 @@ } \robust@def*\XDeclareCommandOption{% \let\@fileswith@pti@ns\@badrequireerror - \let\cmdoption\cpttrue + \let\cmdoption\cptswtrue \cpt@testfam\cpt@declarecmdoption } \robust@def*\XDeclareCommandOptions{% \let\@fileswith@pti@ns\@badrequireerror - \let\cmdoption\cpttrue + \let\cmdoption\cptswtrue \cpt@testfam\cpt@declarecmdoptions } \robust@def*\XDeclareBooleanOption{% \let\@fileswith@pti@ns\@badrequireerror - \let\cmdoption\cptfalse + \let\cmdoption\cptswfalse \cpt@testfam\cpt@declarecmdoption } \robust@def*\XDeclareBooleanOptions{% \let\@fileswith@pti@ns\@badrequireerror - \let\cmdoption\cptfalse + \let\cmdoption\cptswfalse \cpt@testfam\cpt@declarecmdoptions } -\robust@def*\cpt@checkbool#1#2#3{% +\robust@def*\cptcheckbool#1#2#3{% \lowercase{% \edef\cpt@resa{\s@expandarg\cpttrimspaces{\cptrm-`\q#1}}% }% @@ -3947,13 +4173,13 @@ \if\cmdoption \def\cpt@rsvda{\csn@def{#4#2}{####1}}% \else - \csn@newif{#4#2}% + \csnnewif{#4#2}% \def\cpt@rsvda{% - \cpt@checkbool{####1}{option #2}{\usename{#4#2\cpt@resa}}% + \cptcheckbool{####1}{option #2}{\usename{#4#2\cpt@resa}}% }% \fi \long\def\cpt@rsvdb##1{% - \long\csn@gdef{#1@ds@#2}####1{##1\relax}% + \csn@gdef{#1@ds@#2}####1{##1\relax}% }% \expandafter\cpt@rsvdb\expandafter{\cpt@rsvda#5}% } @@ -3981,7 +4207,7 @@ } \robust@def*\XDeclareBiBooleanOptions{% \let\@fileswith@pti@ns\@badrequireerror - \let\cmdoption\cptfalse + \let\cmdoption\cptswfalse \cpt@testfam\cpt@declarebibooloptions } \robust@def*\cpt@declarebibooloptions<#1>#2{% @@ -4049,19 +4275,19 @@ \cptexpandarg\cpt@testopt {\cpt@d@clareswoption{\cpt@currfam}{\cpt@curropt}}{}% } -\robust@def\cpt@d@clareswoption#1#2[#3]{% +\robust@def*\cpt@d@clareswoption#1#2[#3]{% \cptexpandarg{\cpt@testpnopt{\cpt@d@cl@reswoption {#1}{#2}{#3}}}{\@currname @}% } -\robust@def\cpt@d@cl@reswoption#1#2#3(#4)#5{% +\robust@def*\cpt@d@cl@reswoption#1#2#3(#4)#5{% \cpt@d@cl@reoption{#1}{#2}{#3}% \def\cpt@rsvda{% - \cpt@checkbool{####1}{#2}{% - \letcsntocsn{#4#2}{cpt\cpt@resa}% + \cptcheckbool{####1}{#2}{% + \letcsntocsn{#4#2}{cptsw\cpt@resa}% }% }% \long\def\cpt@rsvdb##1{% - \long\csn@gdef{#1@ds@#2}####1{##1\relax}% + \csn@gdef{#1@ds@#2}####1{##1\relax}% }% \expandafter\cpt@rsvdb\expandafter{\cpt@rsvda#5}% } @@ -4147,7 +4373,7 @@ \csv@@parse*[,]\cpt@curropts } \robust@def*\XLogDisabledOptions{% - \CurrIfnextchar<\cpt@disabledoptionlist + \ifnextcharTF<\cpt@disabledoptionlist \cpt@dis@bledoptionlist } \robust@def*\cpt@disabledoptionlist<#1>{% @@ -4203,7 +4429,7 @@ \cpt@ifoptdis@bled{##1}{#2}% }% \csv@@parse*[,]\cpt@currfams - \if@boolTF{cpt@swa}\if@boolTF\if@boolFT{cpt@choicefd}% + \ifboolTF{cpt@swa}\ifboolTF\ifdefboolFT{cpt@choicefd}% } \robust@def*\cpt@ifoptdis@bled#1#2{% \ifcsndefFT{#1@disabledoptions}{}{% @@ -4225,7 +4451,7 @@ \cpt@ifoptd@f{##1}{#2}% }% \csv@@parse*[,]\cpt@currfams - \if@boolTF{cpt@swa}\if@boolTF\if@boolFT{cpt@choicefd}% + \ifboolTF{cpt@swa}\ifboolTF\ifdefboolFT{cpt@choicefd}% } \robust@def*\cpt@ifoptd@f#1#2{% \ifcsndefFT{#1@ds@#2}{}{% @@ -4295,7 +4521,7 @@ \cpt@testst{\cpt@testfam\cpt@processoptions}% } \robust@def*\cpt@processoptions<#1>{% - \if@boolTF{cpt@st}{% + \ifboolTF{cpt@st}{% \cpt@testopt{\cpt@xprocessoptions#1}{}% }{% \cpt@testopt{\cpt@yprocessoptions#1}{}% @@ -4319,7 +4545,7 @@ \edef\CurrentOption{\unexpanded{##1}}% \ifcsnullTF\CurrentOption{}{% \cpt@findoption@a - \if@boolFT{cpt@optfd}{}{% + \ifdefboolFT{cpt@optfd}{}{% \ifcsndefFT{#1@ds@\cpt@curropt}{}{% \ifcsnullTF\cpt@currna{% \cpt@igoptfalse @@ -4564,7 +4790,6 @@ }% \kv@@loop*[,]\cpt@curroptvals } -% Alias keys must always come from the parent's family: \robust@def*\XExecuteAliasOption#1{% \cpt@testopt{\cpt@executealiasoption#1}{}% } @@ -4619,7 +4844,7 @@ }% } \robust@def*\cpt@useoption{% - \if@boolFT{cpt@inpox}{}{% + \ifdefboolFT{cpt@inpox}{}{% \oifinset@sp@TF,\OptionFound\cpt@processedoptions{}{% \cptgaddtolist*\cpt@processedoptions\OptionFound }% @@ -4631,9 +4856,9 @@ \cpt@removecurroption\CurrentOption }% }% - \if@boolTF{cpt@igopt}{}{% + \ifboolTF{cpt@igopt}{}{% \ifcsndefFT{\cpt@currfam @ds@\cpt@curropt}{}{% - \if@boolTF{cpt@olddx}{% + \ifboolTF{cpt@olddx}{% \usename{\cpt@currfam @ds@\cpt@curropt}% }{% \ifcsnullTF\cpt@currval{% @@ -4730,9 +4955,9 @@ }% } \robust@def*\cpt@optionstate{% - \cpt@currfams,\cpt@curroptvals,\cpt@currfam,\cpt@currna, - \cpt@curropt,\cpt@currval,\CurrentOption,\OptionFound, - \ifcpt@inpox,\ifcpt@optfd,\ifcpt@igopt,\DeclaredOptions, + \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{% @@ -4762,12 +4987,203 @@ \BeforeStartOfDocument{% \cpt@cleanup\cpt@processedoptions } +\robust@redef*\@fileswith@pti@ns#1[#2]#3[#4]{% + \begingroup + \edef\fileopts{\unexpanded{#2}}% + \ifcsnullTF\fileopts{}{\cpt@sttrue\cpt@kvnormalize[,]\fileopts}% + \def\fileswithopts##1##2{% + \noexpand\@onefilewithoptions{##1}% + [\expandcsonce\fileopts]\unexpanded{[#4]##2}% + }% + \def\file@withopts##1{\cptpassexpanded{\toks@{##1}}}% + \toks@{}% + \ifxTF#1\@clsextension{% + \ifx\@classoptionslist\relax + \xdef\@classoptionslist{\expandcsonce\fileopts}% + \file@withopts{\fileswithopts{#3}{#1\@documentclasshook}}% + \else + \file@withopts{\fileswithopts{#3}{#1}}% + \fi + }{% + \edef\cpt@tempa{\cptzapspaces{#3}}% + \DiscardEmptyEntry + \def\csv@do##1{% + \file@withopts{\the\toks@\fileswithopts{##1}\@pkgextension}% + }% + \csv@@loop*\cpt@tempa + }% + \expandafter\endgroup\the\toks@ +} +\robust@redef*\@onefilewithoptions#1[#2][#3]#4{% + \@pushfilename + \xdef\@currname{#1}% + \global\let\@currext#4% + \letcsntocs{\@currname.\@currext-h@@k}\@empty + \let\CurrentOption\@empty + \@reset@ptions + \makeatletter + \defpass\reserved@a{% + \@ifl@aded\@currext{#1}{% + \cpt@ifoptions\@currext{#1}{#2}{}{% + \edef\reserved@a{\cpt@optionlist{#1.\@currext}}% + \@onelevel@sanitize\reserved@a + \ltx@err{Option clash for \@cls@pkg\space #1}{% + The package #1 has already been loaded + with options:\MsgBrk + \space\space[\reserved@a].\MsgBrk + There has now been an attempt to load it with options + \MsgBrk\space\space[\unexpanded{#2}].\MsgBrk + Adding the global options:\MsgBrk + \space\space'\reserved@a,\unexpanded{#2}'\MsgBrk + to your \noexpand\documentclass declaration may fix this. + }% + }% + }{% + \@pass@ptions\@currext{#2}{#1}% + \gletcsntocs{ver@\@currname.\@currext}\@empty + \InputIfFileExists{\@currname.\@currext}{}{% + \@missingfileerror\@currname\@currext + }% + \let\@unprocessedoptions\@@unprocessedoptions + \usename{\@currname.\@currext-h@@k}% + \undefcsn{\@currname.\@currext-h@@k}% + \@unprocessedoptions + }% + \def\cpt@tempa####1 v####2 ####3\@nil####4{% + \edef####4{'####1\ifblankTF{####2}{}{ v####2}'}% + }% + \cpt@tempa#3 v \@nil\cpt@tempb + \cptthreexp\cpt@tempa\csname ver@#1.\@currext + \expandafter\endcsname\@space v \@nil\cpt@tempc + \@ifl@ter\@currext{#1}{#3}{}{% + \cptexpandarg\AtEndDocument{% + \ltx@warn{% + You requested,\on@line, version\MsgBrk + \cpt@tempb\@space of \@cls@pkg\@space #1,\MsgBrk + but only version \cpt@tempc\MsgBrk is available + }% + }% + }% + \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi + \@popfilename + \@reset@ptions + }% +} +\robust@def*\cpt@removevalues#1{% + \docommalist{#1}{\cpt@rem@vevalues{##1}}% +} +\robust@def*\cpt@rem@vevalues#1{% + \ifxTF#1\@empty\gobble@to@relax\relax + \xifinsetTF{=}{\cptoxdetok{#1}}{}\gobble@to@relax + \begingroup + \def\cpt@resa{}% + \def\cpt@resb##1=##2\cpt@nil{% + \edef\cpt@resa{\csliststack,\cpt@resa\unexpanded{##1}}% + }% + \docommalist*{#1}{\cpt@resb##1=\cpt@nil}% + \let#1\cpt@resa + \postgroupdef#1\endgroup + \cpt@relax +} +\robust@redef*\ExecuteOptions#1{% + \pushfunctions\ExecuteOptions\CurrentOption\cpt@optdepth + \edef\CurrentOption{\unexpanded{#1}}% + \cpt@sttrue\cpt@kvnormalize[,]\CurrentOption + \cpt@removevalues\CurrentOption + \docommalist*\CurrentOption{% + \def\CurrentOption{##1}% + \csname ds@##1\endcsname + }% + \popfunctions\ExecuteOptions\cpt@optdepth +} +\robust@redef\@pass@ptions#1#2#3{% + \begingroup + \ifsingletokenTF{#2}{% + \ifmacroTF{#2}{% + \let\@expand\expandcsonce + }{% + \let\@expand\unexpanded + }% + }{% + \let\@expand\unexpanded + }% + \ifcsndefTF{opt@#3.#1}{% + \ifblankTF{#2}{}{% + \cptexpandarg{\cptexpandsecond{\cptfiltermergekv[,]}% + {\cptmakecs{opt@#3.#1}}}{\@expand{#2}}{}% + }% + }{% + \csn@edef{opt@#3.#1}{\@expand{#2}}% + }% + \globalizecsn{opt@#3.#1}% + \endgroup +} +\robust@redef*\OptionNotUsed{% + \ifxTF\@currext\@clsextension{% + \cptexpandargonce{\cptfiltermergekv[,]% + \@unusedoptionlist}\CurrentOption\nofilter + }{}% +} +\robust@redef*\@use@ption{% + \oifinset@sp@FT,\CurrentOption\@unusedoptionlist{}{% + \cptexpandargonce{\cptfilterremovekv[,]% + \@unusedoptionlist}\CurrentOption\nofilter + }% + \csname ds@\CurrentOption\endcsname +} +\let\@@fileswith@pti@ns\@fileswith@pti@ns +\robust@redef*\ProcessOptions{% + \pushfunctions\ProcessOptions\CurrentOption\cpt@optdepth + \cpt@sttrue\cpt@csvnormalize[,]\@declaredoptions + \cpt@sttrue\cpt@kvnormalize[,]\@classoptionslist + \edef\@curroptions{\cpt@optionlist{\@currname.\@currext}}% + \cpt@sttrue\cpt@kvnormalize[,]\@curroptions + \cpt@removevalues{\@classoptionslist,\@curroptions}% + \let\ds@\@empty + \cpt@ifstar\@xprocess@ptions\@process@ptions +} +\robust@redef*\@process@ptions{% + \edef\@curr@ptions{% + \ifx\@currext\@clsextension\else\expandcsonce + \@classoptionslist,\fi\expandcsonce\@curroptions + }% + \docommalist*\@declaredoptions{% + \def\CurrentOption{##1}% + \oifinset@sp@TF,\CurrentOption\@curr@ptions{% + \@use@ption + \letcsntocs{ds@##1}\@empty + }{}% + }% + \@process@pti@ns +} +\robust@redef*\@xprocess@ptions{% + \ifxTF\@currext\@clsextension{}{% + \docommalist*\@classoptionslist{% + \def\CurrentOption{##1}% + \oifinset@sp@TF,\CurrentOption\@declaredoptions{% + \@use@ption + \letcsntocs{ds@##1}\@empty + }{}% + }% + }% + \@process@pti@ns +} +\robust@redef*\@process@pti@ns{% + \docommalist*\@curroptions{% + \def\CurrentOption{##1}% + \ifcsndefTF{ds@##1}\@use@ption{\@use@ption\default@ds}% + }% + \docommalist*\@declaredoptions{\letcsntocs{ds@##1}\relax}% + \popfunctions\ProcessOptions\cpt@optdepth + \let\@fileswith@pti@ns\@@fileswith@pti@ns + \AtEndOfPackage{\let\@unprocessedoptions\relax}% +} \cptpassunexpanded{% \begingroup \def\cpt@tempa{\endgroup - \gnewletcs\kernel@DeclareOption\DeclareOption - \gnewletcs\kernel@ProcessOptions\ProcessOptions - \gnewletcs\kernel@ExecuteOptions\ExecuteOptions + \gnewletcs\cpt@kernelDeclareOption\DeclareOption + \gnewletcs\cpt@kernelProcessOptions\ProcessOptions + \gnewletcs\cpt@kernelExecuteOptions\ExecuteOptions \gdef\DeclareOption{\cpt@olddxtrue\XDeclareOption}% \gdef\ProcessOptions{\cpt@olddxtrue\XProcessOptions}% \gdef\ExecuteOptions{\cpt@olddxtrue\XExecuteOptions}% @@ -4777,9 +5193,9 @@ \let\documentclass\@twoclasseserror \if@compatibility\else \def\usepackage{% - \gletcs\DeclareOption\kernel@DeclareOption - \gletcs\ProcessOptions\kernel@ProcessOptions - \gletcs\ExecuteOptions\kernel@ExecuteOptions + \gletcs\DeclareOption\cpt@kernelDeclareOption + \gletcs\ProcessOptions\cpt@kernelProcessOptions + \gletcs\ExecuteOptions\cpt@kernelExecuteOptions \cpt@olddxfalse \RequirePackage }% @@ -4789,14 +5205,13 @@ \fi }% }% - \ifx\cpt@documentclass\cpt@undefined - \expandafter\cpt@tempa\else\expandafter\endgroup\fi + \ifdefTF\cpt@documentclass\endgroup\cpt@tempa } \cptonlypreamble{% \cptonlypreamble,\cptloadpackages,\ifpackagewithoptionsTF, \ifclasswithoptionsTF,\cpt@ifoptions, \cptpushcatcodes,\cptpopcatcodes,\UseNormalCatcodes, - \rsv@UseNormalCatcodes,\StyleFilePurpose,\StyleFileInfo, + \UseNorm@lCatcodes,\StyleFilePurpose,\StyleFileInfo, \AfterEndOfStyleFile,\StyleFileRCSInfo,\SetStyleFileMessages, \XDeclareOption,\XDeclareOptions,\XDeclareCommandOption, \XDeclareCommandOptions,\XDeclareBooleanOption, @@ -4811,19 +5226,11 @@ } \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 +\XDeclareCommandOptions{% + option-stack-limit,optionstacklimit,key-stack-limit, + keystacklimit,key-depth-limit,keydepthlimit +}[4](cpt@){% + \xdef\cpt@optionstacklimit{\number#1}% } \XDeclareBooleanOption{usepox}[true](cpt@){% \ifcpt@usepox @@ -4837,55 +5244,10 @@ \XDisableOptions*{draft,final} \XDeclareOption*{\cpt@warn{Unknown option '\CurrentOption' ignored}} \XExecuteOptions{% - verbose=false,usepox=true,optionstacklimit=4, - kernelifnextchar=false + verbose=false,usepox=true,optionstacklimit=4 }\relax \XProcessOptions*\relax -\robust@def\indris@nil#1\fi#2\indris@do#3\indris@nil{\fi#1#2} -\newvariables{if}{lastindris}[false] -\robust@def*\indrisloop{\cpt@teststopt\cpt@indrisloop{,}} -\robust@def*\cpt@indrisloop[#1]#2#3{% - \pushfunctions\cpt@indrisloop - {\indris@do,\indrisnr,\iflastindris,% - \ifloopbreak,\user@do,\getnextindris}\indrisdepth - \cpt@stchoose{cpt@st}{#2}\cpt@rsvda\indrisloop - \cpt@sttrue\cpt@csvnormalize[#1]\cpt@rsvda - \lastindrisfalse\loopbreakfalse - \chardef\indrisnr\z@pt - \ifsingletokenTF{#3}{% - \ifmacroTF{#3}{}{\cpt@notcserr{#3}}% - }{% - \cpt@notonetokenerr{#3}% - }% - \let\user@do#3% - \def\getnextindris##1#1##2\indris@nil{% - \edef\nextindris{\unexpanded\expandafter{\@gobble##1}}% - \letcsntocs{nextindris@\cptrm\indrisdepth}\nextindris - }% - \def\indris@do##1#1##2\indris@nil{% - \edef\currindris{\unexpanded\expandafter{\@gobble##1}}% - \letcsntocs{currindris@\cptrm\indrisdepth}\currindris - \ifcat$\detokenize\expandafter{\@gobble##2.}$\indris@nil - \lastindristrue\fi - \if@boolTF{lastindris}{% - \def\nextindris{}% - \csn@def{nextindris@\cptrm\indrisdepth}{}% - }{% - \ifcsvbreakTF{##1}\loopbreak\relax - \if@boolTF{loopbreak}{% - \defpass\reserved@a####1\indris@nil{\cptdoremainder{####1}}% - }{% - \getnextindris.##2\indris@nil - }% - }% - \pushnumber\indrisnr - \expandafter\user@do\expandafter{\@gobble##1}% - \indris@do.##2\indris@nil - }% - \expandafter\indris@do\expandafter.\cpt@rsvda#1\indris@nil - \popfunctions\cpt@indrisloop\indrisdepth -} \cptpopcatcodes \cptrestorecatcodes \declarefutureletset[fl@]{lbracket,star,rquote} |