%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% % % % This is file 'ltxtools.sty', version 0.0.1, September 2011. % % % % This package and accompanying files may be distributed and/or % % modified under the conditions of the LaTeX Project Public License, % % either version 1.3 of this license or any later version. The latest % % version of this license is in http://www.latex-project.org/lppl.txt % % and version 1.3 or later is part of all distributions of LaTeX % % version 2005/12/01 or later. % % % % The LPPL maintenance status of this software is 'author-maintained'. % % % % This software is provided 'as it is', without warranty of any kind, % % either expressed or implied, including, but not limited to, the % % implied warranties of merchantability and fitness for a particular % % purpose. % % % % Copyright (c) 2011 Ahmed Musa (amusa22@gmail.com). % % % %++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++% \@ifpackageloaded{catoptions}{}{\RequirePackage{catoptions}[2011/07/07]} \UseNormalCatcodes \StyleFilePurpose{A collection of (La)TeX utilities} \StyleFileRCSInfo $Id: ltxtools.sty,v 0.0.1 2011/09/20 09:00:00 Ahmed Musa Exp $ \ProvidesPackage{ltxtools}[\StyleFileInfo] \NeedsTeXFormat{LaTeX2e}[2005/12/01] \SetStyleFileMessages[LTS@]{info}{warn}{err} \catcode`\&=\thr@@ \robust@def*\LTS@verbosewarn#1{\ifLTS@verbose\LTS@warn{#1}\fi} \robust@def*\LTS@verboseinfo#1{\ifLTS@verbose\LTS@info{#1}\fi} \newvariables{if}[LTS@]{st,pl,cl,rt,pm,lt,verbose}[false] \def\@empty{} \new@def\LTS@car#1#2\car@nil{#1} \new@def\LTS@cartwo#1#2#3\car@nil{#1#2} \new@def\LTS@cartworev#1#2#3\car@nil{#2#1} \new@def\LTS@cdr#1#2\cdr@nil{#2} \new@def\LTS@cdrtwo#1#2#3\cdr@nil{#3} \new@def\LTS@carcube#1#2#3#4\car@nil{#1#2#3} \newletcs\LTS@nil\relax \new@def*\LTS@nnil{\LTS@nil} \long\def\@firstofone#1{#1} \long\def\@firstoftwo#1#2{#1} \long\def\@secondoftwo#1#2{#2} \long\def\@firstofthree#1#2#3{#1} \long\def\@secondofthree#1#2#3{#2} \long\def\@thirdofthree#1#2#3{#3} \long\def\@gobbleone#1{} \long\def\@gobbletwo#1#2{} \long\def\@gobblethree#1#2#3{} \long\def\@gobblefour#1#2#3#4{} \letcsntocs{LTS@0of1}\@gobbleone \letcsntocs{LTS@1of1}\@firstofone \letcsntocs{LTS@1of2}\@firstoftwo \letcsntocs{LTS@2of2}\@secondoftwo \def\strip@prefix#1>{} \new@def*\realmeaning#1{\expandafter\strip@prefix\meaning#1} \robust@def*\sanitizecs#1{\edef#1{\realmeaning#1}} \new@edef*\LTS@hashchar{\string#} \robust@def*\preservebracedefQ#1#2{% \def\preserve@prefix{#1}% \def\preserve@delimiter{#2}% } \preservebracedefQ\relax\@nil \robust@def*\preservebracedef#1{% \cpt@presbr@setup\reserved@a#1.% } \robust@def*\PreserveBraceDef#1#2{% \cpt@presbr@setup \long\edef\preserve@after{\unexpanded{#1}}% \afterassignment\preserve@after \reserved@a#2.% } \robust@def*\cpt@presbr@setup{% \cptexpandsecondonce{\def\reserved@a##1##2}% \preserve@delimiter{% \preserve@prefix\edef##1{% \unexpanded\expandafter{\cpt@removetodot##2}% }% }% } \robust@def*\getdefaultoptarg#1{% \begingroup \edef\LTS@tempa##1{% \def##1####1\cptoxdetok{\@backslashchar#1}####2&% }% \LTS@tempa\LTS@tempa{% \ifblankTF{##2}{% \endgroup\def\@optarg{}% }{% \xifinsetTF{\cptoxdetok{\@backslashchar#1}}{##2}{% \edef\LTS@tempa####1{% \def####1########1\cptoxdetok{\@backslashchar#1}&% }% \LTS@tempa\LTS@tempa{\endgroup \def\@optarg{####1}% \cptscantokens\@optarg }% \LTS@tempa##2&% }{% \endgroup\def\@optarg{}% }% }% }% \edef\LTS@tempb##1{##1\cptoxdetok{\@backslashchar#1}&}% \LTS@tempb{\expandafter\LTS@tempa\meaning#1}% } % \ifx ... \LTS@texdie{I am exiting now}\stop\fi \robust@def\LTS@texdie#1#2\fi{\fi\immediate\write16{#1}\batchmode#2} \robust@def*\LTS@emergencystop{% \immediate\write\sixt@@n{OK, I'm exiting now.}% \interactionmode\z@pt\stop } \robust@def*\ltsensurecomma{\cpt@ifnextchar,{}{\LTS@err{Don’t forget comma}}} \robust@def*\LTS@nohyphens{\hyphenpenalty\@M\exhyphenpenalty\@M} \robust@def*\ltsfulllet#1#2{% \def\reserved@e##1##2{% \LTS@stfalse\LTS@cltrue\LTS@ifonetoken{##1}{}{##2}% }% \reserved@e{#1}{% \LTS@err{Multiple or blank arguments '\detokenize{#1}'}\@ehc }% \reserved@e{#2}{% \LTS@err{Multiple or blank arguments '\detokenize{#2}'}\@ehc \@gobble }% \let#1=#2% \ifdefFT#2{}{% \ifcsndefTF{\string#2}{% \letcsntocsn{\string#1}{\string#2}% }{% \ifcsndefFT{\cptgobblescape#2\@space}{}{% \letcsntocsn{\cptgobblescape#1\@space} {\cptgobblescape#2\@space}% \ifcsndefFT{\string#2\@space}{}{% \letcsntocsn{\string#1\@space}{\string#2\@space}% }% }% }% }% } \robust@def*\newletcsset{% \cpt@ifstar {\let\LTS@let\ltsfulllet\LTS@newletcsset}% {\let\LTS@let\let\LTS@newletcsset}% } \robust@def*\LTS@newletcsset#1{% \def\reserved@f##1##2\LTS@nil{% \ifblankFT{##2}{}{% \LTS@err{The partner of command '\string##1' is void}{% \noexpand\newletcsset error. }% }% \ifdefTF{##1}{% \cpt@isdeferr{##1}% }{% \LTS@let##1=##2% }% }% \def\csv@do##1{% \ifblankTF{##1}{}{% \reserved@f##1\LTS@nil }% }% \csv@@parse[,]{#1}% } \robust@def\LTS@checkoptprefix#1#2#3#4{% \def\LTS@checkopt@a{% \ifstrcmpTF{#4}{+}{% \ifstrcmpTF{#2#3}{*!}{% #1#2#4#3% }{% \ifstrcmpTF{#2#3}{!*}{#1#3#4#2}{#1#2#3#4}% }% }{% \LTS@checkopt@b }% }% \def\LTS@checkopt@b{% \ifstrcmpTF{#4}{!}{% \ifstrcmpTF{#2#3}{*+}{% #1#2#3#4% }{% \ifstrcmpTF{#2#3}{+*}{#1#3#2#4}{#1#2#3#4}% }% }{% \LTS@checkopt@c }% }% \def\LTS@checkopt@c{% \ifstrcmpTF{#3}{*}{% \ifstrcmpTF{#2}{+}{% \ifsingletokenTF{#4}{#1#3#2#4}{#1#3#2{#4}}% }{% \ifstrcmpTF{#2}{!}{% \ifsingletokenTF{#4}{#1#3#2#4}{#1#3#2{#4}}% }{% \ifsingletokenTF{#4}{#1#2#3#4}{#1#2#3{#4}}% }% }% }{% \LTS@checkopt@d }% }% \def\LTS@checkopt@d{% \ifstrcmpTF{#3}{+}{% \ifstrcmpTF{#2}{*}{% \ifsingletokenTF{#4}{#1#2#3#4}{#1#2#3{#4}}% }{% \ifstrcmpTF{#2}{!}{% \ifsingletokenTF{#4}{#1#3#2#4}{#1#3#2{#4}}% }{% \ifsingletokenTF{#4}{#1#2#3#4}{#1#2#3{#4}}% }% }% }{% \LTS@checkopt@e }% }% \def\LTS@checkopt@e{% \ifsingletokenTF{#4}{% \long\def\@gtempa{#4}% }{% \long\def\@gtempa{{#4}}% }% \LTS@checkopt@f }% \def\LTS@checkopt@f{% \ifsingletokenTF{#3}{% \ifsingletokenTF{#2}{% \LTS@checkopt@g{#1#2#3}% }{% \LTS@checkopt@g{#1{#2}#3}% }% }{% \ifsingletokenTF{#2}{% \LTS@checkopt@g{#1#2{#3}}% }{% \LTS@checkopt@g{#1{#2}{#3}}% }% }% }% \def\LTS@checkopt@g##1{% \begingroup \long\edef\x{\endgroup\unexpanded{##1}}% \expandafter\x\@gtempa }% \ifstrcmpTF{#4}{*}{% \ifstrcmpTF{#2#3}{+!}{% #1#4#2#3% }{% \ifstrcmpTF{#2#3}{!+}{% #1#4#3#2% }{% \ifsingletokenTF{#2}{% \ifsingletokenTF{#3}{#1#2#3#4}{#1#2{#3}#4}% }{% \ifsingletokenTF{#3}{#1{#2}#3#4}{#1{#2}{#3}#4}% }% }% }% }{% \LTS@checkopt@a }% } \robust@def*\LTS@suffixerr#1#2#3{% \if\detokenize{#1#2}\relax \LTS@err{Invalid suffix '#1' to command '\string#3'}\@ehc \fi } \robust@def*\LTS@blankargerr#1#2{% \LTS@err{Invalid blank/empty argument to command '\string#1'}\@ehc } % #1: parser, #2: csv list \robust@def*\getlastcsv#1#2{% \cpt@ch@cklistparser{#1}% \def\rest{}% \def\LTS@getlastcsv##1#1##2#1{% \ifx##2\noboundary \edef\last{\unexpanded{##1}}% \expandafter\cpt@removetonnil \else \edef\rest{\csliststack#1\rest\unexpanded{##1}}% \expandafter\LTS@getlastcsv \fi ##2#1% }% \LTS@getlastcsv#2#1\noboundary#1\noboundary#1\cpt@nnil } \robust@def*\getlasttsv#1{% \def\rest{}% \LTS@getlasttsv#1\noboundary\noboundary\cpt@nnil } \robust@def*\LTS@getlasttsv#1#2{% \ifx#2\noboundary \edef\last{\unexpanded{#1}}% \expandafter\cpt@removetonnil \else \edef\rest{\expandcsonce\rest\unexpanded{#1}}% \expandafter\LTS@getlasttsv \fi #2% } \robust@def*\ifstringcase{\LTS@testst\LTS@ifstringcase} \robust@def\LTS@ifstringcase#1#2:{% \ifblankTF{#2}{% \LTS@blankargerr\ifstringcase{second}% }{% \LTS@testopt{\LTS@ifstringcase@a{#1}#2}{}% }% } \robust@def\LTS@ifstringcase@a#1#2[#3]{% \ifLTS@st \let\LTS@ifstringcase@b\ifstrcmpTF \else \let\LTS@ifstringcase@b\ifstreqTF \fi \def\LTS@ifstringcase@c##1##2##3\LTS@nil{% \LTS@ifstringcase@b{#1}{##1}{##2}{% \ifnullTF{##3}{#3}{% \LTS@ifstringcase@c##3\LTS@nil }% }% }% \LTS@ifstringcase@c#2\LTS@nil } \robust@def\ifstringcases#1#2:{% \ifblankTF{#2}{% \LTS@blankargerr\ifstringcases{second}% }{% \LTS@testopt{\LTS@ifstringcases{#1}#2}{}% }% } \long\def\LTS@ifstringcases#1#2[#3]{% \begingroup \toks@{}% \long\def\LTS@tempa##1##2{% \ifstrcmpTF{##1}{\LTS@nil}{% \oifblankFT{\the\toks@}{}{\toks@{#3}}% }{% \ifstrcmpTF{#1}{##1}{% \toks@\expandafter{\the\toks@##2}% \LTS@tempa }{% \LTS@tempa }% }% }% \LTS@tempa#2\LTS@nil\LTS@nil \expandafter\endgroup\the\toks@\relax } \robust@def\ifmembercases#1#2:{% \ifblankTF{#2}{% \LTS@blankargerr\ifmembercases{second}% }{% \LTS@testopt{\LTS@ifmembercases{#1}#2}{}% }% } \robust@def\LTS@ifmembercases#1#2[#3]{% \begingroup \toks@{}% \long\def\LTS@tempa##1##2{% \ifstrcmpTF{##1}{\LTS@nil}{% \oifblankFT{\the\toks@}{}{\toks@{#3}}% }{% \ifinsetTF{,#1,}{,##1,}{% \toks@\expandafter{\the\toks@##2}% \LTS@tempa }{% \LTS@tempa }% }% }% \LTS@tempa#2\LTS@nil\LTS@nil \expandafter\endgroup\the\toks@\relax } \robust@def\ifnumcase{% \let\LTS@ifnumcase@b\LTS@ifnumcase \LTS@ifnumcase@a } \robust@def\LTS@ifnumcase@a#1#2:{% \LTS@suffixerr{*}{#1}\ifnumcase \ifblankTF{#2}{% \LTS@blankargerr\ifnumcase{second}% }{% \LTS@testopt{\LTS@ifnumcase@b{#1}#2}{}% }% } \robust@def\LTS@ifnumcase#1#2[#3]{% \def\LTS@ifnumcase@c##1##2##3\LTS@nil{% \ifnumcmpTF#1=##1{% ##2% }{% \ifnullTF{##3}{% #3% }{% \LTS@ifnumcase@c##3\LTS@nil }% }% }% \LTS@ifnumcase@c#2\LTS@nil } \robust@def\ifnumcases{% \let\LTS@ifnumcase@b\LTS@ifnumcases \LTS@ifnumcase@a } \robust@def\LTS@ifnumcases#1#2[#3]{% \begingroup \toks@{}% \long\def\LTS@tempa##1##2{% \ifstrcmpTF{##1}{\LTS@nil}{% \oifblankFT{\the\toks@}{}{\toks@{#3}}% }{% \ifnumcmpTF#1=##1{% \toks@\expandafter{\the\toks@##2}% \LTS@tempa }{% \LTS@tempa }% }% }% \LTS@tempa#2\LTS@nil\LTS@nil \expandafter\endgroup\the\toks@\relax } %% David Kastrup: \newcommand*\ltsreplicate[1]{% \csname LTS@repl\expandafter\LTS@replicate \romannumeral\number\number#1 000q\endcsname } \long\def\LTS@replicate#1#2\endcsname#3{#1\endcsname{#3}#2} \long\def\LTS@replm#1#2{#1\csname LTS@repl#2\endcsname{#1}} \let\LTS@replq\@gobble %%-- \new@def*\useifnotempty#1{% \ifdefinedTF#1{% \ifcsnullTF{#1}{}{#1}% }{% \cpt@notdeferr{#1}% }% } \robust@def*\makecsn#1#2{% \ifblankTF{#1}{}{% \edef#2{\cpttrimspaces{#1}}% \edef#2{\expandafter\cptgobblescape#2}% }% } \makecsn{\\}\@backslashchar \robust@def*\get@csname{\LTS@testst\LTS@getcsname} \new@def*\LTS@getcsname#1#2{% \begingroup \ifcsnullTF#1{% \edef#2{\ifLTS@st{}\fi}% }{% \escapechar\m@one \ifLTS@st \edef#2{{\expandafter\string#1}}% \else \edef#2{\expandafter\string#1}% \fi }% \postgroupdef#2\endgroup } \robust@def*\ltsemptify{% \LTS@checkoptprefix{\LTS@teststcl\LTS@emptify}% } \def\LTS@emptify#1{% \is@long@or@relax\is@global@or@relax \glob@lrel@x\l@ngrel@x\def#1{}% } \robust@def*\ltsemptifycsset{% \LTS@checkoptprefix{\LTS@testplcl\LTS@emptifycsset}% } \robust@def*\ltsemptifycsset@{% \LTS@plfalse\LTS@clfalse\LTS@emptifycsset } \new@def*\LTS@emptifycsset#1{% \is@global@or@relax \def\csv@do##1{% \ifLTS@pl \glob@lrel@x\emptifycsn{##1}% \else \LTS@ensurescape{##1}% \glob@lrel@x\def##1{}% \fi }% \csv@@parse[,]{#1}% } \new@def\swapbracetwo#1#2{{#2}{#1}} \new@def\swapbracefirst#1#2{#2{#1}} \new@def\swapbracesecond#1#2{{#2}#1} \new@def\swapfirstthird#1#2#3{#3{#2}{#1}} \new@edef*\LTS@istrue{\string\iftrue} \new@edef*\LTS@isfalse{\string\iffalse} % \ltsinputfiles[x]{a,b}[tex]{if file exists}: \robust@def*\ltsinputfiles{\cpt@testopt\LTS@Inp@tFiles{}} \def\LTS@Inp@tFiles[#1]#2{\cpt@testopt{\LTS@Inp@tF@les[#1]#2}{tex}} \def\LTS@Inp@tF@les[#1]#2[#3]#4{% \begingroup \toks@{}% \def\csv@do##1{% \toks@\expandafter{\the\toks@\InputIfFileExists{#1##1.#3}% {#4}{\@missingfileerror{#1##1}{#3}}}% }% \edef\LTS@tempa{\cptzapspaces{#2}}% \csv@@loop*[,]\LTS@tempa \expandafter\endgroup\the\toks@ } \robust@def\safefullexpand#1{% \begingroup \LTS@safeactivesedef\reserved@a{\endgroup#1}\reserved@a } \robust@def\safeexpandarg#1#2{% \begingroup \LTS@safeactivesedef\reserved@a{\endgroup\unexpanded{#1}{#2}}% \reserved@a } \robust@def\safeexpandsecond#1#2{% \begingroup \LTS@safeactivesedef\reserved@a{\endgroup\unexpanded{#1}#2}% \reserved@a } \robust@def\ltsexpandargs#1#2#3#4\LTS@nil{% \cptpassexpanded{% \ifcase#1\relax \unexpanded{#2}{#3}% \or \unexpanded{#2#3}{#4}% \or \unexpanded{#2}{#3}{#4}% \or \unexpanded{#2}{#3}\unexpanded{#4}% \else \LTS@err{Unknown expansion type '\string#1' for \string\ltsexpandargs}{I expected your first argument '\string#1' to \string\ltsexpandargs\MsgBrk to be in the interval [0,3].}% \fi }% } \robust@def*\safeexpandtwoargs#1#2#3{% \begingroup \LTS@safeactivesedef\reserved@a{\endgroup\noexpand#1{#2}{#3}}% \reserved@a } \robust@def*\expanddetoktwoargs#1#2#3{% \cptexpandtwoargs#1{\cptoxdetok{#2}}{\cptoxdetok{#3}}% } %% Ulrich Diez: \new@def*\stepexpandarg#1{% 0\csname @space\expandafter\LTS@stepexpandarg \romannumeral\number\number#1000D\endcsname } \new@def*\LTS@stepexpandarg#1{% \if#1m\expandafter\expandafter \csname endcsname\expandafter\LTS@stepexpandarg\fi } %%-- \robust@def*\StepExpandArg{\LTS@testopt\LTS@StepExpandArg{}} \robust@def*\LTS@StepExpandArg[#1]#{% \begingroup \edef\LTS@tempa{\endgroup\unexpanded{#1}}% \expandafter\LTS@tempa\romannumeral\stepexpandarg } \robust@def*\nameidef#1#2#3{% \expandafter\def\csname#1\expandafter \endcsname\expandafter{\romannumeral\stepexpandarg{#2}#3}% } \robust@def*\namejdef#1#{\romannumeral\LTS@namejdef{#1}} \new@def*\LTS@namejdef#1#2#3#{\LTS@n@mejdef{#1}{#2}{#3}} \newcommand\LTS@n@mejdef[5]{% \expandafter\cptswap\expandafter{% \csname#2\expandafter\cptswap\expandafter{\expandafter{% \romannumeral\stepexpandarg{#4}#5% }}{\endcsname #3}% }{0 #1}% } \new@def*\ltsexpandtimes#1{% \expandafter\LTS@expandtimes\expandafter {\romannumeral\number#1000}% } \new@def*\LTS@expandtimes#1#2{% \ifnullTF{#1}{% \unexpanded{#2}% }{% \expandafter\ifnullTF\expandafter{\@gobble#1}{% \unexpanded\expandafter{#2}% }{% \expandafter\swapbracefirst\expandafter{#2}% {\expandafter\LTS@expandtimes\expandafter{\@gobble#1}}% }% }% } % Reserve condition. Eg, turn \iffoundTF to \iffoundFT, % \iffoundFT to \iffoundTF, \iffoundT to \iffoundF, etc. % If there is no 'TF' (or 'T' or 'F') at end of csname, % then use \unless: \new@def*\revcond#1{% \LTS@revcond@b{#1}\LTS@cartworev{TF}{% \LTS@revcond@c{#1}\LTS@cdrtwo{FT}% }{% \LTS@revcond@b{#1}\LTS@cartworev{FT}{% \LTS@revcond@c{#1}\LTS@cdrtwo{TF}% }{% \LTS@revcond@b{#1}\LTS@car{T}{% \LTS@revcond@c{#1}\LTS@cdr{F}% }{% \LTS@revcond@b{#1}\LTS@car{F}{% \LTS@revcond@c{#1}\LTS@cdr{T}% }{% \unless#1% }% }% }% }% } \def\LTS@revcond@a#1{% \expandafter\expandafter\expandafter\directreverse \expandafter\expandafter\expandafter {\cptremovescape{#1}}% } \new@def*\LTS@revcond@b#1#2#3{% \expandafter\ifstrcmpTF\expandafter{\romannumeral0\expandafter#2% \romannumeral0\LTS@revcond@a{#1}\car@nil}{#3}% } \new@def*\LTS@revcond@c#1#2#3{% \usename{\expandafter\expandafter\expandafter\directreverse \expandafter\expandafter\expandafter{\expandafter#2\romannumeral0% \LTS@revcond@a{#1}\cdr@nil}#3}% } \robust@def*\ifonetokenTF{% \LTS@checkoptprefix{\LTS@teststcl\LTS@ifonetoken}% } \robust@def*\LTS@ifonetoken#1{% \begingroup \ifbracedTF{#1}{% \aftergroup\@secondoftwo }{% \def\reserved@a##1\LTS@nil{% \def\reserved@a{% \aftercsname\aftergroup{LTS@\expandafter\ifnullTF \expandafter{\@gobble##1}12of2}% }% \ifLTS@cl % Strictly one token: \ifblankTF{##1}{\aftergroup\@secondoftwo}{\reserved@a}% \else % Nil or one token: \ifblankTF{##1}{\aftergroup\@firstoftwo}{\reserved@a}% \fi }% \ifLTS@st\expandafter\expandafter\fi\reserved@a#1\LTS@nil }% \endgroup } \robust@def*\ifonetokenFT#1{\ifonetokenTF{#1}\@secondoftwo\@firstoftwo} \robust@def*\ifonetoken#1\do#2{% \LTS@stfalse\LTS@cltrue \LTS@ifonetoken{#1}{#2}{% \LTS@err{More than one token in '\detokenize{#1}'}\@ehc }% } \new@def*\ifboxvoidTF#1{% \usename{@\ifvoid#1\@empty first\else second\fi ftwo}% } \new@def*\ifboxvoidFT#1{\usename{LTS@\ifboxvoidTF{#1}21of2}} \new@def\LTS@csnifx@a#1\or#2\fi\@@nil{\fi#1} \new@def\LTS@csnifx@b#1\fi\@@nil{\fi#1} \new@def\LTS@csnifx@c#1#2#3#4{% \ifcase\numexpr#1\relax \LTS@csnifx@a \ifcsnameTF{#3}% {\usename{ifx#2\cptthreexp}\usename{#3}{#4}}% {\usename{ifx#2}{#4}\LTS@undefined}% \or \LTS@csnifx@b \ifcsnameTF{#4}% {\usename{ifx#2\cptthreexp}\usename{#4}{#3}}% {\usename{ifx#2}{#3}\LTS@undefined}% \fi\@@nil } %% Eg, \csifxcsnTF\x{y}{T}{F}, \csnifxcsTF{y}\x{T}{F} \newcommand*\csnifxcsTF[2]{\LTS@csnifx@c0{TF}{#1}{#2}} \newcommand*\csnifxcsFT[2]{\LTS@csnifx@c0{FT}{#1}{#2}} \newcommand*\csifxcsnTF[2]{\LTS@csnifx@c1{TF}{#1}{#2}} \newcommand*\csifxcsnFT[2]{\LTS@csnifx@c1{FT}{#1}{#2}} \newcommand*\csnifxcsnTF[2]{\aftercsname\csifxcsnTF{#1}{#2}} \newcommand*\csnifxcsnFT[2]{\aftercsname\csifxcsnFT{#1}{#2}} \new@def*\ifdefinedTF#1{% \usename{LTS@\ifdefined#1\@empty1\else2\fi of2}% } \new@def*\ifdefinedFT#1{\usename{LTS@\ifdefinedTF{#1}21of2}} \let\then\iffalse \new@def*\ifnnum#1\then{% \ifdim\LTS@ptlt\LTS@ptgt\LTS@pteq#1pt\cpt@removetonnil<=>\cpt@nnil } \new@def*\LTS@ptlt#1<{#1pt<} \new@def*\LTS@ptgt#1>{#1pt>} \new@def*\LTS@pteq#1={#1pt=} \new@def*\realnumcmp{TT\fi\ifnum\realnums} \new@def*\realnums#1\then{% \dimexpr\LTS@dptlt\LTS@dptgt\LTS@dpteq#1pt% \cpt@removetonnil<=>\cpt@nnil\@space } \new@def*\LTS@dptlt#1<{#1pt<\dimexpr} \new@def*\LTS@dptgt#1>{#1pt>\dimexpr} \new@def*\LTS@dpteq#1={#1pt=\dimexpr} \begingroup \catcode`\Y=12 \catcode`\Z=12 \lccode`\Y=`\p \lccode`\Z=`\t \lowercase{% \defpass\x{\endgroup \new@def*\LTS@ifinteger@a##1.##2YZ{% \expandafter\ifx\expandafter\\\romannumeral0% \ifnum##2>\z@pt\else\expandafter\@gobble\fi \LTS@ifinteger@b\@space\\\cpt@removetonnil\cpt@nnil }% }% } \new@def\LTS@ifinteger@b#1\cpt@nnil{\noexpand\cpt@nnil} \new@def\LTS@ifinteger#1\then{% \expandafter\LTS@ifinteger@a \the\dimexpr\LTS@mminus\LTS@pplus#1\p@ \cpt@removetonnil+-\cpt@nnil\relax } \def\LTS@mminus#1-{#1\p@-} \def\LTS@pplus#1+{#1\p@+} \new@def\ifintegerTF#1#{% \usename{LTS@\LTS@ifinteger#1\then1\else2\fi of2}% } \new@def\LTS@IfInteger#1\then{% \begingroup \toks@{}% \LTS@integerparse{#1}{-}% \toks@\expandafter{\expandafter}% \expandafter\LTS@integerparse\expandafter{\the\toks@}{+}% \defpass\LTS@tempa{% \xifinsetFT{\p@\p@\LTS@nil}{\the\toks@\LTS@nil}{}{% \def\LTS@tempb####1\p@\LTS@nil{% \toks@{####1}% \LTS@tempa }% \expandafter\LTS@tempb\the\toks@\LTS@nil }% }% \edef\LTS@tempa{\the\dimexpr\the\toks@}% \expandafter\endgroup\expandafter\LTS@ifinteger \expandafter\rem@pt\LTS@tempa\then } \new@def\LTS@integerparse#1#2{% \def\LTS@tempa##1#2##2\LTS@nil{% \ifblankTF{##2}{% \toks@\expandafter{\the\toks@##1\p@}% }{% \ifstrcmpTF{#2}{##2}{% \toks@\expandafter{\the\toks@##1\p@}% }{% \toks@\expandafter{\the\toks@##1\p@#2}% \LTS@tempa##2#2\LTS@nil }% }% }% \LTS@tempa#1\LTS@nil } \new@def\IfIntegerTF#1#{% \LTS@ifinteger#1\then \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi } \robust@def*\ifonedefTF{% \begingroup\def\case@nr{0}\LTS@testpl\LTS@ifonedef } \robust@def*\ifonedefFT{% \begingroup\def\case@nr{1}\LTS@testpl\LTS@ifonedef } \robust@def*\LTS@ifonedef#1{% \cpt@choicefdfalse \def\csv@do##1{% \usename{if\ifLTS@pl csn\fi defFT}{##1}{}{% \cpt@choicefdtrue\loopbreak }% }% \csv@@parse[,]{#1}% \LTS@onecase } \robust@def*\ifonetrueTF{% \begingroup \def\case@nr{0}% \LTS@testst{\LTS@testopt\LTS@ifonetrue{}}% } \robust@def*\ifonetrueFT{% \begingroup \def\case@nr{1}% \LTS@testst{\LTS@testopt\LTS@ifonetrue{}}% } \def\LTS@ifonetrue[#1]#2{% \cpt@choicefdfalse \edef\reserved@a{\ifLTS@st*\fi}% \def\csv@do##1{% \uselivecsn{if#1##1}% \cpt@choicefdtrue\loopbreak \fi }% \expandafter\csv@@parse\reserved@a[#1]{#2}% \LTS@onecase } \robust@def*\LTS@onecase{% \edef\next##1##2##3{% \ifcase\case@nr ##11##22##32\or##12##21##32\or##11##20##31\or ##10##21##31% \fi }% \aftercsname\endgroup{LTS@\next\ifcpt@choicefd\else{\fi of}}% } \new@def*\ifcsndefeqTF#1#2{% \ifcsndefFT{#1}\@secondoftwo {\ifcsndefFT{#2}\@secondoftwo {\aftercsname\ifxTF{#1\aftercsname}{#2}}}% } \new@def*\ifcsndefeqFT#1#2{\usename{LTS@\ifcsndefeqTF{#1}{#2}21of2}} \robust@def*\LTS@notdefinable{% \PackageError{ltxtools}% {Command '\@backslashchar\LTS@rsvda' or '\@backslashchar\@qend\LTS@rsvda' already defined}% {Command '\@backslashchar\LTS@rsvda' already defined, or name '\@backslashchar\@qend\LTS@rsvda' illegal.}% } \robust@def*\LTS@saveprimitive#1#2{% \begingroup \cpt@swafalse \edef\LTS@tempa{\string#1}% \edef\LTS@tempb{\meaning#1}% \ifx\LTS@tempa\LTS@tempb \cpt@swatrue \else \edef\LTS@tempb{\meaning#2}% \ifx\LTS@tempa\LTS@tempb\else\LTS@s@veprimitive#1#2\fi \fi \expandafter\endgroup\ifcpt@swa\let#2#1\fi } \robust@def*\LTS@s@veprimitive#1#2{% \def\LTS@tempb##1#1##2##3\edef{\edef\LTS@tempb{##2}\edef}% \LTS@tempb \nullfont{select font nullfont}% \topmark{\string\topmark:}% \firstmark{\string\firstmark:}% \botmark{\string\botmark:}% \splitfirstmark{\string\splitfirstmark:}% \splitbotmark{\string\splitbotmark:}% #1{\string#1}% \edef\LTS@tempa{\expandafter\strip@prefix\meaning\LTS@tempb}% \edef\LTS@tempb{\meaning#1}% \ifx\LTS@tempa\LTS@tempb \cpt@swatrue \else \@latex@error{Command \noexpand#1 no longer a primitive}\@ehc \fi } \robust@def*\LTS@badargerr#1#2{% \LTS@err{Bad '\string#2' argument for command '\string#1'}{% Bad '\string#2' argument for command '\string#1'.\MsgBrk You need to look again at user instruction\MsgBrk for command '\string#1'. }% } \newletcs\ifpackageloadedTF\@ifpackageloaded \newletcs\ifclassloadedTF\@ifclassloaded \new@def*\ifpackageloadedFT#1{\ifpackageloadedTF{#1}\@secondoftwo\@firstoftwo} \new@def*\ifclassloadedFT#1{\ifclassloadedTF{#1}\@secondoftwo\@firstoftwo} \new@def*\LTS@ifclasscurr{\LTS@ifpkg@cls@curr\@clsextension} \new@def*\LTS@ifpackagecurr{\LTS@ifpkg@cls@curr\@pkgextension} \new@def*\LTS@ifpkg@cls@curr#1#2#3{% \usename{LTS@\ifnum\cptsevenxp\@parse@version \usename{ver@#2.#1}//00\@nil<\expandafter \@parse@version#3//00\@nil2\else1\fi of2}% } \new@def*\ifclasscurrentTF{\LTS@ifloadedcurr{class}} \new@def*\ifpackagecurrentTF{\LTS@ifloadedcurr{package}} \let\ifpkgcurrTF\ifpackagecurrentTF \new@def*\LTS@ifloadedcurr#1#2#3{% \usename{if#1loadedTF}{#2}{% \usename{LTS@if#1curr}{#2}{#3}{% \@firstoftwo }{% \LTS@err{Loaded version of #2 package is not current}% {You need a higher version of #2 package:\MsgBrk The version of #2 package available on your TeX\MsgBrk installation is lower than you require.}% \@secondoftwo }% }{% \@secondoftwo }% } \new@def*\ifpackagecurrentFT#1{\ifpackagecurrentTF{#1}\@secondoftwo\@firstoftwo} \new@def*\ifclasscurrentFT#1{\ifclasscurrentTF{#1}\@secondoftwo\@firstoftwo} % #1: package name % #2: package date (mandatory) \new@def*\NeedPackage#1#2{% \ifx\documentclass\@twoclasseserror \def\reserved@a{\usepackage}% \else \def\reserved@a{\RequirePackage}% \fi \cptexpanded{\LTS@testopt{\LTS@needpackage{#1}{#2}% \expandcsonce\reserved@a}}{}% } \newletcs\needpackage=\NeedPackage % #3: \usepackage or \RequirePackage; % #4: options, if any \robust@def*\LTS@needpackage#1#2#3[#4]{% % If the package has been loaded and is current, don't % reload: \ifpackagecurrentTF{#1}{#2}{}{#3[#4]{#1}[#2]}% } \newcommand*\removeouterbraces[1]{% \romannumeral\ifstrcmpTF{#1}{all}{% \LTS@r@movebraces }{% \expandafter\LTS@removeouterbraces \expandafter{\romannumeral#1000}% }% } \newcommand\LTS@removeouterbraces[2]{% \ifnullTF{#1}{0 #2}{% \expandafter\ifnullTF\expandafter{\@gobble#2}{% \ifbracedTF{#2}{% \expandafter\swapbracefirst \expandafter{\@iden#2}% {\expandafter\LTS@removeouterbraces\expandafter{\@gobble#1}}% }{0 #2}% }{0 #2}% }% } \newcommand\LTS@r@movebraces[1]{% \expandafter\ifnullTF\expandafter{\@gobble#1}{% \ifbracedTF{#1}{% \expandafter\LTS@r@movebraces\expandafter{\@iden#1}% }{0 #1}% }{0 #1}% } \robust@def*\LTS@ensuremacro#1{% \ifmacroTF{#1}{}{\cpt@notcserr{#1}}% } \robust@def*\LTS@ensurescape#1{% \ifescapedTF{#1}{}{\cpt@notescapederr{#1}}% } \robust@def*\LTS@ensurenoscape#1{% \ifescapedTF{#1}{\cpt@isescapederr{#1}}{}% } \robust@def*\LTS@ensurescape@csset#1#2{% \docommalist{#2}{% \usename{LTS@ensure\ifnullTF{#1}{}{no}scape}{##1}% }% } \robust@def\LTS@ifnextchar#1#2#3{% \LTS@ifn@@tchar\bgroup {\LTS@ifn@@tchar{#1}{#2}{#3}}% {\LTS@ifn@xtchar{#1}{#2}{#3}}% } \new@def\LTS@ifn@xtchar#1#2#3#4{% \csname LTS@\if\detokenize{#1#4}1\else2\fi of2\endcsname {#2}{#3}#4% } \newcsndef{LTS@ifnextch} {\futurelet\next\LTS@ifn@@tch@r} \new@def\LTS@ifn@@tchar#1#2#3{% \begingroup \let\reserved@a=#1\toks@{#2}\toks1{#3}% \futurelet\next\LTS@ifn@@tch@r } \new@def*\LTS@ifn@@tch@r{% \ifx\next\@sptoken \let\LTS@next\LTS@ifnextch \else \ifx\next\reserved@a \edef\LTS@next{\endgroup\the\toks@}% \else \edef\LTS@next{\endgroup\the\toks1}% \fi \fi \LTS@next } \robust@def*\NoGobbleSpaceIfnextchar#1#2#3{% \begingroup \let\reserved@a=#1\toks@{#2}\toks1{#3}% \futurelet\next\LTS@nogobblespaceifnext } \new@def*\LTS@nogobblespaceifnext{% \cptpassexpanded{\endgroup \ifxTF\next\reserved@a{\the\toks@}{\the\toks1}% }% } \robust@def*\LTS@ifchar#1#2#3{% \LTS@ifnextchar #1{\begingroup\defpass\x#1{\endgroup#2}}{#3}% } \robust@def*\LTS@ifstar{\LTS@ifchar*} \robust@def*\LTS@ifplus{\LTS@ifchar+} \robust@def*\LTS@ifclam{\LTS@ifchar!} \robust@def*\LTS@ifdot{\LTS@ifchar.} \robust@def*\LTS@ifright{\LTS@ifchar>} \robust@def*\LTS@ifleft{\LTS@ifchar<} \robust@def*\LTS@ifprime{\LTS@ifchar'} \robust@def*\ifnextisbrack#1#2{\LTS@ifnextchar[{#1}{#2}} \robust@def*\ifnextisparen#1#2{\LTS@ifnextchar({#1}{#2}} \robust@def*\ifnextisleftang#1#2{\LTS@ifnextchar<{#1}{#2}} \robust@def*\LTS@testst#1{\LTS@ifstar{\LTS@sttrue#1}{\LTS@stfalse#1}} \robust@def*\LTS@testpl#1{\LTS@ifplus{\LTS@pltrue#1}{\LTS@plfalse#1}} \robust@def*\LTS@testcl#1{\LTS@ifclam{\LTS@cltrue#1}{\LTS@clfalse#1}} \robust@def*\LTS@testpm#1{\LTS@ifprime{\LTS@pmtrue#1}{\LTS@pmfalse#1}} \robust@def*\LTS@testrt#1{\LTS@ifright{\LTS@rttrue#1}{\LTS@rtfalse#1}} \robust@def*\LTS@testlt#1{\LTS@ifleft{\LTS@lttrue#1}{\LTS@ltfalse#1}} \robust@def*\LTS@teststpl#1{\LTS@testst{\LTS@testpl{#1}}} \robust@def*\LTS@teststplcl#1{\LTS@testst{\LTS@testpl{\LTS@testcl{#1}}}} \robust@def*\LTS@teststplpm#1{\LTS@testst{\LTS@testpl{\LTS@testpm{#1}}}} \robust@def*\LTS@teststcl#1{\LTS@testst{\LTS@testcl{#1}}} \robust@def*\LTS@teststpm#1{\LTS@testst{\LTS@testpm{#1}}} \robust@def*\LTS@testplcl#1{\LTS@testpl{\LTS@testcl{#1}}} \robust@def*\LTS@testopt#1#2{\ifnextisbrack{#1}{#1[{#2}]}} \robust@def*\LTS@testltopt#1#2{\ifnextisleftang{#1}{#1<{#2}>}} \robust@def*\LTS@testpnopt#1#2{\ifnextisparen{#1}{#1({#2})}} \new@def*\LTS@Test@pt#1{\usename{LTS@\ifnullTF{#1}12of2}} \new@def*\LTS@IfBrack#1#2#3{\LTS@IfBr@ck#1&[&{#2}{#3{#1}}} \new@def*\LTS@IfBr@ck#1[#2#{\LTS@Test@pt{#1#2}} \new@def*\LTS@TestOpt#1#2#3{\LTS@IfBr@ck#1&[&{#2#1}{#2[{#3}]{#1}}} \new@def*\LTS@IfStar#1#2#3{\LTS@IfSt@r#1&*&{#2}{#3{#1}}} \new@def*\LTS@IfSt@r#1*#2#{\LTS@Test@pt{#1#2}} \new@def*\LTS@IfPlus#1#2#3{\LTS@IfPl@s#1&+&{#2}{#3{#1}}} \new@def*\LTS@IfPl@s#1+#2#{\LTS@Test@pt{#1#2}} % Look ahead for many characters: \robust@def\ltsifnextchars#1#2#3{% \begingroup \long\def\special@car{\futurelet\next\special@car@a}% \long\def\special@car@a##1##2\car@nil{% \ifx\next\temp@bgroup\toks@{{##1}}\else\toks@{##1}\fi }% \let\temp@bgroup\bgroup \let\bgroup\LTS@undefined \def\LTS@tempa{#1}\def\LTS@tempb{#2}% \def\LTS@tempc{#3}\def\LTS@tempd{}% \LTS@ifnextchars@a } \def\LTS@ifnextchars@a{\futurelet\next\LTS@ifnextchars@b} \def\LTS@ifnextchars@b{% \ifxTF\next\@sptoken{% \afterassignment\LTS@ifnextchars@a\let\next= % }{% \LTS@ifnextchars@c }% } \def\LTS@ifnextchars@c#1{% \ifx\next\temp@bgroup\toks1{{#1}}\else\toks1{#1}\fi \expandafter\special@car\LTS@tempa\car@nil \xifstrcmpTF{\the\toks@}{\the\toks1}{% \edef\LTS@tempd{\expandcsonce\LTS@tempd\the\toks@}% \toks@\cptthreexp{\expandafter\cpt@cdr\LTS@tempa\cdr@nil}% \edef\LTS@tempa{\the\toks@}% \ifcsnullTF\LTS@tempa{% \cptthreexp\endgroup\expandafter\LTS@tempb\LTS@tempd }{% \LTS@ifnextchars@a }% }{% \edef\LTS@tempd{\expandcsonce\LTS@tempd\the\toks1}% \cptthreexp\endgroup\expandafter\LTS@tempc\LTS@tempd }% } \robust@def*\ltscommanormalize#1#2{% \let\LTS@inkv\cptswfalse \edef#2{\comma@kv@normalize{#1}}% } \robust@def*\ltskvnormalize#1#2{% \let\LTS@inkv\cptswtrue \edef#2{\comma@kv@normalize{#1}}% } \begingroup \catcode`\!=13 \uccode`\~=`\,% \uccode`\!=`\=% \uppercase{\endgroup \def\comma@kv@normalize#1{% \unexpanded\expandafter{\romannumeral-`\q \LTS@activecomma,#1,~\LTS@nil}% }% \def\LTS@activecomma#1~#2\LTS@nil{% \ifblankTF{#2}{% \ifcondTF\if\LTS@inkv\fi{% \LTS@activeequal#1!\LTS@nil }{% \LTS@spacecomma#1 ,\LTS@nil }% }{% \LTS@activecomma#1,#2\LTS@nil }% }% } \defpass\LTS@tempa#1{% \begingroup \uccode`\~=`\=% \uppercase{\endgroup \def\LTS@activeequal##1~##2\LTS@nil{% \ifblankTF{##2}{% \LTS@spacecomma##1#1,\LTS@nil }{% \LTS@activeequal##1=##2\LTS@nil }% }% }% \def\LTS@spacecomma##1#1,##2\LTS@nil{% \ifblankTF{##2}{% \LTS@commaspace##1,#1\LTS@nil }{% \LTS@spacecomma##1,##2\LTS@nil }% }% \def\LTS@commaspace##1,#1##2\LTS@nil{% \ifblankTF{##2}{% \ifcondTF\if\LTS@inkv\fi{% \LTS@spaceequal##1#1=\LTS@nil }{% \LTS@doublecomma##1,,\LTS@nil }% }{% \LTS@commaspace##1,##2\LTS@nil }% }% \def\LTS@spaceequal##1#1=##2\LTS@nil{% \ifblankTF{##2}{% \LTS@equalspace##1=#1\LTS@nil }{% \LTS@spaceequal##1=##2\LTS@nil }% }% \def\LTS@equalspace##1=#1##2\LTS@nil{% \ifblankTF{##2}{% \LTS@doublecomma##1,,\LTS@nil }{% \LTS@equalspace##1=##2\LTS@nil }% }% }{ } \def\LTS@doublecomma#1,,#2\LTS@nil{% \ifblankTF{#2}{% \ifcondTF\if\LTS@inkv\fi{% \LTS@doubleequal#1==\LTS@nil }{% \LTS@remleadcomma#1\LTS@nil }% }{% \LTS@doublecomma#1,#2\LTS@nil }% } \def\LTS@doubleequal#1==#2\LTS@nil{% \ifblankTF{#2}{% \LTS@remleadcomma#1\LTS@nil }{% \LTS@doubleequal#1=#2\LTS@nil }% } \def\LTS@commaequalerr#1,=#2\LTS@nil{% \ifblankTF{#2}{}{% \LTS@err{There is ',=' in your key-value list}\@ehc }% } \new@def*\LTS@remleadcomma,#1\LTS@nil{\noexpand#1} % !! Enter in manual. Preserves braces. Takes arbitrary parser. % General list parser. Use '#1' in for current % item on level 1, ##1 on level 2, etc: % \ltsdocsvlist[]{} % \ltsdocsvlist*[]{} \robust@def*\ltsdocsvlist{\cpt@teststopt\lts@docsvlist,} \robust@def*\lts@docsvlist[#1]#2#3{% \pushfunctions\ltsdocsvlist {\cpt@csvdo,\cpt@csvact,\ifloopbreak}\cpt@csvdepth \cpt@stchoose{cpt@st}{#2}\cpt@csvarg\ltsdocsvlist \def\cpt@csvact##1{#3}% \def\cpt@csvdo##1#1{% \ifcsvbreakTF{##1}\loopbreak\relax \ifboolTF{loopbreak}{% \gobble@to@sentinel\cpt@csvnil#1% }{% \edef\cpt@csvarg{\unexpanded\expandafter{\@gobble##1}}% \ifxTF\cpt@csvarg\cpt@csvnil{}{% \expandafter\cpt@csvact\expandafter{\cpt@csvarg}\relax \cpt@csvdo.% }% }% }% \loopbreakfalse \cpt@sttrue\cpt@csvnormalize[#1]\cpt@csvarg \expandafter\cpt@csvdo\expandafter.\cpt@csvarg#1\cpt@csvnil#1% \popfunctions\ltsdocsvlist\cpt@csvdepth } % !! Enter in manual: \robust@def*\commacsvloop{% \let\LTS@nmlz\cptswfalse \let\LTS@inkv\cptswfalse \cpt@testst\LTS@commaparse } \robust@def*\commacsvparse{% \let\LTS@nmlz\cptswtrue \let\LTS@inkv\cptswfalse \cpt@testst\LTS@commaparse } \robust@def*\commakvloop{% \let\LTS@nmlz\cptswfalse \let\LTS@inkv\cptswtrue \cpt@testst\LTS@commaparse } \robust@def*\commakvparse{% \let\LTS@nmlz\cptswtrue \let\LTS@inkv\cptswtrue \cpt@testst\LTS@commaparse } \robust@def*\LTS@commaparse#1{% \cpt@stchoose{cpt@st}{#1}\LTS@tempa\LTS@commaparse \pushfunctions\LTS@commaparse {\ifloopbreak,\sav@comma@do}\cpt@csvdepth \ifdefTF\comma@do{% \let\sav@comma@do\comma@do }{% \cpt@notdeferr\comma@do }% \ifdefswitchTF{LTS@nmlz}{% \edef\LTS@tempa{\s@expandarg\comma@kv@normalize\LTS@tempa}% \ifdefswitchTF{LTS@inkv}{% \expandafter\LTS@commaequalerr\LTS@tempa,=\LTS@nil }{}% }{}% \loopbreakfalse \let\currsentinel\cpt@commanil \expandafter\LTS@c@mmaparse\LTS@tempa,\cpt@commanil,% \popfunctions\LTS@commaparse\cpt@csvdepth \undefcs\comma@do } \robust@def*\LTS@c@mmaparse#1,{% \ifsentinelTF{#1}{}{% \ifcsvbreakTF{#1}\loopbreak\relax \ifboolTF{loopbreak}{% \gobble@to@sentinel\cpt@commanil,% }{% \sav@comma@do{#1}\relax\LTS@c@mmaparse }% }% } \newvariables{if}{lastfox}[false] \newcommand*\LTS@foxnil{\LTS@foxnil} % \foxloop[]{}{} % \foxloop*[]{}{} % You can use \currfox, \nextfox, and % \currfoxnr within to access the current % element of , the next element of , and % the serial number of the current item, respectively, at % various levels of nesting. is given in roman numerals, % eg, \currfoxi, \currfoxii. % You can inset \csvbreak as an element of to break % out of the loop. Similarly, you can use \loopbreak within % to break out of the loop. % You can insert \csvpause as an element of to pause the loop. \robust@def*\foxloop{% \LTS@testst{\LTS@testopt\LTS@fox@@a{,}}% } \robust@def*\LTS@fox@@a[#1]{% \cpt@checklistparser{#1}\relax \usename{LTS@fox@\ifLTS@st b\else a\fi}[#1]% } \robust@def*\LTS@fox@a[#1]#2{% \declarefoxlistparser{#1}% \LTS@fox@@b{#2}% } \robust@def*\LTS@fox@b[#1]#2{% \declarefoxlistparser{#1}% \expandafter\LTS@fox@@b\expandafter{#2}% } \robust@def*\declarefoxlistparser#1{% % ##1 -> list; ##2 -> callback: \long\def\LTS@fox@@b##1##2{% \pushfunctions\foxloop{% \getnextfox,\LTS@foxrema,\foxparser,\LTS@fox@@d,% \currfox,\nextfox,\currfoxnr,\iflastfox,\ifloopbreak }\cpt@csvdepth \pushnumber\foxdepth \def\foxparser{#1}% \long\def\LTS@foxrema####1\LTS@foxnil#1{% \long\edef\foxremainder{\unexpanded{####1}}% \ifcsemptyTF\foxremainder\relax {\cpt@trimparsers[#1]\foxremainder}% }% \chardef\currfoxnr\z@ \def\getnextfox####1#1####2\getnextfox{% \edef\nextfox{\expandcsonce{\cpt@removetodot####1}}% \ifxTF\nextfox\LTS@foxnil{% \lastfoxtrue \let\nextfox\@empty \letcsntocs{nextfox\romannumeral\cpt@csvdepth}\@empty }{% \lastfoxfalse \letcsntocs{nextfox\romannumeral\cpt@csvdepth}\nextfox }% }% \def\LTS@fox@@c####1####2{% \getnextfox.####1\getnextfox ####2\relax % Rather than evaluate \iflastfox here for every item, % let \ifx\currfox\LTS@foxnil terminate the loop. \ifboolTF{loopbreak}{}{% \LTS@fox@@d.####1\LTS@fox@@d{####2}% }% }% \long\def\LTS@fox@@d####1#1####2\LTS@fox@@d####3{% \edef\currfox{\expandcsonce{\cpt@removetodot####1}}% \letcsntocs{currfox\romannumeral\cpt@csvdepth}\currfox \edef\currfoxnr{\the\numexpr\currfoxnr+1}% \letcsntocs{currfoxnr\romannumeral\cpt@csvdepth}\currfoxnr \ifxTF\currfox\LTS@foxnil{}{% \ifxTF\currfox\cpt@csvbreak{% \LTS@foxrema####2% }{% \ifxTF\currfox\cpt@csvpause{% \message{^^J! List pause: ^^JType x or X to quit, or to proceed^^J}% {\endlinechar-1\global\read-1 to\@gtempa}% \lowercase\expandafter{\expandafter\def\expandafter \@gtempa\expandafter{\@gtempa}}% \xifstrcmpTF\@gtempa{x}{% \LTS@foxrema####2% }{% \LTS@fox@@c{####2}{####3}% }% }{% \LTS@fox@@c{####2}{####3}% }% }% }% }% \loopbreakfalse\lastfoxfalse \cpt@stfalse\cpt@csvnormalize[#1]{##1}% \expandafter\LTS@fox@@d\expandafter .\normalized@list#1\LTS@foxnil#1\LTS@fox@@d{##2}% \popfunctions\foxloop\cpt@csvdepth \popnumber\foxdepth }% } \new@def*\ltsprotectedtokens#{% etoolbox \ifx\protect\@typeset@protect \LTS@protectedtoken\@firstofone\fi \ifx\protect\@unexpandable@protect \LTS@protectedtoken\LTS@unexpandable\fi \ifx\protect\noexpand \LTS@protectedtoken\unexpanded\fi \ifx\protect\string \LTS@protectedtoken\detokenize\fi \@firstofone } \new@def*\LTS@protectedtoken#1#2\@firstofone{\fi#1} \new@def\LTS@unexpandable#1{\unexpanded{\ltsprotectedtokens{#1}}} \new@def\LTS@neverexpand#1{% \unexpanded{\unexpanded{\unexpanded{\unexpanded{% \unexpanded{\unexpanded{\unexpanded{\unexpanded{#1}}}}}}}}% } \new@def*\LTS@csnalloc#1{\usename{new#1\aftercsname}} \providerobust@def*\csnnewif{\LTS@csnalloc{if}} \robust@def*\csnnewtoks{\LTS@csnalloc{toks}} \robust@def*\csnnewcount{\LTS@csnalloc{count}} \robust@def*\csnnewdimen{\LTS@csnalloc{dimen}} \robust@def*\csnnewskip{\LTS@csnalloc{skip}} \robust@def*\csnnewmuskip{\LTS@csnalloc{muskip}} \robust@def*\csnnewbox{\LTS@csnalloc{box}} \robust@def*\csnnewwrite{\LTS@csnalloc{write}} \robust@def*\csnnewread{\LTS@csnalloc{read}} \robust@def*\LTS@createtwincmds#1{% \begingroup\escapechar92\relax\expandafter\endgroup \if\expandafter\LTS@car\string#1x\car@nil\@backslashchar\else \LTS@err{Non-escaped command name '\detokenize{#1}'}\@ehc \fi \ifcsdefinable#1\relax \ifcsndefinable{No\cptremovescape{#1}}\relax } \robust@def*\CreateTwinBooleanCommands#1#2{% \LTS@createtwincmds{#1}% \ifcsndefinable{if\cptremovescape{#2}}{% \csnnewif{\cptremovescape{#2}}% }% \def#1{\gletcsntocs{if\cptremovescape{#2}}\iftrue}% \csn@def{No\cptremovescape{#1}}{% \gletcsntocs{if\cptremovescape{#2}}\iffalse }% \usename{No\cptremovescape{#1}}% } \robust@def*\CreateTwinSwitchCommands#1#2{% \LTS@createtwincmds{#1}% \def#1{\global\let#2\cptswtrue}% \csn@def{No\cptremovescape{#1}}{\global\let#2\cptswfalse}% \usename{No\cptremovescape{#1}}% } % Eg, \CreateTwinNumberCommands\StrictCheck\strict \robust@def*\CreateTwinNumberCommands#1#2{% \LTS@createtwincmds{#1}% \def#1{\global\chardef#2\@ne}% \csn@def{No\cptremovescape{#1}}{\global\chardef#2\z@pt}% \usename{No\cptremovescape{#1}}% } \CreateTwinSwitchCommands\ExpandPrimitives\LTS@expprim \CreateTwinSwitchCommands\WrapQuotes\LTS@wq \CreateTwinSwitchCommands\ConvertInputToLowercase\LTS@lwc \CreateTwinSwitchCommands\StrictHashCheck\stricthashcheck \robust@def*\LTS@detok@zap#1{% \LTS@ensuremacro{#1}% \edef#1{\s@expandarg\cptzapspaces{\detokenize\expandafter{#1}}}% } \new@def*\is@global@or@relax{% \ifLTS@cl\let\glob@lrel@x\global\else\let\glob@lrel@x\relax\fi } \let\glob@lrel@x\relax \new@def*\is@long@or@relax{% \ifLTS@st\let\l@ngrel@x\relax\else\let\l@ngrel@x\long\fi } \begingroup \endlinechar\m@one \def\siso@do#1{\catcode`#1\string=\active} \siso@@loop{!"$&'()*+,-./:;<=>?[]^_|~} \new@gdef\LTS@safeactivesedef#1#2{% \begingroup \def\siso@do##1{% \ifnum\catcode`##1\string=\active\edef##1{\string##1}\fi }% \siso@@loop{!"$&'()*+,-./:;<=>?[]^_|~}% \cptexpandsecond\endgroup {\edef\noexpand#1{\noexpand\unexpanded{#2}}}% } \endgroup \robust@def*\reversetokens{\LTS@testst\LTS@reverse} \new@def*\LTS@reverse#1#2{% \begingroup \def\LTS@tempa##1\reverse@nil{% \def\LTS@tempa####1####2{% \expandafter\ifxTF\cpt@car####2\car@nil \endreverse{####1}{\LTS@tempa{####2####1}}% }% \toks@\expandafter{\romannumeral0\LTS@tempa{}##1\@space\endreverse}% }% \ifLTS@st\expandafter\expandafter\fi \LTS@tempa#2\reverse@nil \cptexpandsecond\endgroup {\edef\noexpand#1{\noexpand\unexpanded{\the\toks@}}}% } \newletcs\endreverse\end \new@def\directreverse#1{\LTS@directreverse{}#1\endreverse} \new@def\LTS@directreverse#1#2{% \expandafter\ifxTF\cpt@car#2\car@nil\endreverse{% \if@test\expandafter\@iden\else\expandafter\unexpanded\fi{#1}% }{% \LTS@directreverse{#2#1}% }% } \new@def\robustreverse#1{\LTS@robustreverse{}.#1\endreverse} \new@def\LTS@robustreverse#1#2\endreverse{% \LTS@r@bustreverse{#1}% {\expandafter\ifleftbracedTF\expandafter{\cpt@removetodot#2}}#2\endreverse } \new@def\LTS@r@bustreverse#1#2.#3{% \expandafter\ifxTF\cpt@car#3\car@nil\endreverse{% \if@test\expandafter\@iden\else\expandafter\unexpanded\fi{#1}% }{% #2{\LTS@robustreverse{{#3}#1}}{\LTS@robustreverse{#3#1}}.% }% } % Create a delimiter for command Rabfe (meaning 'Remove all but % first undelimited element'): \robust@def*\DeclareRabfeDelimiter{\LTS@testst\LTS@DeclareRabfeDelimiter} \robust@def*\LTS@DeclareRabfeDelimiter#1{% \ifLTS@st \long\def\ltsgetfirstelement##1##2#1{{##1}}% \else \long\def\ltsgetfirstelement##1##2#1{##1}% \fi } \DeclareRabfeDelimiter{\LTS@nil} % Eg, #1 with two delimiters: % \LTS@DeclareRabfeDelimiter\LTS@nil % \edef\x{% % \removeallbutfirstelement{xyz\LTS@nil\LTS@nil}} % \new@def\removeallbutfirstelement#1{% Ulrich Diez \romannumeral-`\q \expandafter\expandafter\expandafter\ifnullTF \expandafter\expandafter\expandafter{% \expandafter\@gobble\ltsgetfirstelement#1}{% \expandafter\@firstofone\expandafter{% \ltsgetfirstelement#1}% }{% \expandafter\expandafter\expandafter\@gobblefour \expandafter\removeallbutfirstelement \expandafter{\ltsgetfirstelement#1}% }% } \robust@def*\remleadparser{\LTS@testopt\LTS@remleadparser{,}} \new@def\LTS@remleadparser[#1]#2{% \LTS@ensuremacro{#2}% \begingroup \def\reserved@a#1{\futurelet\next\reserved@d}% \@namedef{reserved@b} {\reserved@a#1}% \def\reserved@d{% \ifx\next\@sptoken \expandafter\reserved@b \else \ifx#1\next \cptthreexp\reserved@a \else \cptthreexp\reserved@c \fi \fi }% \def\reserved@c##1\LTS@nil{\endgroup\edef#2{\unexpanded{##1}}}% \expandafter\reserved@a\expandafter#1#2\LTS@nil } \robust@def*\remtrailparser{\LTS@testopt\LTS@remtrailparser{,}} \robust@def*\LTS@remtrailparser[#1]#2{% \begingroup \LTS@ensuremacro{#2}% \let\trimpr@nil\relax \defpass\LTS@rsvda{% \despacecontent#2% \xifinsetFT{#1\trimpr@nil}{\expandcsonce#2\trimpr@nil}{}{% \def\LTS@rsvdb####1#1\trimpr@nil{% \edef#2{\unexpanded{####1}}% \LTS@rsvda }% \expandafter\LTS@rsvdb#2\trimpr@nil }% }% \postgroupdef#2\endgroup } \robust@def*\ltsremoveparser{\LTS@testopt\LTS@remparser{,}} \robust@def*\LTS@remparser[#1]#2{% \LTS@remleadparser[#1]#2% \LTS@remtrailparser[#1]#2% } \robust@def*\SelectiveSanitize{\LTS@testopt\s@lectivesanitize\@M} \robust@def*\s@lectivesanitize[#1]#2#3{% \LTS@ensuremacro{#3}% \begingroup \cpt@cnta#1\advance\cpt@cnta\@ne \let\temp@bgroup\bgroup \let\bgroup\@undefined \cptexpandsecond {\s@l@ctivesanitize#3}{{\detokenize{#2}}{\expandcsonce#3}}% \postgroupdef#3\endgroup } \robust@def*\s@l@ctivesanitize#1#2#3{% \def\LTS@i{\futurelet\next\LTS@ii}% \def\LTS@ii{% \expandafter\LTS@iii\meaning\next\LTS@nil \ifx\next\end \let\cmd\@gobbleone \else \ifx\next\@sptoken \edef#1{\expandcsonce#1\@space}% \lowercase{\def\cmd} {\LTS@i}% \else \let\cmd\LTS@iv \fi \fi \cmd }% \def\LTS@iii##1##2\LTS@nil{% \if##1\@backslashchar\let\next\relax\fi }% \def\LTS@iv##1{% \toks@\expandafter{#1}\toks1{##1}% \ifx\next\temp@bgroup \advance\cpt@cnta\m@one \ifnum\cpt@cnta>\z@pt \begingroup \cptexpandsecond\s@l@ctivesanitize {\noexpandcsn{\string#1}{#2}{\the\toks1}}% \edefpass#1{\endgroup\toks1{\expandcsnonce{\string#1}}}% \fi \edef#1{\the\toks@{\the\toks1}}% \advance\cpt@cnta\@ne \else \edef#1{\expandafter\string\the\toks1}% \expandafter\cpt@in\expandafter{#1}{#2}% \edef#1{\the\toks@\ifcpt@in#1\else\the\toks1\fi}% \fi \LTS@i }% \def#1{}\LTS@i#3\end } \robust@def*\LTS@checksanitya#1#2{\LTS@checksanity{,}{#1}#2} \robust@def*\LTS@checksanityb#1#2{\LTS@checksanity{,.=}{#1}#2} \robust@def*\LTS@checksanityc#1#2{\LTS@checksanity{,;}{#1}#2} \robust@def*\LTS@checksanityd#1#2{\LTS@checksanity{,;:|-=}{#1}#2} \robust@def*\LTS@checksanity#1#2#3{% \cpt@checkfalse \def\tsv@do##1{% \ifboolTF{cpt@check}{}{% \LTS@ch@cksanity{##1}{#2}% }% }% \tsv@@parse{#1}% \ifboolTF{cpt@check}{% \edef#3{\unexpanded{#2}}% \SelectiveSanitize[1]{#1}#3% }{}% } \robust@def*\LTS@ch@cksanity#1#2{% \ifbelongFT{#1}{#2}{}{% \defpass\reserved@a##1#1##2\LTS@nil{% \ifblankTF{##2}{\cpt@checktrue\loopbreak}{}% }% #2#1\LTS@nil }% } \robust@def*\LTS@ensureothersanity#1#2{% \begingroup \edef#2{\unexpanded{#1}}% \LTS@scantoksb#2% \postgroupdef#2\endgroup } % #1 : optional parser % #2 : a control sequence or name (+ -> name) of original list % #3 : new list to merge with #2 (* -> #3 is a macro) % #4 : filter (use \nofilter when there isn't a filter) \robust@def*\ltsfiltermergecsv{% \begingroup \let\LTS@parse\csv@@parse \LTS@checkoptprefix {\LTS@teststplcl{\LTS@testopt\LTS@filtermergelists{,}}}% } \robust@def*\ltsfiltermergekv{% \begingroup \let\LTS@parse\kv@@parse \LTS@checkoptprefix {\LTS@teststplcl{\LTS@testopt\LTS@filtermergelists,}}% } \robust@def*\LTS@filtermergelists[#1]#2#3#4{% \edef\temp@do {\noexpandcsn{\ifxTF\LTS@parse\csv@@parse{csv}{kv}@do}}% \def\LTS@tempa{}% \ifLTS@pl \ifcsndefTF{#2}{\letcstocsn\LTS@tempa{#2}}{}% \else \ifdefTF{#2}{\let\LTS@tempa#2}{}% \fi \cpt@stchoose{LTS@st}{#3}\LTS@tempb\LTS@filtermergelists \cptdeclarefilter{#4}% \cpt@useemptyfalse \def\LTS@tempf##1{\csliststack#1\LTS@tempa\unexpanded{##1}}% \expandafter\def\temp@do##1{% \edef\LTS@tempb{\unexpanded{##1}}% % csv/kv loops don't use cpt@swa. So it is safe % to use it here: \cpt@swatrue \cpt@usefilter\LTS@tempb\LTS@tempc \let\LTS@tempd\LTS@tempa \def\LTS@tempa{}% \expandafter\def\temp@do####1{% \edef\LTS@tempd{\unexpanded{####1}}% \cpt@usefilter\LTS@tempd\LTS@tempe \ifx\LTS@tempc\LTS@tempe \cpt@swafalse \edef\LTS@tempa{\LTS@tempf{##1}}% \else \edef\LTS@tempa{\LTS@tempf{####1}}% \fi }% \ifcsnullTF\LTS@tempd{}{\LTS@parse*[#1]\LTS@tempd}% \ifdefboolFT{cpt@swa}{}{\edef\LTS@tempa{\LTS@tempf{##1}}}% }% \ifcsnullTF\LTS@tempb{}{\LTS@parse*[#1]\LTS@tempb}% \cptpassexpanded{% \ifLTS@cl\global\fi \let\ifLTS@pl\cptmakecs{#2}\else\noexpand#2\fi \noexpand\LTS@tempa }% % If cl is true, then global assignment has already been done: \ifboolTF{LTS@cl}\endgroup{% \ifboolTF{LTS@pl}{% \expandafter\postgroupdef\csname#2\endcsname\endgroup }{% \postgroupdef#2\endgroup }% }% } \robust@def*\filter@merge@csv#1{% \begingroup \let\LTS@parse\csv@@parse \LTS@sttrue \LTS@ifstringcase{#1}% {fff}{\LTS@stfalse\LTS@plfalse\LTS@clfalse}% {tff}{\LTS@sttrue\LTS@plfalse\LTS@clfalse}% {ttf}{\LTS@sttrue\LTS@pltrue\LTS@clfalse}% {ttt}{\LTS@sttrue\LTS@pltrue\LTS@cltrue}% {ftt}{\LTS@stfalse\LTS@pltrue\LTS@cltrue}% {fft}{\LTS@stfalse\LTS@plfalse\LTS@cltrue}% {tft}{\LTS@sttrue\LTS@plfalse\LTS@cltrue}:% [\LTS@err{No match for \string\filter@merge@csv}\@ehc]% \LTS@filtermergelists } % #1: parser % #2: new single element, in a macro or otherwise; % #3: old list (in a macro); % #4: filter (a macro); % We want to filter #2 before entering the result in #3: \robust@def*\singleelementfiltermerge{% \LTS@testcl{\LTS@testopt\LTS@sefm,}% } \robust@def*\LTS@sefm[#1]#2#3#4{% \cptdeclarefilter{#4}% \cpt@usefilter{#2}\reserved@a \edef\reserved@a{\simpleexpandarg\cpttrimspace\reserved@a}% \ifdefTF#3{}{\def#3{}}% \xifinsetTF{#1\cptoxdetok\reserved@a#1}{#1\cptoxdetok#3#1}{}{% \ifLTS@cl\global\fi \edef#3{\csliststack#1#3\expandcsonce\reserved@a}% }% } % #1 : control sequence of old (non-separated) list % #2 : new update (a non-separated list) % #3 : filter (use \nofilter when there isn't a filter) \robust@def*\ltsfiltermergetsv{\LTS@testcl\LTS@filtermergetokens} \robust@def*\LTS@filtermergetokens#1#2#3{% \begingroup \let\ifLTS@mergecl\ifLTS@cl \cptdeclarefilter{#3}% \ifdefTF{#1}{}{\emptify#1}% \def\LTS@tempa{#2}% \LTS@tfor@b\LTS@tempa\LTS@tempa{% \cpt@swatrue \cpt@usefilter\LTS@tempa\LTS@tempb \let\LTS@tempc#1\emptify#1% \LTS@tfor@b\LTS@tempc\LTS@tempc{% \cpt@usefilter\LTS@tempc\LTS@tempd \ifx\LTS@tempb\LTS@tempd \cpt@swafalse \edef#1{\expandcsonce#1\expandcsonce\LTS@tempa}% \else \edef#1{\expandcsonce#1\expandcsonce\LTS@tempc}% \fi }% \ifcpt@swa\edef#1{\expandcsonce#1\expandcsonce\LTS@tempa}\fi }% \ifLTS@mergecl \globalize#1\endgroup \else \cptpassacross#1\endgroup \fi } % #1 : optional list parser; % #2 : control sequence (or, if +, cs name) of csv list; % #3 : non-contiguous sublist to remove % ('*' implies that this is a control sequence); % #4 : filter (use \nofilter when there isn't a filter); \robust@def*\filterremovecsv{% \begingroup \let\LTS@parse\csv@@parse \LTS@checkoptprefix {\LTS@teststplcl{\LTS@testopt\LTS@filterremoveelements{,}}}% } \robust@def*\filterremovekv{% \begingroup \let\LTS@parse\kv@@parse \LTS@checkoptprefix {\LTS@teststplcl{\LTS@testopt\LTS@filterremoveelements{,}}}% } \robust@def*\LTS@filterremoveelements[#1]#2#3#4{% \cpt@checklistparser{#1}\relax \begingroup \edef\temp@do {\noexpandcsn{\ifxTF\LTS@parse\csv@@parse{csv}{kv}@do}}% \letcstocsn\LTS@normalize {cpt@\ifxTF\LTS@parse\csv@@parse{csv}{kv}normalize}% \ifLTS@pl \ifcsndefTF{#2}{}{\emptifycsn{#2}}% \letcstocsn\LTS@tempa{#2}% \else \ifdefTF{#2}{}{\def#2{}}% \let\LTS@tempa#2% \fi \cpt@stchoose{LTS@st}{#3}\LTS@tempb\LTS@filterremoveelements \ifcsnullTF\LTS@tempb{} {\cpt@sttrue\LTS@normalize[#1]\LTS@tempb}% \cptdeclarefilter{#4}% \def\LTS@tempd{}% \expandafter\def\temp@do##1{% \edef\LTS@tempa{\unexpanded{##1}}% \cpt@usefilter\LTS@tempa\LTS@tempc \oifinset@sp@TF#1\LTS@tempc\LTS@tempb{}{% \edef\LTS@tempd{\csliststack#1\LTS@tempd\unexpanded{##1}}% }% }% \ifcsnullTF\LTS@tempa{}{\LTS@parse*[#1]\LTS@tempa}% \cptpassexpanded{% \ifLTS@cl\global\fi \let\ifLTS@pl\cptmakecs{#2}\else\noexpand#2\fi \noexpand\LTS@tempd }% \ifboolTF{LTS@cl}\endgroup{\postgroupdef#2\endgroup}% } % \purgeelements is faster than \filterremoveelements but it % first detokenizes the tokens. It thus isn't as versatile. % Also inherent leading and trailing spaces may cause % problems in the removal of elements. It is handy in % cleaning \@unusedoptionlist. % #1: optional parser; % #2: noncontiguous sublist; % #3: container of original list \robust@def*\purgeelements{% \LTS@testst{% \let\ifLTS@purgest\ifLTS@st \begingroup \@makeother{\#}% \LTS@testopt{\expandafter\endgroup\LTS@p@rgeelements}{,}% }% } % The parameter character '#' must be innocent when % calling \purgeelements: \robust@def*\LTS@purgeelements{% \LTS@err{Use \noexpand\purgeelements instead}\@ehc } \robust@def*\LTS@p@rgeelements[#1]#2#3{% \cpt@checklistparser{#1}\relax \begingroup \def\csv@do##1{% \ifblankTF{##1}{}{% \def\LTS@tempb####1#1##1#1####2\LTS@nil{####1#1####2\purge@nil}% \def\LTS@tempc####1#1\purge@nil####2\purge@nil{% \ifx#1####1\@empty\else####1\fi }% \def\LTS@tempa{% \cptthreexp\LTS@tempc\expandafter\LTS@tempb\expandafter #1\detokenize\expandafter{#3}#1\purge@nil#1##1#1\LTS@nil }% \expandafter\edef\expandafter#3\expandafter{\LTS@tempa}% }% }% \ifblankTF{#2}{}{\cptexpandarg{\csv@@loop[#1]}{\detokenize{#2}}}% \postgroupdef#3\endgroup \LTS@remparser[#1]#3% \ifboolTF{LTS@purgest}{}{\LTS@scantoks@hash#3}% \undefcs\ifLTS@purgest } % #1 : container of original (non-separated) tokens % #2 : non-separated members to delete (* -> a macro) % #2 : filter \robust@def*\filterdeletetokens{\LTS@teststcl\LTS@deletetokens} \robust@def*\LTS@deletetokens#1#2#3{% \let\ifLTS@fdelcl\ifLTS@cl \begingroup \cptdeclarefilter{#3}% \def\siso@do##1{% \edef\LTS@tempa{\unexpanded{##1}}% \cpt@usefilter\LTS@tempa\LTS@tempc \edef\LTS@tempa{\expandcsonce\LTS@tempc}% \cptexpandsecond{% \def\LTS@tempb####1}{\expandcsonce\LTS@tempa}####2####3\LTS@nil{% \edef\LTS@tempb{\unexpanded{####2}}% \ifxTF\LTS@nnil\LTS@tempb{}{% \cptexpandsecond{\def\LTS@tempb########1}{% \expandcsonce\LTS@tempa}########2\LTS@nil{% \edef#1{\unexpanded{########1########2}}% }% \expandafter\LTS@tempb#1\LTS@nil }% }% \cptexpandsecond\LTS@tempb {\expandcsonce#1\expandcsonce\LTS@tempa}{\LTS@nil}\LTS@nil }% \ifboolTF{LTS@st}{% \expandafter\siso@@loop\expandafter{#2}% }{% \siso@@loop{#2}% }% \postgroupdef#1\endgroup \ifLTS@fdelcl\globalize#1\fi \undefcs\ifLTS@fdelcl } % #1 : container of original (non-separated) tokens % #2 : non-separated members to delete \robust@def*\simpledeletetokens#1#2{% \def\siso@do##1{% \def\LTS@tempa####1##1####2####3\LTS@nil{% \edef\LTS@tempa{\unexpanded{####2}}% \ifx\LTS@nnil\LTS@tempa\else \def\LTS@tempa########1##1########2\LTS@nil{% \edef#1{\unexpanded{########1########2}}% }% \expandafter\LTS@tempa#1\LTS@nil \fi }% \expandafter\LTS@tempa#1##1{\LTS@nil}\LTS@nil }% \expandafter\siso@@loop\expandafter{#2}% } \robust@def*\DeclareVerbatimDelimiter#1{% \ifsingletokenFT{#1}{% \LTS@err{Verbatim delimiter isn't a single token}\@ehc }{% \def\LTS@v@rbatimstore##1#1##2#1{% \endgroup \LTS@v@rb@timstore{##2}% }% }% } \robust@def*\LTS@v@rb@timst@re{% \begingroup \@sanitize\obeyspaces \LTS@v@rbatimstore } \robust@def*\verbatimstore#1{% \long\def\LTS@v@rb@timstore##1{\def#1{##1}}% \LTS@v@rb@timst@re } \robust@def*\ltsretokenize{\LTS@testst\LTS@retokenize} \robust@def\LTS@retokenize#1#2{% \begingroup \edef\LTS@tempa{\unexpanded{#2}}% \ifLTS@st \def\LTS@ret@kenize##1\LTS@nil{\protected@edef#1{##1}}% \else \def\LTS@ret@kenize##1\LTS@nil{\edef#1{\unexpanded{##1}}}% \fi \cpteveryscan \everyeof{\LTS@nil}% \expandafter\LTS@ret@kenize\scantokens\expandafter{\LTS@tempa}% \relax\postgroupdef#1\endgroup } \robust@def*\LTS@scantoksa#1{% \begingroup \edef#1{\long\def\string#1{\detokenize\expandafter{#1}}}% \cpteveryscan \scantokens\expandafter{#1}\relax \postgroupdef#1\endgroup } \robust@def*\LTS@scantoks@hash#1{% \begingroup \edef#1{\long\def\string#1{\detokenize\expandafter{#1}}}% \catcode`\#=6\relax\cpteveryscan \scantokens\expandafter{#1}\relax \postgroupdef#1\endgroup } \robust@def*\LTS@scantoksb#1{% \begingroup \def\siso@do##1{\catcode`##1\string=12\relax}% \siso@@loop{=,;|-+?><}% \LTS@scantoksa#1% \postgroupdef#1\endgroup } \robust@def*\LTS@scantoksc{\LTS@testplcl\LTS@sc@ntoksc} \robust@def\LTS@sc@ntoksc#1{% \def\comma@do##1{% \ifboolTF{LTS@pl}{% \expandafter\LTS@ensuremacro\csname ##1\endcsname \letcstocsn\reserved@e{##1}% }{% \LTS@ensuremacro{##1}% \let\reserved@e##1% }% \LTS@scantoksa\reserved@e \cptpassexpanded{% \ifLTS@cl\global\fi\let\ifLTS@pl \cptmakecs{##1}\else\unexpanded{##1}\fi \noexpand\reserved@e }% }% \commacsvparse{#1}% } \robust@def*\LTS@scantoksd#1#2{% \cptexpandsecond{#1\cpteveryscan\scantokens}{% {#2}% \everyeof{\the\everyeof}% \noexpand\endlinechar\the\endlinechar\relax \catcode`\noexpand\@=\the\catcode`\@\relax \catcode`\noexpand\ =\the\catcode`\ \relax \catcode`\noexpand\\=\the\catcode`\\\relax \catcode`\noexpand\{=\the\catcode`\{\relax \catcode`\noexpand\}=\the\catcode`\}\relax }% } \providecommand*\newbool{\ltsnewbool} \providecommand*\setbool{\ltssetbool} \providecommand*\booltrue{\ltsbooltrue} \providecommand*\boolfalse{\ltsboolfalse} \providecommand*\setbooltrue{\ltssetbooltrue} \providecommand*\setboolfalse{\ltssetboolfalse} \robust@def*\ltsnewbool#1{\cpt@swatrue\LTS@testopt{\LTS@newbool{#1}}{false}} \robust@def*\defbool#1{\cpt@swafalse\LTS@testopt{\LTS@newbool{#1}}{false}} \new@def*\LTS@newbool#1[#2]{% \ifinsetFT{,}{#1}{}{% \begingroup \edef\LTS@tempa{\ifcpt@swa'\string\ltsnewbool' \else'\string\ltsdefbool'\fi}% \edef\LTS@tempb{\ifcpt@swa'\string\NewBooleans' \else'\string\DefBooleans'\fi}% \LTS@err{Command \LTS@tempa\@space doesn't accept list}% {Please submit only one boolean to \LTS@tempa\MsgBrk at a time. You may consider using\LTS@tempb\MsgBrk if you really want to define a set of booleans.}% \endgroup }% \LTS@ensurenoscape{#1}% \LTS@badboolname{#1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{if#1}\relax \LTS@getboolstate\ltsnewbool{#2}% }{% \ifcsndefFT{if#1}{}{% \LTS@verbosewarn{Boolean '\@backslashchar if#1' redefined}% }% \LTS@getboolstate\ltsdefbool{#2}% }% \csnnewif{#1}% \usename{#1\LTS@boolval}% } \robust@def*\NewBooleans{\cpt@swatrue\LTS@testopt\LTS@NewBooleans{}} \robust@def*\DefBooleans{\cpt@swafalse\LTS@testopt\LTS@NewBooleans{}} \robust@def*\LTS@NewBooleans[#1]#2{% \LTS@testopt{\LTS@B@oleans{#1}{#2}}{false}% } \new@def*\LTS@B@oleans#1#2[#3]{% \cptexpandsecond\LTS@getboolstate {\ifboolTF{cpt@swa}\NewBooleans\DefBooleans}{#3}% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \LTS@badboolname{#1##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{if#1##1}\relax }{% \ifcsndefFT{if#1##1}{}{% \LTS@verbosewarn{Boolean '\@backslashchar if#1##1' redefined}% }% }% \csnnewif{#1##1}% \usename{#1##1\LTS@boolval}% }% \commacsvparse{#2}% } \robust@def*\ltssetbool#1#2{% \ifcsndefFT{if#1}{% \LTS@noboolerr{#1}% }{% \LTS@getboolstate\ltssetbool{#2}% \csname#1\LTS@boolval\endcsname }% } \robust@def*\ltssetbooltrue#1{% \ifcsndefFT{if#1}{\LTS@noboolerr{#1}}{\usename{#1true}}% } \newletcs\ltsbooltrue\ltssetbooltrue \robust@def*\ltssetboolfalse#1{% \ifcsndefFT{if#1}{\LTS@noboolerr{#1}}{\usename{#1false}}% } \newletcs\ltsboolfalse\ltssetboolfalse \robust@def*\LTS@noboolerr#1{% \LTS@err{Boolean/switch '\string#1' is undefined}% {You need to first define the boolean/switch '\string#1'.}% } \robust@def*\LTS@boolnameerr#1{% \LTS@err{'\string\if#1' not valid as a boolean/switch}% {Invalid boolean/switch name '\string#1'.}% } \new@def*\LTS@boolvalerr#1#2{% \LTS@err{Invalid boolean/switch value '#2' in \string#1}% {Valid boolean/switch values are \LTS@validboolvalues.}% } \new@def*\LTS@validboolvalues{true,false} \robust@def*\AddValidBooleanValues#1{% \ltsfiltermergecsv![,]\LTS@validboolvalues{#1}\nofilter } \robust@def*\RemoveValidBooleanValues#1{% \filterremovecsv!\LTS@validboolvalues{#1}\nofilter } \robust@def*\LTS@getboolstate#1#2{% \lowercase{% \xifinsetTF{,#2,}{,\LTS@validboolvalues,}{% \edef\LTS@boolval{#2}% }% }{% \LTS@boolvalerr{#1}{#2}% }% } \robust@def*\LTS@badboolname#1{% \begingroup \xifstrcmpTF{\expandafter\LTS@cartwo\string#1xx\car@nil}{if}{% \LTS@boolnameerr{if}% }{% \edef\LTS@tempa{\s@expandarg\cpttrimspaces{\cptrm-`\q#1}}% \oifstrcmpTF\LTS@tempa{x}{\LTS@boolnameerr{x}}{% \oifstrcmpTF\LTS@tempa{on}{\LTS@boolnameerr{on}}{% \oifstrcmpTF\LTS@tempa{off}{\LTS@boolnameerr{off}}{% \oifstrcmpTF\LTS@tempa{tog}{\LTS@boolnameerr{tog}}{% \oifstrcmpTF\LTS@tempa{bool}{\LTS@boolnameerr{bool}}{% \oifstrcmpTF\LTS@tempa{switch}{\LTS@boolnameerr{switch}}{}% }% }% }% }% }% }% \endgroup } \providecommand*\newswitch[1]{\cpt@swatrue\LTS@testopt{\LTS@newswitch#1}{false}} \robust@def*\defswitch#1{\cpt@swafalse\LTS@testopt{\LTS@newswitch#1}{false}} \robust@def*\LTS@newswitch#1[#2]{% \ifinsetFT{,}{#1}{}{% \begingroup \edef\LTS@tempa{\ifcpt@swa'\string\newswitch' \else'\string\defswitch'\fi}% \edef\LTS@tempb{\ifcpt@swa'\string\NewSwitches' \else'\string\DefSwitches'\fi}% \LTS@err{Command \LTS@tempa\@space doesn't accept list}% {Please submit only one switch to \LTS@tempa\MsgBrk at a time. You may consider using\LTS@tempb\MsgBrk if you really want to define a set of switches.}% \endgroup }% \LTS@ensurenoscape{#1}% \LTS@badboolname{#1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1}\relax \LTS@getboolstate\newswitch{#2}% }{% \ifcsndefFT{#1}{}{% \LTS@verbosewarn{Switch '\@backslashchar#1' redefined}% }% \LTS@getboolstate\defswitch{#2}% }% \letcsntocsn{#1}{cpt\LTS@boolval}% } \robust@def*\NewSwitches{\cpt@swatrue\LTS@testopt\LTS@NewSwitches{}} \robust@def*\DefSwitches{\cpt@swafalse\LTS@testopt\LTS@NewSwitches{}} \robust@def*\LTS@NewSwitches[#1]#2{% \LTS@testopt{\LTS@Sw@tches{#1}{#2}}{false}% } \new@def*\LTS@Sw@tches#1#2[#3]{% \cptexpandsecond\LTS@getboolstate {\ifboolTF{cpt@swa}\NewSwitches\DefSwitches}{#3}% \docommalist{#2}{% \LTS@ensurenoscape{##1}% \LTS@badboolname{#1##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{if#1##1}\relax }{% \ifcsndefFT{if#1##1}{}{% \LTS@verbosewarn{Switch '\@backslashchar if#1##1' redefined}% }% }% \letcsntocsn{#1##1}{cpt\LTS@boolval}% }% } \robust@def*\NewTogs{\cpt@swatrue\LTS@testopt\LTS@NewTogs{}} \robust@def*\DefTogs{\cpt@swafalse\LTS@testopt\LTS@NewTogs{}} \new@def*\LTS@NewTogs[#1]#2{\LTS@testopt{\LTS@NewT@gs[#1]{#2}}{false}} \new@def*\LTS@NewT@gs[#1]#2[#3]{% \cptexpandsecond\LTS@getboolstate {\ifcpt@swa\NewTogs\else\DefTogs\fi}{#3}% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \cptpassexpanded{\ifcpt@swa\newtog\else\deftog\fi}{#1##1}% \usename{settog\LTS@boolval}{#1##1}% }% \commacsvparse{#2}% } \robust@def*\NewToks{\cpt@swatrue\LTS@testopt\LTS@NewToks{}} \robust@def*\DefToks{\cpt@swafalse\LTS@testopt\LTS@NewToks{}} \new@def*\LTS@NewToks[#1]#2{% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1##1}\relax }{% \ifcsndefFT{#1##1}{}{% \LTS@verbosewarn{Token register '\@backslashchar #1##1' redefined}% }% }% \csnnewtoks{#1##1}% }% \commacsvparse{#2}% } \robust@def*\NewCounts{\cpt@swatrue\LTS@testopt\LTS@NewCounts{}} \robust@def*\DefCounts{\cpt@swafalse\LTS@testopt\LTS@NewCounts{}} \new@def*\LTS@NewCounts[#1]#2{\LTS@testopt{\LTS@N@wCounts[#1]#2}{}} \new@def*\LTS@N@wCounts[#1]#2[#3]{% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1##1#3}\relax }{% \ifcsndefFT{#1##1#3}{}{% \LTS@verbosewarn{Counter register '\@backslashchar #1##1#3' redefined}% }% }% \csnnewcount{#1##1#3}% }% \commacsvparse{#2}% } \robust@def*\NewCounters{\cpt@swatrue\LTS@testopt\LTS@NewCounters{}} \robust@def*\DefCounters{\cpt@swafalse\LTS@testopt\LTS@NewCounters{}} \new@def*\LTS@NewCounters[#1]#2{\LTS@testopt{\LTS@N@wCounters[#1]#2}{}} \new@def*\LTS@N@wCounters[#1]#2[#3]{% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1##1#3}\relax }{% \ifcsndefFT{#1##1#3}{}{% \LTS@verbosewarn{Counter register '\@backslashchar #1##1#3' redefined}% }% }% \@definecounter{#1##1#3}% }% \commacsvparse{#2}% } \newletcs\NewNumbers\NewCounters \robust@def*\NewDimens{\cpt@swatrue\LTS@testopt\LTS@NewDimens{}} \robust@def*\DefDimens{\cpt@swafalse\LTS@testopt\LTS@NewDimens{}} \new@def*\LTS@NewDimens[#1]#2{% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1##1}\relax }{% \ifcsndefFT{#1##1}{}{% \LTS@verbosewarn{Dimension register '\@backslashchar #1##1' redefined}% }% }% \csnnewdimen{#1##1}% }% \commacsvparse{#2}% } \robust@def*\NewBoxes{\cpt@swatrue\LTS@testopt\LTS@NewBoxes{}} \robust@def*\DefBoxes{\cpt@swafalse\LTS@testopt\LTS@NewBoxes{}} \new@def*\LTS@NewBoxes[#1]#2{% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1##1}\relax }{% \ifcsndefFT{#1##1}{}{% \LTS@verbosewarn{Box register '\@backslashchar #1##1' redefined}% }% }% \csnnewbox{#1##1}% }% \commacsvparse{#2}% } \robust@def*\NewSkips{\cpt@swatrue\LTS@testopt\LTS@NewSkips{}} \robust@def*\DefSkips{\cpt@swafalse\LTS@testopt\LTS@NewSkips{}} \new@def*\LTS@NewSkips[#1]#2{% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1##1}\relax }{% \ifcsndefFT{#1##1}{}{% \LTS@verbosewarn{Skip register '\@backslashchar #1##1' redefined}% }% }% \csnnewskip{#1##1}% }% \commacsvparse{#2}% } \newletcs\NewLengths\NewSkips \newletcs\DefLengths\DefSkips \robust@def*\NewMuSkips{\cpt@swatrue\LTS@testopt\LTS@NewMuSkips{}} \robust@def*\DefMuSkips{\cpt@swafalse\LTS@testopt\LTS@NewMuSkips{}} \new@def*\LTS@NewMuSkips[#1]#2{% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1##1}\relax }{% \ifcsndefFT{#1##1}{}{% \LTS@verbosewarn{\noexpand\muskip register '\@backslashchar #1##1' redefined}% }% }% \csnnewmuskip{#1##1}% }% \commacsvparse{#2}% } \robust@def*\NewWrites{\cpt@swatrue\LTS@testopt\LTS@NewWrites{}} \robust@def*\DefWrites{\cpt@swafalse\LTS@testopt\LTS@NewWrites{}} \new@def*\LTS@NewWrites[#1]#2{% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1##1}\relax }{% \ifcsndefFT{#1##1}{}{% \LTS@verbosewarn{Write stream '\@backslashchar #1##1' redefined}% }% }% \csnnewwrite{#1##1}% }% \commacsvparse{#2}% } \robust@def*\NewReads{\cpt@swatrue\LTS@testopt\LTS@NewReads{}} \robust@def*\DefReads{\cpt@swafalse\LTS@testopt\LTS@NewReads{}} \new@def*\LTS@NewReads[#1]#2{% \def\comma@do##1{% \LTS@ensurenoscape{##1}% \ifboolTF{cpt@swa}{% \ifcsndefinable{#1##1}\relax }{% \ifcsndefFT{#1##1}{}{% \LTS@verbosewarn{Read stream '\@backslashchar #1##1' redefined}% }% }% \csnnewread{#1##1}% }% \commacsvparse{#2}% } \robust@def*\checknewcommands{% \LTS@checkoptprefix{\LTS@teststpl\LTS@checknewcmds}% } \new@def*\LTS@checknewcmds#1{% \begingroup \edef\LTS@tempa{\ifLTS@st*\fi}% \def\csv@do##1{% \usename{ifcs\ifLTS@pl n\fi definable}{##1}\relax }% \expandafter\csv@@parse\LTS@tempa[,]{#1}% \endgroup } \new@def*\LTS@post@prefixerr#1{% \LTS@err{Bad prefixes for command '\string#1'}% {You have wrongly prefixed command '\string#1'\MsgBrk with both star sign and exclamation mark.\MsgBrk You have to choose one of them. The star expands\MsgBrk the arguments once, while the exclamation mark\MsgBrk expands the arguments fully.}% } \robust@def*\postgroup{\LTS@teststcl\LTS@postgroup} \new@def\LTS@postgroup#1{% \ifLTS@st \ifLTS@cl \LTS@post@prefixerr\postgroup \else \edef\LTS@tempa{\unexpanded{#1}}% \expandallonce\LTS@tempa \fi \else \ifLTS@cl \if\detokenize{#1*}% \LTS@post@prefixerr\postgroup \fi \let\next\@firstofone \else \let\next\unexpanded \fi \fi \advance\@tempcnta\@ne \csn@xdef{LTS@aft@rgroup@\romannumeral\@tempcnta}{% \gundefcsn{LTS@aft@rgroup@\romannumeral\@tempcnta}% \ifboolTF{LTS@st}{\@firstofone\LTS@tempa\@gobble}\next{#1}% }% \aftercsname\aftergroup{LTS@aft@rgroup@\romannumeral\@tempcnta}% } \robust@def*\postassignment{\LTS@teststcl\LTS@postassignment} \robust@def\LTS@postassignment#1{% \begingroup \ifboolTF{LTS@st}{% \ifboolTF{LTS@cl}{% \LTS@post@prefixerr\postassignment }{% \edef\LTS@tempa{\unexpanded{#1}}% \expandallonce\LTS@tempa }% }{% \ifboolTF{LTS@cl}{% \if\detokenize{#1*}% \LTS@post@prefixerr\postassignment \fi \let\next\@firstofone }{% \let\next\unexpanded }% }% \advance\@tempcnta\@ne \aftercsname\xdef{LTS@p@stassignment@\romannumeral\@tempcnta}{% \gundefcsn{LTS@p@stassignment@\romannumeral\@tempcnta}% \ifboolTF{LTS@st}{\@firstofone\LTS@tempa\@gobble}\next{#1}% }% \aftercsname{\endgroup\afterassignment} {LTS@p@stassignment@\romannumeral\@tempcnta}% } \robust@def*\minorpostassignment{\LTS@testst\LTS@minorpostassignment} \robust@def\LTS@minorpostassignment#1{% \begingroup \advance\@tempcnta\@ne \csn@xdef{LTS@p@stassignment@\romannumeral\@tempcnta}{% \gundefcsn{LTS@p@stassignment@\romannumeral\@tempcnta}% \ifLTS@st\expandafter\@iden\else\expandafter\unexpanded\fi{#1}% }% \aftercsname{\endgroup\afterassignment} {LTS@p@stassignment@\romannumeral\@tempcnta}% } \robust@def*\LTS@undef{\LTS@testcl\LTS@und@f} \new@def*\LTS@und@f#1{% \is@global@or@relax \docommalist{#1}{% \ifsingletoken@sp@TF{##1}{% \LTS@ensurescape{##1}% \glob@lrel@x\undefcs##1% }{% \cpt@notonetokenerr{##1}% }% }% } \robust@def*\ltsundefcslist{% \LTS@checkoptprefix{\LTS@teststplcl{\cpt@testopt\LTS@undefcslist{,}}}% } \new@def*\LTS@undefcslist[#1]#2{% \is@global@or@relax \edef\reserved@a{\ifLTS@st*\fi}% \def\csv@do##1{% \ifLTS@pl \glob@lrel@x\undefcsn{##1}% \else \glob@lrel@x\undefcs##1% \fi }% \expandafter\csv@@parse\reserved@a[#1]{#2}% } \robust@def*\declarepackagecmd{\LTS@testopt\LTS@declarepkgcmd{}} \new@def\LTS@declarepkgcmd[#1]#2{% \LTS@ensurescape{#2}% \ifdefTF#2{% \letcsntocs{Saved\cptremovescape#2}#2% \cptpassexpanded{% \AtTagEndPackage{% \let\noexpand#2\noexpandcsn{Saved\cptremovescape#2}% \gundefcs\noexpandcsn{Saved\cptremovescape#2}% }% }% }{% \AtTagEndPackage{\gundefcs#2}% }% #1\def#2% } \robust@def*\declaredocumentcmd{\LTS@testopt\LTS@declaredoccmd{}} \new@def\LTS@declaredoccmd[#1]#2{% \LTS@ensurescape{#2}% \ifcsdefinable#2\relax \ifinstylefileTF{% \cptpassexpanded{% \LTS@AtBeginDocument{% \let\noexpand#2\noexpandcsn{Saved\cptremovescape#2}% \gundefcs\noexpandcsn{Saved\cptremovescape#2}% }% }% \postassignment{% \letcsntocs{Saved\cptremovescape#2}#2% \gundefcs#2% }% }{}% #1\def#2% } \robust@def*\LTS@providedef{\LTS@teststcl{\LTS@pr@videdef\relax}} \robust@def*\LTS@providerobustdef{\LTS@teststcl{\LTS@pr@videdef\protected}} \new@def\LTS@pr@videdef#1#2{% \is@long@or@relax\is@global@or@relax \LTS@ensurescape{#2}% \ifdefTF#2{% \LTS@verboseinfo{Command '\string#2' already defined: \MsgBrk Not redefined}% \minorpostassignment{\gundefcs\pr@v@de}% }{% \minorpostassignment{% \gletcs#2\pr@v@de \gletcsntocs{LTS@test@\cptremovescape#2}#2% \gundefcs\pr@v@de }% }% \glob@lrel@x\l@ngrel@x#1\def\pr@v@de } \new@def\testprovidedcommand#1{% \LTS@ensurescape{#1}% \begingroup \ifmacroFT#1{% \aftergroup\@secondoftwo }{% \aftercsname\aftergroup{LTS@\cptthreexp \ifxTF\usename{LTS@test@\cptremovescape#1}#112of2}% }% \endgroup } \robust@def*\LTS@reviewcommandhandler#1{% \LTS@verboseinfo{% Previously 'provided' definition of '\string#1'\MsgBrk is retained. Your new definition was ignored\MsgBrk }% } \robust@def*\reviewcommand{\LTS@testopt\LTS@revcommand{}} \new@def\LTS@revcommand[#1]#2#3{% \testprovidedcommand#2{% \LTS@reviewcommandhandler{#2}% }{% #1\def#2{#3}% }% } % #1: list of comma-separated command pairs: \robust@def*\newprovidedcommands#1{% \def\reserved@e##1##2\LTS@nil{% \ifdefTF{##2}{% \LTS@providerobustdef*##1{##2}% }{% \cpt@notdeferr{##2}% }% }% \def\csv@do##1{\reserved@e##1\LTS@nil}% \csv@@parse[,]{#1}% } \new@def*\ifrelaxTF#1{% \ifdefinedTF{#1}% {\usename{LTS@\expandafter\ifxTF\cpt@car#1\car@nil \relax12of2}}\@secondoftwo } \new@def*\ifcsnrelaxTF#1{% \ifcsnameFT{#1}\@secondoftwo {\usename{LTS@\aftercsname\expandafter\ifxTF\cpt@car#1\car@nil \relax12of2}}% } \def\ifcsnrelaxFT#1{\usename{LTS@\ifcsnrelaxTF{#1}21of2}} \new@def*\ifdefaxTFN#1{% \ifdefinedTF{#1}% {\usename{LTS@\expandafter\ifxTF\cpt@car#1\car@nil \relax21of3}}\@thirdofthree } \new@def*\ifcsndefaxTFN#1{% \ifcsnameTF{#1}% {\usename{LTS@\expandafter\ifxTF\csname#1\endcsname \relax21of3}}\@thirdofthree } \robust@def*\ifargifTF#1{% \usename{LTS@\ifnum\pdfstrcmp {\expandafter\LTS@carcube\string#1xxx\car@nil}% {\string\if}=\z@pt1\else2\fi of2}% } \robust@def*\LTS@detokenize{\LTS@testst\LTS@det@kenize} \robust@def*\LTS@det@kenize#1#2{% \edef#2{\detokenize{#1}}% \ifLTS@st \simpleexpandarg\ifargifTF#2{% \LTS@err{'\@backslashchar if' not valid}\@ehc }{% \LTS@scantoksa#2% \edef#2{\cpttxdetok#2}% }% \fi } \new@def*\LTS@detokdespace{\LTS@testpl\LTS@det@kdespace} \new@def\LTS@det@kdespace#1{% \ifboolTF{LTS@pl}{% \edef\LTS@resa{\detokenize{#1}}% \despacecontent\LTS@resa }{% \ifdefTF{#1}{}{% \LTS@err{Command '\string#1' is undefined}{Command '\string\LTS@detokdespace' doesn't accept undefined \MsgBrk commands when submitted without the '+' prefix.}% }% \ifargifTF{#1}{% \LTS@err{Invalid argument '\string#1' for command\MsgBrk '\string\LTS@detokdespace'}{Command '\string\LTS@detokdespace' doesn't accept '\@backslashchar if'\MsgBrk when submitted without the '+' prefix.}% }{% \edef#1{\cptoxdetok{#1}}% \despacecontent#1% }% }% } \robust@def*\ifltxprotectTF#1{% \begingroup \ifmacroFT#1{% \aftergroup\@secondoftwo }{% \edef\LTS@tempa##1{\def##1####1\string\protect####2&}% \LTS@tempa\LTS@tempa{% \aftercsname\aftergroup{LTS@\ifblankTF{##2}21of2}}% \edef\LTS@tempb##1{##1\realmeaning#1\string\protect&}% \LTS@tempb\LTS@tempa }% \endgroup } \robust@def*\ifltxprotectFT#1{% \ifltxprotectTF{#1}\@secondoftwo\@firstoftwo } \robust@def*\ifcsnltxprotectTF{\aftercsname\ifltxprotectTF} \robust@def*\ifetexprotectedTF#1{% \begingroup \edef\LTS@tempa##1{\def##1####1\string\protected####2&}% \LTS@tempa\LTS@tempa{% \aftercsname\aftergroup{LTS@\ifblankTF{##2}21of2}}% \edef\LTS@tempb##1{##1\meaning#1\string\protected&}% \LTS@tempb\LTS@tempa \endgroup } \robust@def*\ifetexprotectedFT#1{% \ifetexprotectedTF{#1}\@secondoftwo\@firstoftwo } \robust@def*\ifcsnprotectedTF{\aftercsname\ifetexprotectedTF} \robust@def*\apptocs{% \LTS@checkoptprefix{\LTS@teststplcl{\LTS@hooktomac{>}}}% } \robust@def*\preptocs{% \LTS@checkoptprefix{\LTS@teststplcl{\LTS@hooktomac{<}}}% } \robust@def\LTS@hooktomac#1#2#3{% \ifLTS@st\let\@expandb\expandcsonce\else\let\@expandb\unexpanded\fi \cpt@getmacroprefix{#2}% \ifLTS@pl \let\@ifdef\ifcsndefFT\let\@expanda\expandcsnonce \def\LTS@i##1{\def\@def####1{\aftercsname##1{####1}}}% \else \let\@ifdef\ifdefFT\let\@expanda\expandcsonce \def\LTS@i##1{\def\@def####1{##1####1}}% \fi \ifLTS@cl\LTS@i\xdef\else\LTS@i\edef\fi \@ifdef{#2}{% \macroprefix\@def{#2}{\@expandb{#3}}% }{% \ifx#1>% \macroprefix\@def{#2}{\@expanda{#2}\@expandb{#3}}% \else \macroprefix\@def{#2}{\@expandb{#3}\@expanda{#2}}% \fi }% \LTS@undef!{\@ifdef,\@def,\@expanda,\@expandb,\LTS@i}% } \robust@def*\LTS@uaddtolist{\chardef\LTS@addnr\z@pt\LTS@addt@list} \robust@def*\LTS@addtolist{\chardef\LTS@addnr\@ne\LTS@addt@list} \robust@def*\LTS@xaddtolist{\chardef\LTS@addnr\tw@\LTS@addt@list} \robust@def*\LTS@addt@list#1{% \ifx#1*% \LTS@err{Star (*) isn't valid as suffix to \noexpand\LTS@addtolist or \string\LTS@listadd}% \fi \LTS@testplcl{\LTS@testlt{\LTS@testopt\LTS@addt@l@st{,}}}% #1% } \new@def*\LTS@addt@l@st[#1]{% \edef\parser{\detokenize{#1}}% \ifLTS@cl\let\@def\xdef\else\let\@def\edef\fi \ifLTS@pl\expandafter\aftercsname\fi\LTS@addt@l@@t } \robust@def\LTS@addt@l@@t#1#2{% \ifcase\LTS@addnr \let\@expand\unexpanded \or \let\@expand\expandcsonce \else \let\@expand\@iden \fi \begingroup \toks@{\endgroup \ifdefFT{#1}{% \@def#1{\@expand{#2}}% }{% \ifcsnullTF#1{% \@def#1{\@expand{#2}}% }{% \ifboolTF{LTS@lt}{% \@def#1{\@expand{#2}\parser\expandcsonce{#1}}% }{% \@def#1{\expandcsonce{#1}\parser\@expand{#2}}% }% }% }% }% \usename{% \ifnum\LTS@addnr=\z@pt\else\ifnum\LTS@addnr=\@ne o\else x\fi\fi ifblankTF% }{#2}{\ifcpt@useempty\the\toks@\else\endgroup\fi}{\the\toks@}% \undefcs\@expand\undefcs\@def \chardef\LTS@addnr\@ne } \robust@def*\LTS@listadd#1{% \LTS@plfalse\LTS@clfalse\LTS@ltfalse\chardef\LTS@addnr\z@pt \LTS@addt@l@st[#1]% } \robust@def*\LTS@olistadd#1{% \LTS@plfalse\LTS@clfalse\LTS@ltfalse\chardef\LTS@addnr\@ne \LTS@addt@l@st[#1]% } \robust@def*\LTS@xlistadd#1{% \LTS@plfalse\LTS@clfalse\LTS@ltfalse\chardef\LTS@addnr\tw@ \LTS@addt@l@st[#1]% } \robust@def*\addtolistexpanded{% \LTS@testcl{\LTS@testopt\LTS@addtolistexpanded{,}}% } \robust@def*\LTS@addtolistexpanded[#1]#2#3{% \begingroup \toks@{\endgroup \ifdefTF#2{% \usename{protected@\ifLTS@cl x\else e\fi def}% #2{#2\ifcsnullTF{#2}{}{#1}#3}% }{% \usename{protected@\ifLTS@cl x\else e\fi def}#2{#3}% }% }% \oifblankTF{#3}{\ifcpt@useempty\the\toks@\else\endgroup\fi} {\the\toks@}% } \renew@def*\@check@eq#1#2{% \expandafter\ifxTF\cpt@car#1\car@nil{#2}{}{% \LTS@verbosewarn{% Previous definition of '\string#1'\MsgBrk doesn't match your new definition.\MsgBrk I haven't redefined '\string#1'}% }% } \ifpkgcurrTF{atveryend}{2010/03/24}{}{% \RequirePackage{atveryend}[2010/03/24]} \robust@def*\LTS@notprerr{% \LTS@err{You have issued a preamble command here}% {Move shown command to document preamble.}% } \robust@def*\LTS@notenderr{% \LTS@err{You've called an \noexpand\enddocument command\MsgBrk at the wrong place}{% Move command to before \string\enddocument. }% } \robust@def*\LTS@AtBeginDocument{\AtBeginDocument} \robust@def*\LTS@BeforeBeginDocument{% \grightaddtocs\LTS@beforedocstart } \new@def*\LTS@beforedocstart{} \leftaddtocs\document{% \endgroup \let\LTS@BeforeBeginDocument\@firstofone \LTS@beforedocstart \let\LTS@BeforeBeginDocument\LTS@notprerr \gundefcs\LTS@beforedocstart \begingroup } \robust@def*\LTS@AfterBeginDocument{% \grightaddtocs\LTS@afterdocstart } \new@def*\LTS@afterdocstart{} \robust@def*\LTS@AfterAfterBeginDocument{% \grightaddtocs\LTS@afterafterdocstart } \new@def*\LTS@afterafterdocstart{} \rightaddtocs\document{% \let\LTS@AfterBeginDocument\@firstofone \LTS@afterdocstart \let\LTS@AfterBeginDocument\LTS@notprerr \gundefcs\LTS@afterdocstart \let\LTS@AfterAfterBeginDocument\@firstofone \LTS@afterafterdocstart \let\LTS@AfterAfterBeginDocument\LTS@notprerr \gundefcs\LTS@afterafterdocstart \ignorespaces } \LTS@BeforeBeginDocument{\let\LTS@AtBeginDocument\@firstofone} \robust@def*\LTS@AtEndDocument{\AtEndDocument} \robust@def*\LTS@BeforeLastPage{\grightaddtocs\LTS@beforelastpage} \new@def*\LTS@beforelastpage{} \LTS@AtEndDocument{% \let\LTS@bef@relastpage\AtVeryEnd@BeforeClearDocumentHook \def\AtVeryEnd@BeforeClearDocumentHook{% \let\LTS@BeforeLastPage\@firstofone \LTS@beforelastpage\LTS@bef@relastpage \let\LTS@BeforeLastPage\LTS@notenderr \LTS@undef!{\LTS@beforelastpage,\LTS@bef@relastpage}% }% } \robust@def*\LTS@AfterLastPage{\grightaddtocs\LTS@afterlastpage} \new@def*\LTS@afterlastpage{} \LTS@AtEndDocument{% \let\LTS@afterl@stpage\AtVeryEnd@AfterLastShipoutHook \def\AtVeryEnd@AfterLastShipoutHook{% \let\LTS@AfterLastPage\@firstofone \LTS@afterlastpage\LTS@afterl@stpage \let\LTS@AfterLastPage\LTS@notenderr \LTS@undef!{\LTS@afterlastpage,\LTS@afterl@stpage}% }% } \robust@def*\LTS@AfterEndDocument{\grightaddtocs\LTS@afterenddoc} \new@def*\LTS@afterenddoc{} \AtEndOfPackage{\newletcs\AtTagEndOfDocument\LTS@AfterEndDocument} \LTS@AtEndDocument{% \let\LTS@aft@renddoc\AtVeryEnd@AtVeryEndDocumentHook \def\AtVeryEnd@AtVeryEndDocumentHook{% \let\LTS@AfterEndDocument\@firstofone \LTS@afterenddoc\LTS@aft@renddoc \let\LTS@AfterEndDocument\LTS@notenderr \LTS@undef!{\LTS@afterenddoc,\LTS@aft@renddoc}% }% } \robust@def*\LTS@AtEndPackage{\AtEndOfPackage} \robust@def*\LTS@BeforeEndPackage{% \gleftaddtocsn{\@currname.\@currext-h@@k}% } \robust@def*\LTS@AfterEndPackage{% \grightaddtocsn{\@currname.\@currext-LTS@hook}% } \let\LTS@AtEndClass\LTS@AtEndPackage \let\LTS@BeforeEndClass\LTS@BeforeEndPackage \let\LTS@AfterEndClass\LTS@AfterEndPackage \leftaddtocs\@popfilename{% \usename{\@currname.\@currext-LTS@hook}% \gundefcsn{\@currname.\@currext-LTS@hook}% } \robust@def\AtTagEndPackage#1{\AtEndOfPackage{\LTS@AfterEndPackage{#1}}} \newletcs\LTS@AtTagEndPackage\AtTagEndPackage \robust@def\afterpackageloaded#1{% \LTS@after@cls@pkg@loaded{#1}\@pkgextension } \robust@def\afterclassloaded#1{% \LTS@after@cls@pkg@loaded{#1}\@clsextension } \robust@def\LTS@after@cls@pkg@loaded#1#2#3{% \edef\LTS@tempa{\expandafter\ifxTF\cpt@car#2\car@nil \@pkgextension{sty}{cls}}% \cptexpanded{% \LTS@AfterAfterBeginDocument{% \noexpand\ifcsndefTF{ver@#1.\LTS@tempa}{}{% \LTS@warn{Package '#1' was never loaded}% }% }% }% \ifcsndefTF{ver@#1.\LTS@tempa}{% #3\relax }{% \grightaddtocsn{#1.\LTS@tempa-LTS@hook}{#3}% }% } \robust@def*\LTS@preamblecmdhook{} \robust@def*\preamblecommands{\LTS@testpl\LTS@preamblecmds} \new@def*\LTS@preamblecmds#1{% \begingroup \def\@cmd{\preamblecommands}% \let\@ifnopattern\ifnopattern \LTS@pkgpreamplecmd{#1}\LTS@preamblecmdhook{% \cptpassexpanded{% \grightaddtocs\LTS@preamblecmdhook {\LTS@dopreamble\@expand\LTS@tempa}% }% }% \endgroup } \robust@def*\AddPreambleCommands#1{% \def\csv@do##1{% \ltsfiltermergetsv!\LTS@preamblecmdhook {\LTS@dopreamble{##1}}\nofilter }% \csv@@parse[,]{#1}% } \robust@def*\RemovePreambleCommands#1{% \def\csv@do##1{% \filterdeletetokens!\LTS@preamblecmdhook {\LTS@dopreamble{##1}}\nofilter }% \csv@@parse[,]{#1}% } \robust@def*\packagecommands{\LTS@testpl\LTS@packagecmds} \robust@def*\LTS@packagecmds#1{% \begingroup \toks@{}% \def\@cmd{\packagecommands}% \def\@ifnopattern##1\in##2{\ifnopattern##2\in{##1}}% \LTS@pkgpreamplecmd{#1}\LTS@packagecmderr{% \@after\ifparamacroTF\LTS@tempa{% \def\@prepto{\preptoparamcs}% }{% \def\@prepto{\leftaddtocs}% }% \cptexpandarg{\toks@}{\the\toks@\@prepto\@expand\LTS@tempa {\LTS@packagecmderr{\@expand\LTS@tempa}}\relax\relax}% }% \expandafter\endgroup\the\toks@ } \robust@def*\LTS@pkgpreamplecmd#1#2#3{% \ifLTS@pl \def\@scape{\simpleexpandarg\LTS@ensurenoscape}% \let\@after\aftercsname \let\@expand\noexpandcsn \else \def\@scape{\simpleexpandarg\LTS@ensurescape}% \let\@after\expandafter \let\@expand\expandcsonce \fi \def\csv@do##1{% \def\LTS@tempa{##1}% \@after\ifonetoken\LTS@tempa\do{% \@scape\LTS@tempa \@after\ifdefTF\LTS@tempa{% \@after\@ifnopattern\LTS@tempa\in{#2}{#3}{}% }{% \LTS@warn{Command '\@after\string\LTS@tempa' undefined: \MsgBrk ignored by \expandcsonce\@cmd}% }% }% }% \csv@@parse{#1}% } \robust@def*\LTS@dopreamble#1{% \gdef#1{\LTS@err{'\string#1' is a preamble command}% {Move command '\string#1' to document preamble.}}% } \LTS@AfterBeginDocument{% \LTS@preamblecmdhook \gletcs\LTS@dopreamble\@gobbleone } \robust@def*\LTS@packagecmderr#1{% \ifinstylefileTF{}{% \LTS@err{Command '\detokenize{#1}' issued outside style file}% {The command '\detokenize{#1}' is available only in style files.}% }% } \robust@def*\parsemacro{\LTS@testst\LTS@parsemacro} \robust@def*\LTS@parsemacro#1#2#3{% \let\ifLTS@noxpst\ifLTS@st \begingroup \def\LTS@tempd##1{% \emptify\LTS@resa \edef\LTS@tempb{\cptoxdetok{#3}##1&}% \edef\LTS@tempc####1{\def####1########1##1########2&}% \LTS@tempc\LTS@tempc{% \ifblankTF{####2}{% \edef\LTS@resa{\expandcsonce\LTS@resa####1}% }{% \edef\LTS@resa{\expandcsonce\LTS@resa####1\detokenize{#2}##1}% \LTS@tempc####2&% }% }% \expandafter\LTS@tempc\LTS@tempb \edef#3{\expandcsonce\LTS@resa}% }% \edef\LTS@tempa{\cptoxdetok{#1}}% \def\tsv@do##1{\LTS@tempd{##1}}% \tsv@@parse*\LTS@tempa \postgroupdef#3\endgroup % \LTS@scantoksa assumes that #3 has no parameters; % use \LTS@scantoksd otherwise: \ifLTS@noxpst\LTS@scantoksa#3\fi \undefcs\ifLTS@noxpst } \robust@def*\noexpandparse#1{\parsemacro*\@backslashchar\noexpand#1} \robust@def*\NoexpandParse#1{% \let\ifLTS@noxpst\ifLTS@st \begingroup \emptify\LTS@resa \def\LTS@tempd##1{\edef\LTS@resa{\expandcsonce\LTS@resa \noexpand\noexpand\unexpanded{##1}}}% \def\tsv@do##1{% \ifmacroTF{##1}{% \LTS@tempd{##1}% }{% \edef\LTS@tempb{\detokenize{##1}}% \edef\LTS@tempc{\expandafter\LTS@car\LTS@tempb x\car@nil}% \ifxTF\LTS@tempc\@backslashchar{% \LTS@tempd{##1}% }{% \edef\LTS@resa{\expandcsonce\LTS@resa\unexpanded{##1}}% }% }% }% \tsv@@parse*{#1}% \edef#1{\expandcsonce\LTS@resa}% \postgroupdef#1\endgroup \ifLTS@noxpst\LTS@scantoksa#1\fi \undefcs\ifLTS@noxpst } % #1: list; % #2: a defined/undefined command: \robust@def*\despacecommalist#1#2{% \LTS@stfalse\LTS@despacecsvlist[,]{#1}% \let#2=\despaced@list } \robust@def*\despacecsvlist{% \LTS@testst{\LTS@testopt\LTS@despacecsvlist{,}}% } \robust@def*\LTS@despacecsvlist[#1]#2{% \cpt@stchoose{LTS@st}{#2}\despaced@list\LTS@despacecsvlist \ifcsnullTF\despaced@list{}{% \xifinsetTF{\detokenize{#1}}{\cptoxdetok\despaced@list}{% \cpt@sttrue\cpt@csvnormalize[#1]\despaced@list }{% \edef\despaced@list {\simpleexpandarg\cpttrimspaces\despaced@list}% }% }% \ifboolTF{LTS@st}{\let#2=\despaced@list}{}% } \robust@def*\despacexcsvlist{% \LTS@teststpm{% \ifnextisbrack\LTS@despacexcsvlist{\LTS@despacexcsvlist[,]}% }% } \robust@def*\LTS@despacexcsvlist[#1]{% \ifnextisbrack {\LTS@d@spacexcsvlist#1}{\LTS@d@spacexcsvlist#1[#1]}% } % #1: outer parser % #2: inner parser % #3: or % * -> #3 is a macro % ' -> each element of #3 is again a macro of list \robust@def*\LTS@d@spacexcsvlist#1[#2]#3{% \let\ifxdespm\ifLTS@pm \cpt@stchoose{LTS@st}{#3}\reserved@e\LTS@d@spacexcsvlist \def\despaced@list{}% \ifcsnullTF\reserved@e{}{% \def\csv@do##1{% \ifboolTF{xdespm}{% \cpt@sttrue\cpt@csvnormalize[#2]{##1}% \LTS@listadd#1\despaced@list{##1}% }{% \edef\reserved@e{\cpttrimspaces{##1}}% \LTS@olistadd{#1}\despaced@list\reserved@e }% }% \csv@@parse*[#1]\reserved@e }% \ifboolTF{LTS@st}{\let#3=\despaced@list}{}% \undefcs\ifxdespm } \robust@def*\despacetsvlist#1#2{% \LTS@ensuremacro{#2}% \def#2{}% \def\tsv@do##1{\rightaddtocs#2{##1}}% \tsv@@parse{#1}% } \robust@def*\despacextsvlist#1#2{% \LTS@ensuremacro{#2}% \def#2{}% \def\tsv@do##1{% \despacetsvlist{##1}\reserved@e \cptexpandargonce{\rightaddtocs#2}\reserved@e }% \tsv@@parse{#1}% } \robust@def*\newletmanytocs#1#2{% \def\csv@do##1{% \newletcs##1#2% }% \csv@@parse[,]{#1}% } \robust@def*\ltsnewletcs{\LTS@testst\LTS@newletcs} \new@def*\LTS@newletcs#1{% \cpt@ifeql{\LTS@n@wletcs{#1}}{\LTS@n@wletcs{#1}}% } \new@def*\LTS@n@wletcs#1#2{% \ifdefTF#1{% \ifLTS@st \ifdefTF#2{% \let#1=#2% \LTS@verboseinfo{Command '\string#1' redefined}% }{% \LTS@err{Command '\string#2' undefined}% {I can't let '\string#1' to undefined '\string#2'.}% }% \else \LTS@err{Command '\string#1' already defined}% {I can't assign defined '\string#1' to '\string#2'.}% \fi }{% \ifdefTF#2{\let#1=#2}{% \LTS@err{Command '\string#2' undefined}% {I can't let '\string#1' to undefined '\string#2'.}% }% }% } \new@def*\LTS@newletcsnerr#1#2{% \begingroup \def\LTS@tempa{\ifcpt@swa\string#2\else\noexpandcsn{#2}\fi}% \LTS@err{% Command '\LTS@tempa' is already defined }{% Command '\LTS@tempa' is defined: You may use the starred \MsgBrk version of \noexpand#1 for this type of assignment. }% \endgroup } \new@def*\newletcstocs{% \LTS@err{% Command '\string\newletcstocs' is undefined }{% Command '\string\newletcstocs' is undefined. You can use \string\newletcs,\MsgBrk but this can't assign control sequence names.\MsgBrk Perhaps you meant to use \string\newletcsntocs, or\MsgBrk\noexpand\newletcstocsn or \string\newletcsntocsn. }% } \robust@def*\newletcsntocs{\LTS@teststcl\LTS@newletcsntocs} \new@def*\LTS@newletcsntocs#1#2{% \is@global@or@relax \ifLTS@st \glob@lrel@x\letcsntocs{#1}#2% \else \ifcsndefFT{#1}% {\glob@lrel@x\letcsntocs{#1}#2}% {\cpt@swafalse\LTS@newletcsnerr\newletcsntocs{#1}}% \fi } \robust@def*\newletcstocsn{\LTS@teststcl\LTS@newletcstocsn} \new@def*\LTS@newletcstocsn#1#2{% \LTS@ensurescape{#1}% \is@global@or@relax \def\reserved@e{\begingroup\expandafter\endgroup\expandafter \glob@lrel@x\expandafter\let\expandafter#1\csname#2\endcsname}% \ifLTS@st \reserved@e \else \ifdefFT{#1}\reserved@e{% \cpt@swatrue\LTS@newletcsnerr\newletcstocsn{#1}% }% \fi } \robust@def*\newletcsntocsn{\LTS@teststcl\LTS@newletcsntocsn} \new@def*\LTS@newletcsntocsn#1#2{% \is@global@or@relax \def\reserved@e{\begingroup\expandafter\endgroup\expandafter \glob@lrel@x\expandafter\let\csname#1\aftercsname\endcsname{#2}}% \ifLTS@st \reserved@e \else \ifcsndefFT{#1}\reserved@e{% \cpt@swafalse\LTS@newletcsnerr\newletcsntocsn{#1}% }% \fi } \robust@def*\provideletcsntocs{\LTS@testcl\LTS@provideletcsntocs} \new@def*\LTS@provideletcsntocs#1#2{% \is@global@or@relax \ifcsndefTF{#1}{}{\glob@lrel@x\letcsntocs{#1}#2}% } \robust@def*\provideletcstocsn{\LTS@testcl\LTS@provideletcstocsn} \new@def*\LTS@provideletcstocsn#1#2{% \is@global@or@relax \ifdefTF#1{}{% \begingroup\expandafter\endgroup\expandafter\glob@lrel@x \expandafter\let\expandafter#1\csname#2\endcsname }% } \robust@def*\provideletcsntocsn{\LTS@testcl\LTS@provideletcsntocsn} \def\LTS@provideletcsntocsn#1#2{% \is@global@or@relax \ifcsndefTF{#1}{}{% \begingroup\expandafter\endgroup\expandafter\glob@lrel@x \expandafter\let\csname#1\aftercsname\endcsname{#2}% }% } \new@def*\provideletcstocs{% \LTS@err{'\string\provideletcstocs' is undefined}% {Command '\string\provideletcstocs' is undefined. Perhaps you meant \MsgBrk to use \string\provideletcsntocs, or \noexpand\provideletcstocsn or \string\provideletcsntocsn.}% } \robust@def*\numberexpr{% \LTS@checkoptprefix{\LTS@testplcl{\LTS@numexpr{num}}}% } \robust@def*\dimensionexpr{% \LTS@checkoptprefix{\LTS@testplcl{\LTS@numexpr{dim}}}% } \robust@def*\rubberexpr{% \LTS@checkoptprefix{\LTS@testplcl{\LTS@numexpr{glue}}}% } \robust@def*\mrubberexpr{% \LTS@checkoptprefix{\LTS@testplcl{\LTS@numexpr{mu}}}% } \new@def*\LTS@numexpr#1#2{% \if\detokenize{#2*}% \LTS@err{Invalid suffix to '\string\dimensionexpr' or '\string\numberexpr'}{Star (*) not valid as suffix to '\string\dimensionexpr' and '\string\numberexpr'.}% \fi \is@global@or@relax \ifboolTF{LTS@pl}{% \cptexpandsecond{\LTS@n@mexpr{#1}}{\noexpandcsn{#2}}% }{% \LTS@n@mexpr{#1}{#2}% }% } \new@def*\LTS@n@mexpr#1#2#3{% \LTS@ensurescape@notempty{#2}{#3}% \ifdefTF{#2}{% \glob@lrel@x#2=\usename{#1expr}#3\relax }{% \begingroup \LTS@getorderincsvlist[,](\nr){#1}{num,dim,glue,mu}% \edef\LTS@tempa{\ifcase\nr\relax count\or dimen\or skip\or muskip\fi}% \usename{new\LTS@tempa}#2\relax \endgroup \glob@lrel@x#2=\usename{#1expr}#3\relax }% } \robust@def*\numberdef{% \LTS@checkoptprefix{\LTS@testplcl{\LTS@numdef{num}}}% } \robust@def*\dimensiondef{% \LTS@checkoptprefix{\LTS@testplcl{\LTS@numdef{dim}}}% } \robust@def*\rubberdef{% \LTS@checkoptprefix{\LTS@testplcl{\LTS@numdef{glue}}}% } \robust@def*\mrubberdef{% \LTS@checkoptprefix{\LTS@testplcl{\LTS@numdef{mu}}}% } \new@def*\LTS@numdef#1#2{% \if\detokenize{*#2}% \LTS@err{Invalid suffix to '\string\dimensiondef' or '\string\numberdef'}{Star (*) not valid as suffix to '\string\dimensiondef' and '\string\numberdef'.}% \fi \is@global@or@relax \ifboolTF{LTS@pl}{% \cptexpandsecond{\LTS@num@def{#1}}{\noexpandcsn{#2}}% }{% \LTS@num@def{#1}{#2}% }% } \new@def*\LTS@num@def#1#2#3{% \LTS@ensurescape@notempty{#2}{#3}% \glob@lrel@x\edef#2{\the\usename{#1expr}#3\relax}% } \robust@def*\LTS@ensurescape@notempty#1#2{% \LTS@ensurescape{#1}% \ifblankFT{#2}{}{% \LTS@err{Argument '\string#2' is empty}% {Empty argument '\string#2' is invalid.\MsgBrk I expected a nonempty argument here.}% }% } % #1: parser % #2: string to find % #3: list % * -> both #2 and #3 are macros % Call it with [] if there is no parser: \robust@def*\ifexistinTF{\LTS@testst{\LTS@testopt\LTS@ifexistinTF,}} \robust@def*\LTS@ifexistinTF[#1]#2\in#3{% \begingroup \edef\reserved@e{\ifboolTF{LTS@st}\cptoxdetok\detokenize{#2}}% \despacecontent\reserved@e \edef\reserved@f{\ifboolTF{LTS@st}\cptoxdetok\detokenize{#3}}% \cpt@sttrue\cpt@csvnormalize[#1]\reserved@f \edef\x{\detokenize{#1}}% \cptexpandtwoargs{\endgroup\ifinsetTF} {\x\reserved@e\x}{\x\reserved@f\x}% } \robust@def\ifpresentTF#1\in#2#{\ifinsetTF{#1}{#2}} % This is more expensive but offers a variation on \ifexistinTF: \robust@def*\ifpresentinTF{\LTS@testst{\LTS@testopt\LTS@ifpresentinTF,}} \robust@def*\LTS@ifpresentinTF[#1]#2\in#3{% \begingroup \edef\reserved@e{\ifboolTF{LTS@st}\cptoxdetok\detokenize{#2}}% \despacecontent\reserved@e \edef\reserved@f{\ifboolTF{LTS@st}\cptoxdetok\detokenize{#3}}% \cpt@choicefdfalse \def\csv@do##1{% \def\reserved@a{##1}% \ifx\reserved@a\reserved@e\cpt@choicefdtrue\loopbreak\fi }% \csv@@parse*[;]\reserved@f \ifboolTF{cpt@choicefd} {\endgroup\@firstoftwo}{\endgroup\@secondoftwo}% } % You can use \ifleadspaceTF or \iftrailspaceTF to test % tokens beginning or ending with space. \ifendwithTF isn't % suitable for this task: \robust@def*\ifendwithTF#1#2{% \ifblankTF{#2}\@secondoftwo{% \begingroup \edef\LTS@tempa{\s@expandarg\cpttrimspace{\detokenize{#1}}}% \edef\LTS@tempb{\s@expandarg\cpttrimspace{\detokenize{#2}}}% \let\endwith\relax \cptexpandtwoargs\cpt@in{\LTS@tempb\endwith}{\LTS@tempa\endwith}% \aftercsname\endgroup{@\ifcpt@in first\else second\fi oftwo}% }% } \robust@def*\ifbeginwithTF#1#2{% \ifblankTF{#2}\@secondoftwo{% \begingroup \edef\LTS@tempa{\s@expandarg\cpttrimspace{\detokenize{#1}}}% \edef\LTS@tempb{\s@expandarg\cpttrimspace{\detokenize{#2}}}% \let\begwith\relax \cptexpandtwoargs\cpt@in{\begwith\LTS@tempb}{\begwith\LTS@tempa}% \aftercsname\endgroup{@\ifcpt@in first\else second\fi oftwo}% }% } \robust@def*\in@detok#1#2{% \cptexpandtwoargs\cpt@in{\detokenize{#1}}{\detokenize{#2}}% } \newletcs\ifmemberTF\ifinsetTF \newletcs\ifmemberFT\ifinsetFT \robust@def*\ifbelongTF#1#2{% \cptexpandtwoargs\ifinsetTF{\detokenize{#1}}{\detokenize{#2}}% } \robust@def*\ifbelongFT#1#2{\ifbelongTF{#1}{#2}\@secondoftwo\@firstoftwo} \robust@def*\oifbelongTF#1#2{\cptexpandtwoargsonce\ifbelongTF{#1}{#2}} \robust@def*\oifbelongFT#1#2{\cptexpandtwoargsonce\ifbelongFT{#1}{#2}} \robust@def*\xifbelongTF#1#2{\cptexpandtwoargs\ifbelongTF{#1}{#2}} \robust@def*\xifbelongFT#1#2{\cptexpandtwoargs\ifbelongFT{#1}{#2}} \new@def*\ifdraftTF{\usename{LTS@\ifboolTF{LTS@draft}12of2}} \new@def*\ifdraftFT{\usename{LTS@\ifdraftTF21of2}} \new@def*\iffinalTF{\usename{LTS@\ifboolTF{LTS@final}12of2}} \new@def*\iffinalFT{\usename{LTS@\iffinalTF21of2}} \new@def*\ValidCommandPrefixes{\relax\long\global\protected} \robust@def*\newfunction{\begingroup\let\cmd0\LTS@newfunction@a} \robust@def*\LTS@newfunction@a{% \toks@{}% \def\LTS@tempa##1{% \def\cmd{##1}% \LTS@ifnextchar.\LTS@newfunction@b{\LTS@newfunction@b..}% }% \ifcondTF\if\cmd0\fi{% \LTS@starorlong\LTS@tempa }{% \LTS@tempa }% } \robust@def*\LTS@newfunction@b.#1.{% \def\checkprefix{% \let\LTS@rsvda\prefix \simpledeletetokens\LTS@rsvda\ValidCommandPrefixes \ifcsemptyTF\LTS@rsvda{}{% \LTS@err{Illegal prefixes '\expandcsonce\LTS@rsvda' for command '\expandcsonce\cmd'}\@ehc }% }% \ifsingletokenTF{#1}{% \def\prefix{#1}\def\sentinel{}% }{% \def\prefix##1,##2##3\LTS@nil{% \def\prefix{##1}\def\reserved{##2}% \ifx\reserved\LTS@nnil \def\sentinel{}% \else \if\detokenize{##2,}% \def\sentinel{}% \else \def\sentinel{##2}% \fi \fi }% \prefix#1,{\LTS@nil}\LTS@nil \checkprefix }% \expandafter\LTS@testopt\expandafter {\expandafter\LTS@newfunction@c\cmd}0% } \robust@def*\LTS@newfunction@c#1[#2]{% \ifnextisbrack{\LTS@newfunction@e#1[#2]}{\LTS@newfunction@d#1[#2]}% } \robust@def\LTS@newfunction@d#1[#2]#3{% \ifcsdefinable#1{\LTS@newfunction@f#1\@ne{#2}{#3}}% } \robust@def\LTS@newfunction@e#1[#2][#3]#4{% \ifcsdefinable#1{% \cptexpandargonce{\cpt@in\protected}\prefix \edef\LTS@tempa{% \ifcpt@in\LTS@testopt\else\unexpanded{\@protected@testopt#1}\fi \noexpandcsn{\string#1}\unexpanded{{#3}}% }% \cptexpandarg\toks@{% \l@ngrel@x\prefix\def\noexpand#1{\expandcsonce\LTS@tempa}% }% \aftercsname\LTS@newfunction@f{\string#1}\tw@{#2}{#4}% }% } \robust@def\LTS@newfunction@f#1#2#3{% \ifx#2\tw@ \gdef\@gtempa##11{[####1]}% \else \gletcs\@gtempa\@gobble \fi \expandafter\LTS@newfunction@g\expandafter{\number#3}#1% } \robust@def\LTS@newfunction@g#1#2{% \defpass\reserved@a##1#1##2##{% \edef\reserved@a{% \endgroup\the\toks@\l@ngrel@x\prefix \unexpanded{\expandafter\def\expandafter#2\@gtempa}% }% \s@expandarg\cptswap\sentinel{\reserved@a##1#1}% }% 0##1##2##3##4##5##6##7##8##9###1% } \robust@def*\renewfunction{% \begingroup \let\cmd1\LTS@starorlong\LTS@renewfunction } \def\LTS@renewfunction#1{% \ifdefTF#1{% \LTS@verboseinfo{Command '\string#1' redefined}% }{% \LTS@warn{Command '\string#1' was previously undefined, \MsgBrk but now defined with \string\renewfunction}% }% \let\ifcsdefinable\rc@ifcsdefinable \LTS@newfunction@a#1% } %% One-step expandable \l@ngrel@x: \robust@def*\LTS@starorlong#1{% \LTS@ifstar {\def\l@ngrel@x{\relax}#1}{\def\l@ngrel@x{\long}#1}% } \robust@def*\LTS@starornone#1{% \LTS@ifstar {\let\l@ngrel@x\relax\def\st@rn@ne{*}#1}% {\let\l@ngrel@x\long\def\st@rn@ne{}#1}% } \robust@def*\needcommand{\LTS@starornone\LTS@needcommand} \new@def*\LTS@needcommand#1{% \LTS@ensurescape{#1}% \ifdefTF{#1}% {\expandafter\CheckCommand\st@rn@ne}% {\expandafter\newcommand\st@rn@ne}% {#1}% } \robust@def*\ifinlistTF{% \LTS@testst{\LTS@testopt\LTS@ifinlista{,}}% } \robust@def\LTS@ifinlista[#1]#2#3{% \begingroup \def\reserved@e##1#1#2#1##2\LTS@nil{\endgroup \ifblankTF{##2}\@secondoftwo\@firstoftwo }% \ifboolTF{LTS@st}{% \LTS@ensurescape{#3}% \expandafter\reserved@e\expandafter }{% \reserved@e }% #1#3#1#2#1\LTS@nil } \new@def\oifinlistTF#1#2{% \ifx#1,% \LTS@err{Invalid first argument to \string\oifinlistTF}\@ehc \fi \cptexpandsecondargonce\ifinlistTF{#1}{#2}% } \new@def\xifinlistTF#1#2{% \if\detokenize{#1,}% \LTS@err{Invalid first argument '#1' to \string\xifinlistTF}\@ehc \fi \cptexpandsecondarg\ifinlistTF{#1}{#2}% } \robust@def*\LTS@checkch{\LTS@teststpl\LTS@checkchoice} \robust@def\ifinlistbTF#1#2#3#4{% \if\LTS@lwc\LTS@sttrue\else\LTS@stfalse\fi \LTS@pltrue \LTS@checkchoice[\val\nr]{#1}{#2}{#3}{#4}% } \robust@def\ifinlistbFT#1#2#3#4{\ifinlistbTF{#1}{#2}{#4}{#3}} \robust@def\oifinlistbTF#1#2#3#4{% \if\LTS@lwc\LTS@sttrue\else\LTS@stfalse\fi \LTS@pltrue \cptexpandsecond{\LTS@checkchoice[\val\nr]}% {{\expandcsonce{#1}}{\expandcsonce{#2}}}{#3}{#4}% } \robust@def\oifinlistbFT#1#2#3#4{\oifinlistbTF{#1}{#2}{#4}{#3}} \robust@def\xifinlistbTF#1#2#3#4{% \if\LTS@lwc\LTS@sttrue\else\LTS@stfalse\fi \LTS@pltrue \cptexpandsecond {\LTS@checkchoice[\val\nr]}{{#1}{#2}}{#3}{#4}% } \robust@def\xifinlistbFT#1#2#3#4{% \if\LTS@lwc\LTS@sttrue\else\LTS@stfalse\fi \LTS@pltrue \cptexpandsecond {\LTS@checkchoice[\val\nr]}{{#1}{#2}}{#4}{#3}% } \new@def*\LTS@nochoice@handler#1#2{% \LTS@err{% Value '\expandcsonce{#1}' is not in list ^^J'\expandcsonce{#2}' }{% You have submitted an invalid value '\expandcsonce{#1}'\MsgBrk for your key or test parameter. Value '\expandcsonce{#1}'\MsgBrk is not in list:^^J'\expandcsonce{#2}'. }% } \robust@def*\LTS@checkchoice{\LTS@testopt\LTS@ch@ckchoice{}} \robust@def*\LTS@ch@ckchoice[#1]#2#3{% \cpt@choicefdfalse \begingroup \ifLTS@st\lowercase{\fi \ifblankTF{#1}{% \def\LTS@tempa{\endgroup\LTS@ch@@@choice\LTS@nil{#2}{#3}}% }{% \def\LTS@tempa{\endgroup\LTS@ch@@kchoice#1\LTS@nil{#2}{#3}}% }% \ifLTS@st}\fi\LTS@tempa } \robust@def*\LTS@ch@@kchoice#1#2\LTS@nil#3#4{% \ifblankTF{#2}% {\LTS@ch@@@choice#1{#3}{#4}}{\LTS@ch@@@@hoice#1#2{#3}{#4}}% } \robust@def*\LTS@ch@@@choice#1#2#3{% \begingroup \def\LTS@tempc{#1}% \ifx\LTS@tempc\LTS@nnil % From \LTS@ch@ckchoice: \emptify\LTS@tempc \else \def\LTS@tempc{\def#1{#2}}% \fi \cptexpandtwoargs\cpt@in{,\detokenize{#2},}{,\detokenize{#3},}% \usename{cpt@choicefd\ifcpt@in true\else false\fi}% \LTS@ch@@@@@oice\LTS@nochoice@handler{#2}{#3}% } \robust@def*\LTS@ch@@@@hoice#1#2#3#4{% \def#1{#3}\def#2{-1}% \begingroup \LTS@scantoksa#1% \cpt@cnta\z@pt \def\LTS@tempc{}% \def\csv@do##1{% \def\LTS@tempb{##1}% \LTS@scantoksa\LTS@tempb \ifx#1\LTS@tempb \edef\LTS@tempc{% \def\noexpand#1{\unexpanded{##1}}% \def\noexpand#2{\the\cpt@cnta}% }% \cpt@choicefdtrue\loopbreak \fi \advance\cpt@cnta\@ne }% \csv@@parse[,]{#4}% \LTS@ch@@@@@oice\LTS@nochoice@handler{#3}{#4}% } \robust@def\LTS@ch@@@@@oice#1#2#3{% \NoConvertInputToLowercase \ifboolTF{cpt@choicefd}{% \ifboolTF{LTS@pl}{% \rightaddtocs\LTS@tempc\@firstoftwo }{% \rightaddtocs\LTS@tempc\@firstofone }% }{% \ifboolTF{LTS@pl}{% \rightaddtocs\LTS@tempc\@secondoftwo }{% \rightaddtocs\LTS@tempc{#1{#2}{#3}\@gobbleone}% }% }% \expandafter\endgroup\LTS@tempc } \robust@def*\LTS@notpresent@handler#1#2{% \LTS@verboseinfo{None of the tokens '\detokenize{#1}' is found in '\detokenize{#2}'}% } \robust@def*\lwccontent#1{% \ltsifmacroTF{#1}{% \expandafter\if\expandafter\LTS@lwc\expandafter \lowercase\expandafter{\expandafter\fi\expandafter\def \expandafter#1\expandafter{#1}\if\LTS@lwc}\fi }{% \cpt@notcserr{#1}% }% } % #1: parser; % #2: macro to hold order; % #3: nomination/choice; % #4: csv list; % * -> both #3 and #4 are macros: \robust@def*\getorderincsvlist{% \LTS@testst{\LTS@testopt\LTS@getorderincsvlist{,}}% } \robust@def*\LTS@getorderincsvlist[#1]{% \LTS@testpnopt{\LTS@g@torderincsvlist#1}\LTS@order } \robust@def*\LTS@g@torderincsvlist#1(#2)#3#4{% \def#2{-1}% \begingroup \ifboolTF{LTS@st}{% \edef\LTS@tempa{\simpleexpandarg\cpttrimspaces{#3}}% \let\LTS@tempb=#4% }{% \edef\LTS@tempa{\cpttrimspaces{#3}} \edef\LTS@tempb{\unexpanded{#4}}% }% \lwccontent\LTS@tempa\lwccontent\LTS@tempb \edef\LTS@tempa{\cptoxdetok\LTS@tempa}% \edef\LTS@tempb{\cptoxdetok\LTS@tempb}% \cpt@cnta\z@pt\def\LTS@tempc{}% \def\csv@do##1{% \def\LTS@tempb{##1}% \ifx\LTS@tempb\LTS@tempa \edef\LTS@tempc{\def\noexpand#2{\the\cpt@cnta}}% \loopbreak \fi \advance\cpt@cnta\@ne }% \csv@@parse*[,]\LTS@tempb \NoConvertInputToLowercase \expandafter\endgroup\LTS@tempc } % #1: sublist (to check if one member of #1 is in #2); % #2: main comma-separated list; \robust@def*\ifoneincommalistTF#1#2{% \if\LTS@lwc\LTS@sttrue\else\LTS@stfalse\fi \LTS@pltrue \LTS@ch@ckpresence[\val\nr]{#1}{#2}% } % #1: bin (eg, \val\nr); % #2: sublist (to check if one member of #2 is in #3); % #3: main comma-separated list; % For comma-separated list only: \robust@def*\LTS@checkpr{\LTS@teststpl\LTS@checkpresence} \robust@def*\LTS@checkpresence{\LTS@testopt\LTS@ch@ckpresence{}} \new@def*\LTS@ch@ckpresence[#1]#2#3{% \cpt@choicefdfalse \begingroup \ifLTS@st\lowercase{\fi \ifblankTF{#1}{% \def\LTS@tempa{\endgroup\LTS@ch@@@presence\LTS@nil{#2}{#3}}% }{% \def\LTS@tempa{\endgroup\LTS@ch@@kpresence#1\LTS@nil{#2}{#3}}% }% \ifLTS@st}\fi\LTS@tempa } \new@def*\LTS@ch@@kpresence#1#2\LTS@nil#3#4{% \ifblankTF{#2}% {\LTS@ch@@@presence#1{#3}{#4}}% {\LTS@ch@@@@resence#1#2{#3}{#4}}% } \new@def*\LTS@ch@@@presence#1#2#3{% \begingroup \def\LTS@tempc{#1}% \ifxTF\LTS@nnil\LTS@tempc{% \def\LTS@tempc{}% }{% \def\LTS@tempc{\def#1{#3}}% }% \edef\LTS@tempa{\detokenize{#3}}% \cpt@sttrue\cpt@csvnormalize[,]\LTS@tempa % Leave \csv@@parse here! \def\csv@do##1{% \xifinsetFT{,\detokenize{##1},}{,\LTS@tempa,}{}{% \edef\LTS@tempc{\def\noexpand#1{\unexpanded{##1}}}% \cpt@choicefdtrue\loopbreak }% }% \csv@@parse[,]{#2}% \LTS@ch@@@@@oice\LTS@notpresent@handler{#2}{#3}% } \new@def*\LTS@ch@@@@resence#1#2#3#4{% \def#1{}\def#2{-1}% \begingroup \cpt@cnta\z@pt\def\LTS@tempc{}% \def\csv@do##1{% \xifinsetFT{,\detokenize{##1},}{,\detokenize{#4},}{}{% \edef\LTS@tempc{% \def\noexpand#1{\unexpanded{##1}}% \def\noexpand#2{\the\cpt@cnta}% }% \cpt@choicefdtrue\loopbreak }% \advance\cpt@cnta\@ne }% \csv@@parse[,]{#3}% \LTS@ch@@@@@oice\LTS@notpresent@handler{#3}{#4}% } % \ifmanyincsvlistTF[parser](no.){sublist}{mainlist} % Check if the no. of elements of parser-separated list % '#3' found in #4 is equal or greater than '#2'. #4 % is the main list. If the test is true, \itemspresent returns % all the elements found and \noofitems returns the number % of elements found: \ifcsdefinable\itemspresent\relax \ifcsdefinable\noofitems\relax \robust@def*\ifmanyincsvlistTF{% \LTS@testopt\LTS@ifmanyincsvlistTF{,}% } \robust@def*\LTS@ifmanyincsvlistTF[#1]{% \LTS@testpnopt{\LTS@ifm@nyincsvlistTF#1}{1}% } \robust@def*\LTS@ifm@nyincsvlistTF#1(#2)#3#4{% \begingroup \if\LTS@lwc\lowercase{\fi \edef\LTS@tempa{\unexpanded{#3}}% \edef\LTS@tempb{\unexpanded{#4}}% \if\LTS@lwc}\fi \cpt@sttrue\cpt@csvnormalize[#1]\LTS@tempb \def\LTS@tempc{}\cpt@cnta\z@pt \def\csv@do##1{% \edef\x{\detokenize{#1}}% \xifinsetFT{\detokenize{#1##1#1}}{\x\cptoxdetok\LTS@tempb\x}{% \edef\LTS@tempc{\csliststack,\LTS@tempc\unexpanded{##1}}% \advance\cpt@cnta\@ne \ifnum\cpt@cnta>\numexpr#2-1\relax\loopbreak\fi }% }% \csv@@parse*[#1]\LTS@tempa \ifnum\cpt@cnta>\numexpr#2-1\relax \gletcs\itemspresent\LTS@tempc \xdef\noofitems{\the\cpt@cnta}% \else \gdef\itemspresent{}\gdef\noofitems{-1}% \fi \NoConvertInputToLowercase \aftercsname\endgroup {LTS@\ifnumcmpTF\cpt@cnta>\numexpr#2-1{1}2of2}% } % \ifmanyintsvlistTF(no){sublist}{mainlist} % Check if the no. of elements of tsv list #2 % found in #3 is equal or greater than '#1'. #3 % is the main list. If the test is true, \itemspresent returns % all the elements found and \noofitems returns the number % of elements found: \robust@def*\ifmanyintsvlistTF{% \LTS@testpnopt\LTS@ifmanyintsvlistTF{1}% } \robust@def*\LTS@ifmanyintsvlistTF(#1)#2#3{% \begingroup \if\LTS@lwc\lowercase{\fi \edef\LTS@tempa{\unexpanded{#2}}% \edef\LTS@tempb{\unexpanded{#3}}% \if\LTS@lwc}\fi \def\LTS@tempc{}\cpt@cnta\z@pt \def\tsv@do##1{% \xifinsetFT{\detokenize{##1}}{\cptoxdetok\LTS@tempb}{}{% \edef\LTS@tempc{\csliststack,\LTS@tempc\unexpanded{##1}}% \advance\cpt@cnta\@ne \ifnum\cpt@cnta>\numexpr#1-1\relax\loopbreak\fi }% }% \tsv@@parse*\LTS@tempa \ifnum\cpt@cnta>\numexpr#1-1\relax \gletcs\itemspresent\LTS@tempc \xdef\noofitems{\the\cpt@cnta}% \else \gdef\itemspresent{}\gdef\noofitems{-1}% \fi \NoConvertInputToLowercase \aftercsname\endgroup {LTS@\ifnumcmpTF\cpt@cnta>\numexpr#1-1{1}2of2}% } \robust@def*\LTS@undeftogerr#1{% \LTS@err{Toggle '#1' undefined}% {You need to first define toggle '#1' before use.}% } \providecommand*\newtog[1]{\cpt@swatrue\LTS@testopt{\LTS@newtog{#1}}{false}} \robust@def*\deftog#1{\cpt@swafalse\LTS@testopt{\LTS@newtog{#1}}{false}} \new@def*\LTS@newtog#1[#2]{% \begingroup \ifinsetFT{,}{#1}{}{% \edef\x{\ifcpt@swa'\string\newtog'\else'\string\deftog'\fi}% \edef\y{\ifcpt@swa'\string\NewTogs'\else'\string\DefTogs'\fi}% \LTS@err{Command \x doesn't accept list}{% Please submit only one toggle to \x at a time. \MsgBrk You can use \y to define a set of togs. }% }% \endgroup \LTS@ensurenoscape{#1}% \ifboolTF{cpt@swa}{% \ifcsndefFT{cpt@tog@#1}{}{% \LTS@err{Toggle '#1' already defined}% {Please provide a new toggle or use '\string\deftog'.}% }% \LTS@getboolstate\newtog{#2}% }{% \ifcsndefFT{cpt@tog@#1}{}{% \LTS@verbosewarn{Toggle '#1' redefined}% }% \LTS@getboolstate\deftog{#2}% }% \letcsntocsn{cpt@tog@#1}{@\cptstrcmp {\LTS@boolval}{true}{first}{second}oftwo}% } \providecommand*\providetog[1]{% \ifcsndefTF{cpt@tog@#1}{% \LTS@verboseinfo{Toggle '#1' already defined.\MsgBrk Not redefined}% }{% \letcsntocs{cpt@tog@#1}\@secondoftwo }% } \providecommand*\requiretog[1]{% \aftercsname\needcommand{cpt@tog@#1}[2]{##2}% } \newtog{pdf}[false] \newletcs\ifpdfTF\@secondoftwo \newletcs\ifpdfFT\@firstoftwo \ifdefTF\pdfoutput{% \ifnumcmpTF\pdfoutput<\@ne{}{% \settogtrue{pdf}% \let\ifpdfTF\@firstoftwo \let\ifpdfFT\@secondoftwo }% }{} \new@def*\savecs#1{% \LTS@ensurescape{#1}% \ifcsndefTF{saved\cptgobblescape#1}{% \LTS@err{\noexpand#1 already saved. You've to restore \MsgBrk it or undefine '\noexpandcsn{saved\cptgobblescape#1}' before\MsgBrk you can save \noexpand#1 again}\@ehc }{% \ifdefTF#1{% \letcsntocs{saved\cptgobblescape#1}#1% \ifcsndefFT{\string#1}{}{% \letcsntocsn{@saved\cptgobblescape#1}{\string#1}% }% \ifcsndefFT{\cptgobblescape#1\@space}{}{% \letcsntocsn{@@saved\cptgobblescape#1}% {\cptgobblescape#1\@space}% }% \ifcsndefFT{\string#1\@space}{}{% \letcsntocsn{@@@saved\cptgobblescape#1}{\string#1\@space}% }% }{% \LTS@err{Undefined '\string#1' couldn't be saved\on@line}% {You can't restore undefined commands. So why save\MsgBrk undefined '\string#1' here?}% }% }% } \new@def*\restorecs#1{% \LTS@ensurescape{#1}% \ifcsndefTF{saved\cptgobblescape#1}{% \letcstocsn#1{saved\cptgobblescape#1}% \gundefcsn{saved\cptgobblescape#1}% \ifcsndefFT{@saved\cptgobblescape#1}{}{% \letcsntocsn{\string#1}{@saved\cptgobblescape#1}% \gundefcsn{@saved\cptgobblescape#1}% }% \ifcsndefFT{@@saved\cptgobblescape#1}{}{% \letcsntocsn{\cptgobblescape#1\@space}% {@@saved\cptgobblescape#1}% \gundefcsn{@@saved\cptgobblescape#1}% }% \ifcsndefFT{@@@saved\cptgobblescape#1}{}{% \letcsntocsn{\string#1\@space}{@@@saved\cptgobblescape#1}% \gundefcsn{@@@saved\cptgobblescape#1}% }% }{% \LTS@err{No saved version of '\string#1' is available:\MsgBrk '\string#1' couldn't be restored\on@line }{% Unsaved '\string#1' can't be restored.\MsgBrk Note that each call to \noexpand\restorecs undefines the saved command. }% }% } \providecommand*\input@path{} \robust@def*\InputFileOnce{% \savecs\input@path \LTS@testst{\LTS@testpl{\LTS@testopt\LTS@inputfileonce{.}}}% } \new@def*\LTS@inputfileonce[#1]#2{% \ifblankTF{#1}{}{\grightaddtocs\input@path{{#1/}}}% \ifboolTF{LTS@st}{% % Don't check whether the file has already been read: \LTS@inp@tfileonce{#2}% }{% \ifcsndefTF{#2@LTS@read}{% \ifLTS@verbose \LTS@info{File '#2' already read:\MsgBrk File '#2' wasn't read again}% \fi }{% \LTS@inp@tfileonce{#2}% }% }% } \def\LTS@inp@tfileonce#1{% \def\reserved@a##1##2{% \IfFileExists{#1}{##1\@filef@und##2}% }% \ifboolTF{LTS@pl}{% \reserved@a\include }{% \reserved@a\@@input }{% \letcsntocs{#1@LTS@read}\relax \restorecs\input@path }{% \typein[\@gtempa]{^^J! File '\string#1' does not exist. ^^JEnter filename or 'x' and to continue.}% \def\reserved@a{x}% \ifxTF\@gtempa\reserved@a{% \restorecs\input@path }{% \cptexpandarg{\LTS@inputfileonce[]}\@gtempa }% }% } \new@def*\xp@counttokens#1{% \long\def\xp@counttokens##1{% \the\numexpr\expandafter \LTS@xpcounttokens##1#1\cpt@nnil\cpt@nnil\relax }% } \xp@counttokens{ } \new@def\LTS@xpcounttokens#1{% \expandafter\ifxTF\cpt@car#1\car@nil \cpt@nnil{0\cpt@removetonnil}{1+\LTS@xpcounttokens}% } \robust@def*\countalltokens#1{% \def\countalltokens##1{% \let\nr\m@one \def\@counttokens{\futurelet\@let@token\LTS@countalltokens}% \expandafter\@counttokens##1#1\cpt@nnil }% } \countalltokens{ } \robust@def*\LTS@countalltokens{% \ifxTF\@let@token\cpt@nnil\cpt@removetonnil{% \edef\nr{\the\numexpr\nr+1}% \afterassignment\@counttokens \let\@let@token= % }% } \robust@def*\counttokens{\LTS@testst\LTS@counttokens} \robust@def\LTS@counttokens#1{% \begingroup \def\nr{0}\def\emp{0}\def\spo{0}% \def\siso@do##1{% \ifx\@empty##1\@empty \edef\emp{\the\numexpr\emp+1}% \edef\nr{\the\numexpr\nr+1}% \else \ifx##1\@sptoken \edef\spo{\the\numexpr\spo+1}% \edef\nr{\the\numexpr\nr+1}% \else \edef\nr{\the\numexpr\nr+1}% \fi \fi }% \ifboolTF{LTS@st}{% \expandafter\siso@@loop\expandafter{#1}% }{% \siso@@loop{#1}% }% \cptpassexpanded{% \endgroup \def\noexpand\nonempty{\nr}% \def\noexpand\nr{{\nr}{\emp}{\spo}}% }% } \newcommand*\ltscountargs[1]{% \protected\def\ltscountargs##1{% \begingroup \@tempcnta\z@pt\@tempcntb\z@pt\cpt@cnta\z@pt \def\end@countargs{\end@countargs}% \def\LTS@countargs@a{\futurelet\next\LTS@countargs@c}% \def\LTS@countargs@b####1{\LTS@countargs@a}% \expandafter\LTS@countargs@a##1#1\end@countargs }% } \ltscountargs{ } \def\LTS@countargs@c{% \ifxTF\next\end@countargs{% \edef\next{% \endgroup \edef\noexpand\argcount{\the\numexpr\the\@tempcnta-1}% \edef\noexpand\spacecount{\the\numexpr\the\@tempcntb-1}% \edef\noexpand\nonspacecount{\the\cpt@cnta}% }% \expandafter\next\@gobble }{% \advance\@tempcnta\@ne \ifxTF\next\@sptoken{% \advance\@tempcntb\@ne \afterassignment\LTS@countargs@a\let\next= % }{% \advance\cpt@cnta\@ne \LTS@countargs@b }% }% } \robust@def*\macronizetokens{% \begingroup \@makeother{\#}% \endlinechar\m@one \LTS@testopt\LTS@macronize{}% } \robust@def*\LTS@macronize[#1]#2#3{% % Check for catcode-10 tokens while keeping '#' as other: \toks0{#3}% \scantokens{\toks1{#3}}% \xifstrcmpTF{\the\toks0}{\the\toks1}{}{% \LTS@err{I can't macronize unscannable tokens: ^^J^^J||\detokenize{#3}||}\@ehc }% \endgroup \begingroup \LTS@twohashcheck{#3}{}{% \LTS@err{Illegal nested parameters in: ^^J^^J\detokenize{#3}}\@ehc }% \edef\reserved@e{\detokenize{#3}}% \chardef\nr@b\z@pt \xifinsetFT\LTS@hashchar\reserved@e{}{% \def\nr@a{1}% \cptwhilenum\nr@a<10\do{% \cptexpandtwoargs\cpt@in{\LTS@hashchar\nr@a}{\reserved@e}% \ifcpt@in\let\nr@b\nr@a\fi \pushnumber\nr@a }% \ifnum\nr@b>\z@pt \emptify#2\def\nr@a{1}% \cptwhilenum\nr@a<\numexpr\nr@b+1\do{% \edef#2{\expandcsonce#2\LTS@hashchar\nr@a}% \pushnumber\nr@a }% \fi }% \edef#2{#1\def\string#2#2{\reserved@e}}% \LTS@scantoksd\endgroup#2% } \robust@def*\ifmeaningTF#1#2{% \begingroup \ifdefFT{#1}{% \endgroup\@secondoftwo }{% \edef\LTS@tempa{\realmeaning{#1}}% \edef\LTS@tempb{\detokenize{#2}}% \aftercsname\endgroup{LTS@\ifxTF\LTS@tempa\LTS@tempb12of2}% }% } \robust@def*\ifactivecharTF#1{% \begingroup \ltsifmacroTF{#1}{% \edef\LTS@tempa{\string#1}% \def\LTS@tempb{#1}% \edef\LTS@tempb{\realmeaning\LTS@tempb}% \aftercsname\aftergroup{LTS@\ifxTF\LTS@tempa\LTS@tempb12of2}% }{% \aftergroup\@secondoftwo }% \endgroup } \robust@def*\ltsifmacroTF#1{% \begingroup \edef\LTS@tempa##1{\def##1####1\detokenize{macro}:####2&}% \LTS@tempa\LTS@tempa{% \aftercsname\aftergroup{LTS@\ifblankTF{##2}21of2}% }% \edef\LTS@tempb##1{##1\detokenize{macro}:&}% \LTS@tempb{\expandafter\LTS@tempa\meaning#1}% \endgroup } \robust@def*\ltsifmacroFT#1{\ltsifmacroTF{#1}\@secondoftwo\@firstoftwo} \robust@def*\ifparamacroTF#1{% \begingroup \edef\LTS@tempa##1{\def##1####1\detokenize{macro}:####2->####3&}% \LTS@tempa\LTS@tempa{% \aftercsname\aftergroup{LTS@\ifblankTF{##2}21of2}% }% \edef\LTS@tempb##1{##1\detokenize{macro}:->&}% \LTS@tempb{\expandafter\LTS@tempa\meaning#1}% \endgroup } \robust@def*\ifparamacroFT#1{\ifparamacroTF{#1}\@secondoftwo\@firstoftwo} \robust@def*\ifcsnparamacroTF{\aftercsname\ifparamacroTF} \robust@def*\ifprefmacroTF#1{% \begingroup \ifmacroFT{#1}{% \aftergroup\@secondoftwo }{% \edef\LTS@tempa##1{\def##1####1\detokenize{macro}:####2&}% \LTS@tempa\LTS@tempa{% \aftercsname\aftergroup{LTS@\ifblankTF{##1}21of2}% }% \edef\LTS@tempb##1{##1\detokenize{macro}:&}% \LTS@tempb{\expandafter\LTS@tempa\meaning#1}% }% \endgroup } \robust@def*\ifprefmacroFT#1{\ifprefmacroTF{#1}\@secondoftwo\@firstoftwo} \robust@def*\ifprimitiveTF#1{% \begingroup \ltsifmacroTF{#1}{% \endgroup\@secondoftwo }{% \def\LTS@tempa##1##2&{% \aftercsname\endgroup{LTS@\if##1\@backslashchar1\else2\fi of2}% }% \expandafter\LTS@tempa\meaning#1&% }% } \robust@def*\ifprimitiveFT#1{\ifprimitiveTF{#1}\@secondoftwo\@firstoftwo} \robust@def\ifpatternTF#1#2{% \begingroup \edef\LTS@tempa##1{\def##1####1\detokenize{#2}####2&}% \LTS@tempa\LTS@tempa{% \aftercsname\aftergroup{LTS@\ifblankTF{##2}21of2}% }% \edef\LTS@tempb##1{##1\detokenize{#2}&}% \LTS@tempb{\expandafter\LTS@tempa\meaning#1}% \endgroup } \robust@def*\ifpatternFT#1#2{\ifpatternTF{#1}{#2}\@secondoftwo\@firstoftwo} \robust@def*\ifnopattern#1\in#2{\ifpatternFT{#2}{#1}} \robust@def*\ifscannableTF#1{% % Fails if the content of #1 is already detokenized. \begingroup \edef\LTS@rsvda##1{% \def##1####1\detokenize{macro}:####2->####3&{% ####1\def\string\LTS@rsvda####2{####3}% }% \edef##1{##1\meaning#1&}% }% \LTS@rsvda\LTS@rsvda \makeatletter\everyeof{\noexpand}\endlinechar\m@one \scantokens\expandafter{\LTS@rsvda}\relax \aftercsname\endgroup{LTS@\expandafter\ifxTF\cpt@car#1\car@nil \LTS@rsvda12of2}% } \robust@def*\ifscannableFT#1{\ifscannableTF{#1}\@secondoftwo\@firstoftwo} \robust@def*\delimitmacro#1#2{% \ifsingletokenTF{#2}{}{% \LTS@err{Delimiter '\detokenize{#2}' is more than one token}\@ehc }% \ifscannableTF#1{% \begingroup \edef\LTS@tempa##1{% \def##1####1\detokenize{macro:}####2->####3&{% ####1\def\string#1####2\string#2{####3}% }% \edef##1{##1\meaning#1&}% }% \LTS@tempa\LTS@tempa \LTS@scantoksd\endgroup\LTS@tempa }{% \LTS@err{Your \noexpand#1 isn't scannable}{% Sorry, I can't delimit the last parameter of your\MsgBrk command \noexpand#1: it isn't scannable. }% }% } \robust@def*\LTS@stepdownhash{% \begingroup \@makeother{\#}% \endlinechar\m@one \LTS@st@pdownhash } \robust@def*\LTS@st@pdownhash#1#2{% \xifinsetTF{\detokenize{##}}{\detokenize{#1}}{% \edef\LTS@rsvda##1{##1\detokenize{#1##}&}% \edef\LTS@rsvdb##1{\def##1####1\detokenize{##}####2&}% \LTS@rsvdb\LTS@rsvdb{% \ifblankTF{##2}{% \toks@\expandafter{\the\toks@##1}% }{% \cptpassexpanded{\toks@{\the\toks@##1\LTS@hashchar}}% \LTS@rsvdb##2&% }% }% \LTS@rsvda{\toks@{}\LTS@rsvdb}% \edef#2{\the\toks@}% }{% \edef#2{\detokenize{#1}}% }% \postgroupdef#2\endgroup } \robust@def*\LTS@stepuphash{% \begingroup \@makeother{\#}% \endlinechar\m@one \LTS@st@puphash } \robust@def*\LTS@st@puphash#1#2{% \xifinsetTF{\LTS@hashchar}{\detokenize{#1}}{% \edef\LTS@rsvda##1{##1\detokenize{#1}\LTS@hashchar&}% \edef\LTS@rsvdb##1{\def##1####1\LTS@hashchar####2&}% \LTS@rsvdb\LTS@rsvdb{% \ifblankTF{##2}{% \toks@\expandafter{\the\toks@##1}% }{% \cptpassexpanded{\toks@{\the\toks@##1\LTS@hashchar\LTS@hashchar}}% \LTS@rsvdb##2&% }% }% \LTS@rsvda{\toks@{}\LTS@rsvdb}% \edef#2{\the\toks@}% }{% \edef#2{\detokenize{#1}}% }% \postgroupdef#2\endgroup } \robust@def*\LTS@onehashcheck#1{% \begingroup \edef\LTS@rsvda##1{\def##1####1\LTS@hashchar####2&}% \LTS@rsvda\LTS@rsvda{% \aftercsname\aftergroup{LTS@\ifblankTF{##2}12of2}}% \edef\LTS@rsvdb##1{##1\detokenize{#1}\LTS@hashchar&}% \LTS@rsvdb\LTS@rsvda \endgroup } \robust@def*\LTS@twohashcheck#1{% \begingroup \edef\LTS@rsvda##1{\def##1####1\detokenize{##}####2&}% \LTS@rsvda\LTS@rsvda{% \aftercsname\endgroup{LTS@\ifblankTF{##2}12of2}% }% \edef\LTS@rsvdb##1{##1\detokenize{#1}\detokenize{##}&}% \LTS@rsvdb\LTS@rsvda } \robust@def*\robustifycs{\LTS@testopt\LTS@robustifycs{}} \robust@def*\LTS@robustifycs[#1]#2{% \ifdefFT{#2}{% \cpt@notdeferr{#2}% }{% \ltsifmacroTF{#2}{% \ifetexprotectedTF{#2}{% \LTS@verboseinfo {Protected command '\string#2' not re-protected}% }{% \ifltxprotectTF{#2}{% \letcstocsn\LTS@rsvda{\cptgobblescape#2\@space}% \cpt@swatrue }{% \let\LTS@rsvda#2\cpt@swafalse }% \ifparamacroTF\LTS@rsvda{% \ifscannableTF\LTS@rsvda{% \begingroup \edef\LTS@rsvdb##1{% \def##1####1\detokenize{macro}:####2->####3&{% #1\protected####1\def\string\LTS@rsvda####2{####3}% }% \edef##1{##1\meaning\LTS@rsvda&}% }% \LTS@rsvdb\LTS@rsvdb \LTS@scantoksd\endgroup\LTS@rsvdb \let#2\LTS@rsvda }{% \LTS@err{Command '\string#2' can't be made robust}% {Command '\string#2' isn't retokenizable.}% \cpt@swafalse }% }{% \protected#1\edef#2{\expandcsonce\LTS@rsvda}% }% \ifcpt@swa \ifcsndefTF{\string#2\@space}{}% {\undefcsn{\cptgobblescape#2\@space}}% \fi }% }{% \LTS@err{Command '\string#2' isn't a macro}% {Command '\string#2' can't be made robust.}% }% }% } \robust@def*\robustifycsn{\LTS@testopt\LTS@robustifycsn{}} \robust@def*\LTS@robustifycsn[#1]#2{% \cptexpandarg{\robustifycs[#1]}{\noexpandcsn{#2}}% } \robust@def*\robustifycsset{\LTS@testopt\LTS@robustifycsset{}} \robust@def*\LTS@robustifycsset[#1]#2{% \def\csv@do##1{% \LTS@ensuremacro{##1}% \robustifycs[#1]{##1}% }% \csv@@parse[,]{#2}% } \new@def*\LTS@hookfail#1#2{% \LTS@warn{Hooking to command '\string#1' failed:\MsgBrk#2}% } % []{}{}{}{} \robust@def*\apptoparamcs{% \long\def\setarg##1##2{##1##2}% \begingroup\@makeother{\#}\LTS@hooktoparamcs } \robust@def*\preptoparamcs{% \let\setarg\cptswap \begingroup\@makeother{\#}\LTS@hooktoparamcs } \newcommand\LTS@hooktoparamcs[3][]{% \endgroup \ifdefFT{#2}{% \LTS@hookfail{#2}{Command isn't defined or is relaxed}% \@secondoftwo }{% \ltsifmacroTF{#2}{% \ifparamacroTF{#2}{% \ifscannableTF{#2}{% \LTS@twohashcheck{#3}{% \ifblankTF{#1}{% \LTS@h@oktoparamcs{#2}{#3}% }{% \LTS@h@oktoparamcs[#1]{#2}{#3}% }% \@firstoftwo }{% \LTS@hookfail{#2}{Nested commands or parameters}% \@secondoftwo }% }{% \LTS@hookfail{#2}{Macro can't be retokenized\MsgBrk safely after patching}% \@secondoftwo }% }{% \LTS@onehashcheck{#3}{% \LTS@verboseinfo{Macro '\string#2' patched successfully}% \ifetexprotectedTF{#2}\protected\relax #1\edef#2{\setarg{\expandcsonce#2}{\unexpanded{#3}}}% \LTS@verboseinfo{Macro '\string#2' patched successfully}% \@firstoftwo }{% \LTS@hookfail{#2}{Command is a parameterless macro \MsgBrk but you're hooking with a parametered macro}% \@secondoftwo }% }% }{% \LTS@hookfail{#2}{Command isn't a macro}% \@secondoftwo }% }% } \newcommand\LTS@h@oktoparamcs[3][]{% \begingroup \edef\LTS@tempa##1{% \def##1####1\detokenize{macro}:####2->####3&{% #1####1\def\string#2####2{\setarg{####3}{\detokenize{#3}}}% }% \edef##1{##1\meaning#2&}% }% \LTS@tempa\LTS@tempa \LTS@scantoksd\endgroup\LTS@tempa } \robust@def*\TracingPatchesOn{\let\LTS@tracepatches\cptswtrue} \robust@def*\TracingPatchesOff{\let\LTS@tracepatches\cptswfalse} % If 'patchability' has been established: \robust@def*\simplecmdpatch{% \begingroup \@makeother{\#}% \endlinechar\m@one \LTS@testopt\LTS@simplecmdpatch{####1}% } \new@def*\LTS@simplecmdpatch[#1]#2#3#4{% \if\LTS@tracepatches \typeout{^^J** Debugging patches: command '\string#2'}% \fi \endgroup \begingroup \edef\LTS@tempa##1##2{% \def##1####1\detokenize{macro:}####2->####3&{% #1\def\string#2####2{##2####3&}% }% \def##2####1\detokenize{#3}####2&{####1\detokenize{#4}####2}% \edef##1{##1\meaning#2&}% }% \LTS@tempa\LTS@tempa\LTS@tempb \catcode`\#=6\relax\makeatletter \LTS@scantoksd\endgroup\LTS@tempa } \robust@def*\patchcs{% \LTS@ifstar\LTS@patchcs@b\LTS@patchcs@a } \robust@def*\LTS@patchcs@a{% \let\LTS@hashcheckorno\LTS@twohashcheck \begingroup \@makeother{\#}\endlinechar\m@one % If \LTS@testopt uses a different definition of % \@ifnextchar, the number of hash characters here % would have to change; it will most likely become 8: \LTS@testopt\LTS@patchcs{####1}% } \robust@def*\LTS@patchcs@b{% \if\stricthashcheck \LTS@err{Patching failed: you can't use the star (*) \MsgBrk variant while strict hash check is in force. \MsgBrk Relax strict hash check with '\string\NoStrictHashCheck'}\@ehc \fi \let\LTS@hashcheckorno\ifblankFT \begingroup \@makeother{\#}\endlinechar\m@one \LTS@testopt\LTS@patchcs{####1}% } \new@def*\LTS@patchcs[#1]#2#3#4{% \if\LTS@tracepatches \typeout{^^J** Debugging patches: command '\string#2'}% \fi \LTS@hashcheckorno{#4}{% \LTS@p@tchcs{#1}{#2}{#3}{#4}% }{% \endgroup \LTS@patchdebug{--}{Nested parameters}% \@secondoftwo }% } \new@def*\LTS@p@tchcs#1#2#3#4{% \LTS@ifpatchable{#2}{#3}{#4}{% \LTS@patchdebug{++}{Command is patchable}% \LTS@patchdebug{==}{Patching has begun}% \begingroup \edef\LTS@tempa##1##2{% \def##1####1\detokenize{macro:}####2->####3&{% #1\def\string#2####2{##2####3&}% }% \def##2####1\detokenize{#3}####2&{####1\detokenize{#4}####2}% \edef##1{##1\meaning#2&}% }% \LTS@tempa\LTS@tempa\LTS@tempb \LTS@scantoksd\endgroup\LTS@tempa \LTS@patchdebug{==}{Patching completed successfully}% \@firstoftwo }{% \LTS@patchdebug{--}{Patching couldn't be completed}% \@secondoftwo }% } \new@def*\LTS@patchdebug#1#2{% \if\LTS@tracepatches \typeout{[debug] #1 #2}% \fi } \robust@def*\LTS@ifpatchable#1#2#3{% \endgroup \ifdefswitchTF{stricthashcheck}{% \LTS@patchdebug{==}{'stricthashcheck' set true}% % If #3 is macronizable, then it is scannable. % Macronizing doesn't accept nested hash, but % we're already in strict mode here. \macronizetokens\LTS@rsvda{#3}% \LTS@patchdebug{++}{No illegal nested parameters in command}% }{}% \ifdefFT{#1}{% \LTS@patchdebug{--}{Command not defined}% \@secondoftwo }{% \LTS@patchdebug{++}{Command is defined}% \ltsifmacroTF{#1}{% \LTS@patchdebug{++}{Command is a macro}% \ifscannableTF{#1}{% \LTS@patchdebug{++}{Macro can be retokenized safely after patching}% \LTS@hashcheckorno{#2}{% \LTS@patchdebug{++}{No nested parameters in command or 'stricthashcheck' is false}% \ifpatternTF{#1}{#2}{% \LTS@patchdebug{++}{Requested search pattern found}% \@firstoftwo }{% \LTS@patchdebug{--}{Requested search pattern not found}% \@secondoftwo }% }{% \LTS@patchdebug{--}{Nested commands or parameters}% \@secondoftwo }% }{% \LTS@patchdebug{--}{Macro can't be retokenized safely after patching}% \@secondoftwo }% }{% \LTS@patchdebug{--}{Command isn't a macro}% \@secondoftwo }% }% } \robust@def*\ifpatchableTF{\begingroup\LTS@ifpatchable} \robust@def*\reverseexpansion#1#2{% \ifnumcmpFT#2=\@ne{}{% \LTS@err{Invalid expansion order '\string#2' for '\string\reverseexpansion'}{Why not just use '\string\expandafter' here instead\MsgBrk of '\string\reverseexpansion'?}% \@gobbleone }% \ifcase\numexpr#2-2\relax \def\LTS@rsvda{2,2}% \or \def\LTS@rsvda{3,4,4}% \or \def\LTS@rsvda{4,6,8,8}% \else \LTS@err{Invalid expansion order \string#2} {Number '\string#2' of '\string\reverseexpansion' is too large.}% \expandafter\@gobble \fi \def\csv@do##1{% \LTS@sttrue \LTS@expandoneahead#1{##1}% }% \csv@@loop*[,]\LTS@rsvda } \robust@def*\expandoneahead{\LTS@testst\LTS@expandoneahead} \robust@def\LTS@expandoneahead#1#2{% \begingroup \makecsn{\{}\lb\makecsn{\}}\rb \toks@{}% \@tempcnta\m@one \def\LTS@i{\futurelet\next\LTS@iv}% \def\LTS@ii{\afterassignment\LTS@i\let\next= }% \def\LTS@iii##1{% \ifnum\@tempcnta<#2\relax \ifx##1\bgroup\relax \toks@\expandafter{\the\expandafter\toks@\expandafter\expandafter\lb}% \else \ifx##1\egroup\relax \toks@\expandafter{\the\expandafter\toks@\expandafter\expandafter\rb}% \else \toks@\expandafter{\the\toks@\expandafter##1}% \fi \fi \else \ifx##1\bgroup \toks@\expandafter{\the\expandafter\toks@\lb}% \else \ifx##1\egroup \toks@\expandafter{\the\expandafter\toks@\rb}% \else \toks@\expandafter{\the\toks@##1}% \fi \fi \fi }% \def\LTS@iv{% \advance\@tempcnta\@ne \ifx\next\end \let\cmd\@gobbleone \else \ifx\next\@sptoken \toks@\expandafter{\the\toks@ \expandafter\@space}% \let\cmd\LTS@ii \else \ifx\next\bgroup \LTS@iii\bgroup\let\cmd\LTS@ii \else \ifx\next\egroup \LTS@iii\egroup\let\cmd\LTS@ii \else \let\cmd\LTS@v \fi \fi \fi \fi \cmd }% \def\LTS@v##1{\LTS@iii##1\LTS@i}% \ifdefboolFT{LTS@st}{}\expandafter\LTS@i#1\end \edef\LTS@resa{\the\toks@}% \postgroupdef\LTS@resa\endgroup \LTS@scantoksa\LTS@resa \ifLTS@st\let#1\LTS@resa\fi } \robust@def*\expandallonce{\LTS@testopt\LTS@expandallonce\@M} \robust@def*\LTS@expandallonce[#1]#2{% \begingroup \let\temp@bgroup\bgroup \let\bgroup\LTS@undefined \cpt@cnta#1\relax\advance\cpt@cnta\@ne \LTS@exp@ndallonce#2% \postgroupdef#2\endgroup \NoExpandPrimitives } \new@def*\LTS@exp@ndallonce#1{% \def\LTS@i{\futurelet\next\LTS@ii}% \def\LTS@ii{% \expandafter\LTS@iii\meaning\next\LTS@nil \ifx\next\end \let\cmd\@gobbleone \else \ifx\next\@sptoken \edef#1{\expandcsonce#1\@space}% \csn@def{cmd} {\LTS@i}% \else \let\cmd\LTS@iv \fi \fi \cmd }% \def\LTS@iii##1##2\LTS@nil{\if##1\@backslashchar\let\next\relax\fi}% \def\LTS@iv##1{% \toks@\expandafter{#1}\toks1{##1}% \ifx\next\temp@bgroup \advance\cpt@cnta\m@one \ifnum\cpt@cnta>\z@pt \begingroup \aftercsname\edef{\string#1}{\the\toks1}% \aftercsname\LTS@exp@ndallonce{\string#1}% \toks1\cptsevenxp{\usename{\string#1}}% \edefpass#1{\endgroup\toks1{\the\toks1}}% \fi \edef#1{\the\toks@{\the\toks1}}% \advance\cpt@cnta\@ne \else \edef#1{\the\toks1}% \LTS@exp@nd@llonce#1% \edef#1{\the\toks@\expandcsonce#1}% \fi \LTS@i }% \expandafter\emptify\expandafter#1\expandafter\LTS@i#1\end } \robust@def*\LTS@exp@nd@llonce#1{% \begingroup \oifmacroTF#1{% \edef#1{\noexpand\expandcsonce\expandcsonce#1} }{% \edef\LTS@rsvda{\cptsevenxp\LTS@car\cptoxdetok{#1}x\car@nil}% \ifxTF\LTS@rsvda\@backslashchar{% \simpleexpandarg\ifprimitiveTF{#1}{% \if\LTS@expprim \edef#1{\expandcsonce#1}% \else \edef#1{\noexpand\noexpand\expandcsonce#1}% \fi }{% \edef#1{\noexpand\noexpand\expandcsonce#1}% }% }{% \edef#1{\expandcsonce#1}% }% }% \postgroupdef#1\endgroup } \new@def*\CurrentPackageOrClass{\@cls@pkg\@space'\@currname'} \new@def*\LTS@parsedate#1/#2/#3 v#4\LTS@nil{#1/#2/#3} \robust@def*\LTS@notloadederr#1{% \ifcsndefTF{ver@#1.\@pkgextension}{}{% \LTS@err{Package '#1' wasn't loaded}% {Document has begun and package '#1' wasn't loaded.\MsgBrk You wanted package '#1' loaded.}% }% } \new@def*\LTS@notloaded{} \robust@def*\ensurepackageloaded#1{% \def\csv@do##1{% \grightaddtocs\LTS@notloaded{\LTS@doloaded{##1}}% }% \csv@@parse[,]{#1}% } \LTS@AtBeginDocument{% \let\LTS@doloaded\LTS@notloadederr \LTS@notloaded \gletcs\LTS@doloaded\@gobbleone } \robust@def*\QuotationMarks#1{% \begingroup \ifinsetTF,{#1}{% \def\LTS@tempa##1,##2\LTS@nil{% \ifblankTF{##2}{% \LTS@err{Unbalanced quotation marks '#1'}\@ehc }{% \protected@xdef\LTS@lquote{% {\ltsprotectedtokens{\normalcolor\normalfont}##1}}% \protected@xdef\LTS@rquote{% {\ltsprotectedtokens{\normalcolor\normalfont}##2}}% }% }% \LTS@tempa#1\LTS@nil }{% \LTS@err{I can't find comma in quotation marks '#1'}\@ehc }% \endgroup } \QuotationMarks{`,'} \new@def*\ApplyToQuotes#1{% \ifnumcmpTF\LTS@quotednr@b>\z@pt{% \LTS@err{You haven't called '\string\ApplyNilToQuotes'\MsgBrk since you last called '\string\ApplyToQuotes'}\@ehc \@gobbleone }{% \gdef\LTS@quotefmt{#1}% }% \let\LTS@quotednr@b\@ne } \new@def*\ApplyNilToQuotes{% \gletcs\LTS@quotefmt\@firstofone \chardef\LTS@quotednr@b\z@pt } \ApplyNilToQuotes \def\quote@while{\cpt@choicefdfalse\quote@loop} \def\quote@loop#1{% \ifboolTF{cpt@choicefd}{% \quote@end }{% \ifx#1\quote@repeat\quote@repeat\fi \ifx#1\quote@next\cpt@choicefdtrue\fi }% \quote@loop } \def\quote@repeat#1\quote@loop{\fi} \def\quote@end#1\quote@repeat{} \chardef\LTS@quotednr@a\z@pt \chardef\LTS@quotednr@b\z@pt \robust@def*\quoted{% \pushnumber\LTS@quotednr@a \ifnumcmpTF\LTS@quotednr@a>\tw@{% \cpt@toodeep\quoted\tw@ }{% \begingroup \@makeother{\#}% \LTS@testst\LTS@quoted }% } \new@def*\LTS@quoted#1{% \def\LTS@quotearg{{\LTS@quotefmt{#1}}}% \gletcsntocs{ifLTS@st@\romannumeral\LTS@quotednr@a}\ifLTS@st \def\LTS@tempa{% \ifLTS@st@i \protected@edef\lquote{\LTS@lquote}% \protected@edef\rquote{\LTS@rquote}% \else \protected@edef\lquote{\LTS@lquote\LTS@lquote}% \protected@edef\rquote{\LTS@rquote\LTS@rquote}% \fi }% \def\LTS@tempb##1##2{% \ifnum\LTS@quotednr@a>\@ne \LTS@tempa \else \protected@edef\lquote{##1\LTS@lquote}% \protected@edef\rquote{##2\LTS@rquote}% \fi }% \ifLTS@st \LTS@tempb\LTS@lquote\LTS@rquote \else \LTS@tempb{}{}% \fi \def\popnumber{\noexpand\popnumber\noexpand}% \protected@edef\rquote{\rquote\popnumber\LTS@quotednr@a}% \futurelet\quote@next\LTS@qu@ted } \new@def*\LTS@qu@ted{% \def\LTS@quotefnt{\footnote\footnotetext\footnotemark\mpfootnotemark}% \def\LTS@quote@a{% \if\LTS@wq \expandafter\quote@while\LTS@quotefnt\quote@repeat \ifcpt@choicefd \protected@xdef\LTS@qu@t@d####1####2{% \lquote\expandcsonce\LTS@quotearg\unskip####1{####2}\rquote }% \else \protected@xdef\LTS@qu@t@d####1{% \lquote\expandcsonce\LTS@quotearg\unskip####1\rquote}% \fi \else \protected@xdef\LTS@qu@t@d{% \lquote\expandcsonce\LTS@quotearg\rquote\unskip}% \fi }% \protected@edef\LTS@tempa{,;:.!?\expandcsonce\LTS@quotefnt}% \expandafter\quote@while\LTS@tempa\quote@repeat \ifcpt@choicefd \expandafter\LTS@quote@a \else \protected@xdef\LTS@qu@t@d{\lquote\expandcsonce\LTS@quotearg\rquote}% \fi \expandafter\endgroup\LTS@qu@t@d } \robust@def*\MakeQuoteCommand{\LTS@testst\LTS@MakeQuoteCommand} \robust@def*\LTS@MakeQuoteCommand#1{% \begingroup \lccode`\~=`#1% \lowercase{\endgroup \newcsnedef*{\string~@quote}{\the\catcode`~}% \ifLTS@st \ifdefFT~{}{\letcsntocs{\string~@@quote}~}% \let~\quoted \else \newletcs~\quoted \fi \catcode`#1=\active }% } \robust@def*\DeleteQuoteCommand#1{% \begingroup \lccode`\~=`#1% \lowercase{\endgroup \ifcsndefTF{\string~@@quote}{% \letcstocsn~{\string~@@quote}% }{% \gletcs~\LTS@undefined }% \catcode`#1=\usename{\string~@quote}% }% } \robust@def*\nameabbrev#1#2{% \begingroup \LTS@ensurescape{#1}% \makecsn#1\LTS@tempa \expandafter\LTS@testopt\expandafter {\expandafter\LTS@nameabbrev\expandafter{\LTS@tempa}{#2}}{}% } \new@def*\LTS@nameabbrev#1#2[#3]{% \ifblankTF{#3}{% \LTS@err{Empty abbreviation for name '\noexpandcsn{#1}'}\@ehc }{% \newcsnpgdef*{#1long}{#2\sspace}% \newcsnpgdef*{#1short}{#3\sspace}% \newcsnpgdef*{#1first}{#2~(#3)\sspace}% }% \newcsnpgdef*{#1}{% \ifnamedefTF{nameabbrev@#1}{% #3\sspace }{% \csn@gdef{nameabbrev@#1}{}% \usename{#1first}\sspace }% }% \endgroup } \newletcs\killifdocstarted\@iden \LTS@AfterAfterBeginDocument{% \LTS@scantoksa\sspace@exceptions \let\killifdocstarted\@gobble } \robust@def*\sspace@while{\cpt@choicefdfalse\sspace@loop} \robust@def*\sspace@loop#1{% \ifboolTF{cpt@choicefd}{% \sspace@end }{% \ifx#1\sspace@repeat\sspace@repeat\fi \ifx#1\sspace@next\cpt@choicefdtrue\fi }% \sspace@loop } \robust@def\sspace@repeat#1\sspace@loop{\fi} \robust@def\sspace@end#1\sspace@repeat{} \robust@def*\sspace@exceptions{% \},.'/?;:!~-)\ \/\bgroup\egroup\sspace\nobreak\penalty \@sptoken\@space\@xobeysp\footnote\footnotemark } \robust@def*\sspace{\begingroup\futurelet\sspace@next\LTS@sspace} \robust@def*\LTS@sspace{% \killifdocstarted{\LTS@scantoksa\sspace@exceptions}% \expandafter\sspace@while\sspace@exceptions\sspace@repeat \expandafter\endgroup \ifcpt@choicefd\else\expandafter\@space\fi } \robust@def*\AddSspaceExceptions#1{% \ltsfiltermergetsv!\sspace@exceptions{#1}\nofilter } \robust@def*\RemoveSspaceExceptions#1{% \filterdeletetokens!\sspace@exceptions{#1}\nofilter } \long\def\LTS@exprerr#1{% \ltx@err{Invalid test expression}{#1.}% } \robust@def*\ltsifexprTF#1{% \begingroup \let\LTS@expr@neg\cptswfalse \@tempcnta\z@pt \LTS@expr@beg \LTS@expr@bgroup#1(\expr@nil \LTS@expr@end \LTS@expr@eval@end } \def\LTS@expr@beg{% \begingroup \let\LTS@expr@neg\cptswfalse \@tempcnta\z@pt } \def\LTS@expr@end{% \LTS@expr@eval@end\LTS@expr@true\LTS@expr@false } \def\LTS@expr@eval@end{% \aftercsname\endgroup {@\ifnum\@tempcnta<\z@pt second\else first\fi oftwo}% } \def\LTS@expr@true{% \advance\@tempcnta\if\LTS@expr@neg\m@one\else\z@pt\fi \let\LTS@expr@neg\cptswfalse } \def\LTS@expr@false{% \advance\@tempcnta\if\LTS@expr@neg\z@pt\else\m@one\fi \let\LTS@expr@neg\cptswfalse } \long\def\LTS@expr@bgroup#1(#2\expr@nil{% \LTS@expr@egroup#1)\expr@nil \ifblankTF{#2}{}{% \LTS@expr@beg \LTS@expr@bgroup#2\expr@nil }% } \long\def\LTS@expr@egroup#1)#2\expr@nil{% \LTS@expr@and#1and\expr@nil \ifblankTF{#2}{}{% \LTS@expr@end \LTS@expr@egroup#2\expr@nil }% } \long\def\LTS@expr@and#1and#2\expr@nil{% \LTS@expr@or#1or\expr@nil \ifblankTF{#2}{}{% \ifnum\@tempcnta<\z@pt \@tempcnta\m@one \else \@tempcnta\z@pt \fi \LTS@expr@and#2\expr@nil }% } \long\def\LTS@expr@or#1or#2\expr@nil{% \LTS@expr@not#1not\expr@nil \ifblankTF{#2}{}{% \ifnum\@tempcnta<\z@pt \@tempcnta\z@pt \else \@tempcnta\@ne \fi \LTS@expr@or#2\expr@nil }% } \long\def\LTS@expr@not#1not#2\expr@nil{% \LTS@expr@tog#1togg\expr@nil \ifblankTF{#2}{}{% \let\LTS@expr@neg\cptswtrue \LTS@expr@not#2\expr@nil }% } \long\def\LTS@expr@tog#1togg#2\expr@nil{% \LTS@expr@bool#1bool\expr@nil \ifblankTF{#2}{}{\LTS@expr@tog@a#2\expr@nil}% } \long\def\LTS@expr@tog@a#1#2\expr@nil{% \ifcsndefTF{cpt@tog@\cpttrimspaces{#1}}{% \usename{cpt@tog@#1}\LTS@expr@true\LTS@expr@false }{% \LTS@exprerr{Toggle '#1' undefined}% \LTS@expr@false }% \LTS@expr@tog#2\expr@nil } \long\def\LTS@expr@bool#1bool#2\expr@nil{% \LTS@expr@test#1test\expr@nil \ifblankTF{#2}{}{\LTS@expr@bool@a#2\expr@nil}% } \long\def\LTS@expr@bool@a#1#2\expr@nil{% \ifcsndefTF{if\cpttrimspaces{#1}}{% \csname if#1\endcsname \LTS@expr@true \else \LTS@expr@false \fi }{% \LTS@exprerr{Boolean '#1' undefined}% \LTS@expr@false }% \LTS@expr@bool#2\expr@nil } \long\def\LTS@expr@test#1test#2\expr@nil{% \ifblankTF{#1}{}{% \LTS@exprerr{The invalid part is: '\detokenize{#1}'}% }% \ifblankTF{#2}{}{% \LTS@expr@test@a#2\expr@nil }% } \long\def\LTS@expr@test@a#1#2\expr@nil{% \cpttrimspaces{#1}% \LTS@expr@true\LTS@expr@false \LTS@expr@test#2\expr@nil } % \newenviron, \renewenviron {}{}. % Collect environment body in \envbody: \ltsnewbool{LTS@alwaystrim} \new@def*\AlwaysTrimEnvironmentEntries{% \global\LTS@alwaystrimtrue } \new@def*\trimenvspaces{% \ifboolTF{LTS@alwaystrim}\cpttrimspaces\unexpanded } \new@def*\everyeoenv#1{\gdef\LTS@everyeoenv{#1}} \everyeoenv{\@ignoretrue} \robust@def*\newenviron{\cpt@starorlong\LTS@newenviron} \robust@def*\LTS@newenviron#1{% \edef\LTS@tempa{\trimenvspaces{#1}}% \cptexpandarg\cpt@testopt {\LTS@n@wenviron{\expandcsonce\LTS@tempa}}0% } \robust@def*\LTS@n@wenviron#1[#2]{% \cpt@ifbrack {\LTS@n@wenv@ron#1[#2]} {\LTS@n@wenv@r@n{#1}{[#2]}}% } \robust@def*\LTS@n@wenv@ron#1[#2][#3]{\LTS@n@wenv@r@n{#1}{[#2][{#3}]}} \robust@def*\renewenviron{\cpt@starorlong\LTS@renewenviron} \robust@def*\LTS@renewenviron#1{% \edef\LTS@tempa{\trimenvspaces{#1}}% \ifcsndefTF\LTS@tempa{} {\@latex@error{Environment #1 is undefined}\@ehc}% \letcsntocs\LTS@tempa\relax \letcsntocs{end\LTS@tempa}\relax \expandafter\LTS@newenviron\expandafter{\LTS@tempa}% } \robust@def\LTS@n@wenv@r@n#1#2#3#4{% \ifcsndefTF{#1}{}{\letcsntocsn{#1}{end#1}}% \aftercsname\new@command{#1}#2{% \edef\LTS@beforebody{\trimenvspaces{#3}}% \LTS@collectbody }% \l@ngrel@x\csn@edef{end#1}{% \begingroup \defpass\noexpand\x{\endgroup\trimenvspaces{#4}}% }% } \robust@def*\LTS@collectbody{% \begingroup \toks@{}% \everyeof{\end{EOF}\relax}% \LTS@coll@ctbody } \robust@def\LTS@coll@ctbody#1\end#2{% \toks1{% \cptexpanded{% \toks@{\the\toks@\trimenvspaces{#1}% \noexpand\end{\expandcsonce\LTS@tempa}}% }% \LTS@coll@ctbody }% \edef\LTS@tempa{\trimenvspaces{#2}}% \ifxTF\LTS@tempa\@currenvir{% \edef\LTS@tempb{\LTS@pushbegin#1\begin\end\cpt@relax}% \ifcsemptyTF\LTS@tempb{% \cptexpandsecond\endgroup{% \edef\noexpand\envbody{\noexpand\unexpanded{% \the\toks@\ifblankTF{#1}{}{\trimenvspaces{#1}}% }}% \unexpanded{% \LTS@beforebody\relax\LTS@everyeoenv \ifboolTF{LTS@alwaystrim}\@ignoretrue\relax }% \noexpand\end{\LTS@tempa}% }% }{% \the\toks1 }% }{% \oifstrcmpTF{\LTS@tempa}{document}{% \expandafter\endgroup\expandafter \@checkend\expandafter{\LTS@tempa}% }{% \oifstrcmpTF{\LTS@tempa}{EOF}{% \expandafter\endgroup\expandafter \@checkend\expandafter{\LTS@tempa}% }{% \the\toks1 }% }% }% } \new@def\LTS@pushbegin#1\begin#2{% \expandafter\ifxTF\cpt@car#2x\car@nil\end{% \@gobble }{% \xifstrcmpTF{\detokenize\expandafter{\romannumeral-`\q \trimenvspaces{#2}}}{\cptoxdetok\LTS@tempa}{% x\cpt@gobbletorelax }{% \LTS@pushbegin }% }% } \packagecommands{% \packagecommands,\AtEndOfPackage, \LTS@AtEndPackage,\AtEndOfClass,\LTS@AtEndClass, \LTS@BeforeEndPackage,\LTS@BeforeEndClass,\LTS@AfterEndPackage, \LTS@AfterEndClass,\ifclasscurrentTF,\ifclasscurrentFT } \preamblecommands{% \preamblecommands,\LTS@BeforeBeginDocument,\ensurepackageloaded, \needpackage } \XDeclareBiBooleanOptions{draft,final}[true](LTS@){}{} \XDeclareBooleanOption{verbose}[true](LTS@){% \ifLTS@verbose\cpt@verbosetrue\else\cpt@verbosefalse\fi } \XDeclareSwitchOption{tracepatches}[true](LTS@){% \ifdefswitchTF{LTS@tracepatches}{% \LTS@info{'tracepatches' set true\on@line}% }{}% } \XDeclareOption*{\LTS@warn{Unknown option '\CurrentOption' ignored}} \XExecuteOptions{verbose=false,final=true,tracepatches=false} \XProcessOptions*\relax \endinput %%% End of file ltxtools.sty %%%