% Flow.m4 divert(-1) `Some experimental flow-chart macros. Every subchart is in [] brackets, with .N, .S, .E and .W internally defined. Follow this convention if you define compound constructs.' `Default sizes:' define(`fboxwid',linewid*2) define(`fboxht',linewid*0.75) define(`farrowht',linewid*0.5) `The basic task box: fbox( "contents", [wid x ht y] ) The first argument is the text string, the second is an optional size specification. To adjust the box size to the size of the typeset text, see the discussion of the \boxdims macro in the manual.' define(`fbox',`[B:box ifelse(`$2',,`wid fboxwid ht fboxht',`$2') \ fill_(fillval) `$1' N: B.n; S:B.s; E:B.e; W: B.w ]') `If-then ftest( "test text", [wid x ht y] )' define(`ftest',`[B:box ifelse(`$2',,`wid fboxwid*0.8 ht fboxht*1.2',`$2') invis N: B.n; S: B.s; E: B.e; W: B.w shade(fillval,line from 0.5 between last box.n and last box.e \ to last box.e then to last box.s then to last box.w then to last box.n \ then to 0.5 between last box.n and last box.e) ifelse(`$1',,,`$1' at B) ]') `case statement fcase([wid x ht y (of tests)], "Test 1","task 1", ..., "Test n","task n")' define(`fcase',`[ down; S: Here; xe = S.x fcaseloop_(1,$@) ifelse(`$2',,`E:S; W:S; N:S',`E:(xe+linewid/2,B1.E.y); W:T1.W; N:T1.N') fcasearrow_(1,$@) arrow from E to (E,S) then to S ]') define(`fcaseloop_',`ifelse(`$3',,, `T`$1': ftest(`$3',`$2') with .N at S B`$1': `$4' with .nw at T`$1'.E+(linewid/2,min(T`$1'.ht,fboxht)/2) arrow right linewid/4 from T`$1'.E then down T`$1'.E.y-B`$1'.W.y \ then to B`$1'.W S: (T`$1'.S.x,min(T`$1'.S.y,B`$1'.S.y)-linewid/3) ifelse(`$5',,`line',`arrow') from T`$1'.S to S xe = max(xe,B`$1'.E.x) fcaseloop_(incr($1),`$2',shift(shift(shift(shift($@)))))')') define(`fcasearrow_',`ifelse(`$3',,, `arrow from B`$1'.E to (E,B`$1'.E) fcasearrow_(incr($1),`$2',shift(shift(shift(shift($@)))))')') `while statement with explicit test fwhiledo("test text", [wid x ht y], "task text", ["T"|"F"] )' define(`fwhiledo',`[ down T: ftest(`$1',`$2') ifelse(`$4',,"T",`$4') above ljust at T.E arrow right linewid/2 from T.E B: `$3' with .W at Here E: B.E; W: T.w; S: T.S arrow up max(linewid/4,T.n.y-B.n.y+arrowht*1.5) from B.N then left B.x-T.x N: Here arrow to T.n ]') `repeat statement with explicit test frepeatuntil("test", [wid x ht y], "task", ["F"|"T"] )' define(`frepeatuntil',`[ N: Here B: `$3' with .N at N W: B.W arrow down linewid/3 T: ftest(`$1',`$2') E: B.E+(linewid/2+max(0,T.e.x-B.e.x),0) arrow from T.e to (E,T) then to E then to B.E ifelse(`$4',,"F",`$4') above ljust at T.e S: T.S ]') `if-then-else fifthenelse( "test", [wid x ht y], [left tasks], [right tasks], ["F"|"left label"], ["T"|"right label"])' define(`fifthenelse',`[ T: ftest(`$1',`$2') N: T.N ifelse(`$5',,"F",`$5') below rjust at T.W ifelse(`$6',,"T",`$6') below ljust at T.E L: ifelse(`$3',,`T.S; W:T.W; LS:L',`$3 with .ne at ((T.W.x+T.x)/2,T.S.y) W: L.W; LS:L.S arrow from T.W to (L.N,T.W) then to L.N') R: ifelse(`$4',,`T.S; E:T.E; RS:R',`$4 with .nw at ((T.E.x+T.x)/2,T.S.y) E: R.E; RS: R.S arrow from T.E to (R.N,T.E) then to R.N') S: (T.x,min(LS.y,RS.y)-linewid/3) arrow from LS to (LS,S) arrow from RS to (RS,S) line to (LS,Here) ]') divert(0)dnl % Here is a test file exercising the above definitions .PS linethick_(1.0) arrowwid = 0.05 arrowht = 0.1 fillval = 0.8 down Case: fcase(, "Case 1",[fbox("Task 1"); W:last [].W; N:last [].N arrow down linewid/3 from last [].S fbox("Task 1.5") with .N at Here; E:last [].E; S:last [].S], "Case 2",fbox("Task 2" "is bigger",wid fboxwid*1.2 ht fboxht*3/2), "Case 3",fbox("Task 3")dnl ) "\sl .N" at Case.N rjust above; "\sl .S" at Case.S rjust below "\sl .E" at Case.E ljust; "\sl .W" at Case.W rjust "\sl Case statement" below at Case.s+(0,-0.2) Whiledo: fwhiledo("$i < n$",,fbox("Task")) with .nw at Case.ne+(0.5,0) "\sl .N" at Whiledo.N rjust; "\sl .S" at Whiledo.S rjust below "\sl .E" at Whiledo.E ljust; "\sl .W" at Whiledo.W rjust "\sl While-do" below at Whiledo.s+(0,-0.2) Repeatuntil: frepeatuntil("$n \geq 5$",,fbox("Task")) \ with .sw at Case.se + (0.5,0.2) "\sl .N" at Repeatuntil.N rjust above; "\sl .S" at Repeatuntil.S rjust below "\sl .E" at Repeatuntil.E ljust; "\sl .W" at Repeatuntil.W rjust "\sl Repeat-until" below at Repeatuntil.s+(0,-0.2) Ifthenelse: fifthenelse("$A