%  fchart.tex  -- Version 2.0 -- Copyright (c) 1992 M.Schollmeyer -- 6.12.1992
\message{fchart  -- Version 2.0 -- Copyright (c) 1992 M.Schollmeyer}
%
% 1. Setzt Struktogramme in TeX/LaTeX
%    Aufbau eines Struktogramms:
%
%    \FLOATCHART(<dimen>){<text>}{
%      \S{<text>}
%      \IF(<text>){ <statement> }{ <statement> }
%      \WHILE(<text>){ <statement> }
%      \REPEAT <statement> \UNTIL(<text>)
%      \SWITCH(<text>){\CASE(<text>){ <statement> }\DEFAULT(<text>){ <statement> }}
%      \FOR(<text>){<text>}(<text>){ <statement> }
%      \FOREVER{ <statement> }
%    }
%
%      oder (nur in LaTeX):
%
%    \begin{floatchart}(<dimen>){<text>}
%      <commands>
%    \end{floatchart}
%
%    Folgende Variablen k"onnen extern modifiziert werden:
%    Defaultwerte in eckigen Klammern
%
%    \flnwidth[=.5pt]		   Strichdicke f"ur horizontale und vertikale
%				   Linien
%    \boxskip[=8pt]		   Abstand des Textes von den Linien
%    \boxindent[=20pt]		   Einzug f"ur Verschachtelungen
%    \quality[=200]		   Qualit"at f"ur diagonale Linien (klein=schlecht)
%    \def\fnname{\tt Program \bf } Text f"ur Titelzeile
%    \def\fnvar{\tt VAR \it }	   Text f"ur Variablen-Definitionen
%    \def\fnwhile{\tt While }	   Text f"ur While-Schleife
%    \def\fnuntil{\tt Until }	   Text f"ur While-Until-Schleife
%    \def\fnfor{\tt For }	   Text f"ur For-Next-Schleife
%    \def\fnyes{Yes }		   Text f"ur If-Then-Konstruktion
%    \def\fnno{No }		   Text f"ur If-Then-Konstruktion
%    \fnnotext			   Kein Text f"ur obige Variablen
%    \fndeftext 		   Default Text f"ur obige Variablen
%
%
% 2. Setzt Ablaufpl"ane
%
%    \node<c>{name}<t>{title}{subnodes} -> prints a note
%	 <c> -> optional argument specifying leaders:
%	   <c>=! -> bar
%	   <c>=~ -> serpentine line
%	   <c>=+ -> this one is a refnode
%	 {name} -> name of this note, will be set in angles '<name>'
%	 <t> -> optional character specifying if there is a title
%	   <t>=- -> there is a title
%	 {title} -> title for this node, will be set \hangindended
%	 {subnode} -> optional argument specifying subnodes
%
%    Folgende Variablen k"onnen extern modifiziert werden:
%    Defaultwerte in eckigen Klammern
%
%    \halfnodeindent[=1em]	   Halber Einzug f"ur Unterknoten
%
% 3. Below is a complete list of all commands in 'fchart'
%
% \@ifnextch@r
% \@true
% \@false
% \textch@r
% \@@ifnc
% \@ifundefined
% \b@xwidth
% \flnwidth
% \boxskip
% \boxindent
% \b@xheight
% \quality
% \@frightskip
% \fndeftext
% \fnname
% \fnvar
% \fnwhile
% \fnuntil
% \fnfor
% \fnyes
% \fnno
% \fnnotext
% \floatchart
% \TITLE
% \VAR
% \endfloatchart
% \@statement
% \S
% \FOREVER
% \WHILE
% \REPEAT
% \SWITCH
% \CASE
% \DEFAULT
% \VOID
% \caseslash
% \cross
% \IF
% \@ifthenelse
% \@ifthen
% \FOR
% \@exprht
% \halfnodeindent
% \leaderb@r
% \le@derwr
% \node
% \i@node
% \leaderbar
% \ii@node
% \next
% \iii@node
% \iv@node
% \refnode
% \nodemark
% \newnode
% \expsubn@de
% \killnod@s
% \r@store
% \addton@des
% \killnodes

\catcode`@=11 % Make AT letter

%
% \@ifnextchar t{true}{false}
%     Expands to {true} if the next token is <t>
%		 {false} if the next token is not <t>
%
\def\@ifnextch@r #1#2#3{\def\@true{#2}\def\@false{#3}\let\testch@r#1
  \futurelet\nextch@r\@@ifnc}
\def\@@ifnc{
  \ifx\nextch@r\testch@r\let\@exec\@true
  \else\let\@exec\@false\fi\@exec
}

%  \@ifundefined{NAME}{YES}{NO}
%		     : If \NAME is undefined then it executes YES,
%		       otherwise it executes NO.  More precisely,
%		       true if \NAME either undefined or = \relax.
% taken from \LaTeX
\long\def\@ifundefined#1#2#3{\expandafter\ifx\csname
  #1\endcsname\relax#2\else#3\fi}

\newdimen\b@xwidth		     % Aktuelle Breite der Boxen
\newdimen\flnwidth  \flnwidth=.5pt   % Linienbreite f"ur Boxen
\newdimen\boxskip  \boxskip=8pt      % Rand f"ur Boxen
\newdimen\boxindent  \boxindent=20pt % Einzug f"ur Boxen
\newdimen\b@xheight		     % H"ohe der Boxen (switch--case)
\newcount\quality \quality=200
\newskip\@frightskip \@frightskip=\z@ plus 1fil

\def\fndeftext{
  \gdef\fnname{\tt Program \bf }
  \gdef\fnvar{\tt VAR \it }
  \gdef\fnwhile{{\tt While} }
  \gdef\fnuntil{{\tt Until} }
  \gdef\fnfor{{\tt For} }
  \gdef\fnyes{\tt Yes }
  \gdef\fnno{\tt No }
}
\fndeftext

\def\fnnotext{
  \let\fnname\empty
  \let\fnvar\empty
  \let\fnwhile\empty
  \let\fnuntil\empty
  \let\fnfor\empty
  \let\fnyes\empty
  \let\fnno\empty
}

% Die folgenden Definitionen sind f"ur \LaTeX
%
\def\floatchart(#1)#2{%
  \vbox\bgroup%
    \def\TITLE##1{\fnname ##1}%
    \def\VAR##1{\fnvar ##1}%
    \tolerance10000%
    \hsize=#1 \b@xwidth=#1%
    \parindent\z@%
    \hrule width\b@xwidth height\flnwidth%
    \vrule width\flnwidth%
    \kern-\flnwidth%
    \vbox\bgroup\rightskip=\@frightskip%
      \S{#2}%
}%

\def\endfloatchart{%
    \hfill\egroup%
    \kern -\flnwidth%
    \vrule width\flnwidth%
  \egroup%
}%

% Die folgenden Definitionen sind f"ur \TeX oder \LaTeX
%
\def\FLOATCHART(#1)#2#3{\floatchart(#1){#2}{#3}
  \endfloatchart}


\long\def\@statement#1{\begingroup%
  \advance\b@xwidth by -2\boxskip \advance\b@xwidth by -2\flnwidth%
  \vskip \boxskip%
  \hbox{\hskip \boxskip%
    \vbox{\rightskip=\@frightskip%
      \hsize=\b@xwidth #1%
    }\hskip \boxskip%
  }%
  \vskip \boxskip%
  \endgroup%
  \hrule width\b@xwidth height\flnwidth%
}%
\let\S\@statement%

\def\FOREVER#1{\vskip 3\boxskip plus 1fil%
  \hbox{\hskip\boxindent\vrule width\flnwidth%
    \kern -\flnwidth%
    \vbox{\advance\b@xwidth by -\boxindent%
      \hsize=\b@xwidth%
      \vrule width\b@xwidth height\flnwidth%
      {#1}}%
  }
  \vskip 2\boxskip plus 1fil%
  \vrule width\b@xwidth height\flnwidth%
}%

\def\WHILE(#1)#2{{%
  \advance\b@xwidth by -2\boxskip \advance\b@xwidth by -2\flnwidth%
  \vskip \boxskip%
  \hbox{\hskip \boxskip%
    \vbox{\hsize=\b@xwidth\fnwhile {#1}}\hskip \boxskip}%
    \vskip \boxskip%
  }%
  \nointerlineskip%
  \hbox{\vrule width\boxindent height\flnwidth%
    \vrule width\flnwidth%
    \kern -\flnwidth%
    \vbox{\advance\b@xwidth by -\boxindent%
      \hsize=\b@xwidth%
      \vrule width\b@xwidth height\flnwidth%
      \vskip -\flnwidth%
      \nointerlineskip%
      {#2}%
    }%
  }%
  \nointerlineskip%
}%

\def\REPEAT#1\UNTIL(#2){\begingroup%
  \hbox{\hskip \boxindent%
    \vrule width\flnwidth%
    \kern -\flnwidth%
    \vbox{\advance\b@xwidth by -\boxindent%
      \hsize=\b@xwidth%
      {#1}%
    }%
  }%
  \endgroup\begingroup%
  \advance\b@xwidth by -2\boxskip \advance\b@xwidth by -2\flnwidth%
  \vskip \boxskip plus 1fil%
  \nointerlineskip%
  \hbox{\hskip \boxskip%
    \vbox{%
      \hsize=\b@xwidth\fnuntil #2%
    }%
    \hskip \boxskip%
  }%
  \vskip \boxskip plus 1fil%
  \endgroup%
  \vrule width\b@xwidth height\flnwidth%
}%

\def\SWITCH(#1)#2{\begingroup%
  \advance\b@xwidth by -2\boxskip \advance\b@xwidth by -2\flnwidth%
  \vskip \boxskip plus 1fil%
  \hbox{%
    \hskip \boxskip%
    \vbox{%
      \hsize=\b@xwidth #1%
    }%
    \hskip \boxskip%
  }%
  \vskip \boxskip plus 1fil%
  \endgroup\begingroup%
  \count255=0%
  \def\CASE(##1)##2{\global\advance\count255 by 1}%
  \let\DEFAULT\CASE%
  {#2}\advance\b@xwidth by -\flnwidth%
  \hbox to\b@xwidth{%
    \dimen@=\b@xwidth \divide\dimen@ by\count255%
    \advance\b@xwidth by -\dimen@%
    \caseslash%
  }%
  \nointerlineskip%
  \vskip -1pt%
  \divide\b@xwidth by\count255%
  \hsize=\b@xwidth%
  \def\CASE(##1)##2{\hskip \z@\vbox{\S{##1}}%
    \vrule width\flnwidth\kern-\flnwidth\hskip \z@}%
  \def\DEFAULT(##1)##2{\hskip \z@\vbox{\S{##1}}%
    \hskip \z@}%
  \hbox{\hskip \z@#2}%
  \vskip -1pt%
  \def\CASE(##1)##2{\hskip \z@%
    \vbox{##2}\vrule width\flnwidth\kern-\flnwidth\hskip \z@%
  }%
  \def\DEFAULT(##1)##2{\hskip \z@%
    \vbox{##2}\hskip \z@%
  }%
  \nointerlineskip%
  \let\VOID\cross%
  % maximale H"ohe ermitteln und \b@xheight setzten
  \b@xheight=\z@%
  \setbox0=\hbox{#2}\b@xheight=\ht0%
  % Boxen setzten
  \hbox{\hskip\z@#2\hskip\flnwidth}%
  \nointerlineskip%
  \endgroup%
}%

\def\caseslash{\begingroup%
  \advance\count255 by -1%
  \dimen@i=\z@ \dimen@ii=\boxindent \divide\dimen@ii by\count255%
  \divide\dimen@ii by\quality%
  \advance\count255 by -1%
  \hbox to \b@xwidth{%
    \loop%
      \count254=\quality%
      {\loop%
	\vbox to \boxindent{%
	  \vskip\dimen@i\hrule width\flnwidth height\flnwidth\vss\vfill%
	}%
	\hss\hfill%
	\global\advance\dimen@i by \dimen@ii \advance\count254 by -1%
	\ifnum\count254>0%
      \repeat}%
      \advance\count255 by -1%
      \ifnum\count255>0%
      {\dimen@ii=\boxindent \advance\dimen@ii by -\dimen@i%
	\vbox to \boxindent{%
	  \vskip\dimen@i\hrule width\flnwidth height\dimen@ii\vss\vfill%
	}%
	\hss\hfill%
      }%
    \repeat%
    \hfill%
  }%
  \hbox to\dimen@{%
    \dimen@ii=\boxindent \divide\dimen@ii by\quality%
    \count 254=\quality%
    \dimen@i=\boxindent%
    \loop%
      \vbox to \boxindent{%
	\vskip\dimen@i\hrule width\flnwidth height\flnwidth\vss\vfill%
      }%
      \hss\hfill%
      \advance\dimen@i by -\dimen@ii%
      \advance\count254 by -1%
      \ifnum\count254>0%
    \repeat%
    \hfill%
  }%
  \endgroup%
}%

\def\cross{%
  \ifdim\b@xheight=\z@\else % ignorieren, wenn wir beim scannen sind%
    \baselineskip=\flnwidth%
    \vskip \z@%
    \vbox to \b@xheight{%
      \dimen@=\b@xwidth \advance\dimen@ by -2\flnwidth%
      \count254=\quality \dimen@i=\b@xwidth \divide\dimen@i by\count254%
      \multiply\dimen@i by 2%
      \loop%
	\vskip \z@%
	\hbox to \b@xwidth{%
	  \hfill\vrule height\flnwidth width\flnwidth%
	  \hskip\dimen@ \vrule height\flnwidth width\flnwidth\hfill%
	}%
	\vss%
	\advance\dimen@ by -\dimen@i%
	\advance\count254 by -1%
      \ifnum\count254>0%
      \repeat%
    }%
    \hrule height \flnwidth%
  \fi%
}%

\def\IF(#1)#2{
  \@ifnextch@r \bgroup{\@ifthenelse{#1}{#2}}{\@ifthen{#1}{#2}}}

\def\@ifthenelse#1#2#3{\SWITCH(#1){\CASE(\fnyes){#2}\DEFAULT(\fnno){#3}}}
\def\@ifthen#1#2#3{\SWITCH(#1){\CASE(\fnyes){#2}\DEFAULT(\fnno){\VOID}}}

\def\FOR(#1)#2(#3)#4{\let\fnwhile\fnfor\WHILE(#1 { \tt #2 } #3){#4}}%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% nodes
%
%
% \@exprht -> \skip for titles that span multiple lines
\newdimen\@exprht \@exprht=\z@
% \halfnodeindent -> half of the indentation for subnodes
\newskip\halfnodeindent \halfnodeindent=1em
% \maxnode -> last number for reference node
\newcount\maxnode \maxnode=\z@

% gereral leaders
\def\leaderb@r{\cleaders\hrule width.5pt\vfil}
\def\le@derwr{\cleaders\vbox{\vskip 5.7pt\smash{$\wr$}}\vfil}

% \node<c>{name}<t>{title}{subnodes} -> prints a note
%     <c> -> optional argument specifying leaders:
%	<c>=!  -> bar
%	<c>=~  -> serpentine line
%	<c>+=+ -> this one is a refnode
%     {name} -> name of this note, will be set in angles '<name>'
%		or name of refnode
%     <t> -> optional character specifying if there is a title
%	<t>=- -> there is a title (not for reference nodes)
%     {title} -> title for this node, will be set \hangindent`ed
%     {subnode} -> optional argument specifying subnodes
%
\def\node{\bgroup%
  \parindent\z@ \@exprht=\z@%
  \@ifnextch@r \bgroup{\i@node\space}%
    \i@node}%

% \i@node sets leaders and checks for reference node
%   #1 -> \space if there are no options or the option token
\def\i@node#1{%
  % setup leader bar
  \let\leaderbar\empty \let\next\ref@node%
  \ifx!#1\let\leaderbar\leaderb@r%
    \else\ifx~#1\let\leaderbar\le@derwr%
      \else\ifx+#1\let\next\fref@node%
  \fi\fi\fi%
  \@ifnextch@r +\ref@node{\next\space}}%

\def\fref@node#1{\ref@node+}%

% \ref@node -> checks for refnotes and defnodes
%
\def\ref@node#1#2{%
  \ifx+#1\let\next=\v@node%
    \else\let\next=\ii@node%
  \fi%
  \@ifnextch@r -{\next{#2}}{\next{#2}\space}}%

% \ii@node -> checks for title
%   #1 -> name or subnodes
%   #2 -> '-' if there is a title
\def\ii@node#1#2{%
  \ifx-#2\let\next=\iii@node%
    \else\let\next=\iv@node%
  \fi%
  \next{#1}}%

% \iii@node -> expands notes with title
%   #1 -> name
%   #2 -> title
\def\iii@node#1#2{%
  \vbox\bgroup%
    \setbox0=\vbox{\hangindent 3\halfnodeindent\strut$\langle${#1}%
	$\rangle\longrightarrow$ #2\strut\par}%
    \@exprht=\ht0%
    \vbox{\box0\vskip-\@exprht\vskip 10pt}%
    \advance\@exprht-10pt%
    \@ifnextch@r \bgroup \expsubn@de \skip@title%
}%

% \skip@title -> skips vertical space for node with title but without subnodes
\def\skip@title{%
  \ifdim\@exprht>\z@%
    \hbox to 2\halfnodeindent{\hss\vbox to \@exprht{\leaderbar}\hss}%
  \fi%
  \egroup\egroup%
}%

% \iv@node -> expands ordinary nodes
%   #1 -> name
\def\iv@node#1{%
  \vbox\bgroup%
    \hbox{\strut$\langle${#1}$\rangle$}%
    \@ifnextch@r \bgroup \expsubn@de {\egroup\egroup}}%

% \v@node -> expand a reference node
%   #1 -> name
%   #2 -> ignored
\def\v@node#1#2{%
  \vbox\bgroup%
    \hbox to \tw@\halfnodeindent{\hss\nodemark{#1}\hss}%
    % force \skip below node
    \@exprht=6pt%
    \@ifnextch@r \bgroup \expsubn@de {\expsubn@de{}}}%

% \nodemark -> \bigcirc with argument centered
\def\nodemark#1{%
  \@ifundefined{n@#1}{\newnode{#1}}{}%
  \hbox to 10pt{\rlap{$\bigcirc$}\hfil$\scriptstyle%
  \nodech@r{#1}$\hfil}}%

% \nodech@r -> gets character for a defnode name
%   #1 -> name
\def\nodech@r#1{
  \expandafter\ifcase\csname n@#1\endcsname\nodetable\fi}

\def\nodetable{
  a\or b\or c\or d\or e\or f\or g\or h\or i\or k\or
  l\or m\or n\or o\or p\or q\or r\or s\or t\or u\or
  v\or w\or x\or y\or z\else *}

% \newnode -> creates a command sequence \n@<name> wich is set
%	      to \maxnode++ and adds it to the restore list
%   #1 -> name
\def\newnode#1{%
  \expandafter\xdef\csname n@#1\endcsname{\the\maxnode}%
  \global\advance\maxnode 1%
  \addton@des{n@#1}}%

\def\killnod@s{}%
\def\addton@des#1{\begingroup%
   \let\r@store\relax%
   \xdef\killnod@s{\killnod@s\r@store{#1}}\endgroup}%

\def\killnodes{\begingroup%
  \def\r@store##1{%
    \expandafter\let\csname ##1\endcsname\relax}%
  \killnod@s\xdef\killnodes{}\endgroup\global\maxnode=\z@}%

% \expsubn@de -> expands a subnode
%   #1 -> subnodes
\def\expsubn@de#1{%
  \hbox{%
    \setbox0=\vbox{\advance\hsize -2\halfnodeindent\vskip\@exprht\relax #1}%
    \hbox to 2\halfnodeindent{\hss\vbox to \ht0{\leaderbar}\hss}%
    \box0%
  }%
  \egroup\egroup%
}%

\catcode`@=12 % Make AT other

% end of file fchart.tex
