summaryrefslogtreecommitdiff
path: root/graphics/circuit_macros/examples/svg/SLD.m4
blob: 96f04f723546394b79932d6d61573eeb0a48f041 (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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
divert(-1)

# This section defines *DRAFT* SLD elements with or without attached
# circuit breakers.  Many other elements applicable to SLD drawings are
# already in libcct.m4.  The contributions and suggestions of Benjamin
# Vilmann are acknowledged with thanks.

# Notes for 1-terminal SLD elements:
# Argument 1 is normally the linespec of the stem to set the element direction
#   and length. See also: PtoL defined in libgen.m4.
# For a 0-length stem (which has undefined direction):
#   arg1 can also be U, D, L, R (for up, down, left, right),
#   or a number to set the direction in degrees, optionally followed by
#   `at position' to set the position (Here by default).
#   Zero-length stem examples: sl_box(U), sl_box(45 at Here+(1,0))
# Argument 2 contains semicolon (;)-separated key-value attributes
#   of the element head as applicable: e.g., name=Carol; text="Stop"; lgth=expr 
# If argument 3 is blank then no breaker is drawn.  A non-blank argument 3
#   is C for a default closed breaker in the stem, O for an open breaker,
#   or key-value pairs to specify breaker details.
# The element body (head) can be named with name=. It is overlaid with
#   or contained in a [] block.

# Notes for 2-terminal SLD elements:
# These obey the normal Circuit_macro two-terminal conventions.
# They can be labelled using rlabel() or llabel() as well as directly.
# Argument 2 contains key-value pairs to customize the element body,
#   e.g., name=Name; text="text"; wdth=expr; ...
# Nonblank arguments 3 and 4 put a breaker in the input and output respectively.

# Notes for attached breakers:
# Nonblank arguments 3 and 4 of the two-terminal elements and argument 3 of
#   the 1-terminal elements specify a breaker in the input, output, and stem
#   respectivlely. An O creates a default-size open breaker, and C a closed
#   breaker, otherwise the argument contains key-value pairs to specify the
#   details of the box; e.g., box=dotted 2bp__ shaded "green"

# Notes for composite elements within a [ ] block:
# The SLD current transformer macro sl_ct is composite.
# Internal labels L (for inductor) and terminals Ts, Tc, and Te are defined.

define(`sldlib_')
ifdef(`libcct_',,`include(libcct.m4)divert(-1)')

# Default size parameters.  These can be redefined in a diagram.

define(`brksiz_',`dimen_*3/16')   # Default inline box breaker size
define(`drosiz_',`dimen_/4')      # Default sl_drawout (chevron) size

# One-terminal elements ###################################################

                            `sl_disk( stem linespec, keys, breaker )
                                 keys: name=Name;
                                       text="text";
                                       diam=expr;
                                       circle=circle attributes; eg diam expr'
                                `default breaker name Bd'
define(`sl_disk',
 `sl_eleminit_(`$1')
  setkeys_(`$2',`name::N; circle::N; text::N; diam:dimen_*2/3')dnl
  ifelse(`$3',,
   `ifelse(m4name,,,m4name:) circle diam m4diam \
      at last line.end + vec_(m4diam/2,0) m4circle m4text
    [ box invis wid_ m4diam ht_ m4diam ] at last circle
    line from last line.end  to last line.start',
   `m4br_one(`sl_disk',`$1',`$2',m4brk_(`$3',Bd))') ')

                            `sl_box( stem linespec, keys, breaker )
                                 keys: name=Name; lgth=expr; wdth=expr;
                                       text="text";
                                       box= box attributes; (e.g. shade "red")'
                                `default breaker name Bb'
define(`sl_box',
 `sl_eleminit_(`$1')
  setkeys_(`$2',`name::N; wdth:dimen_*2/3; lgth:dimen_*2/3; box::N; text::N')dnl
  ifelse(`$3',,
   `line from last line.end to last line.start 
    { ifelse(m4name,,,m4name:) [S:Here; lbox(m4lgth,m4wdth,m4box)] \
        with .S at last line.start }
    ifelse(m4text,,,`{m4text at last []}')',
   `m4br_one(`sl_box',`$1',`$2',m4brk_(`$3',Bb))') ')

                            `sl_grid( stem linespec, keys, breaker )
                                 keys: name=Name; lgth=expr; wdth=expr;'
                                `default breaker name Bgr'
define(`sl_grid',
 `sl_eleminit_(`$1')
  setkeys_(`$2',`name::N; wdth:dimen_*4/5; lgth:dimen_*2/3; box::N; text::N')dnl
  ifelse(`$3',,
   `line from last line.end to last line.start 
    { ifelse(m4name,,,m4name:) [S:Here
      { ifelse(m4name,,,m4name:) lbox(m4lgth,m4wdth) }
      { line to rvec_(m4lgth/2, m4wdth/2)
        line to rvec_(m4lgth/2,-m4wdth/2)
        line to rvec_(-m4lgth/2,-m4wdth/2)
        line to rvec_(-m4wdth/2, m4wdth/2) }
      { line from rvec_(0,m4wdth/2) to rvec_(m4lgth,-m4wdth/2) }
      line from rvec_(0,-m4wdth/2) to rvec_(m4lgth,m4wdth/2)
      ] with .S at last line.start } ',
   `m4br_one(`sl_grid',`$1',`$2',m4brk_(`$3',Bgr))') ')

                            `sl_load( stem linespec, keys, breaker )
                                 keys: name=Name; lgth=expr; wdth=expr;
                                       head= arrowhead attributes;'
                                `default breaker name Bl'
define(`sl_load',
 `sl_eleminit_(`$1')
  setkeys_(`$2',`name::N; wdth:dimen_*0.32; lgth:dimen_*0.45; head::N')dnl
  ifelse(`$3',,
   `line from last line.end to last line.start 
    { ifelse(m4name,,,m4name:) [S:Here; line to rvec_(0,m4wdth/2) \
        then to rvec_(m4lgth,0) then to rvec_(0,-m4wdth/2) \
        then to Here m4head ] with .S at last line.start } ',
   `m4br_one(`sl_load',`$1',`$2',m4brk_(`$3',Bl))') ')

                            `sl_meterbox( stem linespec, keys, breaker )
                                  keys: sl_box attributes'
                                `default breaker name Bm'
define(`sl_meterbox',
 `sl_eleminit_(`$1')
  setkeys_(`$2',`name::N; wdth:dimen_*2/3; lgth:dimen_*2/3; box::N; text::N')dnl
  ifelse(`$3',,
   `line from last line.end to last line.start 
    {ifelse(m4name,,,m4name:) [S:Here;
      { B: rotbox( m4lgth, m4wdth, m4box ) with .W at S }
      a = rp_ang*rtod_
      if (abs(a-90) < 45) || (abs(a-180) < 45) || (abs(a+180) < 45) then { 
        C: rvec_(m4lgth*2/5,0)
        line from rvec_(m4lgth*4/5,m4wdth/2) to rvec_(m4lgth*4/5,-m4wdth/2) } \
      else { C: rvec_(m4lgth*3/5,0)
         line from rvec_(m4lgth/5,m4wdth/2) to rvec_(m4lgth/5,-m4wdth/2) }
      ifelse(m4text,,,`m4text at C')
      ] with .S at last line.start}',
   `m4br_one(`sl_meterbox',`$1',`$2',m4brk_(`$3',Bm))') ')

                            `sl_generator( stem linespec, keys, breaker )'
                                `default breaker name Bd'
define(`sl_generator',`sl_disk($@)
  { ACsymbol(at last circle,,,R)
    m4lcd = last circle.diam
    [ box invis wid_ m4lcd ht_ m4lcd ] at last circle } ')

                            `sl_syncmeter( stem linespec, keys, breaker )'
                                `default breaker name Bd'
define(`sl_syncmeter',`sl_disk($@)
  { Syncsymb(at last circle)
    m4lcd = last circle.diam
    [ box invis wid_ m4lcd ht_ m4lcd ] at last circle } ')

                            `sl_lamp( stem linespec, keys, breaker )'
                                `default breaker name Bd'
define(`sl_lamp',`sl_disk($@)
  { line from last circle.ne to last circle.sw
    line from last circle.nw to last circle.se
    m4lcd = last circle.diam
    [ box invis wid_ m4lcd ht_ m4lcd ] at last circle } ')

# One-terminal utilities ##################################################

                            `Syncsymb(at position, rad)
                                Symbol for sync meter'
define(`Syncsymb',`[ define(`m4ssrad',`ifelse(`$2',,(dimen_/4),`($2)')')dnl
 Origin: Here
 {arc <-> ht arrowht/2 wid arrowwid*2/3 \
   from Rect_(m4ssrad,30) to Rect_(m4ssrad,150) with .c at Here}
 line from (0,m4ssrad) to (0,-m4ssrad/2)
 `$3' ] with .Origin ifelse(`$1',,`at Here',`$1')')

                            `m4br_one( `name', stem linespec, body keys,
                               breaker keys )'
                            `Draw the breaker in the stem then the element'
define(`m4br_one',
 `M4_S: last line.start
  setkey_(`$4',lgth,brksiz_)dnl
  line from M4_S to last line.end+vec_(-(m4lgth)*5/2,0)
  sl_breaker(to rvec_(m4lgth,0),`$4')
  $1(to rvec_((m4lgth)*3/2,0),`$3')
  move to M4_S ')

                            `sl_eleminit_(linespec or (for zero length)
                                U|D|L|R|number [at location])'
define(`sl_eleminit_',
 `ifelse(regexp(`$1',^ *[UDLR0123456789]),-1,
   `eleminit_(`$1',dimen_)',
   `pushdef(`M4pos',`ifinstr(`$1',` at ',`patsubst(`$1',^.* at *)')')dnl
    ifelse(M4pos,,,`move to M4pos;') setdir_(patsubst(`$1',` at.*'))
   line invis from Here to Here popdef(`M4pos')')')

# Two-terminal elements ###################################################

                            `sl_transformer(linespec,keys,
                              input breaker keys, output breaker keys)
                             keys:
                               type=I|S
                               (type=I) scale=expr; (default 1.5)
                                        cycles=n; (default 4)
                               (type=S) body=shaded "color";
                               name=Body name;
                               (breaker default names BrI, BrO)'
define(`sl_transformer',
 `setkeys_(`$2',name::N; type:I:N; cycles:4:N; body::N;  scale:1.5:; )dnl
  ifelse(`$3'`$4',,
   `ifinstr(m4type,S,
     `source(`$1',G,,,m4body)',
     `eleminit_(`$1'); m4atmp = rp_ang; m4slen = rp_len
      define(`m4swd',`dimen_*3/16*m4scale')dnl
      { line to rvec_((m4slen-m4swd)/2,0)
        {ifelse(m4name,,SL_box,m4name): [ linewid = linewid*m4scale
          {L1: inductor(to vec_(0,-m4cycles*dimen_/8),,m4cycles)}
          {point_(m4atmp)
           L2: inductor(from vec_(dimen_*3/16,-m4cycles*dimen_/8) \
             to vec_(dimen_*3/16,0),,m4cycles)}
           C2: last line.c; point_(m4atmp) ] with .L1.c at Here}
        line from rvec_(m4swd,0) to rvec_((m4slen+m4swd)/2,0) }
      line invis to rvec_(rp_len,0)') ',
   `m4br_two(`sl_transformer',`$1',`$2',m4brk_(`$3',BrI),m4brk_(`$4',BrO),
      ifelse(`$3',,,I)`'ifelse(`$4',,,O))') ')

                            `Two-terminal box'
                            `sl_ttbox(linespec,keys,breaker keys,breaker keys)
                             keys= lgth=expr; wdth=expr; box=attributes;
                               supp=additional rotbox commands; name=Body name;
                               text="text";
                               (breaker default names BrI, BrO)'
define(`sl_ttbox',
 `setkeys_(`$2',`lgth:dimen_*3/4; wdth:dimen_*3/4;
    name::N; box::N; text::N; supp::N')dnl
  ifelse(`$3'`$4',,
   `eleminit_(`$1')
    {line to rvec_((rp_len-m4lgth)/2,0)
      {ifelse(m4name,,,m4name:)rotbox(m4lgth,m4wdth,m4box,,m4supp) \
        with .W at Here }
      {ifelse(m4text,,,`{m4text at rvec_(m4lgth/2,0)}') }
     line from rvec_(m4lgth,0) to rvec_((rp_len+m4lgth)/2,0)}
    line invis to rvec_(rp_len,0) ',
   `m4br_two(`sl_ttbox',`$1',`$2',m4brk_(`$3',BrI),m4brk_(`$4',BrO),
      ifelse(`$3',,,I)`'ifelse(`$4',,,O))') ')

define(`m4brk_',`ifelse(`$1',,,
  `ifelse(`$1',C,,`$1',O,box=fill 0,`$1')`'ifelse(`$2',,,;name=`$2')')')

                            `sl_rectifier(ttbox args)'
define(`sl_rectifier',
 `sl_ttbox(`$@')
  { line from last [].Line.ne to last [].Line.sw
    AC: ACsymbol(at last [].C+(-m4lgth/6, m4wdth/4),,,R)
    DC: DCsymbol(at 2nd last [].C+( m4lgth/6,-m4wdth/4),,,R) } ')

                            `sl_inverter(ttbox args)'
define(`sl_inverter',
 `sl_ttbox(`$@')
  { line from last [].Line.ne to last [].Line.sw
    DC: DCsymbol(at last [].C+(-m4lgth/6, m4wdth/4),,,R)
    AC: ACsymbol(at 2nd last [].C+( m4lgth/6,-m4wdth/4),,,R) } ')

                            `sl_breaker(linespec, type=[A|C][D]; ttbox keys)
                               C is for curved breaker
                               D is for sl_drawout'
define(`sl_breaker',
 `setkeys_(`$2',`lgth:brksiz_; wdth:brksiz_; name::N; type::N')dnl
  ifinstr(m4type,C,
   `ifinstr(m4type,D,
     `m4ch_two(`cbreaker',`$1')',
     `ifelse(m4name,,,m4name:) cbreaker(`$1')')',
   `ifinstr(m4type,D,
     `m4ch_two(`sl_ttbox',`$1',lgth=m4lgth;wdth=m4wdth;`$2';name=Br)',
     `sl_ttbox(`$1',lgth=m4lgth;wdth=m4wdth;`$2')') ') ')

                            `sl_reactor(linespec,keys,breaker keys,breaker keys)
                             keys=
                               diam=expr,
                             (Default breaker names BrI and BrO)'
define(`sl_reactor',
 `setkeys_(`$2',`diam:sourcerad_*4/3; type::N')dnl
  ifelse(`$3'`$4',,
   `eleminit_(`$1')
    { line to rvec_(rp_len/2,0) then to rvec_(rp_len/2,-m4diam/2); round
      arc rad m4diam/2 cw from Here to rvec_(m4diam/2,m4diam/2) \
        with .c at rvec_(0,m4diam/2); round
      line to rvec_(rp_len/2-m4diam/2,0) }
    {[ box invis ht m4diam wid m4diam ] at rvec_(rp_len/2,0)}
    line invis to rvec_(rp_len,0) ',
   `m4br_two(`sl_reactor', `$1', lgth=m4diam*2;`$2',
      m4brk_(`$3',BrI),m4brk_(`$4',BrO),ifelse(`$3',,,I)`'ifelse(`$4',,,O))')')

                            `sl_busbar( linespec, nports, keys )
                             Labels P1, P2 ... Pnports are defined on the line.
                                  keys: line=line attributes;
                                        port=D; (dotted ports)
                             The bus extends beyond the first and last points
                              by dimen_/5 which can be redefined as
                                line=chop -(expr)'
define(`sl_busbar',
 `define(`m4npoints',`ifelse(`$2',,2,`$2')')dnl
  setkeys_(`$3',`line:thick 1.6 chop -dimen_/5:N; port::N')dnl
  [ tmp_ang = rp_ang
    eleminit_(`$1',(m4npoints-1)*dimen_)
    Start: last line.start; End: last line.end
    for_(1,m4npoints,1,
     `P`'m4x: (m4x-1)/(m4npoints-1) between Start and End dnl
     ifinstr(m4port,D,` ;dot(at P`'m4x)')')
    Line: line from Start to End m4line
    Start: last line.start; End: last line.end
    point_(tmp_ang) ] ')

                            `sl_drawout(linespec, keys, R)
                             Drawout (i.e. plugin) chevron element;
                               keys:  type=T; (truncated leads)
                                      lgth=expr; (body size)
                                      wdth=expr;
                                      name=Name; (body name)
                                      line= line attributes (e.g. thick 2)
                               arg3=R reverse direction'
define(`sl_drawout',
  `setkeys_(`$2',`lgth:drosiz_; wdth:drosiz_; type::N; name::N; line::N')dnl
   eleminit_(`$1',ifelse(m4type,T,m4lgth))
   ifelse(`$3',R,`{M4ds: Here; move to last line.end; rp_ang = rp_ang+pi_')
   {line to rvec_(rp_len/2,0)
    ifelse(m4name,,,m4name:) [
     S: Here; {line from rvec_(-m4lgth/2,m4wdth/2) to Here then
       to rvec_(-m4lgth/2,-m4wdth/2) m4line }
     E: rvec_(m4lgth/2,0); line from rvec_(0,m4wdth/2) to E then
       to rvec_(0,-m4wdth/2) m4line ] with .S at Here
     ifelse(m4type,T,,
      line from last [].E to last [].E+vec_((rp_len-m4lgth)/2,0))}
    ifelse(`$3',R,`rp_ang = rp_ang-pi_; move to M4ds}')
   line invis to rvec_(rp_len,0) ')

# Two-terminal utilities ##################################################

                            `Breakers in the input and output lines:'
                            `m4br_two(`2-term element macroname in quotes',
                                linespec, body keys,
                                input breaker keys,
                                output breaker keys,
                                I|O|IO)'
                            `(Default breaker names are BrI and BrO)'
define(`m4br_two',
 `define(`m4il',`ifinstr(`$6',I,`setkey_(`$4',lgth,brksiz_) m4lgth',0)')dnl
  define(`m4ol',`ifinstr(`$6',O,`setkey_(`$5',lgth,brksiz_) m4lgth',0)')dnl
  define(`m4bl',`setkey_(`$3',lgth,dimen_*4/3) m4lgth')dnl
  eleminit_(`$2',dimen_*3)
  M4start: Here; M4end: last line.end
  M4cc: last line.c+vec_(((m4il*3/2)-(m4ol*3/2)),0)
  M4ii: M4cc+vec_(-min((m4bl/2+m4il/2),distance(M4start,M4cc)-m4il),0)
  line from M4start to ifinstr(`$6',I,
   `M4ii+vec_(-m4il,0); sl_breaker(to M4ii,`$4';name=BrI)',M4ii)
  M4oi: M4cc+vec_(min((m4bl/2+m4ol/2),distance(M4end,M4cc)-m4ol),0)
  $1(from M4ii to M4oi,`$3')
  ifinstr(`$6',O,`sl_breaker(to M4oi+vec_(m4ol,0),`$5';name=BrO)')
  line to M4end
  line invis from M4start to M4end ')

                            `Chevrons in the input and output lines:'
                            `m4ch_two(`2-term element macroname in quotes',
                                linespec, body keys,
                                input breaker keys,
                                output breaker keys,
                                I|O|IO)'
define(`m4ch_two',
 `define(`m4bl',`setkey_(`$3',lgth,dimen_*3/8) m4lgth')dnl
  eleminit_(`$2',dimen_*3)
  M4start: Here; M4end: last line.end
  M4elem: $1(to rvec_(m4bl+2*drosiz_,0) with .c at last line.c,`$3')
  sl_drawout(from last line.start-vec_(drosiz_,0) to last line.start,type=T,R)
  line from last line.start to M4start
  sl_drawout(from M4elem.end to M4elem.end+vec_(drosiz_,0),type=T)
  line to M4end
  line invis from M4start to M4end')

# Composite elements ###################################################

                            `sl_ct( at position, stem length, U|D|L|R|expr,
                                scale=expr) (default scale is 1.5)'
define(`sl_ct',
 `[ setdir_(`$3'); setkey_(`$4',scale,1.5); linewid = linewid*m4scale
    L: inductor(to vec_(2*dimen_/8,0),,2)
      stemlen = ifelse(`$2',,dimen_/5,`$2')
      line from L.start to L.start+vec_(0,-stemlen)
    Ts: Here
      line from L.end to L.end+vec_(0,-stemlen)
    Te: Here
      line from L.c to L.c+vec_(0,-stemlen)
    Tc: Here
    resetdir_ ] with .L.c at ifelse(`$1',,Here,patsubst(`$1',^ *at *)) ')

# #######################################################################

divert(0)dnl