r3tex

custom LuaTeX format
git clone git://git.rr3.xyz/r3tex
Log | Files | Refs | README | LICENSE

commit 759bae6da6c075507d0b9fe057afebd0935db12a
parent 15284bb24903877a83ad34a7884fef6caa6fb650
Author: robert <robertrussell.72001@gmail.com>
Date:   Sun, 10 Oct 2021 17:19:50 -0700

Improve \fornum; add \foreach and \loop...\repeat

Diffstat:
Mloop.tex | 70+++++++++++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 47 insertions(+), 23 deletions(-)

diff --git a/loop.tex b/loop.tex @@ -1,29 +1,53 @@ -\newstack\forstack -\newcount\forcnt -\newcount\formax -\long\def\fornum#1=#2..#3#4\do#5{% - \forsave - \def\forbody{\edef#1{\the\forcnt}#5}% - \forcnt=#2\relax \formax#3#4\relax - \ifnum\forcnt<\formax \forincr \else \fordecr \fi - \if=#3\forbody\fi % One more iteration if equals sign present. - \forrestore +% TODO: make loops expandable with immediateassign{ment,ed}? + +% The classical Plain TeX \loop macro (approximately). +% Needs grouping to be nested. +\def\loop#1\repeat{\def\@body{#1}\@iterate} +\let\repeat=\fi +\def\@iterate{\@body\ea\@iterate\fi} + +% Loops that can be nested use this stack. +\newstack\@loopstack + +\newcount\@forcnt +\newcount\@forlim +\newcount\@forstep +\long\def\fornum#1=#2..#3\do{\fornumstep#1=#2..#3:1\do} +\long\def\fornumstep#1=#2..#3:#4\do#5{% + \@forsave + \def\@body{\edef#1{\the\@forcnt}#5}% + \@forcnt=\numexpr#2\relax + \@forlim=\numexpr#3\relax + \@forstep=\numexpr#4\relax + \@forloop + \@forrestore } -\def\forincr{\ifnum\forcnt<\formax \forbody \incr\forcnt \ea\forincr \fi} -\def\fordecr{\ifnum\forcnt>\formax \forbody \decr\forcnt \ea\fordecr \fi} -\def\forsave{% - \pushtok\forstack\forbody - \pushcount\forstack\forcnt - \pushcount\forstack\formax +\def\@forloop{% + \ifnum\@forcnt \ifnum\@forstep<0>\else<\fi \@forlim + \@body \advance\@forcnt\@forstep \ea\@forloop + \fi } -\def\forrestore{% - \popcount\forstack \formax=\pcount - \popcount\forstack \forcnt=\pcount - \poptok\forstack \let\forbody=\ptok +\def\@forsave{% + \pushtok\@loopstack\@body + \pushcount\@loopstack\@forcnt + \pushcount\@loopstack\@forlim + \pushcount\@loopstack\@forstep +} +\def\@forrestore{% + \popcount\@loopstack \@forstep=\pcount + \popcount\@loopstack \@forlim=\pcount + \popcount\@loopstack \@forcnt=\pcount + \poptok\@loopstack \let\@body=\ptok } -% TODO: make fornum expandable with immediateassign{ment,ed}; need LuaTeX update -% TODO: loop ... repeat -% TODO: foreach +\def\foreach#1\do#2#{\@foreachA{#1}{#2}} +\def\@foreachA#1#2#3{% + \pushtok\@loopstack\@body + \long\gdef\@body#2{#3\futurelet\@next\@foreachB}% + \@body#1\@foreachend + \poptok\@loopstack \let\@body=\ptok +} +\def\@foreachB{\ifx\@next\@foreachend \ea\selectx \else \ea\@body \fi} +\def\@foreachend{\errmessage{this can not happen}} \endinput