r3tex

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

control.tex (2361B)


      1 % The classical Plain TeX \loop macro (approximately).
      2 % Needs grouping to be nested.
      3 \def\loop#1\repeat{\def\@body{#1}\@iterate}
      4 \let\repeat=\fi
      5 \def\@iterate{\@body\ea\@iterate\fi}
      6 
      7 % Loops that can be nested use this stack.
      8 \newqueue\@ctrlstack
      9 
     10 \newcount\@forcnt
     11 \newcount\@forlim
     12 \newcount\@forstep
     13 \def\fornum#1=#2..#3\do{\fornumstep#1=#2..#3:1\do}
     14 \def\fornumstep#1=#2..#3:#4\do#{%
     15 	\@forsave
     16 	\@forcnt=\numexpr#2\relax
     17 	\@forlim=\numexpr#3\relax
     18 	\@forstep=\numexpr#4\relax
     19 	\@forstart{#1}%
     20 }
     21 \def\@forstart#1#2{%
     22 	\def\@body{\edef#1{\the\@forcnt}#2}%
     23 	\@forloop
     24 	\@forrestore
     25 }
     26 \def\@forloop{%
     27 	\ifnum\@forcnt \ifnum\@forstep<0 >\else <\fi \@forlim
     28 		\@body
     29 		\advance\@forcnt\@forstep
     30 		\ea\@forloop
     31 	\fi
     32 }
     33 \def\@forsave{%
     34 	\let\qtok=\@body \pushtok\@ctrlstack
     35 	\qnum=\@forcnt \pushnum\@ctrlstack
     36 	\qnum=\@forlim \pushnum\@ctrlstack
     37 	\qnum=\@forstep \pushnum\@ctrlstack
     38 }
     39 \def\@forrestore{%
     40 	\popnum\@ctrlstack \@forstep=\qnum
     41 	\popnum\@ctrlstack \@forlim=\qnum
     42 	\popnum\@ctrlstack \@forcnt=\qnum
     43 	\poptok\@ctrlstack \let\@body=\qtok
     44 }
     45 
     46 \def\foreach#1\do#2#{\@foreachA{#1}{#2}}
     47 \def\@foreachA#1#2#3{%
     48 	\let\qtok=\@body \pushtok\@ctrlstack
     49 	\gdef\@body#2{#3\futurelet\@next\@foreachB}%
     50 	\@body#1\@foreachend
     51 	\poptok\@ctrlstack \let\@body=\qtok
     52 }
     53 \def\@foreachB{\ifx\@next\@foreachend \ea\selectx \else \ea\@body \fi}
     54 \def\@foreachend{\errmessage{this can not happen}}
     55 
     56 \newcount\swnum
     57 \def\switchnum#1#{%
     58 	\qnum=\sqnum \pushnum\@ctrlstack \swnum=\numexpr#1\relax
     59 	\let\qtok=\case \pushtok\@ctrlstack \let\case=\@casenum 
     60 	\@fallthroughfalse \@switchnum
     61 }
     62 \def\@switchnum#1{#1\@endswitch \popnum\@ctrlstack \swnum=\qnum}
     63 \def\@casenum#1#{%
     64 	\if@fallthrough
     65 		\ea\@case
     66 	\else\ifnum\swnum=\numexpr#1\relax
     67 		\ea\ea\ea\@case
     68 	\else
     69 		\ea\ea\ea\selectx
     70 	\fi\fi
     71 }
     72 
     73 \newdimen\swdim
     74 \def\switchdim#1#{%
     75 	\qdim=\swdim \pushdim\@ctrlstack \swdim=\dimexpr#1\relax
     76 	\let\qtok=\case \pushtok\@ctrlstack \let\case=\@casedim 
     77 	\@fallthroughfalse \@switchdim
     78 }
     79 \def\@switchdim#1{#1\@endswitch \popdim\@ctrlstack \swdim=\qdim}
     80 \def\@casedim#1#{%
     81 	\if@fallthrough
     82 		\ea\@case
     83 	\else\ifdim\swdim=\dimexpr#1\relax
     84 		\ea\ea\ea\@case
     85 	\else
     86 		\ea\ea\ea\selectx
     87 	\fi\fi
     88 }
     89 
     90 \newif\if@fallthrough
     91 \def\@endswitch{\poptok\@ctrlstack \let\case=\qtok}
     92 \def\fallthrough{\@fallthroughtrue}
     93 \def\@case#1#2\@endswitch{\@fallthroughfalse#1\if@fallthrough#2\fi\@endswitch}
     94 
     95 \endinput