%-------------------------------------------------------------------------- % Created by T.Birnthaler (FAU Erlangen-Nuernberg, IMMD5 (Mustererkennung)) %-------------------------------------------------------------------------- \message{Document Style Option `strukto' Version 2.0, as of 11. November 1989} % % Befehle zum Erzeugen von Struktogrammen: % % Erzeugung: % \begin{struktogramm}{Breite}{Einrueckung} % Anweisungen % \end{struktogramm} % % Breite: % bestimmt die vollstaendige Breite des Struktogramms % % Einrueckung: % bestimmt die Einrueckungsbreite des Koerpers von Schleifenkonstrukten % (der Balken neben IFx-Konstrukten wird halb so breit) % % Masse: (Bedeutung: Defaultwert) % \struktohskip (horiz. Abstand aller Texte zu senkr. Linien: 0.5ex) % % Anweisungen: (duerfen geschachtelt werden !) % \IF[w,w,w]{Bedingung}THEN{Anweisung}ELSE{Anweisung} (Standard: % \IF*[w,w,w]{Bedingung}THEN{Anweisung}ELSE{Anweisung} IF, THEN, ELSE) % % \IFx{Bedingung}THEN{Anweisung}ELSE{Anweisung} % \IFx*{Bedingung}THEN{Anweisung}ELSE{Anweisung} % % \FOR[w]{Zaehler}DO{Anweisung} (Standard: FOR) % \WHILE[w]{Bedingung}DO{Anweisung} (Standard: WHILE) % \REPEAT[w]{Anweisung}UNTIL{Bedingung} (Standard: UNTIL) % \LOOP[w]{Anweisung} (Standard: LOOP) % % \BLOCK{elementare Anweisung} % \BLOCK*{elementare Anweisung} % % Bedingung, Zaehler, elementare Anweisung: % beliebiger Text mit TeX-Kommandos zum Zeilenumbruch, % Schriftartwechsel, ... % (!!! aber keine Struktogrammanweisungen !!!). % % w = Schluesselwort: (optionale(r) Parameter) % ein kurzer Text wie z.B. FOR, F"UR, $\forall$, ..., ersetzt das % jeweilige Standard-Schluesselwort (darf auch leer sein). % % Hinweise: % -- elementare Anweisungen *muessen* in \BLOCK oder \BLOCK* eingeschachtelt % werden, damit sie richtig eingerueckt werden koennen. % -- Bei leerem ELSE-Anweisungsteil (...ELSE{}) wird der ELSE-Teil der % IF-Anweisung nicht erzeugt (er *muss* aber trotzdem angegeben werden). % -- Eine Linie nach dem Schluesselwoertern THEN und ELSE entsteht durch % eine Struktogramm- oder \BLOCK-Anweisung, aber nicht durch \BLOCK*. % % -- Bei der x-Version von IF wird links vom IF-Konstrukt eine schmale % Spalte gezogen (halbe Einrueckbreite). % -- Bei der *-Version von IF und IFx wird ein senkrechter Strich % rechts vom Schluesselwoert IF auf der gleichen Hoehe wie beim % THEN- und ELSE-Teil gezogen, und die IF-, THEN- und ELSE-Teile sind % gleich breit. % -- Bei der *-Version des BLOCK-Kommandos wird links davon keine % Linie gezogen (nur in THEN- und ELSE-Teilen sinnvoll). % % -- Leerzeichen ... % ... am Anfang einer Zeile werden *nicht* beachtet. % ... zwischen Argumenten werden *nicht* beachtet. % ... in Argumenten werden beachtet. % % -- Die Anzahl an Verschachtelungsstufen kann *nicht* beliebig weit % getrieben werden, da TeX irgendwann ueberlauft (die Grenze liegt % etwa bei 6-7 Stufen). %----------------------------------------------------------------------- % interne Boxen \newbox\strukto@keyword@box \newbox\strukto@if@box \newbox\strukto@then@box \newbox\strukto@else@box \newbox\strukto@strut@box \newbox\strukto@box % Masse \newdimen\strukto@width \newdimen\strukto@indent \newdimen\struktohskip \newdimen\strut@height % intern % Linien ohne Dicke \def\strukto@vrule{\vrule\hskip-0.4pt} \def\strukto@hrule{\hrule\vskip-0.4pt} % Standard-Leerraum um Schluesselworte (darf leer sein) \def\strukto@keyword#1{% \hbox{\def\next{#1}% \ifx\next\empty\else \hskip\struktohskip\strut #1\hskip\struktohskip \fi }% } \newenvironment{struktogramm}[2]{% % -- begin of preamble --- \bgroup % \strukto@width=#1 \strukto@indent=#2 % % wegen Beruecksichtigung der Schriftgroesse hier \struktohskip=.5ex \strut@height=\ht\strutbox % % Ausgleich fuer Hoehe 0 von \strukto@vrule \advance\strut@height by 0.4pt \setbox\strukto@strut@box=\hbox{\vrule height \strut@height depth \dp\strutbox width 0pt}% % % Kommandos nur lokal gueltig \def\IF{\STRUKTO@IF}% \def\IFx{\STRUKTO@IFx}% \def\FOR{\STRUKTO@FOR}% \def\WHILE{\STRUKTO@WHILE}% \def\REPEAT{\STRUKTO@REPEAT}% \def\LOOP{\STRUKTO@LOOP}% \def\BLOCK{\STRUKTO@BLOCK}% % \setbox\strukto@box\hbox to \strukto@width \bgroup \@parboxrestore %Standardabsatz-Parameter einschalten \vtop\bgroup \strukto@hrule %oberer Rand }% --- end of preamble --- {% --- begin of postable --- \egroup %vbox beenden \hskip-0.4pt\vrule \egroup %hbox beenden \leavevmode \box\strukto@box \egroup }% --- end of postamble --- % Behandlung von Befehlsvarianten und optionalen Parametern \def\STRUKTO@IF{\@ifstar{\STRUKTO@@IF{}{l}}% {\STRUKTO@@IF{}{}}} \def\STRUKTO@IFx{\@ifstar{\STRUKTO@@IF{x}{l}}% {\STRUKTO@@IF{x}{}}} \def\STRUKTO@@IF#1#2{\@ifnextchar[{\STRUKTO@@@IF{#1}{#2}}% {\STRUKTO@@@IF{#1}{#2}[IF,THEN,ELSE]}} \def\STRUKTO@FOR{\@ifnextchar[{\STRUKTO@GENERAL}% {\STRUKTO@GENERAL[FOR]}} \def\STRUKTO@WHILE{\@ifnextchar[{\STRUKTO@GENERAL}% {\STRUKTO@GENERAL[WHILE]}} \def\STRUKTO@LOOP{\@ifnextchar[{\STRUKTO@@LOOP}% {\STRUKTO@@LOOP[LOOP]}} \def\STRUKTO@@LOOP[#1]{\STRUKTO@GENERAL[#1]{}DO} \def\STRUKTO@REPEAT{\@ifnextchar[{\STRUKTO@@REPEAT}% {\STRUKTO@@REPEAT[UNTIL]}} \def\STRUKTO@BLOCK{\@ifstar{\STRUKTO@@BLOCK{}}% {\STRUKTO@@BLOCK{l}}} % IF-THEN-ELSE-Konstrukt % % |#3 #6 % ---------------- % |#4 #7 % ---------------- % |#5 #8 % ---------------- % x -> Schalter x: schmaler Balken links neben Konstrukt % * -> Schalter l: durchgehende Linie nach IF-Schluesselwort % % 1.Arg: switch x % 2.Arg: switch l % 3.Arg: IF-keyword % 4.Arg: THEN-keyword % 5.Arg: ELSE-keyword % 6.Arg: condition (text) % 7.Arg: then-part (struktogramm) % 8.Arg: else-part (struktogramm) % \long\def\STRUKTO@@@IF#1#2[#3,#4,#5]#6THEN#7ELSE#8{% % % Schluesselwortboxen erzeugen \setbox\strukto@if@box=\strukto@keyword{#3}% \setbox\strukto@then@box=\strukto@keyword{#4}% \setbox\strukto@else@box=\strukto@keyword{#5}% % % laengste der drei Boxen bestimmen \let\strukto@keyword@box=\strukto@if@box \ifdim\wd\strukto@then@box > \wd\strukto@keyword@box \let\strukto@keyword@box=\strukto@then@box \fi \ifdim\wd\strukto@else@box > \wd\strukto@keyword@box \let\strukto@keyword@box=\strukto@else@box \fi % \vtop{% \hsize=\strukto@width \hbox to \strukto@width{% % \def\test{#1}% \if\test x% <-- IF-THEN-ELSE links mit Balken versehen ? \strukto@vrule \hskip.5 \strukto@indent \strukto@vrule \advance\strukto@width by -.5 \strukto@indent \fi % % IF-Teil \vtop{% \hsize=\strukto@width % \hbox to \strukto@width{% \strukto@vrule \copy\strukto@if@box \def\test{#2}% \if\test l% <-- IF-Teil wie THEN- u. ELSE-Teil einruecken ? \hfill \strukto@vrule \advance\strukto@width by -\wd\strukto@keyword@box \else \advance\strukto@width by -\wd\strukto@if@box \fi \hskip\struktohskip % linke Texteinr. \vtop{% \hsize=\strukto@width \advance\hsize by -\struktohskip % linke Texteinr. beruecks. \advance\hsize by -\struktohskip % rechte Texteinr. beruecks. \noindent\copy\strukto@strut@box #6\strut }% \hskip\struktohskip % rechte Texteinr. }% % % THEN-Teil \nointerlineskip \hrule \nointerlineskip \hbox to \strukto@width{% \strukto@vrule % linker Rand \copy\strukto@then@box \hfill \vtop{% \def\test{#2}% \if\test l% <-- THEN-Teil wie IF- u. ELSE-Teil einruecken ? \advance\strukto@width by -\wd\strukto@keyword@box \else \advance\strukto@width by -\wd\strukto@then@box \fi \hsize=\strukto@width #7% }% }% % % ELSE-Teil \def\test{#8}% \ifx\test\empty\else % <-- ELSE-Teil vorhanden ? \nointerlineskip \hrule \nointerlineskip \hbox to \strukto@width{% \strukto@vrule % linker Rand \copy\strukto@else@box \hfill \vtop{% \def\test{#2}% \if\test l% <-- ELSE-Teil wie IF- u. THEN-Teil einruecken ? \advance\strukto@width by -\wd\strukto@keyword@box \else \advance\strukto@width by -\wd\strukto@else@box \fi \hsize=\strukto@width #8% }% }% \fi }% }% \strukto@hrule % unterer Rand }% \nointerlineskip } % FOR-, WHILE-, LOOP-Konstrukt % % |#1 #2 % -------------- % | | #3 % ------------------ % 1.Arg: FOR-keyword % 2.Arg: condition (text) % 3.Arg: body (struktogramm) % \long\def\STRUKTO@GENERAL[#1]#2DO#3{% \vtop{% \hsize=\strukto@width % % FOR-Teil \hbox to \strukto@width{% \strukto@vrule \setbox\strukto@keyword@box=\strukto@keyword{#1}% \copy\strukto@keyword@box \hskip\struktohskip % linke Texteinr. \vtop{% \hsize=\strukto@width \advance\hsize by -\wd\strukto@keyword@box \advance\hsize by -\struktohskip % linke Texteinr. beruecks. \advance\hsize by -\struktohskip % rechte Texteinr. beruecks. \noindent\copy\strukto@strut@box #2\strut }% \hskip\struktohskip % rechte Texteinr. }% \nointerlineskip % % Koerper \hbox to \strukto@width{% \strukto@vrule % linker Rand \hskip\strukto@indent \strukto@vrule % linker Rand (eigentlich ueberfluessig) \vtop{% \advance\strukto@width by -\strukto@indent \hsize=\strukto@width \nointerlineskip \hrule #3% }% }% \strukto@hrule % unterer Rand }% \nointerlineskip } % REPEAT-UNTIL-Konstrukt % % | | #2 % -------------- % |#1 #3 % ------------------ % 1.Arg: UNTIL-keyword % 2.Arg: body (struktogramm) % 3.Arg: condition (text) % \long\def\STRUKTO@@REPEAT[#1]#2UNTIL#3{% \vtop{% \hsize=\strukto@width % % Koerper \hbox to \strukto@width{% \strukto@vrule % linker Rand \hskip\strukto@indent \strukto@vrule % linker Rand (eigentlich ueberfluessig) \vtop{% \advance\strukto@width by -\strukto@indent \hsize=\strukto@width #2% \hrule }% }% \nointerlineskip % % UNTIL-Teil \hbox to \strukto@width{% \strukto@vrule \setbox\strukto@keyword@box=\strukto@keyword{#1}% \copy\strukto@keyword@box \hskip\struktohskip % linke Texteinr. \vtop{% \hsize=\strukto@width \advance\hsize by -\wd\strukto@keyword@box \advance\hsize by -\struktohskip % linke Texteinr. beruecks. \advance\hsize by -\struktohskip % rechte Texteinr. beruecks. \noindent\copy\strukto@strut@box #3\strut }% \hskip\struktohskip % rechte Texteinr. }% \strukto@hrule % unterer Rand }% \nointerlineskip } % | #2 % ---------------- % * -> Schalter l: keine Linie links von Block % % 1.Arg: switch l % 2.Arg: body (text) % \long\def\STRUKTO@@BLOCK#1#2{% \vtop{% \hsize=\strukto@width \hbox to \strukto@width{% \def\test{#1}% \if\test l% <-- linken Rand ziehen ? \strukto@vrule \fi \hskip\struktohskip % linke Texteinr. \vtop{% \hsize=\strukto@width \advance\hsize by -\struktohskip % linke Texteinr. beruecks. \advance\hsize by -\struktohskip % rechte Texteinr. beruecks. \noindent\copy\strukto@strut@box #2\strut }% \hskip\struktohskip % rechte Texteinr. }% \strukto@hrule % unterer Rand }% \nointerlineskip }