summaryrefslogtreecommitdiff
path: root/graphics/circuit_macros/examples/FlowchartDefs.m4
blob: 2e5c3ade9e7411d4a952bc5bf84e4fd1f6fc0ade (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
divert(-1)
  Google flowchart display symbol
  FlowchartDefs.m4
                                `Some experimental flow-chart macros.  
                                In the following, every block (subchart) is
                                in [] brackets, with .N, .S, .E and .W
                                internally defined.  Follow this convention
                                if you create compound constructs.

                                Generally, the first argument is one
                                or more strings; the second adjusts
                                the size, and the third can be used
                                to add color, dashed lines, labels,
                                or other embellishements.  Default is
                                grey fill if arg3 is blank.

                                These macros have been renamed from earlier
                                versions because of slight differences of
                                arguments.'

define(`FlowchartDefs_')

                               `Default sizes:'
define(`fboxwid',linewid*2)
define(`fboxht',linewid*0.75)
define(`farrowht',linewid*0.5)

                               `Fbox( "text", wid expr ht expr, attributes )
                                The basic task box: arg1 may be 1 or more
                                text strings. Attributes include box
                                line and fill specs.  To adjust the box
                                size to the size of the typeset text, see
                                the \boxdims macro in the manual. Example:
                                Fbox("$x < 1$",,
                                     shaded rgbstring(0.46,0.53,0.63))'
define(`Fbox',`[ boxwid = fboxwid; boxht = fboxht
 Box: box `$2' ifelse(`$3',,`fill_(fillval)',`$3') `$1'
  N: Box.n; S:Box.s; E:Box.e; W: Box.w
 `$4']')

                               `Fdelay("text",wid expr ht expr,attributes)'
define(`Fdelay',`[ boxwid = fboxwid; boxht = fboxht
  Box: box invis `$2'
  N: Box.n; S: Box.s; E: Box.e; W: Box.w
  arc from Box.se-(Box.ht/2,0) to Box.ne-(Box.ht/2,0) \
    with .c at Box.e-(Box.ht/2,0) `$3'
  line to Box.nw to Box.sw to Box.se-(Box.ht/2,0) `$3'
  ifelse(`$1',,,`$1' at Box)
 `$4']')

                               `Fdisplay("text",wid expr ht expr,attributes)'
define(`Fdisplay',`[ boxwid = fboxwid; boxht = fboxht
  Box: box invis `$2'
  N: Box.n; S: Box.s; E: Box.e; W: Box.w
  NE: Box.ne-(Box.ht/4,0); SE: (NE,Box.s)
  NW: Box.nw+(Box.ht/2,0); SW: (NW,Box.s)
  ifelse(`$3',,,`
  box wid NE.x-NW.x ht Box.ht with .ne at NE `$3' invis
    line from W to NW then to SW then to W `$3' invis ')
  arc from SE to NE with .c at E-(Box.ht*2/3,0) `$3'
  line to NW `$3'
  arc from NW to W with .c at (NW,Box)+(Box.ht/4,-Box.ht/4) `$3'
  arc from W to SW with .c at (NW,Box)+(Box.ht/4,Box.ht/4) `$3'
  line to SE `$3'
  ifelse(`$1',,,`$1' at Box)
 `$4']')

                               `Fstored("text",wid expr ht expr,attributes)'
define(`Fstored',`[ boxwid = fboxwid; boxht = fboxht
  Box: box invis `$2'
  r = Box.ht*7/8; d = r - sqrt(r^2-(Box.ht/2)^2)
  N: Box.n; S: Box.s; E: Box.e-(d,0); W: Box.w
  NW: Box.nw+(d,0); SW: (NW,Box.s); NE: Box.ne; SE: Box.se
  ifelse(`$3',,,`
    box wid NE.x-NW.x ht Box.ht with .nw at NW `$3' invis ')
  arc from NW to SW with .c at Box.w+(r,0) `$3'; round
  line to SE; round
  arc cw to NE with .c at E+(r,0) fill_(1); round
  line to NW `$3'; round
  ifelse(`$1',,,`$1' at Box)
 `$4']')

                               `Fconnect("text",
                                  wid expr ht expr[:U|D|L|R|angle], attributes)'
define(`Fconnect',`[ boxht = fboxht; boxwid = boxht
  define(`m4wh',`m4Leftstr(`$2')')dnl
  define(`m4wid',`patsubst(patsubst(m4wh, ht .*),^wid ,)')dnl
  ifelse(m4wid,,`define(`m4wid',boxwid)')dnl
  define(`m4ht',`patsubst(m4wh,.* *ht *,)')dnl
  ifelse(m4ht,,`define(`m4ht',boxht)')dnl
  define(`m4cpt',`m4Rightstr(`$2')')dnl
  setdir_(ifelse(m4cpt,,`ifdef(`m4a_',rp_ang*rtod_,0)',m4cpt))
# {Box: [lbox(m4wid,m4ht,invis)]}
  W: Here; NW: vec_(0,m4ht/2); N: vec_(m4wid/2,m4ht/2); NE: vec_(m4wid,m4ht/2)
  SW: vec_(0,-m4ht/2); S: vec_(m4wid/2,-m4ht/2); SE: vec_(m4wid,-m4ht/2)
  E: vec_(m4wid,0); C: 3/8 between W and E
  line from 1/2 between NW and N \
    to NW to SW to S to E to N to 1/2 between NW and N `$3'
  ifelse(`$1',,,`$1' at C)
 `$4'; resetdir_ ]')

                               `Fdata("text",wid expr ht expr,
                                  xslant,attributes)'
define(`Fdata',`[ boxwid = fboxwid; boxht = fboxht
  Box: box invis `$2'
  xs = ifelse(`$3',,fboxht/6,`($3)/2')
  NE: Box.ne+(xs,0); SE: Box.se-(xs,0)
  NW: Box.nw+(xs,0); SW: Box.sw-(xs,0)
  N: Box.n; E: Box.e; S: Box.s; W: Box.w
  line from N to NE then to SE then to SW then to NW then to N \
    ifelse(`$4',,`fill_(fillval)',`$4')
  ifelse(`$1',,,`$1' at Box)
  `$5']')

                               `Fprep("text",wid expr ht expr,attributes)'
define(`Fprep',`[ boxwid = fboxwid; boxht = fboxht
  Box: box invis `$2'
  NE: Box.ne-(fboxht/4,0); E: Box.e; SE: (NE,Box.s); N: Box.n
  NW: Box.nw+(fboxht/4,0); W: Box.w; SW: (NW,Box.s); S: Box.s
  line from N to NE to E to SE to SW to W to NW to N \
    ifelse(`$3',,`fill_(fillval)',`$3')
  ifelse(`$1',,,`$1' at Box)
  `$4']')

                               `Fkeyboard("text",wid expr ht expr,attributes)'
define(`Fkeyboard',`[ boxwid = fboxwid; boxht = fboxht
  Box: box invis `$2'
  NW: Box.nw-(0,min(Box.ht/4,Box.wid/16)); W: Box.w; SW: Box.sw; S: Box.s
  NE: Box.ne+(0,min(Box.ht/4,Box.wid/16)); E: Box.e; SE: Box.se; N: 0.5 between NW and NE
  line from N to NE to SE to SW to NW to N ifelse(`$3',,`fill_(fillval)',`$3')
  ifelse(`$1',,,`$1' at Box)
  `$4']')

                               `Fdocument("text",wid expr ht expr,attributes)'
define(`Fdocument',`[ boxwid = fboxwid; boxht = fboxht
  Box: box invis `$2'; Q: move from Box.sw to Box.se
  NE: Box.ne; E: Box.e; SE: Box.se-(0,Box.ht/4); N: Box.n
  NW: Box.nw; W: Box.w; SW: Box.sw-(0,Box.ht/4); S: Box.s-(0,Box.ht/4)
  line from SE to NE to NW to SW `$3'
  arc to S with .c at (0.5 between SW and S) + (0,Box.ht) `$3'
  arc to SE with .c at (0.5 between S and SE) -(0,Box.ht) cw \
    ifelse(`$3',,,``$3' shaded rgbstring(1,1,1)')
  ifelse(`$1',,,`$1' at Box)
  `$4']')

                               `Fkeying("text",wid expr ht expr,attributes)'
define(`Fkeying',`[ boxwid = fboxwid; boxht = fboxht
  Box: box `$2' invis
  hsq = (Box.wid/2)^2-(Box.ht/2)^2
  if hsq > 0 then { d = Box.wid/2-sqrt(hsq) } else { d = 0 }
  W: Box.w; NW: Box.nw+(d,0); N: Box.n; NE: Box.ne-(d,0)
  E: Box.e; SE: Box.se-(d,0); S: Box.s; SW: Box.sw+(d,0)
  if hsq >= 0 then { x = 0 } else { x = sqrt(-hsq) }
  box wid NE.x-NW.x ht N.y-S.y `$3' invis at Box
  arc from SE to NE with .c at Box - (x,0) `$3'; round(,,`$3')
  line to NW `$3'; round(,,`$3')
  arc to SW with .c at Box + (x,0) `$3'; round(,,`$3')
  line to SE `$3'; round(,,`$3')
  ifelse(`$1',,,`$1' at Box)
  `$4']')

                               `If-then
                                Ftest( "text", wid expr ht expr, attributes )'
define(`Ftest',`[boxwid = fboxwid*0.8; boxht = fboxht*1.4
 Box: box ifelse(`$2',,,`$2') invis
 N: Box.n; S: Box.s; E: Box.e; W: Box.w 
 line from 0.5 between last box.n and last box.e to last box.e to last box.s \
  to last box.w to last box.n to 0.5 between last box.n and last box.e \
  ifelse(`$3',,`fill_(fillval)',`$3')
  ifelse(`$1',,,`$1' at Box)
 `$4']')

                               `Fcase: case statement
                                Fcase(wid expr ht expr,
                                  "Test string 1"[:attributes],task, ...,
                                  "Test string n"[:attributes],task )'
                               `arg1 adjusts the size of the tests
                                The optional attributes for each string apply
                                to the Ftest containing the string.
                                The Ftest blocks are labeled Test1, Test2, ...
                                A task is a flow subchart with internal
                                names .E and .S defined. The tasks are
                                labeled Task1, Task2, ...  '
define(`Fcase',`[ down; S: Here; sx = S.x
  Fcaseloop_(1,$@)
  ifelse(`$2',,`E:S; W:S; N:S',
   `E:(sx+linewid/2,Task1.E.y); W:Test1.W; N:Test1.N')
  Fcasearrow_(1,$@)
  arrow from E to (E,S) then to S ]')

  define(`Fcaseloop_',`ifelse(`$3',,,
   `Test`$1': Ftest(patsubst(`$3',":.*,"),`$2',
      ifinstr(`$3',":,`patsubst(`$3',.*":,)')) with .N at S
    Task`$1': `$4' with .nw at Test`$1'.E+(linewid/2,min(Test`$1'.ht,fboxht)/2)
      arrow right linewid/4 from Test`$1'.E \
        then down Test`$1'.E.y-Task`$1'.W.y then to Task`$1'.W
    S: (Test`$1'.S.x,min(Test`$1'.S.y,Task`$1'.S.y)-linewid/3)
      ifelse(`$5',,`line',`arrow') from Test`$1'.S to S
      sx = max(sx,Task`$1'.E.x)
      Fcaseloop_(incr($1),`$2',shift(shift(shift(shift($@)))))')')
  define(`Fcasearrow_',`ifelse(`$3',,,
   `arrow from Task`$1'.E to (E,Task`$1'.E)
    Fcasearrow_(incr($1),,shift(shift(shift(shift($@)))))')')
  
                               `while statement with explicit test
                                Fwhiledo("test text", wid x ht y,
                                          attributes, task spec )
                                The task structure is given label Task '
define(`Fwhiledo',`[ down
  Test: Ftest(`$1',`$2',`$3')
    arrow right linewid/2 from Test.E
  Task: `$4' with .W at Here
  E: Task.E; W: Test.w; S: Test.S
    arrow up max(linewid/4,Test.n.y-Task.n.y+arrowht*1.5) \
      from Task.N then left Task.x-Test.x
  N: Here
    arrow to Test.n
 `$5']')

                               `repeat statement with explicit test
                                Frepeatuntil("test",wid x ht y,
                                              attributes, task spec )
                                The task structure is given label Task '
define(`Frepeatuntil',`[ N: Here
  Task: ifelse(`$4',,Here,`$4' with .N at N)
  W: Task.W
    arrow from Task.S down linewid/3
  Test: Ftest(`$1',`$2',`$3')
  E: Task.E+(linewid/2+max(0,Test.e.x-Task.e.x),0)
    arrow from Test.e to (E,Test) then to E then to Task.E
  S: Test.S
 `$5']')

                               `if-then-else
                                Fifthenelse( "test", wid x ht y, attributes,
                                              left tasks, right tasks)
                                The left task structure is given label
                                Ltask and the right task structure is
                                given label Rtask '
define(`Fifthenelse',`[ Test: Ftest(`$1',`$2',`$3')
  N: Test.N
  Ltask: ifelse(`$4',,`Test.S; W:Test.W; LS:Ltask',
      `$4 with .ne at ((Test.W.x+Test.x)/2,Test.S.y)
    W: Ltask.W; LS:Ltask.S
    arrow from Test.W to (Ltask.N,Test.W) then to Ltask.N')
  Rtask: ifelse(`$5',,`Test.S; E:Test.E; RS:Rtask',
      `$5 with .nw at ((Test.E.x+Test.x)/2,Test.S.y)
    E: Rtask.E; RS: Rtask.S
    arrow from Test.E to (Rtask.N,Test.E) then to Rtask.N')
  S: (Test.x,min(LS.y,RS.y)-linewid/3)
    arrow from LS to (LS,S)
    arrow from RS to (RS,S)
    line to (LS,Here)
  `$6']')
divert(0)dnl