drawio_dsl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/setup ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # frozen_string_literal: true
4
+
5
+ set -euo pipefail
6
+ IFS=$'\n\t'
7
+ set -vx
8
+
9
+ bundle install
10
+
11
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Attach configuration to the DrawIO DSL module
4
+ module DrawioDsl
5
+ # Used to attach configuration to KConfig module
6
+ module ConfigurationExtension
7
+ def drawio
8
+ return @drawio if defined? @drawio
9
+
10
+ @drawio = DrawioDsl::Configuration.new
11
+ end
12
+ end
13
+
14
+ # Configuration container for the DrawIO DSL
15
+ class Configuration
16
+ include KLog::Logging
17
+
18
+ BaseStyle = Struct.new(:white_space, :html, :rounded, :shadow, :sketch, :glass, keyword_init: true)
19
+
20
+ ElementDefaults = Struct.new(:type, :x, :y, :w, :h, :style_modifiers)
21
+ ElementThemeStyle = Struct.new(:fill_color, :stroke_color, :font_color, :gradient, keyword_init: true)
22
+
23
+ attr_accessor :base_style
24
+
25
+ # Theme colors
26
+ attr_accessor :themes
27
+
28
+ # Element shapes
29
+ attr_accessor :element
30
+ attr_accessor :square
31
+ attr_accessor :rectangle
32
+ attr_accessor :circle
33
+ attr_accessor :process
34
+ attr_accessor :ellipse
35
+ attr_accessor :triangle
36
+ attr_accessor :parallelogram
37
+ attr_accessor :hexagon
38
+
39
+ def initialize
40
+ @base_style = BaseStyle.new(white_space: :wrap, html: 1, rounded: nil, shadow: nil, sketch: nil, glass: nil)
41
+
42
+ @element = ElementDefaults.new(:element , 0, 0, 20, 20, '')
43
+ @square = ElementDefaults.new(:square , 0, 0, 160, 160, '')
44
+ @rectangle = ElementDefaults.new(:rectangle , 0, 0, 240, 120, '')
45
+ @circle = ElementDefaults.new(:circle , 0, 0, 160, 160, 'ellipse')
46
+ @process = ElementDefaults.new(:process , 0, 0, 240, 120, 'shape=process')
47
+ @ellipse = ElementDefaults.new(:ellipse , 0, 0, 240, 120, 'ellipse')
48
+ @triangle = ElementDefaults.new(:triangle , 0, 0, 160, 160, 'rhombus')
49
+
50
+ @themes = {}
51
+ add_themes
52
+ end
53
+
54
+ def palette(theme)
55
+ @themes[theme]
56
+ end
57
+
58
+ def random_theme
59
+ @themes.keys.sample
60
+ end
61
+
62
+ private
63
+
64
+ def add_theme(name, **opts)
65
+ @themes[name] = ElementThemeStyle.new(**opts)
66
+ end
67
+
68
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
69
+ def add_themes
70
+ add_theme(:style_01 , fill_color: '#f5f5f5', stroke_color: '#666666', font_color: '#333333')
71
+ add_theme(:style_02 , fill_color: '#dae8fc', stroke_color: '#6c8ebf', font_color: '#333333')
72
+ add_theme(:style_03 , fill_color: '#d5e8d4', stroke_color: '#82b366', font_color: '#333333')
73
+ add_theme(:style_04 , fill_color: '#ffe6cc', stroke_color: '#d79b00', font_color: '#333333')
74
+ add_theme(:style_05 , fill_color: '#fff2cc', stroke_color: '#d6b656', font_color: '#333333')
75
+ add_theme(:style_06 , fill_color: '#f8cecc', stroke_color: '#b85450', font_color: '#333333')
76
+ add_theme(:style_07 , fill_color: '#e1d5e7', stroke_color: '#9673a6', font_color: '#333333')
77
+ add_theme(:style_08 , fill_color: '#60a917', stroke_color: '#2D7600', font_color: '#ffffff')
78
+ add_theme(:style_09 , fill_color: '#008a00', stroke_color: '#005700', font_color: '#ffffff')
79
+ add_theme(:style_10 , fill_color: '#1ba1e2', stroke_color: '#006EAF', font_color: '#ffffff')
80
+ add_theme(:style_11 , fill_color: '#0050ef', stroke_color: '#001DBC', font_color: '#ffffff')
81
+ add_theme(:style_12 , fill_color: '#6a00ff', stroke_color: '#3700CC', font_color: '#ffffff')
82
+ add_theme(:style_13 , fill_color: '#aa00ff', stroke_color: '#7700CC', font_color: '#ffffff')
83
+ add_theme(:style_14 , fill_color: '#d80073', stroke_color: '#A50040', font_color: '#ffffff')
84
+ add_theme(:style_15 , fill_color: '#a20025', stroke_color: '#6F0000', font_color: '#ffffff')
85
+ add_theme(:style_16 , fill_color: '#e51400', stroke_color: '#B20000', font_color: '#ffffff')
86
+ add_theme(:style_17 , fill_color: '#fa6800', stroke_color: '#C73500', font_color: '#000000')
87
+ add_theme(:style_18 , fill_color: '#f0a30a', stroke_color: '#BD7000', font_color: '#000000')
88
+ add_theme(:style_19 , fill_color: '#e3c800', stroke_color: '#B09500', font_color: '#000000')
89
+ add_theme(:style_20 , fill_color: '#6d8764', stroke_color: '#3A5431', font_color: '#ffffff')
90
+ add_theme(:style_21 , fill_color: '#647687', stroke_color: '#314354', font_color: '#ffffff')
91
+ add_theme(:style_22 , fill_color: '#76608a', stroke_color: '#432D57', font_color: '#ffffff')
92
+ add_theme(:style_23 , fill_color: '#a0522d', stroke_color: '#6D1F00', font_color: '#ffffff')
93
+ add_theme(:style_24 , fill_color: '#fad7ac', stroke_color: '#b46504')
94
+ add_theme(:style_25 , fill_color: '#fad9d5', stroke_color: '#ae4132')
95
+ add_theme(:style_26 , fill_color: '#b0e3e6', stroke_color: '#0e8088')
96
+ add_theme(:style_27 , fill_color: '#b1ddf0', stroke_color: '#10739e')
97
+ add_theme(:style_28 , fill_color: '#d0cee2', stroke_color: '#56517e')
98
+ add_theme(:style_29 , fill_color: '#bac8d3', stroke_color: '#23445d')
99
+ add_theme(:style_30 , fill_color: '#f5f5f5', stroke_color: '#666666', gradient: '#b3b3b3')
100
+ add_theme(:style_31 , fill_color: '#dae8fc', stroke_color: '#6c8ebf', gradient: '#7ea6e0')
101
+ add_theme(:style_32 , fill_color: '#d5e8d4', stroke_color: '#82b366', gradient: '#97d077')
102
+ add_theme(:style_33 , fill_color: '#ffcd28', stroke_color: '#d79b00', gradient: '#ffa500')
103
+ add_theme(:style_34 , fill_color: '#fff2cc', stroke_color: '#d6b656', gradient: '#ffd966')
104
+ add_theme(:style_35 , fill_color: '#f8cecc', stroke_color: '#b85450', gradient: '#ea6b66')
105
+ add_theme(:style_36 , fill_color: '#e6d0de', stroke_color: '#996185', gradient: '#d5739d')
106
+ add_theme(:style_37 , fill_color: '#eeeeee', stroke_color: '#36393d')
107
+ add_theme(:style_38 , fill_color: '#f9f7ed', stroke_color: '#36393d')
108
+ add_theme(:style_39 , fill_color: '#ffcc99', stroke_color: '#36393d')
109
+ add_theme(:style_40 , fill_color: '#cce5ff', stroke_color: '#36393d')
110
+ add_theme(:style_41 , fill_color: '#ffff88', stroke_color: '#36393d')
111
+ add_theme(:style_42 , fill_color: '#cdeb8b', stroke_color: '#36393d')
112
+ add_theme(:style_43 , fill_color: '#ffcccc', stroke_color: '#36393d')
113
+ end
114
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
115
+ end
116
+ end
117
+
118
+ KConfig::Configuration.register(:drawio, DrawioDsl::ConfigurationExtension)
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ # DrawioDsl is a DSL for draw-io diagrams.
5
+ class DomBuilder
6
+ attr_reader :actions
7
+ attr_reader :last_action
8
+
9
+ attr_reader :current_page
10
+ attr_reader :current_element
11
+
12
+ def initialize
13
+ @actions = []
14
+ @last_action = {}
15
+ end
16
+
17
+ def reset
18
+ @actions = []
19
+ @last_action = {}
20
+ set_diagram
21
+ set_layout_engine
22
+ end
23
+
24
+ def queue_action(action)
25
+ @actions << action
26
+ @last_action = action
27
+ end
28
+
29
+ def set_layout_engine(**opts)
30
+ @layout_engine = DrawioDsl::LayoutEngine.new(**opts)
31
+ end
32
+
33
+ def layout_engine
34
+ return @layout_engine if defined? @layout_engine
35
+
36
+ set_layout_engine
37
+ end
38
+
39
+ def set_diagram(**opts)
40
+ @diagram = DrawioDsl::Schema::Diagram.new(**opts)
41
+ end
42
+
43
+ def diagram
44
+ return @diagram if defined? @diagram
45
+
46
+ set_diagram
47
+ end
48
+
49
+ def add_page(**opts)
50
+ @current_page = DrawioDsl::Schema::Page.new(diagram, **opts)
51
+
52
+ current_page.id = SecureRandom.alphanumeric(3) unless current_page.id
53
+
54
+ diagram.pages << @current_page
55
+ @current_page
56
+ end
57
+
58
+ def add_element(element)
59
+ @current_element = element
60
+
61
+ element.id = "#{current_page.id}-#{current_page.elements.length + 1}" unless element.id
62
+
63
+ layout_engine.container.place_element(element)
64
+
65
+ current_page.elements << element
66
+ @current_element
67
+ end
68
+
69
+ def add_square(**opts)
70
+ square = DrawioDsl::Schema::Square.new(current_page, **opts)
71
+ add_element(square)
72
+ end
73
+
74
+ def add_rectangle(**opts)
75
+ rectangle = DrawioDsl::Schema::Rectangle.new(current_page, **opts)
76
+ add_element(rectangle)
77
+ end
78
+
79
+ def add_circle(**opts)
80
+ circle = DrawioDsl::Schema::Circle.new(current_page, **opts)
81
+ add_element(circle)
82
+ end
83
+
84
+ def add_process(**opts)
85
+ process = DrawioDsl::Schema::Process.new(current_page, **opts)
86
+ add_element(process)
87
+ end
88
+
89
+ def add_ellipse(**opts)
90
+ ellipse = DrawioDsl::Schema::Ellipse.new(current_page, **opts)
91
+ add_element(ellipse)
92
+ end
93
+
94
+ def debug
95
+ puts JSON.pretty_generate(actions)
96
+ puts JSON.pretty_generate(diagram.to_h)
97
+ end
98
+
99
+ def dom
100
+ diagram.to_h
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ # DrawioDsl is a DSL for draw-io diagrams.
5
+ class Drawio < KDirector::Directors::BaseDirector
6
+ default_builder_type(DrawioDsl::DomBuilder)
7
+
8
+ def layout(**opts)
9
+ builder.set_layout_engine(**opts)
10
+
11
+ self
12
+ end
13
+
14
+ def diagram(**opts)
15
+ builder.set_diagram(**opts)
16
+
17
+ self
18
+ end
19
+
20
+ def page(name = nil, **opts, &block)
21
+ page = DrawioDsl::DrawioPage.new(self, **opts.merge(name: name))
22
+ page.instance_eval(&block) if block_given?
23
+
24
+ self
25
+ end
26
+ end
27
+
28
+ # DrawioDsl::DrawioPage is created when you call .page on the draw-io DSL.
29
+ class DrawioPage < KDirector::Directors::ChildDirector
30
+ attr_reader :auto_layout
31
+ attr_reader :current_x
32
+ attr_reader :current_y
33
+
34
+ def initialize(parent, **opts)
35
+ super(parent, **opts)
36
+
37
+ @auto_layout = true
38
+ @current_x = 20
39
+ @current_y = 20
40
+
41
+ builder.add_page(**opts)
42
+ end
43
+
44
+ def square(**opts)
45
+ opts = attach_xy(**opts)
46
+ builder.add_square(**opts)
47
+ update_layout
48
+ end
49
+
50
+ def rectangle(**opts)
51
+ opts = attach_xy(**opts)
52
+ builder.add_rectangle(**opts)
53
+ update_layout
54
+ end
55
+
56
+ def circle(**opts)
57
+ opts = attach_xy(**opts)
58
+ builder.add_circle(**opts)
59
+ update_layout
60
+ end
61
+
62
+ def process(**opts)
63
+ opts = attach_xy(**opts)
64
+ builder.add_process(**opts)
65
+ update_layout
66
+ end
67
+
68
+ def ellipse(**opts)
69
+ opts = attach_xy(**opts)
70
+ builder.add_ellipse(**opts)
71
+ update_layout
72
+ end
73
+
74
+ private
75
+
76
+ def current_element
77
+ builder.current_element
78
+ end
79
+
80
+ # attr_reader :layout_engine
81
+ # set_layout
82
+
83
+ # layout.container.place_element(element)
84
+
85
+ def update_layout
86
+ return unless auto_layout
87
+
88
+ # puts current_element.page.x
89
+ # puts current_element.page.y
90
+ # puts current_element.page.w
91
+ # puts current_element.page.h
92
+
93
+ @current_x += current_element.w + 20
94
+ @current_y += current_element.h + 20
95
+ end
96
+
97
+ def attach_xy(**opts)
98
+ opts[:x] ||= current_x
99
+ opts[:y] ||= current_y
100
+ opts
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,335 @@
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