drawio_dsl 0.1.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.builders/.templates/command.rb +8 -0
  3. data/.builders/.templates/schema_shape.rb +9 -0
  4. data/.builders/blueprint/shapes.rb +19 -0
  5. data/.builders/boot.rb +1 -0
  6. data/.builders/generators/10-page-margin.rb +46 -0
  7. data/.builders/generators/15-grid-direction.rb +40 -0
  8. data/.builders/generators/16-grid-alignment.rb +73 -0
  9. data/.builders/generators/20-styles.rb +64 -0
  10. data/.builders/generators/25-themes.rb +24 -0
  11. data/.rubocop.yml +6 -1
  12. data/CHANGELOG.md +24 -0
  13. data/lib/drawio_dsl/configuration.rb +58 -45
  14. data/lib/drawio_dsl/dom_builder.rb +66 -23
  15. data/lib/drawio_dsl/drawio.rb +65 -36
  16. data/lib/drawio_dsl/layout_engine.rb +24 -28
  17. data/lib/drawio_dsl/schema/_.rb +23 -0
  18. data/lib/drawio_dsl/schema/common_style.rb +42 -0
  19. data/lib/drawio_dsl/schema/default_palette.rb +31 -0
  20. data/lib/drawio_dsl/schema/diagram.rb +57 -0
  21. data/lib/drawio_dsl/schema/layouts/flex_layout.rb +87 -0
  22. data/lib/drawio_dsl/schema/layouts/grid_layout.rb +102 -0
  23. data/lib/drawio_dsl/schema/layouts/layout.rb +41 -0
  24. data/lib/drawio_dsl/schema/node.rb +53 -0
  25. data/lib/drawio_dsl/schema/page.rb +135 -0
  26. data/lib/drawio_dsl/schema/shapes/callout.rb +9 -0
  27. data/lib/drawio_dsl/schema/shapes/circle.rb +9 -0
  28. data/lib/drawio_dsl/schema/shapes/cloud.rb +9 -0
  29. data/lib/drawio_dsl/schema/shapes/diamond.rb +9 -0
  30. data/lib/drawio_dsl/schema/shapes/ellipse.rb +9 -0
  31. data/lib/drawio_dsl/schema/shapes/hexagon.rb +9 -0
  32. data/lib/drawio_dsl/schema/shapes/note.rb +9 -0
  33. data/lib/drawio_dsl/schema/shapes/process.rb +9 -0
  34. data/lib/drawio_dsl/schema/shapes/rectangle.rb +9 -0
  35. data/lib/drawio_dsl/schema/shapes/shape.rb +125 -0
  36. data/lib/drawio_dsl/schema/shapes/square.rb +9 -0
  37. data/lib/drawio_dsl/version.rb +1 -1
  38. data/lib/drawio_dsl/xml_builder.rb +7 -7
  39. data/lib/drawio_dsl.rb +1 -2
  40. data/package-lock.json +2 -2
  41. data/package.json +1 -1
  42. metadata +30 -6
  43. data/.builders/generators/10-layout.rb +0 -21
  44. data/lib/drawio_dsl/drawio_dsl-OLD.x +0 -335
  45. data/lib/drawio_dsl/layout_container.rb +0 -54
  46. data/lib/drawio_dsl/schema.rb +0 -346
@@ -1,335 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module KDirector
4
- module Dsls
5
- class DrawioXmlBuilder
6
- include KLog::Logging
7
-
8
- attr_reader :host
9
- attr_reader :pages
10
-
11
- attr_reader :current_id
12
- attr_reader :row_index
13
- attr_reader :row_offset
14
-
15
- def initialize(opts, dom)
16
- @host = opts[:host] || SecureRandom.alphanumeric(4)
17
- @pages = dom[:pages] || []
18
- # puts JSON.pretty_generate(dom)
19
-
20
- @current_id = 10
21
- @row_index = 0
22
- @row_offset = 0
23
- end
24
-
25
- def build
26
- xml_builder = Nokogiri::XML::Builder.new do |xml|
27
- xml.mxfile(host: host) do
28
- page_index = 0
29
- pages.each do |page|
30
- build_page(xml, page, page_index)
31
- page_index += 1
32
- end
33
- end
34
- end
35
-
36
- xml_builder.to_xml.sub('<?xml version="1.0"?>', '').strip
37
- end
38
-
39
- private
40
-
41
- def next_id
42
- result = @current_id
43
- @current_id += 1
44
- result
45
- end
46
-
47
- def next_row
48
- @row_index += 150
49
- end
50
-
51
- def current_row_index
52
- row_index + row_offset
53
- end
54
-
55
- def reset_row
56
- @row_index = 0
57
- end
58
-
59
- def random_text
60
- return '' if rand(5) == 1
61
-
62
- words = %w[
63
- substantial
64
- humor
65
- jeans
66
- hover
67
- encouraging
68
- glue
69
- used
70
- statuesque
71
- umbrella
72
- vigorous
73
- horses
74
- outgoing
75
- ]
76
-
77
- # return a random word
78
- words.sample
79
- end
80
-
81
- def element_color
82
- element_colors = %w[
83
- fillColor=#d0cee2;strokeColor=#56517e;fontColor=#333333;
84
- fillColor=#FFCCCC;strokeColor=#36393D;fontColor=#333333;
85
- fillColor=#CDEB8B;strokeColor=#36393D;fontColor=#333333;
86
- fillColor=#FFFF88;strokeColor=#36393D;fontColor=#333333;
87
- fillColor=#CCE5FF;strokeColor=#36393D;fontColor=#333333;
88
- fillColor=#FFCC99;strokeColor=#36393D;fontColor=#333333;
89
- fillColor=#F9F7ED;strokeColor=#36393D;fontColor=#333333;
90
- fillColor=#EEEEEE;strokeColor=#36393D;fontColor=#333333;
91
- fillColor=#BAC8D3;strokeColor=#23445D;fontColor=#333333;
92
- fillColor=#D0CEE2;strokeColor=#56517E;fontColor=#333333;
93
- fillColor=#B1DDF0;strokeColor=#10739E;fontColor=#333333;
94
- fillColor=#B0E3E6;strokeColor=#0E8088;fontColor=#333333;
95
- fillColor=#FAD9D5;strokeColor=#AE4132;fontColor=#333333;
96
- ]
97
-
98
- # return a random color
99
- element_colors.sample
100
- # nil
101
- end
102
-
103
- def build_page(xml, page, page_index)
104
- page_id = SecureRandom.alphanumeric(3).to_s
105
- @row_offset = 50 # Random.rand(350)
106
-
107
- xml.diagram(id: page_id, name: page[:name]) do
108
- size_ratio = Random.rand(0.5..3.0)
109
- size_ratio = 2
110
-
111
- reset_row
112
-
113
- grid = 1
114
- element_style = ''
115
-
116
- case page_index
117
- when 1
118
- element_style = 'sketch=1'
119
- grid = 0
120
- when 2
121
- element_style = 'shadow=1'
122
- when 3
123
- element_style = 'sketch=1;shadow=1'
124
- grid = 0
125
- end
126
-
127
- # background = "##{SecureRandom.hex(3)}"
128
- background = '#FFFACD'
129
- # background = nil
130
-
131
- # background="#FF99CC" backgroundImage="{&quot;src&quot;:&quot;data:page/id,AKs&quot;}" math="0" shadow="1"
132
- xml.mxGraphModel(dx: 800, dy: 583, background: background, grid: grid, gridSize: 10, guides: 1, tooltips: 1, connect: 1, arrows: 1, fold: 1, page: page_index, pageScale: 1, pageWidth: 1169,
133
- pageHeight: 827, math: 0, shadow: 0) do
134
- xml.root do
135
- xml.mxCell(id: "#{page_id}-0")
136
- xml.mxCell(id: "#{page_id}-1", parent: "#{page_id}-0")
137
-
138
- # ------ Row 1 ------
139
-
140
- # Square
141
- xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}", vertex: '1') do
142
- xml.mxGeometry(x: size_ratio * 50 , y: size_ratio * current_row_index, width: size_ratio * 80, height: size_ratio * 80, as: 'geometry')
143
- end
144
- # Rectangle
145
- xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "rounded=0;whiteSpace=wrap;html=1;#{element_style};#{element_color}", vertex: '1') do
146
- xml.mxGeometry(x: size_ratio * 170 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 60, as: 'geometry')
147
- end
148
- # Rectangle - Rounded
149
- xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "rounded=1;whiteSpace=wrap;html=1;#{element_style};#{element_color}", vertex: '1') do
150
- xml.mxGeometry(x: size_ratio * 330 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 60, as: 'geometry')
151
- end
152
-
153
- # ------ Row 2 ------
154
-
155
- next_row
156
-
157
- # Circle
158
- xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "ellipse;whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}",
159
- vertex: '1') do
160
- xml.mxGeometry(x: size_ratio * 50 , y: size_ratio * current_row_index, width: size_ratio * 80, height: size_ratio * 80, as: 'geometry')
161
- end
162
-
163
- # Process
164
- xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text,
165
- style: "shape=process;whiteSpace=wrap;html=1;aspect=fixed;backgroundOutline=1;#{element_style};#{element_color}", vertex: '1') do
166
- xml.mxGeometry(x: size_ratio * 170 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 80, as: 'geometry')
167
- end
168
-
169
- # Ellipse
170
- xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "ellipse;whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}",
171
- vertex: '1') do
172
- xml.mxGeometry(x: size_ratio * 330 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 80, as: 'geometry')
173
- end
174
-
175
- # ------ Row 3 ------
176
-
177
- next_row
178
-
179
- # Rhombus
180
- xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text, style: "rhombus;whiteSpace=wrap;html=1;#{element_style};#{element_color}", vertex: '1') do
181
- xml.mxGeometry(x: size_ratio * 50 , y: size_ratio * current_row_index, width: size_ratio * 80, height: size_ratio * 80, as: 'geometry')
182
- end
183
-
184
- # Parallelogram
185
- xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text,
186
- style: "shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;#{element_style};#{element_color}", vertex: '1') do
187
- xml.mxGeometry(x: size_ratio * 170 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 60, as: 'geometry')
188
- end
189
-
190
- # Hexagon
191
- xml.mxCell(id: "#{page_id}-#{next_id}", parent: "#{page_id}-1", value: random_text,
192
- style: "shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;#{element_style};#{element_color}", vertex: '1') do
193
- xml.mxGeometry(x: size_ratio * 330 , y: size_ratio * current_row_index, width: size_ratio * 120, height: size_ratio * 80, as: 'geometry')
194
- end
195
- end
196
- end
197
- end
198
- end
199
- end
200
-
201
- # DrawioDsl is a DSL for draw-io diagrams.
202
- class DrawioDsl < KDirector::Directors::BaseDirector
203
- def default_template_base_folder
204
- 'drawio'
205
- end
206
-
207
- def page(name = nil, **opts, &block)
208
- page = KDirector::Dsls::DrawioPage.new(self, **opts.merge(name: name))
209
- page.instance_eval(&block) if block_given?
210
-
211
- self
212
- end
213
-
214
- def create_diagram(name = nil, **opts)
215
- xml_builder = DrawioXmlBuilder.new(opts, builder.dom)
216
- add_file(name, content: xml_builder.build)
217
- play_actions
218
-
219
- self
220
- end
221
- end
222
-
223
- class DrawioPage < KDirector::Directors::ChildDirector
224
- attr_reader :name
225
- attr_reader :data
226
-
227
- def initialize(parent, **opts)
228
- super(parent, **opts)
229
- @name = opts[:name] || SecureRandom.alphanumeric(4)
230
- @data = { name: name, elements: [] }
231
-
232
- parent.builder.add(:pages, value: data) # , **repo_info_hash(**defaults))
233
- end
234
-
235
- def element(name = nil, **opts) # , &block)
236
- data[:elements] << opts.merge(name: name)
237
- end
238
-
239
- def square(_name = nil, **opts)
240
- # style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
241
- style = 'whiteSpace=wrap;html=1;aspect=fixed'
242
-
243
- # available params
244
- # x, :y, :width, :height, :value
245
- element(:square, **opts.merge(style: style))
246
- end
247
-
248
- def rectangle(_name = nil, **opts)
249
- # style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
250
- style = 'whiteSpace=wrap;html=1'
251
-
252
- # available params
253
- # x, :y, :width, :height, :value, :rounded
254
- element(:square, **opts.merge(style: style))
255
- end
256
-
257
- def circle(_name = nil, **opts)
258
- # style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
259
- style = 'whiteSpace=wrap;html=1;aspect=fixed'
260
-
261
- # available params
262
- # x, :y, :width, :height, :value
263
- element(:circle, **opts.merge(style: style))
264
- end
265
-
266
- def process(_name = nil, **opts)
267
- # style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
268
- style = 'whiteSpace=wrap;html=1;aspect=fixed'
269
-
270
- # available params
271
- # x, :y, :width, :height, :value
272
-
273
- element(:process, **opts.merge(style: style))
274
- end
275
-
276
- def ellipse(_name = nil, **opts)
277
- # style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
278
- style = 'whiteSpace=wrap;html=1;aspect=fixed'
279
-
280
- # available params
281
- # x, :y, :width, :height, :value
282
-
283
- element(:ellipse, **opts.merge(style: style))
284
- end
285
-
286
- def interface(_name = nil, **opts)
287
- # style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
288
- style = 'whiteSpace=wrap;html=1;aspect=fixed'
289
-
290
- # available params
291
- # x, :y, :width, :height, :value
292
-
293
- element(:ellipse, **opts.merge(style: style))
294
- end
295
-
296
- def object(_name = nil, **opts)
297
- # style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
298
- style = 'whiteSpace=wrap;html=1;aspect=fixed'
299
-
300
- # available params
301
- # x, :y, :width, :height, :value
302
-
303
- element(:ellipse, **opts.merge(style: style))
304
- end
305
-
306
- def component(_name = nil, **opts)
307
- # style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
308
- style = 'whiteSpace=wrap;html=1;aspect=fixed'
309
-
310
- # available params
311
- # x, :y, :width, :height, :value
312
-
313
- element(:ellipse, **opts.merge(style: style))
314
- end
315
-
316
- def package(_name = nil, **opts)
317
- # style = "whiteSpace=wrap;html=1;aspect=fixed;#{element_style};#{element_color}"
318
- style = 'whiteSpace=wrap;html=1;aspect=fixed'
319
-
320
- # available params
321
- # x, :y, :width, :height, :value
322
-
323
- element(:ellipse, **opts.merge(style: style))
324
- end
325
-
326
- def lines(name = nil, **opts); end
327
- def enum(name = nil, **opts); end
328
- def box(name = nil, **opts); end
329
- def down(name = nil, **opts); end
330
- def right(name = nil, **opts); end
331
- def left(name = nil, **opts); end
332
- def up(name = nil, **opts); end
333
- end
334
- end
335
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DrawioDsl
4
- # The layout engine is responsible for laying out the elements on the page.
5
- #
6
- # The layout engine can automatically place elements on the page.
7
- #
8
- # It will keep track of layout boundaries, current position and flow direction.
9
- # Elements are positioned on the page in the order they are added.
10
- # Row/column flow objects will hold information about horizontal and vertical element padding
11
- class LayoutContainer
12
- DEFAULT_DIRECTION = :vertical
13
- DEFAULT_PADDING = 20
14
- DEFAULT_BOUNDARY_HEIGHT = 800
15
- DEFAULT_BOUNDARY_WIDTH = 1000
16
-
17
- attr_reader :engine
18
- attr_accessor :direction
19
- attr_accessor :padding
20
-
21
- def initialize(engine, **opts)
22
- @engine = engine
23
- @direction = opts[:direction] || DEFAULT_DIRECTION
24
- @padding = opts[:padding] || DEFAULT_PADDING
25
- @boundary = opts[:boundary]
26
- end
27
-
28
- def vertical?
29
- @direction == :vertical
30
- end
31
-
32
- def horizontal?
33
- @direction == :horizontal
34
- end
35
-
36
- attr_writer :boundary
37
-
38
- def boundary
39
- @boundary ||= (vertical? ? DEFAULT_BOUNDARY_HEIGHT : DEFAULT_BOUNDARY_WIDTH)
40
- end
41
-
42
- # Place the incoming element by altering it's x, y coordinates based on the rules engine
43
- def place_element(element)
44
- place_vertical(element) if vertical?
45
- end
46
-
47
- def place_vertical(element)
48
- element.x = engine.x
49
- element.y = engine.y
50
-
51
- engine.y += (element.h + padding)
52
- end
53
- end
54
- end