summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/eijkhout/repeat.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/generic/eijkhout/repeat.tex')
-rw-r--r--Master/texmf-dist/tex/generic/eijkhout/repeat.tex206
1 files changed, 206 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/eijkhout/repeat.tex b/Master/texmf-dist/tex/generic/eijkhout/repeat.tex
new file mode 100644
index 00000000000..6d149e15ee7
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/eijkhout/repeat.tex
@@ -0,0 +1,206 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Repeat loop macro, version 0.92, December 2000
+% Copyright Victor Eijkhout 2000
+% file name: repeat.tex
+%
+% Author:
+% Victor Eijkhout
+% Department of Computer Science
+% University of Tennessee, Knoxville TN 37996
+%
+% victor@eijkhout.net
+%
+% This program is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License
+% as published by the Free Software Foundation; either version 2
+% of the License, or (at your option) any later version.
+%
+% This program 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. See the
+% GNU General Public License for more details.
+%
+% For a copy of the GNU General Public License, write to the
+% Free Software Foundation, Inc.,
+% 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA,
+% or find it on the net, for instance at
+% http://www.gnu.org/copyleft/gpl.html
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% General loop macro:
+% \repeat
+% \for{<var>} \from{<start>} \by{<step>} \to{<end>} \downto{<end>}
+% \until{<cond>} \while{<cond>}
+% \do { <loop body> }
+% where all control sequences in between \repeat and \do are optional.
+% The space after each argument is mandatory!
+% (This implies that you will have to write "\from\i" as "\from{\i}".)
+%
+% var: characters to form a control sequence;
+% after \for{index} you can access the loop counter as \index.
+% This is a count register; to print it use \number\index.
+% start,step,end: integers with obvious relations to the loop counter;
+% start and step have a default value of 1
+% cond: (sequence of commands ending in) any TeX \if... test.
+%
+% Count down instead of up with \downto; the increment given in \by
+% is always positive, and is added or subtracted accordingly.
+%
+% Tests: \until is evaluated at the end of the loop body; \while
+% at the beginning of the loop body.
+%
+% Exit from middle of loop: \breakrepeat
+% use this at any place in the loop; in case of a conditional, use
+% \ifsomething ... \expandafter \breakrepeat \fi
+%
+% There are some examples at the end of this file, after the \endinput line.
+%
+% Technical details:
+% The loop body is not executed in a group: the braces are those
+% of a token list.
+% The `for' variable is \let to a \count register.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% revision history:
+% 0.9 first release, January 1999
+% 0.91 documentation update,
+% csarg-like control sequences made REP...
+% counter update made global in case the body issues grouping,
+% copyright notice, February 1999
+% 0.92 installed trace switches, eliminated unwanted space caused by
+% "\for{ijk} \do{...}"
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+
+%%
+%% Prevent multiple loading of this file
+%%
+\expandafter\ifx\csname REPdepth\endcsname\relax
+ \message{Loading loop macro, version 0.92}%
+\else \endinput \fi
+
+%%
+%% Auxiliary stuff
+%%
+\def\REPcsarg#1#2{\expandafter#1\csname#2\endcsname}
+\def\REPcsrom#1{\csname #1\romannumeral\REPdepth\endcsname}
+\def\REPcsargrom#1#2{\expandafter#1\csname#2\romannumeral\REPdepth\endcsname}
+%\def\cscsarg#1#2#3{\expandafter#1\expandafter#2\csname#3\endcsname}
+%\def\REPcsREPcsargrom#1#2#3{\expandafter#1\expandafter#2%
+% \csname#3\romannumeral\REPdepth\endcsname}
+
+\newcount\REPdepth
+\let\endrepeat\relax \def\csprotect{}
+% Trace switches may later be defined by PAC_utils
+\let\REPtraceinit\relax \let\REPtraceexit\relax
+
+%%
+%% Main repeat macro
+%% - go to next level and allocate unique counter/toks if this is the
+%% first time we visit this level
+%% - setup: gather bounds and termination conditions
+%% - scoop up body in token list; after the assignment define and
+%% execute body
+%%
+\def\repeat#1\do{
+ \REPtraceinit % exit in \breakrepeat
+ \advance\REPdepth by 1\relax
+ \REPcsargrom\ifx{REPcount}\relax
+ \REPcsargrom{\csname newcount\expandafter\endcsname}{REPcount}%
+ \REPcsargrom{\csname newtoks\expandafter\endcsname}{REPtoks}%
+ \REPcsargrom{\csname newtoks\expandafter\endcsname}{REPwtest}%
+ \REPcsargrom{\csname newtoks\expandafter\endcsname}{REPutest}%
+ \fi \REPzero \def\REPsign{}\def\REPcomp{>}\REPsetup{#1}%
+ \edef\REPtmp
+ {\def\REPcsargrom\noexpand{REPrepeat}{\REPcsargrom\noexpand{REPbody}}}\REPtmp
+ \afterassignment\REPdxbody\REPcsrom{REPtoks}}
+%%
+%% Define and execute loop body
+%% This is done with an \edef to construct the actual sequence
+%%
+\def\REPdxbody{\REPcsargrom\edef{REPbody}{%
+ \REPcsargrom\the{REPwtest}%
+ \noexpand\the\REPcsargrom\noexpand{REPtoks}%
+ \REPcsargrom\the{REPutest}%
+ \global\REPcsargrom\advance{REPcount} by \REPsign\REPcsrom{REPinc}\relax%
+ \noexpand\endrepeat
+ \REPcsargrom\noexpand{REPrepeat}}%
+ \REPcsrom{REPbody}}
+%%
+%% Stop test
+%% In order to stop, issue a
+%% \breakrepeat which scoops up the rest of the body and exits
+%%
+\def\breakrepeat#1\endrepeat{\REPzero\REPcsargrom\let{REPrepeat}\relax
+ \advance\REPdepth by -1 \REPtraceexit
+ }
+%%
+%% Setup
+%% gather bounds and termination conditions
+%%
+\def\REPsetup#1{%
+ \begingroup
+ \def\for##1 {\edef\REPtmp{%
+ \global\let\REPcsarg\noexpand{##1}\REPcsrom{REPcount}}\REPtmp}%
+ \def\from##1 {\REPcsargrom\global{REPcount}##1\relax}%
+ \def\to##1 {\edef\REPtmp{\global\REPcsargrom\noexpand{REPwtest}=
+ {\REPcsargrom\the{REPwtest}%
+ \noexpand\ifnum\REPcsargrom\noexpand{REPcount}\REPcomp##1\relax
+ \noexpand\expandafter \noexpand\breakrepeat \noexpand\fi}}\REPtmp}%
+ \def\downto##1 {\gdef\REPsign{-}\gdef\REPcomp{<}\to{##1}}%
+ \def\by##1 {\ifnum##1<0 \message{REPEAT: increment has to be >0}%
+ \REPcsargrom\gdef{REPinc}{-##1}\else
+ \REPcsargrom\gdef{REPinc}{##1}\fi}
+ \def\until##1 {\edef\REPtmp{\global\REPcsargrom\noexpand{REPutest}=
+ {\noexpand##1\relax
+ \noexpand\expandafter \noexpand\breakrepeat \noexpand\fi}}\REPtmp}%
+ \def\while##1 {\edef\REPtmp{\global\REPcsargrom\noexpand{REPwtest}=
+ {\noexpand##1\relax \noexpand\else
+ \noexpand\expandafter \noexpand\breakrepeat \noexpand\fi}}\REPtmp}%
+ \from{1} \by{1} #1%
+ \endgroup}
+\def\REPzero
+ {\REPcsrom{REPtoks}{}\REPcsrom{REPutest}{}\REPcsrom{REPwtest}{}%
+ \REPcsargrom\def{REPbody}{}}
+
+\endinput
+
+%\tracingmacros2
+\repeat \for{i} \by{2} \do {
+ \ifnum\i=13 \expandafter\breakrepeat \fi
+ \message{doing \number\i}
+}
+
+\repeat \for{iii} \to{8} \do {}
+\message{After loop: \number\iii}
+
+\repeat \for{i} \from{10} \by{2} \downto{0} \do {
+ \message{countdown \number\i}
+}
+
+\repeat \for{x} \while{\ifnum\x<7} \do {
+ \message{going \number\x}
+}
+
+\repeat \to{3} \do {
+ \message{hello there!}
+}
+
+\newcount\tmpcount
+\repeat \for{j}
+ \until{\tmpcount\j \divide\tmpcount by 37 \noexpand\ifnum\tmpcount=1}
+ \do {
+ \message{testing \number\j}
+}
+
+\repeat \for{i} \by{2} \to{10} \do
+ {\repeat \for{j} \from{\i} \by{3} \to{18} \do
+ {\message{(\number\i.\number\j)}
+ }}
+
+% infinite loop
+%\repeat \do {}
+
+\bye