drawio_dsl 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.builders/.data/shapes.json +218 -0
  3. data/.builders/.templates/basic/configuration_shapes.rb +27 -0
  4. data/.builders/.templates/basic/dom_builder_shapes.rb +16 -0
  5. data/.builders/.templates/basic/drawio_shapes.rb +23 -0
  6. data/.builders/.templates/basic/schema_require.rb +16 -0
  7. data/.builders/.templates/basic/schema_shape.rb +9 -0
  8. data/.builders/.templates/basic/schema_shape_spec.rb +13 -0
  9. data/.builders/blueprint/shapes.rb +48 -0
  10. data/.builders/boot.rb +6 -0
  11. data/.builders/generators/02-generate-app.rb +43 -0
  12. data/.builders/generators/{10-page-margin.rb → sample_diagrams/10-page-margin.rb} +0 -0
  13. data/.builders/generators/{15-grid-direction.rb → sample_diagrams/15-grid-direction.rb} +0 -0
  14. data/.builders/generators/{16-grid-alignment.rb → sample_diagrams/16-grid-alignment.rb} +0 -0
  15. data/.builders/generators/{20-styles.rb → sample_diagrams/20-styles.rb} +0 -0
  16. data/.builders/generators/{25-themes.rb → sample_diagrams/25-themes.rb} +5 -2
  17. data/.builders/generators/sample_diagrams/30-shapes.rb +23 -0
  18. data/.rubocop.yml +20 -3
  19. data/CHANGELOG.md +21 -0
  20. data/README.md +4 -0
  21. data/lib/drawio_dsl/configuration.rb +7 -94
  22. data/lib/drawio_dsl/configuration_extension.rb +13 -0
  23. data/lib/drawio_dsl/configuration_shapes.rb +75 -0
  24. data/lib/drawio_dsl/configuration_themes.rb +63 -0
  25. data/lib/drawio_dsl/dom_builder.rb +4 -35
  26. data/lib/drawio_dsl/dom_builder_shapes.rb +143 -0
  27. data/lib/drawio_dsl/drawio.rb +1 -73
  28. data/lib/drawio_dsl/drawio_shapes.rb +175 -0
  29. data/lib/drawio_dsl/layout_engine.rb +1 -1
  30. data/lib/drawio_dsl/schema/_.rb +40 -0
  31. data/lib/drawio_dsl/schema/common_style.rb +42 -0
  32. data/lib/drawio_dsl/schema/default_palette.rb +31 -0
  33. data/lib/drawio_dsl/schema/diagram.rb +57 -0
  34. data/lib/drawio_dsl/schema/layouts/flex_layout.rb +87 -0
  35. data/lib/drawio_dsl/schema/layouts/grid_layout.rb +102 -0
  36. data/lib/drawio_dsl/schema/layouts/layout.rb +41 -0
  37. data/lib/drawio_dsl/schema/node.rb +53 -0
  38. data/lib/drawio_dsl/schema/page.rb +135 -0
  39. data/lib/drawio_dsl/schema/shapes/actor.rb +9 -0
  40. data/lib/drawio_dsl/schema/shapes/actor2.rb +9 -0
  41. data/lib/drawio_dsl/schema/shapes/callout.rb +9 -0
  42. data/lib/drawio_dsl/schema/shapes/callout2.rb +9 -0
  43. data/lib/drawio_dsl/schema/shapes/callout3.rb +9 -0
  44. data/lib/drawio_dsl/schema/shapes/callout4.rb +9 -0
  45. data/lib/drawio_dsl/schema/shapes/circle.rb +9 -0
  46. data/lib/drawio_dsl/schema/shapes/cloud.rb +9 -0
  47. data/lib/drawio_dsl/schema/shapes/container.rb +9 -0
  48. data/lib/drawio_dsl/schema/shapes/container2.rb +9 -0
  49. data/lib/drawio_dsl/schema/shapes/container3.rb +9 -0
  50. data/lib/drawio_dsl/schema/shapes/container4.rb +9 -0
  51. data/lib/drawio_dsl/schema/shapes/cross.rb +9 -0
  52. data/lib/drawio_dsl/schema/shapes/diamond.rb +9 -0
  53. data/lib/drawio_dsl/schema/shapes/document.rb +9 -0
  54. data/lib/drawio_dsl/schema/shapes/ellipse.rb +9 -0
  55. data/lib/drawio_dsl/schema/shapes/envelop.rb +9 -0
  56. data/lib/drawio_dsl/schema/shapes/face.rb +9 -0
  57. data/lib/drawio_dsl/schema/shapes/hexagon.rb +9 -0
  58. data/lib/drawio_dsl/schema/shapes/note.rb +9 -0
  59. data/lib/drawio_dsl/schema/shapes/process.rb +9 -0
  60. data/lib/drawio_dsl/schema/shapes/rectangle.rb +9 -0
  61. data/lib/drawio_dsl/schema/shapes/rectangle2.rb +9 -0
  62. data/lib/drawio_dsl/schema/shapes/shape.rb +123 -0
  63. data/lib/drawio_dsl/schema/shapes/square.rb +9 -0
  64. data/lib/drawio_dsl/schema/shapes/step.rb +9 -0
  65. data/lib/drawio_dsl/schema/shapes/tick.rb +9 -0
  66. data/lib/drawio_dsl/schema/shapes/triangle.rb +9 -0
  67. data/lib/drawio_dsl/version.rb +1 -1
  68. data/lib/drawio_dsl.rb +6 -1
  69. data/package-lock.json +2 -2
  70. data/package.json +1 -1
  71. metadata +59 -8
  72. data/lib/drawio_dsl/schema.rb +0 -617
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ # DrawioDsl::Shapes is a list of DSL methods (one per shape)
5
+ # :nocov:
6
+ module DrawioShapes
7
+ def random(**opts)
8
+ case rand(27)
9
+ when 0
10
+ actor(**opts)
11
+ when 1
12
+ actor2(**opts)
13
+ when 2
14
+ callout(**opts)
15
+ when 3
16
+ callout2(**opts)
17
+ when 4
18
+ callout3(**opts)
19
+ when 5
20
+ callout4(**opts)
21
+ when 6
22
+ circle(**opts)
23
+ when 7
24
+ cloud(**opts)
25
+ when 8
26
+ cross(**opts)
27
+ when 9
28
+ envelop(**opts)
29
+ when 10
30
+ diamond(**opts)
31
+ when 11
32
+ document(**opts)
33
+ when 12
34
+ ellipse(**opts)
35
+ when 13
36
+ hexagon(**opts)
37
+ when 14
38
+ container(**opts)
39
+ when 15
40
+ container2(**opts)
41
+ when 16
42
+ container3(**opts)
43
+ when 17
44
+ container4(**opts)
45
+ when 18
46
+ note(**opts)
47
+ when 19
48
+ process(**opts)
49
+ when 20
50
+ rectangle(**opts)
51
+ when 21
52
+ rectangle2(**opts)
53
+ when 22
54
+ square(**opts)
55
+ when 23
56
+ step(**opts)
57
+ when 24
58
+ tick(**opts)
59
+ when 25
60
+ face(**opts)
61
+ when 26
62
+ triangle(**opts)
63
+ end
64
+ end
65
+
66
+ def actor(**opts)
67
+ builder.add_actor(**opts)
68
+ end
69
+
70
+ def actor2(**opts)
71
+ builder.add_actor2(**opts)
72
+ end
73
+
74
+ def callout(**opts)
75
+ builder.add_callout(**opts)
76
+ end
77
+
78
+ def callout2(**opts)
79
+ builder.add_callout2(**opts)
80
+ end
81
+
82
+ def callout3(**opts)
83
+ builder.add_callout3(**opts)
84
+ end
85
+
86
+ def callout4(**opts)
87
+ builder.add_callout4(**opts)
88
+ end
89
+
90
+ def circle(**opts)
91
+ builder.add_circle(**opts)
92
+ end
93
+
94
+ def cloud(**opts)
95
+ builder.add_cloud(**opts)
96
+ end
97
+
98
+ def cross(**opts)
99
+ builder.add_cross(**opts)
100
+ end
101
+
102
+ def envelop(**opts)
103
+ builder.add_envelop(**opts)
104
+ end
105
+
106
+ def diamond(**opts)
107
+ builder.add_diamond(**opts)
108
+ end
109
+
110
+ def document(**opts)
111
+ builder.add_document(**opts)
112
+ end
113
+
114
+ def ellipse(**opts)
115
+ builder.add_ellipse(**opts)
116
+ end
117
+
118
+ def hexagon(**opts)
119
+ builder.add_hexagon(**opts)
120
+ end
121
+
122
+ def container(**opts)
123
+ builder.add_container(**opts)
124
+ end
125
+
126
+ def container2(**opts)
127
+ builder.add_container2(**opts)
128
+ end
129
+
130
+ def container3(**opts)
131
+ builder.add_container3(**opts)
132
+ end
133
+
134
+ def container4(**opts)
135
+ builder.add_container4(**opts)
136
+ end
137
+
138
+ def note(**opts)
139
+ builder.add_note(**opts)
140
+ end
141
+
142
+ def process(**opts)
143
+ builder.add_process(**opts)
144
+ end
145
+
146
+ def rectangle(**opts)
147
+ builder.add_rectangle(**opts)
148
+ end
149
+
150
+ def rectangle2(**opts)
151
+ builder.add_rectangle2(**opts)
152
+ end
153
+
154
+ def square(**opts)
155
+ builder.add_square(**opts)
156
+ end
157
+
158
+ def step(**opts)
159
+ builder.add_step(**opts)
160
+ end
161
+
162
+ def tick(**opts)
163
+ builder.add_tick(**opts)
164
+ end
165
+
166
+ def face(**opts)
167
+ builder.add_face(**opts)
168
+ end
169
+
170
+ def triangle(**opts)
171
+ builder.add_triangle(**opts)
172
+ end
173
+ end
174
+ # :nocov:
175
+ end
@@ -34,7 +34,7 @@ module DrawioDsl
34
34
  when :layout_rule
35
35
  @current_layout = node
36
36
  when :shape
37
- current_layout.position_shape(node)
37
+ current_layout&.position_shape(node)
38
38
  end
39
39
  # node.debug(format: :row)
40
40
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common_style'
4
+ require_relative 'default_palette'
5
+ require_relative 'diagram'
6
+ require_relative 'node'
7
+ require_relative 'page'
8
+
9
+ require_relative 'layouts/layout'
10
+ require_relative 'layouts/flex_layout'
11
+ require_relative 'layouts/grid_layout'
12
+
13
+ require_relative 'shapes/shape'
14
+ require_relative 'shapes/actor'
15
+ require_relative 'shapes/actor2'
16
+ require_relative 'shapes/callout'
17
+ require_relative 'shapes/callout2'
18
+ require_relative 'shapes/callout3'
19
+ require_relative 'shapes/callout4'
20
+ require_relative 'shapes/circle'
21
+ require_relative 'shapes/cloud'
22
+ require_relative 'shapes/cross'
23
+ require_relative 'shapes/envelop'
24
+ require_relative 'shapes/diamond'
25
+ require_relative 'shapes/document'
26
+ require_relative 'shapes/ellipse'
27
+ require_relative 'shapes/hexagon'
28
+ require_relative 'shapes/container'
29
+ require_relative 'shapes/container2'
30
+ require_relative 'shapes/container3'
31
+ require_relative 'shapes/container4'
32
+ require_relative 'shapes/note'
33
+ require_relative 'shapes/process'
34
+ require_relative 'shapes/rectangle'
35
+ require_relative 'shapes/rectangle2'
36
+ require_relative 'shapes/square'
37
+ require_relative 'shapes/step'
38
+ require_relative 'shapes/tick'
39
+ require_relative 'shapes/face'
40
+ require_relative 'shapes/triangle'
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ module Schema
5
+ # Common Style is the reused on Diagram, Page and Shape
6
+ #
7
+ # When styles are not provided at each level, then they will inherit from
8
+ # the parent common style.
9
+ #
10
+ # Shapes will use the common style of their page
11
+ class CommonStyle
12
+ attr_accessor :white_space
13
+ attr_accessor :html
14
+ attr_accessor :rounded
15
+ attr_accessor :shadow
16
+ attr_accessor :glass
17
+ attr_accessor :sketch
18
+
19
+ def initialize(**args, &block)
20
+ @white_space = args[:white_space]
21
+ @html = args[:html]
22
+ @rounded = args[:rounded]
23
+ @shadow = args[:shadow]
24
+ @sketch = args[:sketch]
25
+ @glass = args[:glass]
26
+
27
+ instance_eval(&block) if block_given?
28
+ end
29
+
30
+ def to_h
31
+ {
32
+ white_space: white_space,
33
+ html: html,
34
+ rounded: rounded,
35
+ shadow: shadow,
36
+ sketch: sketch,
37
+ glass: glass
38
+ }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ module Schema
5
+ # Default Palette contains palette information that can be inherited at each level
6
+ class DefaultPalette
7
+ attr_accessor :fill_color
8
+ attr_accessor :stroke_color
9
+ attr_accessor :font_color
10
+ attr_accessor :gradient
11
+
12
+ def initialize(owner, **args, &block)
13
+ @fill_color = args[:fill_color]
14
+ @stroke_color = args[:stroke_color]
15
+ @font_color = args[:font_color]
16
+ @gradient = args[:gradient]
17
+
18
+ instance_exec(owner, &block) if block_given?
19
+ end
20
+
21
+ def to_h
22
+ {
23
+ fill_color: fill_color,
24
+ stroke_color: stroke_color,
25
+ font_color: font_color,
26
+ gradient: gradient
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ module Schema
5
+ # Diagram is the root of the schema, it contains pages
6
+ class Diagram
7
+ attr_accessor :host
8
+ attr_accessor :theme
9
+ attr_accessor :style
10
+ attr_accessor :palette
11
+ attr_accessor :pages
12
+
13
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
14
+ def initialize(**args)
15
+ @host = args[:host] || SecureRandom.alphanumeric(3)
16
+
17
+ # Apply a random theme to the diagram if none is specified.
18
+ @theme = args[:theme] || KConfig.configuration.drawio.random_theme
19
+
20
+ @style = DrawioDsl::Schema::CommonStyle.new(**args) do
21
+ default_style = KConfig.configuration.drawio.base_style
22
+
23
+ # Inherit from configured style when specific style not specified.
24
+ @white_space ||= default_style.white_space
25
+ @html ||= default_style.html
26
+ @rounded ||= default_style.rounded
27
+ @shadow ||= default_style.shadow
28
+ @sketch ||= default_style.sketch
29
+ @glass ||= default_style.glass
30
+ end
31
+
32
+ @palette = DrawioDsl::Schema::DefaultPalette.new(self, **args) do |diagram|
33
+ theme_palette = KConfig.configuration.drawio.palette(diagram.theme)
34
+
35
+ # Inherit from theme when specific palette options are not specified.
36
+ @fill_color ||= theme_palette.fill_color
37
+ @stroke_color ||= theme_palette.stroke_color
38
+ @font_color ||= theme_palette.font_color
39
+ @gradient ||= theme_palette.gradient
40
+ end
41
+
42
+ @pages = args[:pages] || []
43
+ end
44
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
45
+
46
+ def to_h
47
+ {
48
+ host: host,
49
+ theme: theme,
50
+ palette: palette.to_h,
51
+ style: style.to_h,
52
+ pages: pages.map(&:to_h)
53
+ }
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ module Schema
5
+ # Provides flex style layouts
6
+ class FlexLayout < Layout
7
+ attr_accessor :direction
8
+ attr_accessor :wrap_at
9
+ attr_reader :gap
10
+ attr_reader :perpendicular_max
11
+
12
+ def initialize(page, **args)
13
+ @type = :flex_layout
14
+ @direction = args[:direction] || :horizontal
15
+ @wrap_at = args[:wrap_at] || (direction == :horizontal ? 1000 : 800)
16
+ @gap = args[:gap] || 20
17
+ @perpendicular_max = 0
18
+
19
+ super(page, **args)
20
+ end
21
+
22
+ def position_shape(shape)
23
+ fire_after_init
24
+
25
+ position_shape_horizontally(shape) if direction == :horizontal
26
+ position_shape_vertically(shape) if direction == :vertical
27
+ end
28
+
29
+ def to_h
30
+ fire_after_init
31
+
32
+ super.merge(
33
+ direction: direction,
34
+ wrap_at: wrap_at,
35
+ boundary: boundary,
36
+ perpendicular_max: perpendicular_max
37
+ )
38
+ end
39
+
40
+ private
41
+
42
+ # rubocop:disable Metrics/AbcSize
43
+ def position_shape_horizontally(shape)
44
+ boundary_violation = page.position_x + shape.w + gap > boundary
45
+
46
+ if boundary_violation
47
+ page.position_x = anchor_x
48
+ page.position_y += perpendicular_max
49
+ end
50
+
51
+ shape.x = page.position_x
52
+ shape.y = page.position_y
53
+
54
+ return if boundary_violation
55
+
56
+ page.position_x += shape.w + gap
57
+ @perpendicular_max = [perpendicular_max, shape.h].max
58
+ end
59
+ # rubocop:enable Metrics/AbcSize
60
+
61
+ # rubocop:disable Metrics/AbcSize
62
+ def position_shape_vertically(shape)
63
+ boundary_violation = page.position_y + shape.h + gap > boundary
64
+
65
+ if boundary_violation
66
+ page.position_y = anchor_y
67
+ page.position_x += perpendicular_max
68
+ end
69
+
70
+ shape.x = page.position_x
71
+ shape.y = page.position_y
72
+
73
+ return if boundary_violation
74
+
75
+ page.position_y += shape.h + gap
76
+ @perpendicular_max = [perpendicular_max, shape.w].max
77
+ end
78
+ # rubocop:enable Metrics/AbcSize
79
+
80
+ def boundary
81
+ return @boundary if defined? @boundary
82
+
83
+ @boundary = wrap_at + (direction == :horizontal ? anchor_x : anchor_y)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ module Schema
5
+ # Provides grid style layouts
6
+ class GridLayout < Layout
7
+ attr_accessor :direction
8
+ attr_accessor :wrap_at
9
+ attr_accessor :grid_size
10
+ attr_accessor :cell_no
11
+ attr_accessor :h_align
12
+ attr_accessor :v_align
13
+
14
+ def initialize(page, **args)
15
+ @type = :grid_layout
16
+ @direction = args[:direction] || :horizontal
17
+ @wrap_at = args[:wrap_at] || 5
18
+ @grid_size = args[:grid_size] || 220
19
+ @h_align = args[:h_align] || :center
20
+ @v_align = args[:v_align] || :center
21
+ @cell_no = 1
22
+
23
+ super(page, **args)
24
+ end
25
+
26
+ def position_shape(shape)
27
+ fire_after_init
28
+
29
+ shape.x = horizontal_shape_alignment(shape)
30
+ shape.y = vertical_shape_alignment(shape)
31
+
32
+ # puts '------------------'
33
+ # puts "cell: #{cell_no}"
34
+ # puts "wrap_at: #{wrap_at}"
35
+ # puts "shape-x: #{shape.x}"
36
+ # puts "shape-y: #{shape.y}"
37
+ # puts "page-x: #{page.position_x}"
38
+ # puts "page-y: #{page.position_y}"
39
+ # puts "anchor-x: #{anchor_x}"
40
+ # puts "anchor-y: #{anchor_y}"
41
+
42
+ move_cell_horizontally if direction == :horizontal
43
+ move_cell_vertically if direction == :vertical
44
+ end
45
+
46
+ def to_h
47
+ super.merge(
48
+ direction: direction,
49
+ wrap_at: wrap_at,
50
+ grid_size: grid_size,
51
+ cell_no: cell_no
52
+ )
53
+ end
54
+
55
+ private
56
+
57
+ # rubocop:disable Metrics/AbcSize
58
+ def horizontal_shape_alignment(shape)
59
+ return page.position_x + ((grid_size - shape.w) / 2) if h_align == :center
60
+ return page.position_x + (grid_size - shape.w) if h_align == :right
61
+
62
+ page.position_x
63
+ end
64
+ # rubocop:enable Metrics/AbcSize
65
+
66
+ # rubocop:disable Metrics/AbcSize
67
+ def vertical_shape_alignment(shape)
68
+ return page.position_y + ((grid_size - shape.h) / 2) if v_align == :center || v_align == :middle
69
+ return page.position_y + (grid_size - shape.h) if v_align == :bottom
70
+
71
+ page.position_y
72
+ end
73
+ # rubocop:enable Metrics/AbcSize
74
+
75
+ def move_cell_horizontally
76
+ if cell_no < wrap_at
77
+ page.position_x += grid_size
78
+ @cell_no += 1
79
+ return
80
+ end
81
+
82
+ # Flow down to the next row
83
+ page.position_x = anchor_x
84
+ page.position_y += grid_size
85
+ @cell_no = 1
86
+ end
87
+
88
+ def move_cell_vertically
89
+ if cell_no < wrap_at
90
+ page.position_y += grid_size
91
+ @cell_no += 1
92
+ return
93
+ end
94
+
95
+ # Flow right to the next column
96
+ page.position_y = anchor_y
97
+ page.position_x += grid_size
98
+ @cell_no = 1
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ module Schema
5
+ # Provides base configuration for automatic layouts
6
+ class Layout < Node
7
+ attr_accessor :type
8
+
9
+ # represents the x coordinate of the top left corner layout area
10
+ # this coordinate is based on the current location of the page
11
+ attr_accessor :anchor_x
12
+ attr_accessor :anchor_y
13
+
14
+ def initialize(page, **args)
15
+ @after_init_fired = false
16
+
17
+ super(page, **args.merge(classification: :layout_rule))
18
+ end
19
+
20
+ def fire_after_init
21
+ return if @after_init_fired
22
+
23
+ @after_init_fired = true
24
+ after_init
25
+ end
26
+
27
+ def after_init
28
+ @anchor_x ||= page.position_x
29
+ @anchor_y ||= page.position_y
30
+ end
31
+
32
+ def to_h
33
+ super.merge(
34
+ type: type,
35
+ anchor_x: anchor_x,
36
+ anchor_y: anchor_y
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DrawioDsl
4
+ module Schema
5
+ # Node is a base class for shapes, connections, positioners and layout rules
6
+ #
7
+ class Node
8
+ attr_accessor :id
9
+ attr_accessor :page
10
+ attr_accessor :classification
11
+
12
+ def initialize(page, **args)
13
+ @page = page
14
+ @id = args[:id]
15
+ @classification = args[:classification] || :unknown
16
+ end
17
+
18
+ def to_h
19
+ {
20
+ id: id,
21
+ classification: classification
22
+ }
23
+ end
24
+
25
+ # def debug(format: :detail)
26
+ # if format == :detail
27
+ # debug_detail(to_h)
28
+ # else
29
+ # debug_row(classification, id)
30
+ # end
31
+ # end
32
+
33
+ # def debug_detail(**key_values)
34
+ # key_values.each do |key, value|
35
+ # puts "#{key.to_s.ljust(15)}: #{value}"
36
+ # end
37
+ # end
38
+
39
+ #
40
+ # def debug_row(classification, id, type = nil, x = nil, y = nil, width = nil, height = nil)
41
+ # row = []
42
+ # row << classification.to_s.ljust(11)
43
+ # row << id.to_s.ljust(6)
44
+ # row << (type.nil? ? '' : type).to_s.ljust(15)
45
+ # row << (x.nil? ? '' : x).to_s.rjust(5)
46
+ # row << (y.nil? ? '' : y).to_s.rjust(5)
47
+ # row << (width.nil? ? '' : width).to_s.rjust(5)
48
+ # row << (height.nil? ? '' : height).to_s.rjust(5)
49
+ # puts row.join(' | ')
50
+ # end
51
+ end
52
+ end
53
+ end