diff options
author | Karl Berry <karl@freefriends.org> | 2011-12-11 00:06:17 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2011-12-11 00:06:17 +0000 |
commit | 44a92a2f3fd5dbdcb0f65858a11cb1bec44eab14 (patch) | |
tree | e8ae9d714742be1622c99bcc3f974c1428f5cc52 /Master/texmf-dist | |
parent | a34e94fe5909c569b9965be4ce9071584c956570 (diff) |
catoptions 0.2.7a (10dec11)
git-svn-id: svn://tug.org/texlive/trunk@24815 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/doc/latex/catoptions/README | 2 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/catoptions/catoptions-guide.pdf | bin | 448327 -> 448712 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/catoptions/catoptions-guide.tex | 59 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg | 4 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/catoptions/catoptions.sty | 505 |
5 files changed, 344 insertions, 226 deletions
diff --git a/Master/texmf-dist/doc/latex/catoptions/README b/Master/texmf-dist/doc/latex/catoptions/README index 9003c0f039d..9ba095695ed 100644 --- a/Master/texmf-dist/doc/latex/catoptions/README +++ b/Master/texmf-dist/doc/latex/catoptions/README @@ -36,6 +36,6 @@ The catcode section of the 'catoptions' package is based on the VERSION -Version 0.2.7, November 2011 +Version 0.2.7a, 2011/12/07 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 e3f6e07ba75..5410aba8d66 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 a2277633ab6..71593145d43 100644 --- a/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.tex +++ b/Master/texmf-dist/doc/latex/catoptions/catoptions-guide.tex @@ -15,7 +15,6 @@ \WrapQuotes \def\xdecs{\fx{\XDeclareOption}\Redstar\sspace} \makeindex -\useshortdoccmds \let\footnote\ltsfootnote \begin{document} @@ -25,9 +24,9 @@ \titlenotes[t1,t2]{% 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 forthcoming user guide of the \pkg'{ltxtools}. + the \pkg'{catoptions}. This manual continues to evolve. } -\version{0.2.7} +\version{0.2.7a} \titleurl{http://mirror.ctan.org/macros/latex/contrib/catoptions/} \author{Ahmed Musa \Email{amusa22@gmail.com}\\Preston, Lancashire, UK} @@ -62,7 +61,7 @@ \docsection(sec:packageloading){Loading the package} -\deffootnote{1}{% +\newfootnote{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 \sref{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 \sref{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})\usefootnote{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. @@ -173,7 +172,7 @@ $$\vbox{% }% }$$ -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 +However, for efficiency reasons, the canonical control sequences will be defined for only the characters (or, indeed, their names) appearing in the user-supplied list \fx{\declarefutureletset}, whose syntax is \start{newmacro}[\declarefutureletset] \declarefutureletset[|nang(stub)]{|nang(set)} @@ -181,7 +180,7 @@ However, for efficiency reasons, the canonical control sequences will be defined Here, \ang{set} is a comma-separated list of names from the \quoted{other} characters listed above. The defined commands are prefixed with an optional \ang{stub}, whose default value is \fx{fl@}. The defined commands have the syntaxes -\start'{newmacro}[Futurelet characters] +\start'{newmacro}[futurelet characters] \|nang(stub)|nang(char) \if|nang(stub)|nang(char) \finish{newmacro} @@ -197,11 +196,11 @@ For instance, with the choices we have the following commands on hand for testing after \fx{\futurelet}: -\start+{example}[Futurelet commands] +\start+{example}[futurelet commands] \fl@space \fl@star \fl@lbracket \iffl@space \iffl@star \iffl@lbracket \finish{example} -\aidx*{Futurelet commands} +\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. @@ -215,7 +214,7 @@ An inefficient call of the form where \quotedtt{all} means that control sequences should be defined for all the available \quoted{other} characters, will define all the following control sequences whenever \fx{\cptfutureletsetup} is called: -\start+{example}[Futurelet commands] +\start+{example}[futurelet commands] \fl@space \fl@exclam \fl@dblquote \fl@hash \fl@dollar \fl@ampersand \fl@lrquote \fl@lparen \fl@rparen \fl@star \fl@plus \fl@comma @@ -234,13 +233,13 @@ where \quotedtt{all} means that control sequences should be defined for all the \iffl@underscore \iffl@lquote \iffl@lbrace \iffl@vert \iffl@rbrace \iffl@tilde \iffl@bslash \finish{example} -\aidxm*{Futurelet commands} +\aidxm*{futurelet commands} 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*'\bs{stub,char} and \fnl*'{\bs if}{stub,char} are as follows: -\start{example}[Futurelet characters] +\start{example}[futurelet characters] \futurelet\next\cmd |textbf(|R(*)) \def\cmd{\ifx\fl@star\next `I saw star'\else `I didn't see star'\fi} \def\cmd{\iffl@star\next{`I saw star'}{`I didn't see star'}} @@ -319,7 +318,7 @@ The \unstform of the macro \fx{\XDeclareOption} declares an option that can be u \XDeclareOption{leftmargin}[.5\hsize]{\setlength\leftmargin{#1}}|xwmlabel(mac:leftmargin) \finish{example} -\deffootnote{2}{% +\newfootnote{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. } @@ -420,7 +419,7 @@ In the parlance of the \pkg'{catoptions,ltxtools}, a switch can assume only one \finish{newmacro} \fxim*{\ifswitchTF,\ifswitchFT} -\deffootnote{4}{% +\newfootnote{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}\usefootnote{4}. It is advisable to always use \fx{\newswitch} instead. It has the syntax @@ -461,7 +460,7 @@ The command \fx{\XDeclareSwitchOptions} is similar to \fx{\XDeclareSwitchOption} \finish{newmacro} \fxim*{\XUnknownOptionHandler} -\deffootnote{3}{% +\newfootnote{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. } @@ -665,25 +664,24 @@ The implementation here differs significantly from the \latex kernel's scheme of \finish{newmacro} \fxim*{\BeforeProcessOptions,\AfterProcessOptions} -The macros \ffx'{\BeforeProcessOptions,\AfterProcessOptions} can be used to process \ang{code} before and after \fx{\XProcessOptions} has run its course. The command \fx{\AfterProcessOptions} is particularly useful when it is required to optionally load a package, depending on the state of an option in the current package. For obvious reasons, \latex doesn't allow the loading of packages in the options section. The command \fx{\AfterProcessOptions} can be used to load packages after the current package's options have been processed. Here is an example for optionally loading sub-packages at the end of the options section: +The commands \ffx'{\BeforeProcessOptions,\AfterProcessOptions} can be used to process \ang{code} just before and immediately after \fx{\XProcessOptions} has run its course. The command \fx{\AfterProcessOptions} is particularly useful when it is required to optionally load a package, depending on the state of an option in the current package. For obvious reasons, \latex doesn't allow the loading of packages in the options section. The command \fx{\AfterProcessOptions} can be used to load packages after the current package's options have been processed. Here is an example for optionally loading sub-packages at the end of the options section: \start{example}[\AfterProcessOptions] \newif\ifloadsubpackages -\robust@def*\inputpackage{\cpt@testopt\inp@tpackage{}} -\robust@def*\inp@tpackage[#1]#2{% +\robust@def*\inputpackage[#1]#2{% \ifloadsubpackages \AfterProcessOptions{\RequirePackage[#1]{#2}}% \fi } \robust@def*\loadsub#1{% - \docommalist{#1}{% + \cptdocommalist{#1}{% \XDeclareOption{##1}{\inputpackage[####1]{##1}}% }% } \loadsub{subpkg1,subpkg2,subpkg3} \finish{example} - +\bigskip \docsubsection(sec:ifoptiondef){Testing if an option is defined} \start{newmacro}[\ifoptdefTF] @@ -795,7 +793,7 @@ 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} 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 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. +\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 aim 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] @@ -830,7 +828,7 @@ Here are some points to note about these list processors: \finish{example} \start+{example}[Using \csvbreak] -\newvariables{count}{m@,n@} +\cptnewvariables{count}{m@,n@} \def\csv@do#1{% \advance\m@\@ne\n@\z@ \def\csv@do##1{% @@ -882,16 +880,17 @@ Empty entries in \ang{list} will be ignored by the normalizer called by \fx{\dof \dofunclist[,]{aaaa, bbbb, {cccc, dddd}, eeee} \end{itemize} -|com(Let us load many packages compactly here. This is just an example of) +|com(Let us load many packages compactly here. This is just a simple example of) |com(|fx(\dofunclist); you can instead use the more appropriate command) |com(|fx(\cptloadpackages) to load packages (see |sref(mac:loadpkg)):) \def\do#1.#2[#3]{% \@ifpackageloaded{#1}{% \@ifpackagelater{#1}{#2}{}{% - \cpt@warn{Older version of package `#1' loaded earlier}% + \cpt@warn{Older version of package `#1' was loaded earlier}% }% }{% - \cptexpandsecond\usepackage{[\cpttrimspaces{#3}]}{#1}[#2]% + \let\elt\cpttrimspaces + \cptexpandsecond\usepackage{[\elt{#3}]{\elt{#1}}[\elt{#2}]}% }% } |com(The default parser |(,|) is implied below:) @@ -919,7 +918,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}. In fact, this is what \fx{\dofunclist} does internally. 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. \docsubsection(sec:indris){Looking ahead in csv lists} @@ -944,7 +943,7 @@ The following provides a simple application of \fx{\indrisloop}, which I posted \start{example}[\indrisloop] \makeatletter -\robust@def*\and@or@comma{% +\robust@def*\andorcomma{% \ifnumcmpTF\indrisnr>\@ne{% \ifboolTF{lastindris}{% \xifstrcmpTF\sav@lastrefsep{and}{ and }{, }% @@ -966,7 +965,7 @@ The following provides a simple application of \fx{\indrisloop}, which I posted \begingroup \def\reserved{#3}% \csv@@normalize*[,]\reserved - \def\do##1{\and@or@comma\ref{##1}}% + \def\do##1{\andorcomma\ref{##1}}% \def\reserved@a##1,##2,##3\@nil{% \ifblankTF{##1}{}{% \ifblankTF{##2}{% @@ -990,7 +989,6 @@ The following provides a simple application of \fx{\indrisloop}, which I posted \end{|R(document)} \finish{example} -%\bigskip \docsection(sec:tsvparse)<Iterating tokenwise>{Parsing \headquoted{tsv} lists} \start+{newmacro}[\tsv@@parse,\tsv@@loop] @@ -1031,6 +1029,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.7a}{2011/12/07} + \item Renamed the user commands \ffx'{\newvariables,\docommalist, \iflacus...\then} to \ffx'{\cptnewvariables,\cptdocommalist, \iflacus...\dolacus}, respectively.\vsecref* + \end{version} \begin{version}{0.2.7}{2011/10/10} \item Introduced the commands \ffx'{\BeforeProcessOptions,\AfterProcessOptions} \vsecref{sec:before-proc-options} \end{version} @@ -1038,7 +1039,7 @@ The following change history highlights significant changes that affect user uti \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* + \item Enlarged the command \fxi{\cptnewvariables} to include \hx{\newwrite} and \fx{\newswitch} \vsecref* \end{version} \begin{version}{0.2.4}{2011/07/04} \item Changes to command \fxi{\cptonlypreamble} \vsecref* diff --git a/Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg b/Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg index a0e96a49764..ab07f1f6b87 100644 --- a/Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg +++ b/Master/texmf-dist/tex/latex/catoptions/catoptions-guide.cfg @@ -1,7 +1,5 @@ \ProvidesFile{catoptions-guide.cfg}% - [2011/09/10 v0.2.7 Configuration file for catoptions-guide.tex (AM)] - -% Change file name: ++++++++++++++++++++++++++++++++++++++++++ + [2011/12/07 v0.2.7a Configuration file for catoptions-guide.tex (AM)] \cptloadpackages{% n-xwatermark|printwatermark; array; diff --git a/Master/texmf-dist/tex/latex/catoptions/catoptions.sty b/Master/texmf-dist/tex/latex/catoptions/catoptions.sty index 33f688ad049..86d5a87a1dd 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.7, October 2011) % +% This is 'catoptions' package, version 0.2.7a, 2011/12/07. % % % % The catoptions package changes LaTeX package loading internals % % so that all subsequently loaded packages can rely on having % @@ -84,6 +84,12 @@ \catcode47=12 \catcode94=7 \catcode126=13 +\AtEndOfPackage{% + \newletcsset{% + \docommalist=\cptdocommalist, + \newvariables=\cptnewvariables, + }% +} \edef\cpt@hashchar{\string#} \begingroup \catcode`#=13 @@ -93,9 +99,9 @@ \@ifdefinable\m@one{\newcount\m@one\m@one\m@ne} \@ifdefinable\z@pt{\newdimen\z@pt\z@pt\z@} \chardef\active=13 -\NeedsTeXFormat{LaTeX2e}[2005/12/01] +\NeedsTeXFormat{LaTeX2e}[2011/06/27] \ProvidesPackage{catoptions} - [2011/10/22 v0.2.7 Securing catcodes and parsing options (AM)] + [2011/12/07 v0.2.7a Securing catcodes and parsing options (AM)] \ifcase% \ifx\eTeXversion\cpt@undefined\z@pt\else \ifnum\eTeXversion<\tw@\z@pt\else\@ne\fi\fi @@ -103,53 +109,46 @@ {This package requires eTeX version 2 or higher.}% \expandafter\endinput \fi - -\@ifdefinable\cpt@nil{\let\cpt@nil\relax} +% \ifcsdefinable, \cpt@starorlong, \cptcommanormalize, etc, +% change later: +\@ifdefinable\ifcsdefinable{\let\ifcsdefinable\@ifdefinable} +\@ifdefinable\ifdefinablelet\relax +\protected\def\ifdefinablelet#1{\ifcsdefinable#1\relax\let#1} +\ifdefinablelet\cpt@nil\relax \newcommand*\cpt@nnil{\cpt@nil} \let\@iden\@firstofone -\@ifdefinable\iofii{\let\iofii\@firstoftwo} -\@ifdefinable\iiofii{\let\iiofii\@secondoftwo} +\ifdefinablelet\iofii\@firstoftwo +\ifdefinablelet\iiofii\@secondoftwo \@ifdefinable\ifforbreak{\newif\ifforbreak} -% \ifcsdefinable, \cpt@starorlong, \cptcommanormalize, etc, -% will change later: -\@ifdefinable\ifcsdefinable{\let\ifcsdefinable\@ifdefinable} -\@ifdefinable\cpt@starorlong{\let\cpt@starorlong\@star@or@long} -\@ifdefinable\cpt@testopt{\protected\def\cpt@testopt{\@testopt}} -\@ifdefinable\cptcommanormalize{\let\cptcommanormalize\unexpanded} +\ifdefinablelet\cpt@starorlong\@star@or@long +\ifdefinablelet\cpt@testopt\@testopt +\ifdefinablelet\cptcommanormalize\unexpanded \protected\def\ifnot@nil#1{% + \begingroup \edef\reserved@a{\unexpanded{#1}}% + \expandafter\endgroup \ifx\reserved@a\@nnil\expandafter\@gobble \else\expandafter\@iden\fi } \newcommand*\cpt@for@nil{\cpt@for@nil} -% Simple, 1-dimensional comma loop. \protected\def\cptfor#1\dofor#2{% - \def\cpt@fordo##1,{% - \edef\reserved@a{\unexpanded{##1}}% - \ifx\reserved@a\cpt@for@nil\expandafter\@gobble\else - \expandafter\@iden\fi{% - \ifforbreak\expandafter\iofii\else\expandafter\iiofii\fi - {\def\reserved@a####1\cpt@for@nil,{}\reserved@a} - {#2\cpt@fordo}% - }% - }% + \def\cpt@fordo##1,{\cpt@for@a,\cpt@fordo{##1}{#2}}% \edef\reserved@a{\cptcommanormalize{#1}}% \forbreakfalse \expandafter\cpt@fordo\reserved@a,\cpt@for@nil,% } -% Simple, 1-dimensional tsv loop: \protected\def\cpttfor#1\dofor#2{% - \def\cpt@tfordo##1{% - \edef\reserved@a{\unexpanded{##1}}% - \ifx\reserved@a\cpt@for@nil\expandafter\@gobble\else - \expandafter\@iden\fi{% - \ifforbreak\expandafter\iofii\else\expandafter\iiofii\fi - {\def\reserved@a####1\cpt@for@nil{}\reserved@a} - {#2\cpt@tfordo}% - }% - }% + \def\cpt@tfordo##1{\cpt@for@a{}\cpt@tfordo{##1}{#2}}% \forbreakfalse\cpt@tfordo#1\cpt@for@nil } +\protected\def\cpt@for@a#1#2#3#4{% + \edef\reserved@a{\unexpanded{#3}}% + \ifx\reserved@a\cpt@for@nil\expandafter\@gobble\else + \expandafter\@iden\fi{% + \ifforbreak\expandafter\iofii\else\expandafter\iiofii\fi + {\def\reserved@a##1\cpt@for@nil#1{}\reserved@a}{#4#2}% + }% +} \ifcsdefinable\cptchardef{% \protected\def\cptchardef#1#2 {% \ifcsdefinable#1{% @@ -303,6 +302,9 @@ }{% \let\cpt@pdfstrcmp\pdfstrcmp } +\long\def\cptifstreq#1#2\then{% + \ifnum\cpt@pdfstrcmp{\detokenize{#1}}{\detokenize{#2}}=\z@pt +} \newcommand\ifstrcmpTF[2]{% \usename{@\ifnum\cpt@pdfstrcmp{\detokenize{#1}}% {\detokenize{#2}}=0first\else second\fi oftwo}% @@ -336,14 +338,10 @@ } \new@def*\cpt@checkoptprefix{\@iden} \robust@def*\provide@def{% - \cpt@checkoptprefix{% - \cpt@testst{\cpt@testcl{\cpt@providedef\relax}}% - }% + \cpt@testst{\cpt@testcl{\cpt@providedef\relax}}% } \robust@def*\providerobust@def{% - \cpt@checkoptprefix{% - \cpt@testst{\cpt@testcl{\cpt@providedef\protected}}% - }% + \cpt@testst{\cpt@testcl{\cpt@providedef\protected}}% } \robust@def*\cpt@providedef#1#2{% \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}% @@ -496,6 +494,7 @@ }% \endgroup } +\newcommand*\neededfutureletchars{} \newcommand*\declarefutureletset[2][fl@]{% \xdef\cpt@fletprefix{\cpttrimspaces{#1}}% \cptexpandargonce{\cptfiltermergecsv[,]\cpt@fletprefixes} @@ -619,6 +618,41 @@ } \endgroup +\robust@def*\UseNormalCatcodes{% + \ifdocstartedTF{% + \cpt@err + {\noexpand\UseNormalCatcodes is a preamble command} + {Preamble command in document body.}% + }{}% + \RecoverAtRequirePackage\UseNormalCatcodes + \let\UseNormalCatcodes\relax + \cptpushcatcodes + \cptnormalcatcodes + \ifcseqTF\@currname\@empty{% + \BeforeStartOfDocument{% + \cptpopcatcodes + }% + }{% + \AfterEndOfStyleFile{% + \cptpopcatcodes + }% + }% +} +\new@def*\cptgetcatcode#1{% + \number + \ifcat\noexpand#1\bgroup1\else + \ifcat\noexpand#1\egroup2\else + \ifcat\noexpand#1$3\else %$ + \ifcat\noexpand#1&4\else + \ifcat\noexpand#1##6\else + \ifcat\noexpand#1^7\else + \ifcat\noexpand#1_8\else + \ifcat\noexpand#1\@sptoken10\else + \ifcat\noexpand#1a11\else + \ifcat\noexpand#1!12\else + \ifcat\noexpand#1\noexpand~13\else + -1\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi +} \robust@def\cpt@ifnextchar#1#2#3{% \begingroup \let\reserved@a=#1% @@ -687,17 +721,22 @@ \cptswapbracefirst\expandafter \expandafter\expandafter{\csname#2\endcsname}{#1}% } -%% For private use only: +%% For internal use; #1 must be one token: \new@def*\simpleexpandarg#1#2{\expandafter#1\expandafter{#2}} -\@ifdefinable\s@expandarg{\let\s@expandarg\simpleexpandarg} +\ifdefinablelet\s@expandarg\simpleexpandarg %%-- \new@def*\cptexpandnext#1#2{% \expandafter\cptswap\expandafter{#2}{#1}% } +\new@def*\cptbexpandnext#1#2{% + \expandafter\expandafter\expandafter\cptswap + \expandafter\expandafter\expandafter{#2}{#1}% +} \new@def*\cptexpandbracenext#1#2{% \expandafter\cptswapbracefirst\expandafter{#2}{#1}% } +\ifdefinablelet\cptexpandbrnext\cptexpandbracenext \new@def*\cptexpandsome#1\expandthis#2#3\expandstop{% \cptexpandnext{#1}{#2}#3% } @@ -931,7 +970,6 @@ }{% \expandafter\ifblankTF\expandafter{\@gobble#2}{% \ifcsdefinable#1{% - % Here we must use \let and not \def: \ifprotectedTF#2{\let#1=#2}{% \ifcsndefinable{shell@\cptremovescape#1}{% \letcsntocs{shell@\cptremovescape#1}=#2% @@ -951,33 +989,6 @@ \new@def*\ifdocstartedTF{% \ifdefTF\cpt@docstarted\iofii\iiofii } -\robust@def*\UseNormalCatcodes{% - \ifdocstartedTF{% - \cpt@err - {\noexpand\UseNormalCatcodes is a preamble command} - {Preamble command in document body.}% - }{}% - \xdef\@pushfilename{% - \gletcs\UseNormalCatcodes\UseNorm@lCatcodes - \expandcsonce\@pushfilename - }% - \let\UseNormalCatcodes\relax - \cptpushcatcodes - \cptnormalcatcodes - \ifcseqTF\@currname\@empty{% - \BeforeStartOfDocument{% - \cptpopcatcodes - }% - }{% - \AfterEndOfStyleFile{% - \cptpopcatcodes - }% - }% -} -\ifcsdefinable\UseNorm@lCatcodes{% - \global\let\UseNorm@lCatcodes\UseNormalCatcodes -} - \long\def\@gobblethree#1#2#3{} \long\def\@firstofthree#1#2#3{#1} \long\def\@secondofthree#1#2#3{#2} @@ -1066,10 +1077,21 @@ \cpt@normalreverse{#2#1}% }% } +\new@def*\robust@reverse@testbrace#1{% + \ifnum\cpt@pdfstrcmp{\detokenize\expandafter{\@gobble#1.}}{}=\z@pt + \expandafter\@secondoftwo\else\expandafter\@firstoftwo\fi + {% + \ifnum\cpt@pdfstrcmp{\expandafter\@car\detokenize{#1}\@nil}% + \leftbracechar=\z@pt + \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi + }{% + \@secondoftwo + }% +} \new@def*\robust@reverse#1{\cpt@robustreverse{}.#1\@nnil} \long\def\cpt@robustreverse#1#2\@nnil{% \cpt@r@bustreverse{#1}% - {\simpleexpandarg\ifbracedTF{\@gobble#2}}#2\@nnil + {\expandafter\robust@reverse@testbrace\expandafter{\@gobble#2}}#2\@nnil } \long\def\cpt@r@bustreverse#1#2.#3{% \expandafter\ifxTF\cpt@car#3\car@nil\@nnil{% @@ -1101,7 +1123,6 @@ } \ifcommandsdefinable{\cpttrimspace,\cpttrimspaces}\relax \long\def\cpttrimspaces#1{\cpt@trimspaces@a\relax{#1}} - \begingroup \catcode`\&=7\catcode`\$=7 \long\gdef\cpt@trimspaces@a#1#2{\cpt@trimspaces@b.#1$.#2& &} @@ -1148,10 +1169,9 @@ \ifdefboolFT{cpt@st}{}{\let#2=\cpt@rsvda}% }% } -\robust@def*\newvariables#1{\cpt@testopt{\cpt@newvariables{#1}}{}} -\ifcsdefinable\newvariable{\let\newvariable\newvariables} +\robust@def*\cptnewvariables#1{\cpt@testopt{\cpt@newvariables{#1}}{}} \robust@def*\cpt@newvariables#1[#2]#3{% - \edef\reserved@a{\cpt@testopt{% + \edef\reserved@a{\noexpand\cpt@testopt{% \cpt@newv@riables{\cpttrimspace{#1}}{\cpttrimspace{#2}}{#3}% }{}}% \reserved@a @@ -1273,27 +1293,12 @@ \endgroup \fi } -\newvariables{if}[cpt@]{usepox,optfd,igopt,inpox,olddx, +\cptnewvariables{if}[cpt@]{usepox,optfd,igopt,inpox,olddx, in,check,choicefd,useempty,swa}[false] -\newvariables{tog}{biboolopts}[false] -\newvariables{count}[cpt@]{optdepth,cnta}[\z@pt] +\cptnewvariables{tog}{biboolopts}[false] +\cptnewvariables{count}[cpt@]{optdepth,cnta}[\z@pt] \new@def*\UseEmptyEntry{\global\cpt@useemptytrue} \new@def*\DiscardEmptyEntry{\global\cpt@useemptyfalse} -\new@def*\cptgetcatcode#1{% - \number - \ifcat\noexpand#1\bgroup1\else - \ifcat\noexpand#1\egroup2\else - \ifcat\noexpand#1$3\else %$ - \ifcat\noexpand#1&4\else - \ifcat\noexpand#1##6\else - \ifcat\noexpand#1^7\else - \ifcat\noexpand#1_8\else - \ifcat\noexpand#1\@sptoken10\else - \ifcat\noexpand#1a11\else - \ifcat\noexpand#1!12\else - \ifcat\noexpand#1\noexpand~13\else - -1\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi -} \new@def\oifnullTF#1{\expandafter\ifnullTF\expandafter{#1}} \new@def\oifnullFT#1{\expandafter\ifnullFT\expandafter{#1}} \new@def\xifnullTF#1{\cptexpandarg\ifnullTF{#1}} @@ -1356,15 +1361,41 @@ \robust@def*\ltxmsg@info{\@latex@info@no@line} \robust@def*\ltxmsg@err{\@latex@error} \robust@redef\cpt@testopt#1#2{\ifnextcharTF[{#1}{#1[{#2}]}} +% Eg, \def\csa{\cpt@testcharopt\csb<{default}>} +% \def\csb<#1>{...} \robust@def*\cpt@testcharopt#1#2#3#4{\ifnextcharTF#2{#1}{#1#2{#3}#4}} + +% Expandable \@testopt: +% Eg, \def\macroa#1{\cpt@xtestopt{#1}\macrob{Mr.}} +% \def\macrob[#1]#2{#1 #2} +% \edef\testa{\macroa{John Johnson}} +% \edef\testb{\macroa[Dr.]{Haiki Heiki}} \new@def*\cpt@xtestopt#1#2#3{% \cpt@xifbrack#1\\[\\{#2#1}{#2[{#3}]{#1}}% } \new@def*\cpt@xifbrack#1[#2\\#3#{% \ifcat$\detokenize{#1#2}$\expandafter\@firstoftwo - \else\expandafter\@secondoftwo\fi + \else\expandafter\@secondoftwo\fi +} +% Eg, \def\macroa{\cpt@newxtestopt\macrob{Mr.}} +% \def\macrob[#1]#2{#1 #2} +% \edef\testa{\expandafter\macroa\activespace{John Johnson}} +% \edef\testb{\macroa[Dr.]{Haiki Heiki}} +\new@def*\cpt@newxtestopt#1#2#3{% + \ifstrcmpTF{ }{#3}{% + \cpt@newxtestopt#1{#2}% + }{% + \ifstrcmpTF{#3}{[}{% + #1[% + }{% + \ifsingletokenTF{#3}{% + #1[#2]#3% + }{% + #1[#2]{#3}% + }% + }% + }% } - \robust@def*\cpt@ifbrack#1#2{\ifnextcharTF[{#1}{#2}} \robust@def\cpt@testpnopt#1#2{\ifnextcharTF({#1}{#1({#2})}} \robust@def\cpt@testltopt#1#2{\ifnextcharTF<{#1}{#1<{#2}>}} @@ -1428,9 +1459,37 @@ \cpt@notonetokenerr{#1}% }% } -\robust@def*\fullletmanytocs#1#2{% - \cptfor#1\dofor{\fulllet{##1}{#2}}% +% Eg, \newletcsset{\a=\b,\x\y} +\robust@def*\newletcsset{% + \cpt@ifstar + {\let\dolet\ltsfulllet\cpt@newletcsset}% + {\let\dolet\let\cpt@newletcsset}% } +\robust@def*\cpt@newletcsset#1{% + \def\cpt@tempa##1##2\cpt@nil{% + \cpt@tempb##1=##2\cpt@nil + }% + \def\cpt@tempb##1=##2\cpt@nil{% + \ifblankFT{##2}{}{% + \cpt@err{The partner of command '\string##1' is void}\@ehc + }% + \ifdefTF{##1}{% + \ifx##1##2\else\cpt@isdeferr{##1}\fi + }{% + \dolet##1=##2% + }% + }% + \cptfor#1\dofor{% + \ifinsetTF{=}{##1}{% + \cpt@tempb##1\cpt@nil + }{% + \cpt@tempa##1\cpt@nil + }% + }% + \undefcs\dolet +} +\robust@def*\cptletmanytocs#1#2{\cptfor#1\dofor{\let##1= #2}} +\robust@def*\fullletmanytocs#1#2{\cptfor#1\dofor{\fulllet{##1}{#2}}} \robust@def*\begintoksgroup{\begingroup\toks@{}} \robust@def*\endtoksgroup{\expandafter\endgroup\the\toks@} @@ -1502,8 +1561,6 @@ \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 \cptfor#2\dofor{% \ifescapedTF{##1}{}{\cpt@notescapederr{##1}}% @@ -1604,7 +1661,12 @@ \the\expandafter\toks@\expandafter{\the\toks1}% \csv@@parse } -\robust@def*\docommalist#1#2{\def\csv@do##1{#2}\csv@@parse{#1}} +\robust@def*\cptdocommalist{\cpt@testst\cpt@docommalist} +\robust@def*\cpt@docommalist#1#2{% + \def\csv@do##1{#2}% + \edefpass\reserved@a{\csv@@parse\ifcpt@st*\fi}% + {#1}% +} \robust@def*\csv@@loop{\cpt@csvkvparse{01}{01}} \robust@def*\csv@@parse{\cpt@csvkvparse{00}{01}} \robust@def*\kv@@loop{\cpt@csvkvparse{01}{00}} @@ -1613,7 +1675,8 @@ \def\cpt@nmlz{#1}\def\cpt@inkv{#2}% \cpt@teststopt\cpt@csvkvp@rse,% } -\new@def*\cpt@csvnil{\cpt@csvnil} +\newletcs\cpt@csvnil\relax +\new@def*\cpt@csvnnil{\cpt@csvnil} \newcommand*\cpt@csvkvp@rse[2][,]{% \cpt@stchoose{cpt@st}{#2}\cpt@csvarg\cpt@csvkvparse \pushfunctions\cpt@csvkvparse{\cpt@csvdo@a,\cpt@csvdo@b,\sav@csv@do,% @@ -1623,15 +1686,12 @@ \cpt@err{'\string\csv@do' or '\string\kv@do' undefined}\@ehc }% \def\cpt@csvdo@a{% - \ifboolTF{loopbreak}{% - \defpass\reserved@a####1\cpt@csvnil#1{\cptdoremainder{####1}}% - }{% - \cpt@csvdo@b.% - }% + \ifboolTF{loopbreak} + {\gobble@to@sentinel\cpt@csvnil#1}{\cpt@csvdo@b.}% }% \def\cpt@csvdo@b##1#1{% \edef\cpt@csvarg{\expandcsonce{\@gobble##1}}% - \ifcseqTF\cpt@csvarg\cpt@csvnil{}{% + \ifcseqTF\cpt@csvarg\cpt@csvnnil{}{% \ifcseqTF\cpt@csvarg\cpt@csvbreak{% \loopbreaktrue }{% @@ -1644,7 +1704,7 @@ \cpt@csvdo@a }% }% - \ifdefswitchFT{cpt@nmlz}{}{% + \ifswitchFT{cpt@nmlz}{}{% \ifcsemptyTF\cpt@csvarg{}{% \cpt@sttrue \usename{cpt@\ifswitchTF{cpt@inkv}{kv}{csv}normalize}% @@ -1659,7 +1719,7 @@ \fi } \robust@def\indris@nil#1\fi#2\indris@do#3\indris@nil{\fi#1#2} -\newvariables{if}{lastindris}[false] +\cptnewvariables{if}{lastindris}[false] \robust@def*\indrisloop{\cpt@teststopt\cpt@indrisloop,} \robust@def*\cpt@indrisloop[#1]#2#3{% \pushfunctions\cpt@indrisloop{% @@ -1760,6 +1820,11 @@ \cpt@tsvparse@b }% } +% \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 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{\sav@siso@do,\ifloopbreak}\cpt@csvdepth @@ -1814,11 +1879,17 @@ \expandafter\csliststack\expandafter#1\csname#2\endcsname }% } -\robust@def*\cptemptify#1{\let#1\@empty} -\robust@def*\cptgemptify#1{\global\let#1\@empty} +\robust@def*\cptemptify#1{% + \ifblankTF{#1}{}{\let#1\@empty}% +} +\robust@def*\cptgemptify#1{% + \ifblankTF{#1}{}{\global\let#1\@empty}% +} \robust@def*\genemptify{\cpt@teststcl\cpt@genemptify} \def\cpt@genemptify#1{% - \ifcpt@cl\global\fi\ifcpt@st\else\long\fi\def#1{}% + \ifblankTF{#1}{}{% + \ifcpt@cl\global\fi\ifcpt@st\else\long\fi\def#1{}% + }% } \robust@def*\cptemptifycsn{\aftercsname\cptemptify} \robust@def*\cptgemptifycsn{\global\aftercsname\cptemptify} @@ -1898,6 +1969,8 @@ \expandafter\csv@@loop\reserved@a[#1]{#2}% \postgroupdef\cptelemnr\endgroup } +% Eg, \ifelemcountTF[;](>)[2]{a;b;c}{T}{F}; +% * -> #4 is a macro \robust@def*\ifelemcountTF{\cpt@teststopt\cpt@ifelemcount@a,} \robust@def*\cpt@ifelemcount@a[#1]{% \cpt@testpnopt{\cpt@ifelemcount@b{#1}}=% @@ -2098,7 +2171,7 @@ #1\relax\expandafter\cpt@iterate\fi\@gobble{#1}% } \new@def\cptwhilecond#1\fi#2{% - #1#2\relax\cptswap{\cpt@whilecond{#1#2\relax}\fi}\fi + #1\relax#2\relax\cptswap{\cpt@whilecond{#1\relax#2\relax}\fi}\fi } \new@def\cpt@whilecond#1\fi{% #1\expandafter\cpt@whilecond\else\@gobbletwo\fi{#1}\fi @@ -2151,8 +2224,6 @@ }% } \cpt@defcheck\cpt@checkeq=\cpt@nil -%%-- - \robust@def*\cpt@defsplit@at#1#2\cpt@nil{% \def#1##1\cpt@nil{% \begingroup @@ -2167,7 +2238,6 @@ }% } \cpt@defsplit@at\cpt@split@ateq=\cpt@nil - \robust@def\DefSuffixChecker#1#2#3#4{% \long\gdef#1##1##2##3##4{% \begintoksgroup @@ -2452,6 +2522,7 @@ }{0 #2}{0 #3}% } \new@def\ifsingletokenFT#1{\ifsingletokenTF{#1}\iiofii\iofii} +% Don't test for \ifleadspaceTF: \new@def\ifsingletoken@sp@TF#1#2#3{% \romannumeral\ifblankTF{#1}{% \@secondoftwo @@ -2484,7 +2555,7 @@ }{% \ifsingletokenTF{#1}{% \xifinsetTF{\detokenize{#1}}\cpt@parserlist{% - #2% + #2% Don't put \relax here! }{% \cpt@listparsererr{#1}% }% @@ -2568,7 +2639,6 @@ \unexpanded{#1}% }% } - \begingroup \catcode`\&=7 \new@gdef*\cptfullexpand#1{% @@ -2593,6 +2663,7 @@ } \endgroup +% [<fallback>]{<teststr>}{<{str1}{act1}{str2}{act2}...>} \new@def*\cptifstreqcase#1{\cpt@xtestopt{#1}\cpt@ifstreqcase{}} \new@def\cpt@ifstreqcase[#1]#2#3{% \expandafter\cptswapbracefirst\expandafter{#2}% @@ -2619,6 +2690,7 @@ }% }% } +% [<default act>]{<teststr>}{<{str1}{act1}{str2}{act2}...>} \new@def*\cptifstrpresentcase#1{\cpt@xtestopt{#1}\cpt@ifstrincase{}} \new@def\cpt@ifstrincase[#1]#2#3{% \expandafter\cptswapbracefirst\expandafter{#2}% @@ -2631,10 +2703,64 @@ }% }% } +\new@def\all@to@endif#1\endif{#1} +\new@def\first@to@endif#1#2\endif{#1} +\new@def*\ifcassenumcmpTF#1#2#3{\ifdimcmpTF#1pt#2pt{#3}} +% Eg, +% \edef\x{% +% \cptifcasse\ifcassestrcmpTF{teststr} +% {str1}{case1 callback} +% {str2}{case2 callback} +% \elseif +% no match +% \endif +% } +% \edef\x{% +% \cptifcasse\ifcassenumcmpTF{testnum} +% {=2}{equal to 2} +% {<3}{less than 3} +% {>4}{greater than 4} +% \elseif +% no match +% \endif +% } +% The omparator command is any test command that yields +% <iofii> or <iiofii> but \ifnumcmpTF can't be used directly. +% Use \ifcassenumcmpTF instead. The user can also define his own +% logical test command and pass it to \cptifcasse, eg, +% \def\test#1#2{\ifinsetTF{#2}{#1}} +\new@def*\cptifcasse#1#2{% + \ifstrcmpTF{#1}\elseif{% + \all@to@endif + }{% + \ifstrcmpTF{#1}\endif{}{% + \ifstrcmpTF{#2}\elseif{% + \all@to@endif + }{% + \ifstrcmpTF{#2}\endif{}{\cpt@ifcasse{#1}{#2}}% + }% + }% + }% +} +\new@def*\cpt@ifcasse#1#2#3{% + \ifstrcmpTF{#3}\elseif{% + \all@to@endif + }{% + \ifstrcmpTF{#3}\endif{}{% + #1{#2}{#3}\first@to@endif{\cpt@ifcasse@i{#1}{#2}}% + }% + }% +} +\new@def*\cpt@ifcasse@i#1#2#3{\cpt@ifcasse{#1}{#2}} \robust@def\cpt@in#1#2{% - \long\def\in@@##1#1{}% - \edef\in@@{\detokenize\expandafter{\in@@#2{}{}#1}}% - \ifcat$\in@@$\cpt@infalse\else\cpt@intrue\fi + \long\def\in@@##1#1##2\in@@{% + \begingroup + \toks@{##2}% + \edef\in@@{\the\toks@}% + \expandafter\endgroup + \ifx\in@@\@empty\cpt@infalse\else\cpt@intrue\fi + }% + \in@@#2{\in@@}#1\in@@ } \robust@def\cptiffound#1\in#2\then{% \cptexpandtwoargs\cpt@in{\cpttrimspace{#1}}{\cpttrimspace{#2}}% @@ -2652,8 +2778,8 @@ \robust@def\oifinset@sp@TF#1#2#3{% \begingroup \edef\parser{\detokenize{#1}}% - \edef\x{{\parser\cptoxdetok{#2}\parser} - {\parser\cptoxdetok{#3}\parser}}% + \edef\x{{\parser\cptoxdetok{#2}\parser}% + {\parser\ifdefTF{#3}{\cptoxdetok{#3}}{}\parser}}% \expandafter\endgroup\expandafter\ifinsetTF\x } \robust@def\oifinset@sp@FT#1#2#3{% @@ -2808,7 +2934,7 @@ \postgroupdef#2\endgroup \let\everymergeitem\@firstofone } -\newvariables{switch}[cpt@]{fromrepl,fromrem}[false] +\cptnewvariables{switch}[cpt@]{fromrepl,fromrem}[false] \robust@def*\cptremoveoneelement{\cpt@teststopt\cpt@removeoneelement,} \robust@def\cpt@removeoneelement[#1]#2#3{% \begingroup @@ -2854,6 +2980,7 @@ \csv@@parse[#1]{#3}% \postgroupdef#2\endgroup } +% \cptreplaceoneelement[<parser>]{<cs>}{<search>}{<replace>} \robust@def*\cptreplaceoneelement{\cpt@teststopt\cpt@replaceoneelement,} \robust@def\cpt@replaceoneelement[#1]#2#3#4{% \begingroup @@ -3049,11 +3176,11 @@ }% }% } -\robust@def*\stripouterbraces{\cpt@testopt\cpt@stripouterbraces\@ne} -\newletcs\stripNouterbraces\stripouterbraces +\robust@def*\cptstripNouterbraces{\cpt@testopt\cpt@stripouterbraces\@ne} +\newletcs\cptstripnbr\cptstripNouterbraces \robust@def*\cpt@stripouterbraces[#1]{% \begingroup - \def\after@def##1##2##3{\postgroupdef##3\endgroup}% + \def\end@def##1##2##3{\postgroupdef##3\endgroup}% \@tempcnta\z@pt \catcode`\{=1 \catcode`\}=2 @@ -3067,24 +3194,24 @@ } \robust@def\cpt@str@pouterbr@ces#1\strip@nil#2#3{% \defifxTF{#1}#2{% - \after@def + \end@def }{% \ifnum\@tempcnta>#3\relax - \expandafter\after@def + \expandafter\end@def \else \expandafter\cpt@str@pouterbraces \fi }% {#3}{#1}{#2}% } -\robust@def\stripallouterbraces#1#2{% +\robust@def\cptstripallouterbraces#1#2{% \edef#2{\unexpanded\cptthreexp{\cpt@stripallouterbraces{#1}}}% } -\newletcs\cptstripallbr\stripallouterbraces -\robust@def\stripallouterbracesincs#1{% - \expandafter\stripallouterbraces\expandafter{#1}#1% +\newletcs\cptstripallbr\cptstripallouterbraces +\robust@def\cptstripallouterbracesincs#1{% + \expandafter\cptstripallouterbraces\expandafter{#1}#1% } -\newletcs\cptstripallbrincs\stripallouterbracesincs +\newletcs\cptstripallbrincs\cptstripallouterbracesincs \robust@def\cpt@stripallouterbraces#1{% \romannumeral\ifbracedTF{#1}{% \expandafter\ifnullTF\expandafter{\@gobble#1}{% @@ -3267,7 +3394,9 @@ \new@def*\cpt@newtog#1[#2]{% \ifinsetTF{,}{#1}{% \cpt@err{Command \noexpand\newtog doesn't accept list} - {Please submit only one toggle to \noexpand\newtog.}% + {Please submit only one toggle to \noexpand\newtog. + \MsgBrk You can use \noexpand\cptnewvariables + for multiple toggles.}% }{}% \ifcsndefTF{cpt@tog@#1}{% \cpt@err{Toggle '#1' already defined}% @@ -3536,6 +3665,7 @@ \ignorespaces#1\cpt@expr@true\cpt@expr@false \cpt@expr@test#2\expr@nil } + \robust@def*\cptifonepresentTF#1#2{% \begingroup \cpt@choicefdfalse @@ -3548,13 +3678,13 @@ \expandafter\endgroup\ifcpt@choicefd \expandafter\iofii\else\expandafter\iiofii\fi } -% #1: listcmd -% #2: comparator: < (ascending) or > (descending) +% Eg, \def\x{13251{8/2}} \cptnumbersort\x> \robust@def*\cptnumbersort#1#2{% \begingroup \let\numcmp\ifnumcmpTF \cpt@sortlist{#1}{#2}% } +% Eg, \def\x{13251{4456789201.12}} \cptbignumbersort\x> \robust@def*\cptbignumbersort#1#2{% \begingroup \ifcsndefTF{ver@fp.sty}{% @@ -3579,6 +3709,7 @@ }{}% \cpt@sortlist{#1}{#2}% } +% Eg, \def\x{ab{west}cdea{east}} \cptalphasort\x< \robust@def*\cptalphasort#1#2{% \begingroup \def\numcmp##1#2##2##{% @@ -3721,7 +3852,6 @@ \ifboolTF{cpt@choicefd} {\endgroup\@firstoftwo}{\endgroup\@secondoftwo}% } -% If package was later loaded (before begin-document). % \ifpackageloadedlaterTF{<package>}{<true>}{<false>} \robust@def*\ifpackageloadedlaterTF{\cpt@ifpkgloadedlater\@pkgextension} \robust@def*\ifclassloadedlaterTF{\cpt@ifpkgloadedlater\@clsextension} @@ -3747,16 +3877,12 @@ }% }% } -% \cptloadpackages[<inner-parser><outer-parser>]{% -% pkga<inner>options<inner>date<outer> -% pkgb<inner>options<inner>date<outer> -% } \robust@def*\cptloadpackages{% \begingroup \endlinechar=-1 \cpt@testopt{\expandafter\endgroup\cpt@loadpackages}{|;}% } -\robust@def*\cpt@loadpackages[#1]#2{% +\robust@def\cpt@loadpackages[#1]#2{% \begingroup \toks@{}% \def\cpt@tempa##1##2\cpt@nil{% @@ -3779,7 +3905,7 @@ \ifblankTF{####2}{% \def\cpt@rsvda{}% }{% - \stripallouterbraces{####2}\cpt@rsvda + \cptstripallouterbraces{####2}\cpt@rsvda }% \@ifpackageloaded{####1}{% \edef\cpt@rsvdb{\detokenize\expandafter @@ -3888,7 +4014,6 @@ \edef#2{\the\toks@}% \postgroupdef#2\endgroup } -% * -> #2 is a listcmd, else it is a list: \robust@def*\csv@@normalize{\cpt@teststopt\cpt@csvnormalize,} \robust@def\cpt@csvnormalize[#1]#2{% \let\cpt@inkv\cptswfalse @@ -3900,9 +4025,6 @@ \cpt@normalizelist{#1}{#2}% } \ifcsdefinable\normalized@list\relax - -\begingroup -\catcode`\^=3 \robust@gdef\cpt@normalizelist#1#2{% \begingroup \let\if@nmlzst\ifcpt@st @@ -3922,10 +4044,10 @@ \nmlz@activeequal \nmlz@spaceletter=% \nmlz@letterspace=% - \toks@\expandafter{\the\toks@^?}% + \toks@\expandafter{\the\toks@^?^}% \nmlz@doubleletter=% \cpt@commaequalerr - \def\reserved@a##1^?##2\cpt@nil{\toks@{##1##2}}% + \def\reserved@a##1^?^##2\cpt@nil{\toks@{##1##2}}% \expandafter\reserved@a\the\toks@\cpt@nil }% \edef\normalized@list{\the\toks@}% @@ -3933,15 +4055,12 @@ \cptexpandsecond\endgroup{% \ifboolTF{@nmlzst}{% \edef\noexpand#2{\ox@unexpanded\normalized@list}% - \undefcs\noexpand\normalized@list }{% \cpt@csexit\normalized@list }% }% \cpt@relax } -\endgroup - \def\setup@parser@nmlz#1{% \begingroup \uccode`\~=`#1% @@ -4026,6 +4145,36 @@ \@latex@error{Invalid value '#1' for '#2'}\@ehc }% } +\robust@def*\RecoverAtRequirePackage#1{% + \ifblankFT{#1}{}{% + \cpt@isblankerr\RecoverAtRequirePackage + }% + \begingroup + \cptfor#1\dofor{% + \ifescapedTF{##1}{% + \ifdefTF{##1}{}{% + \cpt@notdeferr{##1}% + \@gobble + }% + }{% + \cpt@notescapederr{##1}% + \@gobble + }% + \ifcsndefTF{cpt@atpush@\cptremovescape##1}{}{% + \gletcsntocs{cpt@atpush@\cptremovescape##1}##1% + \edef\cpt@tempa{% + \gletcs\unexpanded{##1}=% + \noexpandcsn{cpt@atpush@\cptremovescape##1}% + }% + \xifinsetTF{\cptoxdetok\cpt@tempa}{\cptoxdetok\@pushfilename}{}{% + \xdef\@pushfilename{% + \expandcsonce\cpt@tempa\expandcsonce\@pushfilename + }% + }% + }% + }% + \endgroup +} \let\cpt@documentclass\cpt@undefined \robust@def*\cpt@getdocumentclass{% \def\csv@do##1{% @@ -4087,35 +4236,6 @@ \robust@def*\cpt@testfam#1{% \ifnextcharTF<{#1}{#1<\@currname.\@currext>}% } -\robust@def*\RecoverAtRequirePackage#1{% - \ifblankFT{#1}{}{% - \cpt@isblankerr\RecoverAtRequirePackage - }% - \begingroup - \cptfor#1\dofor{% - \ifescapedTF{##1}{% - \ifdefTF{##1}{}{% - \cpt@notdeferr{##1}% - \@gobble - }% - }{% - \cpt@notescapederr{##1}% - \@gobble - }% - \ifcsndefinable{cpt@atpush@\cptremovescape##1}{% - \gletcsntocs{cpt@atpush@\cptremovescape##1}##1% - }% - \edef\cpt@tempa{% - \gletcs\unexpanded{##1}=\noexpandcsn{cpt@atpush@\cptremovescape##1}% - }% - \xifinsetTF{\cptoxdetok\cpt@tempa}{\cptoxdetok\@pushfilename}{}{% - \xdef\@pushfilename{% - \expandcsonce\cpt@tempa\expandcsonce\@pushfilename - }% - }% - }% - \endgroup -} \robust@def*\cpt@badoptionerr#1{% \expandafter\ifescapedTF\expandafter{#1}{% \cpt@isescapederr{#1}% @@ -4295,18 +4415,18 @@ } \robust@def\cpt@d@cl@recmdoptions#1#2#3(#4)#5{% \trim@@spaces{#1}\cpt@currfam - \begingroup - \toks@{{#3}(#4){#5}}\toks1{}% + \begintoksgroup + \toks1{{#3}(#4){#5}}% \def\csv@do##1{% \cpt@badoptionerr{##1}% \cptexpanded{% - \toks1{\the\toks1\relax - \cpt@d@cl@recmdoption{\cpt@currfam}{##1}\the\toks@ + \toks@{\the\toks@\relax + \cpt@d@cl@recmdoption{\cpt@currfam}{##1}\the\toks1 }% }% }% \csv@@parse[,]{#2}% - \expandafter\endgroup\the\toks1 + \endtoksgroup } \robust@def*\XDeclareBiBooleanOptions{% \let\@fileswith@pti@ns\@badrequireerror @@ -5189,7 +5309,7 @@ }% } \robust@def*\cpt@removevalues#1{% - \cptfor#1\dofor{\cpt@rem@vevalues{##1}}% + \cptdocommalist{#1}{\cpt@rem@vevalues{##1}}% } \robust@def*\cpt@rem@vevalues#1{% \ifcseqTF#1\@empty\cpt@gobbletorelax\relax @@ -5333,12 +5453,11 @@ }% \ifdefTF\cpt@documentclass\endgroup\cpt@tempa } - \cptonlypreamble{% - \cptonlypreamble,\cptloadpackages,\ifpackagewithoptionsTF, - \ifclasswithoptionsTF,\cpt@ifoptions, + \cptonlypreamble,\cpt@getdocumentclass,\cptloadpackages, + \ifpackagewithoptionsTF,\ifclasswithoptionsTF,\cpt@ifoptions, \cptpushcatcodes,\cptpopcatcodes,\UseNormalCatcodes, - \UseNorm@lCatcodes,\StyleFilePurpose,\StyleFileInfo, + \StyleFilePurpose,\StyleFileInfo, \AfterEndOfStyleFile,\StyleFileRCSInfo,\SetStyleFileMessages, \XDeclareOption,\XDeclareOptions,\XDeclareCommandOption, \XDeclareCommandOptions,\XDeclareBooleanOption, @@ -5355,8 +5474,8 @@ \XDeclareBiBooleanOptions{verbose,silent}[true](cpt@){}{} \XDeclareBiBooleanOptions{draft,final}[true](cpt@){}{} \XDeclareCommandOptions{% - option-stack-limit,optionstacklimit,key-stack-limit, - keystacklimit,key-depth-limit,keydepthlimit + option-stack-limit,optionstacklimit,key-stack-limit,% + keystacklimit,key-depth-limit,keydepthlimit% }[4](cpt@){% \xdef\cpt@optionstacklimit{\number#1}% } |