1 % \iffalse meta-comment
4 % The LaTeX3 Project and any individual authors listed elsewhere
7 % This file is part of the LaTeX base system.
8 % -------------------------------------------
10 % It may be distributed and/or modified under the
11 % conditions of the LaTeX Project Public License, either version 1.3c
12 % of this license or (at your option) any later version.
13 % The latest version of this license is in
14 % http://www.latex-project.org/lppl.txt
15 % and version 1.3c or later is part of all distributions of LaTeX
16 % version 2005/12/01 or later.
18 % This file has the LPPL maintenance status "maintained".
20 % The list of all files belonging to the LaTeX base distribution is
21 % given in the file `manifest.txt'. See also `legal.txt' for additional
24 % The list of derived (unpacked) files belonging to the distribution
25 % and covered by LPPL is defined by the unpacking scripts (with
26 % extension .ins) which are part of the distribution.
31 %%% From File: ltcntrl.dtx
34 \ProvidesFile{ltcntrl.dtx}
35 [2014/04/21 v1.0h LaTeX Kernel (program control)]
37 \documentclass{ltxdoc}
38 \GetFileInfo{ltcntrl.dtx}
50 \MaintainedByLaTeXTeam{latex}
59 % \changes{v1.0a}{1994/05/16}{(ASAJ) Split from ltinit.dtx.}
60 % \changes{v1.0b}{1994/11/17}
61 % {\cs{@tempa} to \cs{reserved@a}}
62 % \changes{v1.0c}{1994/11/28}
63 % {Documentation improvements}
65 % \section{Program control structure}
67 % This section defines a number of control structure macros, such as
68 % while-loops and for-loops.
78 % \@whilenum TEST \do {BODY}
79 % \@whiledim TEST \do {BODY} : These implement the loop
80 % while TEST do BODY od
81 % where TEST is a TeX \ifnum or \ifdim test, respectively.
82 % They are optimized for the normal case of TEST initially false.
84 % \@whilesw SWITCH \fi {BODY} : Implements the loop
85 % while SWITCH do BODY od
86 % Optimized for normal case of SWITCH initially false.
88 % \@for NAME := LIST \do {BODY} : Assumes that LIST expands to A1,A2,
90 % Executes BODY n times, with NAME = Ai on the i-th iteration.
91 % Optimized for the normal case of n = 1. Works for n=0.
93 % \@tfor NAME := LIST \do {BODY}
94 % if, before expansion, LIST = T1 ... Tn where each Ti is a
95 % token or {...}, then executes BODY n times, with NAME = Ti
96 % on the i-th iteration. Works for n=0.
98 % NOTES: 1. These macros use no \@temp sequences.
99 % 2. These macros do not work if the body contains anything that
100 % looks syntactically to TeX like an improperly balanced \if
103 % \@whilenum TEST \do {BODY} ==
107 % \@iwhilenum{TEST \relax BODY}
110 % \@iwhilenum {TEST BODY} ==
114 % \@nextwhile = def(\@iwhilenum)
115 % else \@nextwhile = def(\@whilenoop)
117 % \@nextwhile {TEST BODY}
120 % \@whilesw SWITCH \fi {BODY} ==
124 % \@iwhilesw {SWITCH BODY}\fi
128 % \@iwhilesw {SWITCH BODY} \fi ==
132 % \@nextwhile = def(\@iwhilesw)
133 % else \@nextwhile = def(\@whileswnoop)
135 % \@nextwhile {SWITCH BODY} \fi
140 % \begin{macro}{\@whilenoop}
141 % \begin{macro}{\@whilenum}
142 % \begin{macro}{\@iwhilenum}
143 % \changes{v1.0f}{1995/07/09}{Reimplemented using Kabelschacht method}
144 % \changes{v1.0g}{1995/08/16}{Removed \cs{@whilenoop}}
145 % \changes{v1.0g}{1995/08/16}{Made defs long}
147 \long\def\@whilenum#1\do #2{\ifnum #1\relax #2\relax\@iwhilenum{#1\relax
149 \long\def\@iwhilenum#1{\ifnum #1\expandafter\@iwhilenum
150 \else\expandafter\@gobble\fi{#1}}
156 % \begin{macro}{\@whiledim}
157 % \begin{macro}{\@iwhiledim}
158 % \changes{v1.0f}{1995/07/09}{Reimplemented using Kabelschacht method}
159 % \changes{v1.0g}{1995/08/16}{Removed \cs{@whilenoop}}
160 % \changes{v1.0g}{1995/08/16}{Made defs long}
162 \long\def\@whiledim#1\do #2{\ifdim #1\relax#2\@iwhiledim{#1\relax#2}\fi}
163 \long\def\@iwhiledim#1{\ifdim #1\expandafter\@iwhiledim
164 \else\expandafter\@gobble\fi{#1}}
169 % \begin{macro}{\@whileswnoop}
170 % \begin{macro}{\@whilesw}
171 % \begin{macro}{\@iwhilesw}
172 % \changes{v1.0f}{1995/07/09}{Reimplemented using Kabelschacht method}
173 % \changes{v1.0g}{1995/08/16}{Removed \cs{@whileswnoop}}
175 \long\def\@whilesw#1\fi#2{#1#2\@iwhilesw{#1#2}\fi\fi}
176 \long\def\@iwhilesw#1\fi{#1\expandafter\@iwhilesw
177 \else\@gobbletwo\fi{#1}\fi}
183 % \begin{oldcomments}
185 % \@for NAME := LIST \do {BODY} ==
186 % BEGIN \@forloop expand(LIST),\@nil,\@nil \@@ NAME {BODY} END
188 % \@forloop CAR, CARCDR, CDRCDR \@@ NAME {BODY} ==
191 % if def(NAME) = def(\@nnil)
194 % if def(NAME) = def(\@nnil)
196 % \@iforloop CDRCDR \@@ NAME \do {BODY}
201 % \@iforloop CAR, CDR \@@ NAME {BODY} =
203 % if def(NAME) = def(\@nnil)
204 % then \@nextwhile = def(\@fornoop)
206 % \@nextwhile = def(\@iforloop)
208 % \@nextwhile name cdr {body}
210 % \@tfor NAME := LIST \do {BODY}
211 % = \@tforloop LIST \@nil \@@ NAME {BODY}
213 % \@tforloop car cdr \@@ name {body} =
215 % if def(name) = def(\@nnil)
216 % then \@nextwhile == \@fornoop
218 % \@nextwhile == \@forloop
220 % \@nextwhile name cdr {body}
223 % \begin{macro}{\@nnil}
229 % \begin{macro}{\@empty}
235 % \begin{macro}{\@fornoop}
236 % \changes{v1.0g}{1995/08/16}{Made defs long}
237 % \changes{v1.0h}{2007/08/06}{Really make defs long}
239 \long\def\@fornoop#1\@@#2#3{}
243 % \begin{macro}{\@for}
244 % \changes{v1.0d}{1995/04/24}
245 % {Dont expand second argument with \cs{edef}: /1317 (DPC)}
247 \long\def\@for#1:=#2\do#3{%
248 \expandafter\def\expandafter\@fortmp\expandafter{#2}%
249 \ifx\@fortmp\@empty \else
250 \expandafter\@forloop#2,\@nil,\@nil\@@#1{#3}\fi}
254 % \begin{macro}{\@forloop}
255 % \changes{v1.0g}{1995/08/16}{Made defs long}
257 \long\def\@forloop#1,#2,#3\@@#4#5{\def#4{#1}\ifx #4\@nnil \else
258 #5\def#4{#2}\ifx #4\@nnil \else#5\@iforloop #3\@@#4{#5}\fi\fi}
262 % \begin{macro}{\@iforloop}
263 % \changes{v1.0f}{1995/07/09}{Reimplemented using Kabelschacht method}
264 % \changes{v1.0g}{1995/08/16}{Made defs long}
266 \long\def\@iforloop#1,#2\@@#3#4{\def#3{#1}\ifx #3\@nnil
267 \expandafter\@fornoop \else
268 #4\relax\expandafter\@iforloop\fi#2\@@#3{#4}}
272 % \begin{macro}{\@tfor}
273 % \changes{LaTeX209}{1991/10/17}
274 % {(Rms) \cs{xdef} replaced by \cs{def}
275 % (See FMi's array.doc)}
276 % \changes{v1.0c}{1994/03/13}
277 % {(DPC) Add \cs{@tf@r} so a single group is
278 % correctly treated.}
279 % \changes{v1.0f}{1995/07/09}{Reimplemented using Kabelschacht method}
280 % \changes{v1.0g}{1995/08/16}{Made defs long}
282 \def\@tfor#1:={\@tf@r#1 }
283 \long\def\@tf@r#1#2\do#3{\def\@fortmp{#2}\ifx\@fortmp\space\else
284 \@tforloop#2\@nil\@nil\@@#1{#3}\fi}
285 \long\def\@tforloop#1#2\@@#3#4{\def#3{#1}\ifx #3\@nnil
286 \expandafter\@fornoop \else
287 #4\relax\expandafter\@tforloop\fi#2\@@#3{#4}}
291 % \begin{macro}{\@break@tfor}
292 % Break out of a |\@tfor| loop. This should be called \emph{inside}
293 % the scope of an |\if|. See |\@iffileonpath| for an example.
294 % \changes{v1.0l}{1994/05/02}{Macro added (from ltfiles.dtx)}
295 % \changes{v1.0g}{1995/08/16}{Made long}
297 \long\def\@break@tfor#1\@@#2#3{\fi\fi}
301 % \begin{macro}{\@removeelement}
302 % Removes an element from a comma-separated list and puts it into
303 % a control sequence, called as
304 % |\@removeelement{|\meta{element}|}{|\meta{list}|}{|\meta{cs}|}|.
305 % Due to the implementation method the \meta{element} is not allowed
308 \def\@removeelement#1#2#3{%
309 \def\reserved@a##1,#1,##2\reserved@a{##1,##2\reserved@b}%
310 \def\reserved@b##1,\reserved@b##2\reserved@b{%
311 \ifx,##1\@empty\else##1\fi}%
313 \expandafter\reserved@b\reserved@a,#2,\reserved@b,#1,\reserved@a}}
318 % \changes{v1.0e}{1995/04/29}{Removed unused defs for
319 % \cs{@setprotect} and \cs{@resetprotect}}
320 % \changes{v1.0e}{1995/04/29}{Moved init of \cs{protect}