% ProgMacros.tex of January 11, 1984 5:33 pm --- Stolfi
% Macros for programs
% Uses counters 3 (to compute useful width), 5 (current nesting
% level), and 9 (loop variable to count bars)
% Things to fix:
% Parameters to be defined by user (in pt unless stated otherwise):
% \progwidth = width of program body (excl. left and right indent.)
% \progindent = indentation of outermost bracket
% \proglevelindent = extra indentation per level
% \progstepindent = indentation of step text (exc. step number)
% relative to innermost bracket
% \progcommindent = indentation of comment text rel. innermost bracket
% \progcontindent = extra indentation of continuation lines
% \progthickness = thickness of block brackets
% \progvskip = extra skip between steps (in ex)
% \kwfont = keyword font (say, \def\kwfont{\:V\def\mainfont{\:V}})
% PROGRAM BODY
% Usage:
% \progbody{
% \[procedure Foo\&$(x)$;\]
% \BEGIN
% \[\WHILE $x<0$ do\]
% \BEGIN
% \[$x$ \pgets\ 0\]
% \<At this point either $x\neq\pi$ or $x=\pi$\>
% \[$x$ \← $x + 1$;\]
% \[...\]
% \END
% \END
% }
%
\def\progbody{\chcode'137=13\progprog}
\def\progprog#1{\par
\vskip1.0ex plus0.5ex\penalty-500
{\parskip 0 pt \baselineskip -1pt\lineskip 0pt
\def\←{{$\gets$}}
\def\[##1\]{\progstep{##1}}
\def\<##1\>{\progcomm{##1}}
\def\BEGIN{\progear\progvskip0\advcount5 by 1}
\def\END{\advcount5 by-1\progear0\progvskip}
#1\par}
\chcode'137=12
\vskip1.0ex plus0.5ex\penalty-600}
% Program step. Usage: \progstep{x\𡤀} or \[ x \← 0 \]
\def\progstep#1{
\hbox
{\progvbars
\hskip \progstepindent pt\advcount3 by -\progstepindent
\vbox{
\vskip \progvskip ex
{\standardsize
\hbox par\count3pt{\hangindent\progcontindent pt after1\fx #1}}
\vskip \progvskip ex}
\hfil}}
% Program line number. Usage: \[\psno{3} x \← 0 \]
\def\psno#1{\hfil #1\hfilneg}
% Comment. Usage: \progcomm{Here $x>x+1$.} or \< Here $x>x+1$.\>
\def\progcomm#1{\par
\hbox
{\progvbars
\hskip \progcommindent pt\advcount3 by -\progcommindent
\vbox{
{\small
\vskip \progvskip ex
\hbox par \count3pt{\hangindent\progcontindent pt after1 \it #1}}
\vskip \progvskip ex}
\hfil}}
% COMMON KEYWORDS
% Usage: \[\PROC Foo: \] etc.
\def\PROC{\hbox{\kw procedure} }
\def\IF{\hbox{\kw if} }
\def\THEN{\hbox{\kw then} }
\def\ELSE{\hbox{\kw else} }
\def\FI{\hbox{\kw fi} }
\def\FOR{\hbox{\kw for} }
\def\EACH{\hbox{\kw each} }
\def\WHILE{\hbox{\kw while} }
\def\DO{\hbox{\kw do} }
\def\OD{\hbox{\kw od} }
\def\REPEAT{\hbox{\kw repeat} }
\def\UNTIL{\hbox{\kw until} }
% Proc-to-arg spacer. Usage: \[\PROC Foo\&($x,y$): \IF Bar\&($x$)=0 ... \]
\def\&{{\hskip0.2em}}
% PROGRAM FRAGMENTS IN MATH/TEXT MODE
% Usage:$\prg{x\← x + 1}$
\def\prg#1{\hbox{\def\←{ $\gets$}\fx #1}}
% INTERNAL MACROS
% No user-serviceable parts below.
\def\progear#1#2{\par\penalty1000
\hbox
{\progvbars \hskip\proglevelindent pt\advcount3 by -\proglevelindent
\vbox{\vskip #1 ex
\hrule height \progthickness pt width 0.4em
\vskip #2ex}\hfil}
\penalty1000}
\def\progvbars{
\hskip \progindent pt\setcount3 \progwidth
\advcount3 by -\progindent % to indent right margin too
\repeat{\count5}{\vrule width\progthickness pt
\hskip-\progthickness pt
\hskip\proglevelindent pt\advcount3 by -\proglevelindent}
\hskip-\proglevelindent pt\advcount3 by \proglevelindent}