% \iffalse meta-comment % % Copyright 1994 the LaTeX3 project and the individual authors. % All rights reserved. For further copyright information see the file % legal.txt, and any other copyright indicated in this file. % % This file is part of the LaTeX2e system. % ---------------------------------------- % % This system is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % % % IMPORTANT NOTICE: % % For error reports in case of UNCHANGED versions see bugs.txt. % % Please do not request updates from us directly. Distribution is % done through Mail-Servers and TeX organizations. % % You are not allowed to change this file. % % You are allowed to distribute this file under the condition that % it is distributed together with all files mentioned in manifest.txt. % % If you receive only some of these files from someone, complain! % % You are NOT ALLOWED to distribute this file alone. You are NOT % ALLOWED to take money for the distribution or use of either this % file or a changed version, except for a nominal charge for copying % etc. % \fi % % \iffalse %%% File: ltcntrl.dtx %<*driver> % \fi \ProvidesFile{ltcntrl.dtx} [1994/05/16 v1.1a LaTeX Kernel (program control)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltcntrl.dtx} \title{\filename} \date{\filedate} \author{% Johannes Braams\and David Carlisle\and Alan Jeffrey\and Leslie Lamport\and Frank Mittelbach\and Chris Rowley\and Rainer Sch\"opf} \begin{document} \maketitle \DocInput{\filename} \end{document} % % \fi % % \CheckSum{202} % % \changes{v1.1a}{1994/05/16}{(ASAJ) Split from ltinit.dtx.} % % \section{Program control structure} % % This section defines a number of control structure macros, such as % while-loops and for-loops. % % \StopEventually{} % % \begin{oldcomments} % \begin{macrocode} %<*2ekernel> \message{control,} % \end{macrocode} % ********************************************** % * PROGRAM CONTROL STRUCTURE MACROS * % ********************************************** % % \@whilenum TEST \do {BODY} % \@whiledim TEST \do {BODY} : These implement the loop % while TEST do BODY od % where TEST is a TeX \ifnum or \ifdim test, respectively. % They are optimized for the normal case of TEST initially false. % % \@whilesw SWITCH \fi {BODY} : Implements the loop % while SWITCH do BODY od % where SWITCH is a command defined by \newswitch. % Optimized for normal case of SWITCH initially false. % % \@for NAME := LIST \do {BODY} : Assumes that LIST expands to A1,A2, % ... ,An . % Executes BODY n times, with NAME = Ai on the i-th iteration. % Optimized for the normal case of n = 1. Works for n=0. % % \@tfor NAME := LIST \do {BODY} % if, before expansion, LIST = T1 ... Tn where each Ti is a % token or {...}, then executes BODY n times, with NAME = Ti % on the i-th iteration. Works for n=0. % % NOTES: 1. These macros use no \@temp sequences. % 2. These macros do not work if the body contains anything that % looks syntactically to TeX like an improperly balanced \if % \else \fi. % % \@whilenum TEST \do {BODY} == % BEGIN % if TEST % then BODY % \@iwhilenum{TEST \relax BODY} % END % % \@iwhilenum {TEST BODY} == % BEGIN % if TEST % then BODY % \@nextwhile = def(\@iwhilenum) % else \@nextwhile = def(\@whilenoop) % fi % \@nextwhile {TEST BODY} % END % % \@whilesw SWITCH \fi {BODY} == % BEGIN % if SWITCH % then BODY % \@iwhilesw {SWITCH BODY}\fi % fi % END % % \@iwhilesw {SWITCH BODY} \fi == % BEGIN % if SWITCH % then BODY % \@nextwhile = def(\@iwhilesw) % else \@nextwhile = def(\@whileswnoop) % fi % \@nextwhile {SWITCH BODY} \fi % END % % \begin{macrocode} \def\@whilenoop#1{} \def\@whilenum#1\do #2{\ifnum #1\relax #2\relax\@iwhilenum{#1\relax #2\relax}\fi} \def\@iwhilenum#1{\ifnum #1\let\@nextwhile\@iwhilenum \else\let\@nextwhile\@whilenoop\fi\@nextwhile{#1}} % \end{macrocode} % % \begin{macrocode} \def\@whiledim#1\do #2{\ifdim #1\relax#2\@iwhiledim{#1\relax#2}\fi} \def\@iwhiledim#1{\ifdim #1\let\@nextwhile\@iwhiledim \else\let\@nextwhile\@whilenoop\fi\@nextwhile{#1}} % \end{macrocode} % % \begin{macrocode} \long\def\@whileswnoop#1\fi{} \long\def\@whilesw#1\fi#2{#1#2\@iwhilesw{#1#2}\fi\fi} \long\def\@iwhilesw#1\fi{#1\let\@nextwhile\@iwhilesw \else\let\@nextwhile\@whileswnoop\fi\@nextwhile{#1}\fi} % \end{macrocode} % % \@for NAME := LIST \do {BODY} == % BEGIN \@forloop expand(LIST),\@nil,\@nil \@@ NAME {BODY} END % % \@forloop CAR, CARCDR, CDRCDR \@@ NAME {BODY} == % BEGIN % NAME = CAR % if def(NAME) = def(\@nnil) % else BODY; % NAME = CARCDR % if def(NAME) = def(\@nnil) % else BODY % \@iforloop CDRCDR \@@ NAME \do {BODY} % fi % fi % END % % \@iforloop CAR, CDR \@@ NAME {BODY} = % NAME = CAR % if def(NAME) = def(\@nnil) % then \@nextwhile = def(\@fornoop) % else BODY ; % \@nextwhile = def(\@iforloop) % fi % \@nextwhile name cdr {body} % % \@tfor NAME := LIST \do {BODY} % = \@tforloop LIST \@nil \@@ NAME {BODY} % % \@tforloop car cdr \@@ name {body} = % name = car % if def(name) = def(\@nnil) % then \@nextwhile == \@fornoop % else body ; % \@nextwhile == \@forloop % fi % \@nextwhile name cdr {body} % % \begin{macrocode} \def\@nnil{\@nil} \def\@empty{} \def\@fornoop#1\@@#2#3{} % \end{macrocode} % % \begin{macrocode} \def\@for#1:=#2\do#3{\edef\@fortmp{#2}\ifx\@fortmp\@empty \else \expandafter\@forloop#2,\@nil,\@nil\@@#1{#3}\fi} % \end{macrocode} % % \begin{macrocode} \def\@forloop#1,#2,#3\@@#4#5{\def#4{#1}\ifx #4\@nnil \else #5\def#4{#2}\ifx #4\@nnil \else#5\@iforloop #3\@@#4{#5}\fi\fi} % \end{macrocode} % % \begin{macrocode} \def\@iforloop#1,#2\@@#3#4{\def#3{#1}\ifx #3\@nnil \let\@nextwhile\@fornoop \else #4\relax\let\@nextwhile\@iforloop\fi\@nextwhile#2\@@#3{#4}} % \end{macrocode} % \end{oldcomments} % % \begin{macro}{\@tfor} % \changes{LaTeX209}{1991/10/17} % {(Rms) \cmd{\xdef} replaced by \cmd{\def} % (See FMi's array.doc)} % \changes{v1.0c}{1994/03/13} % {(DPC) Add \cmd{\@tf@r} so a single group is % correctly treated.} % \begin{macrocode} \def\@tfor#1:={\@tf@r#1 } \def\@tf@r#1#2\do#3{\def\@fortmp{#2}\ifx\@fortmp\space\else \@tforloop#2\@nil\@nil\@@#1{#3}\fi} \def\@tforloop#1#2\@@#3#4{\def#3{#1}\ifx #3\@nnil \let\@nextwhile\@fornoop \else #4\relax\let\@nextwhile\@tforloop\fi\@nextwhile#2\@@#3{#4}} % \end{macrocode} % \end{macro} % % \begin{macro}{\@break@tfor} % Break out of a |\@tfor| loop. This should be called \emph{inside} % the scope of an |\if|. See |\@iffileonpath| for an example. % \changes{v1.0l}{1994/05/02}{Macro added (from ltfiles.dtx)} % \begin{macrocode} \def\@break@tfor#1\@@#2#3{\fi\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\@removeelement} % % Removes an element from a comma-separated list and put the result in % a control sequence, called as % |\@removeelement{|\meta{element}|}{|\meta{list}|}{|\meta{cs}|}|. % % Added |\ifx,| to remove extra |,|'s. % \begin{macrocode} \def\@removeelement#1#2#3{% \def\@tempa##1,#1,##2\@tempa{##1,##2\@tempb}% \def\@tempb##1,\@tempb##2\@tempb{\ifx,##1\@empty\else##1\fi}% \edef#3{\expandafter\@tempb\@tempa,#2,\@tempb,#1,\@tempa}} % \end{macrocode} % \end{macro} % % \begin{macrocode} \let\protect=\relax % \end{macrocode} % % \begin{macrocode} \def\@setprotect{% \let\@@protect\protect \def\protect{\noexpand\protect\noexpand}} \def\@resetprotect{\let\protect\@@protect} % % \end{macrocode} % %\Finale \endinput