konpeito 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/CHANGELOG.md +75 -0
  4. data/CONTRIBUTING.md +123 -0
  5. data/LICENSE +21 -0
  6. data/README.md +257 -0
  7. data/Rakefile +11 -0
  8. data/bin/konpeito +6 -0
  9. data/konpeito.gemspec +43 -0
  10. data/lib/konpeito/ast/typed_ast.rb +620 -0
  11. data/lib/konpeito/ast/visitor.rb +78 -0
  12. data/lib/konpeito/cache/cache_manager.rb +230 -0
  13. data/lib/konpeito/cache/dependency_graph.rb +192 -0
  14. data/lib/konpeito/cache.rb +8 -0
  15. data/lib/konpeito/cli/base_command.rb +187 -0
  16. data/lib/konpeito/cli/build_command.rb +220 -0
  17. data/lib/konpeito/cli/check_command.rb +104 -0
  18. data/lib/konpeito/cli/config.rb +231 -0
  19. data/lib/konpeito/cli/deps_command.rb +128 -0
  20. data/lib/konpeito/cli/doctor_command.rb +340 -0
  21. data/lib/konpeito/cli/fmt_command.rb +199 -0
  22. data/lib/konpeito/cli/init_command.rb +312 -0
  23. data/lib/konpeito/cli/lsp_command.rb +40 -0
  24. data/lib/konpeito/cli/run_command.rb +150 -0
  25. data/lib/konpeito/cli/test_command.rb +248 -0
  26. data/lib/konpeito/cli/watch_command.rb +212 -0
  27. data/lib/konpeito/cli.rb +301 -0
  28. data/lib/konpeito/codegen/builtin_methods.rb +229 -0
  29. data/lib/konpeito/codegen/cruby_backend.rb +1090 -0
  30. data/lib/konpeito/codegen/debug_info.rb +352 -0
  31. data/lib/konpeito/codegen/inliner.rb +486 -0
  32. data/lib/konpeito/codegen/jvm_backend.rb +197 -0
  33. data/lib/konpeito/codegen/jvm_generator.rb +13412 -0
  34. data/lib/konpeito/codegen/llvm_generator.rb +13191 -0
  35. data/lib/konpeito/codegen/loop_optimizer.rb +363 -0
  36. data/lib/konpeito/codegen/monomorphizer.rb +359 -0
  37. data/lib/konpeito/codegen/profile_runtime.c +341 -0
  38. data/lib/konpeito/codegen/profiler.rb +99 -0
  39. data/lib/konpeito/compiler.rb +592 -0
  40. data/lib/konpeito/dependency_resolver.rb +296 -0
  41. data/lib/konpeito/diagnostics/collector.rb +127 -0
  42. data/lib/konpeito/diagnostics/diagnostic.rb +237 -0
  43. data/lib/konpeito/diagnostics/renderer.rb +144 -0
  44. data/lib/konpeito/formatter/formatter.rb +1214 -0
  45. data/lib/konpeito/hir/builder.rb +7167 -0
  46. data/lib/konpeito/hir/nodes.rb +2465 -0
  47. data/lib/konpeito/lsp/document_manager.rb +820 -0
  48. data/lib/konpeito/lsp/server.rb +183 -0
  49. data/lib/konpeito/lsp/transport.rb +38 -0
  50. data/lib/konpeito/parser/prism_adapter.rb +65 -0
  51. data/lib/konpeito/platform.rb +103 -0
  52. data/lib/konpeito/profile/report.rb +136 -0
  53. data/lib/konpeito/rbs_inline/preprocessor.rb +199 -0
  54. data/lib/konpeito/stdlib/compression/compression.rb +72 -0
  55. data/lib/konpeito/stdlib/compression/compression.rbs +60 -0
  56. data/lib/konpeito/stdlib/compression/compression_native.c +415 -0
  57. data/lib/konpeito/stdlib/compression/extconf.rb +19 -0
  58. data/lib/konpeito/stdlib/crypto/crypto.rb +85 -0
  59. data/lib/konpeito/stdlib/crypto/crypto.rbs +74 -0
  60. data/lib/konpeito/stdlib/crypto/crypto_native.c +312 -0
  61. data/lib/konpeito/stdlib/crypto/extconf.rb +40 -0
  62. data/lib/konpeito/stdlib/http/extconf.rb +19 -0
  63. data/lib/konpeito/stdlib/http/http.rb +125 -0
  64. data/lib/konpeito/stdlib/http/http.rbs +57 -0
  65. data/lib/konpeito/stdlib/http/http_native.c +440 -0
  66. data/lib/konpeito/stdlib/json/extconf.rb +17 -0
  67. data/lib/konpeito/stdlib/json/json.rb +44 -0
  68. data/lib/konpeito/stdlib/json/json.rbs +33 -0
  69. data/lib/konpeito/stdlib/json/json_native.c +286 -0
  70. data/lib/konpeito/stdlib/ui/extconf.rb +216 -0
  71. data/lib/konpeito/stdlib/ui/konpeito_ui_native.cpp +1625 -0
  72. data/lib/konpeito/stdlib/ui/konpeito_ui_native.h +162 -0
  73. data/lib/konpeito/stdlib/ui/ui.rb +318 -0
  74. data/lib/konpeito/stdlib/ui/ui.rbs +247 -0
  75. data/lib/konpeito/type_checker/annotation_parser.rb +67 -0
  76. data/lib/konpeito/type_checker/hm_inferrer.rb +2565 -0
  77. data/lib/konpeito/type_checker/inferrer.rb +565 -0
  78. data/lib/konpeito/type_checker/rbs_loader.rb +1621 -0
  79. data/lib/konpeito/type_checker/type_resolver.rb +276 -0
  80. data/lib/konpeito/type_checker/types.rb +1434 -0
  81. data/lib/konpeito/type_checker/unification.rb +323 -0
  82. data/lib/konpeito/ui/animation/animated_state.rb +80 -0
  83. data/lib/konpeito/ui/animation/easing.rb +59 -0
  84. data/lib/konpeito/ui/animation/value_tween.rb +66 -0
  85. data/lib/konpeito/ui/app.rb +379 -0
  86. data/lib/konpeito/ui/box.rb +38 -0
  87. data/lib/konpeito/ui/castella.rb +70 -0
  88. data/lib/konpeito/ui/castella_native.rb +76 -0
  89. data/lib/konpeito/ui/chart/area_chart.rb +305 -0
  90. data/lib/konpeito/ui/chart/bar_chart.rb +288 -0
  91. data/lib/konpeito/ui/chart/base_chart.rb +210 -0
  92. data/lib/konpeito/ui/chart/chart_helpers.rb +79 -0
  93. data/lib/konpeito/ui/chart/gauge_chart.rb +171 -0
  94. data/lib/konpeito/ui/chart/heatmap_chart.rb +222 -0
  95. data/lib/konpeito/ui/chart/line_chart.rb +289 -0
  96. data/lib/konpeito/ui/chart/pie_chart.rb +219 -0
  97. data/lib/konpeito/ui/chart/scales.rb +77 -0
  98. data/lib/konpeito/ui/chart/scatter_chart.rb +303 -0
  99. data/lib/konpeito/ui/chart/stacked_bar_chart.rb +276 -0
  100. data/lib/konpeito/ui/column.rb +271 -0
  101. data/lib/konpeito/ui/core.rb +2199 -0
  102. data/lib/konpeito/ui/dsl.rb +443 -0
  103. data/lib/konpeito/ui/frame.rb +171 -0
  104. data/lib/konpeito/ui/frame_native.rb +494 -0
  105. data/lib/konpeito/ui/markdown/ast.rb +124 -0
  106. data/lib/konpeito/ui/markdown/mermaid/layout.rb +387 -0
  107. data/lib/konpeito/ui/markdown/mermaid/models.rb +232 -0
  108. data/lib/konpeito/ui/markdown/mermaid/parser.rb +519 -0
  109. data/lib/konpeito/ui/markdown/mermaid/renderer.rb +336 -0
  110. data/lib/konpeito/ui/markdown/parser.rb +805 -0
  111. data/lib/konpeito/ui/markdown/renderer.rb +639 -0
  112. data/lib/konpeito/ui/markdown/theme.rb +165 -0
  113. data/lib/konpeito/ui/render_node.rb +260 -0
  114. data/lib/konpeito/ui/row.rb +207 -0
  115. data/lib/konpeito/ui/spacer.rb +18 -0
  116. data/lib/konpeito/ui/style.rb +799 -0
  117. data/lib/konpeito/ui/theme.rb +563 -0
  118. data/lib/konpeito/ui/themes/material.rb +35 -0
  119. data/lib/konpeito/ui/themes/tokyo_night.rb +6 -0
  120. data/lib/konpeito/ui/widgets/button.rb +103 -0
  121. data/lib/konpeito/ui/widgets/calendar.rb +1034 -0
  122. data/lib/konpeito/ui/widgets/checkbox.rb +119 -0
  123. data/lib/konpeito/ui/widgets/container.rb +91 -0
  124. data/lib/konpeito/ui/widgets/data_table.rb +667 -0
  125. data/lib/konpeito/ui/widgets/divider.rb +29 -0
  126. data/lib/konpeito/ui/widgets/image.rb +105 -0
  127. data/lib/konpeito/ui/widgets/input.rb +485 -0
  128. data/lib/konpeito/ui/widgets/markdown.rb +57 -0
  129. data/lib/konpeito/ui/widgets/modal.rb +163 -0
  130. data/lib/konpeito/ui/widgets/multiline_input.rb +968 -0
  131. data/lib/konpeito/ui/widgets/multiline_text.rb +180 -0
  132. data/lib/konpeito/ui/widgets/net_image.rb +100 -0
  133. data/lib/konpeito/ui/widgets/progress_bar.rb +70 -0
  134. data/lib/konpeito/ui/widgets/radio_buttons.rb +93 -0
  135. data/lib/konpeito/ui/widgets/slider.rb +133 -0
  136. data/lib/konpeito/ui/widgets/switch.rb +84 -0
  137. data/lib/konpeito/ui/widgets/tabs.rb +157 -0
  138. data/lib/konpeito/ui/widgets/text.rb +110 -0
  139. data/lib/konpeito/ui/widgets/tree.rb +426 -0
  140. data/lib/konpeito/version.rb +5 -0
  141. data/lib/konpeito.rb +109 -0
  142. data/test_native_array.rb +172 -0
  143. data/test_native_array_class.rb +197 -0
  144. data/test_native_class.rb +151 -0
  145. data/tools/konpeito-asm/build.sh +65 -0
  146. data/tools/konpeito-asm/lib/asm-9.7.1.jar +0 -0
  147. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KArray.class +0 -0
  148. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KCompression.class +0 -0
  149. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KConditionVariable.class +0 -0
  150. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KCrypto.class +0 -0
  151. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KFile.class +0 -0
  152. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KHTTP.class +0 -0
  153. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KHash.class +0 -0
  154. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KJSON$Parser.class +0 -0
  155. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KJSON.class +0 -0
  156. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KMath.class +0 -0
  157. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KRactor.class +0 -0
  158. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KRactorPort.class +0 -0
  159. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KSizedQueue.class +0 -0
  160. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KThread.class +0 -0
  161. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KTime.class +0 -0
  162. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/RubyDispatch.class +0 -0
  163. data/tools/konpeito-asm/src/ClassIntrospector.java +312 -0
  164. data/tools/konpeito-asm/src/KonpeitoAssembler.java +659 -0
  165. data/tools/konpeito-asm/src/konpeito/runtime/KArray.java +390 -0
  166. data/tools/konpeito-asm/src/konpeito/runtime/KCompression.java +168 -0
  167. data/tools/konpeito-asm/src/konpeito/runtime/KConditionVariable.java +48 -0
  168. data/tools/konpeito-asm/src/konpeito/runtime/KCrypto.java +151 -0
  169. data/tools/konpeito-asm/src/konpeito/runtime/KFile.java +100 -0
  170. data/tools/konpeito-asm/src/konpeito/runtime/KHTTP.java +113 -0
  171. data/tools/konpeito-asm/src/konpeito/runtime/KHash.java +228 -0
  172. data/tools/konpeito-asm/src/konpeito/runtime/KJSON.java +405 -0
  173. data/tools/konpeito-asm/src/konpeito/runtime/KMath.java +54 -0
  174. data/tools/konpeito-asm/src/konpeito/runtime/KRactor.java +244 -0
  175. data/tools/konpeito-asm/src/konpeito/runtime/KRactorPort.java +53 -0
  176. data/tools/konpeito-asm/src/konpeito/runtime/KSizedQueue.java +49 -0
  177. data/tools/konpeito-asm/src/konpeito/runtime/KThread.java +49 -0
  178. data/tools/konpeito-asm/src/konpeito/runtime/KTime.java +53 -0
  179. data/tools/konpeito-asm/src/konpeito/runtime/RubyDispatch.java +416 -0
  180. metadata +267 -0
@@ -0,0 +1,387 @@
1
+ # Mermaid flowchart layout - BFS layered graph layout
2
+ # Assigns x, y, width, height to all nodes and subgraphs
3
+ # Avoids complex data structures (no Hash) for JVM compatibility
4
+
5
+ class MermaidLayout
6
+ def layout(diagram, max_width, padding)
7
+ if diagram.nodes.length == 0
8
+ return
9
+ end
10
+
11
+ assign_layers(diagram)
12
+ calculate_node_sizes(diagram)
13
+
14
+ horizontal = diagram.direction == MERMAID_DIR_LR || diagram.direction == MERMAID_DIR_RL
15
+ if horizontal
16
+ position_horizontal(diagram, padding)
17
+ else
18
+ position_vertical(diagram, padding, max_width)
19
+ end
20
+
21
+ position_subgraphs(diagram)
22
+ end
23
+
24
+ def assign_layers(diagram)
25
+ # Simple BFS layering using node.layer field
26
+ # First, set all layers to -1 (unvisited)
27
+ i = 0
28
+ while i < diagram.nodes.length
29
+ diagram.nodes[i].layer = -1
30
+ i = i + 1
31
+ end
32
+
33
+ # Find root nodes (not a target of any edge)
34
+ i = 0
35
+ while i < diagram.nodes.length
36
+ n = diagram.nodes[i]
37
+ is_root = true
38
+ ei = 0
39
+ while ei < diagram.edges.length
40
+ if diagram.edges[ei].target == n.id
41
+ is_root = false
42
+ break
43
+ end
44
+ ei = ei + 1
45
+ end
46
+ if is_root
47
+ n.layer = 0
48
+ end
49
+ i = i + 1
50
+ end
51
+
52
+ # If no roots, set first node as root
53
+ has_root = false
54
+ i = 0
55
+ while i < diagram.nodes.length
56
+ if diagram.nodes[i].layer == 0
57
+ has_root = true
58
+ break
59
+ end
60
+ i = i + 1
61
+ end
62
+ if !has_root && diagram.nodes.length > 0
63
+ diagram.nodes[0].layer = 0
64
+ end
65
+
66
+ # BFS: propagate layers from roots to children
67
+ # Only assign to unvisited nodes (layer < 0) to handle cycles gracefully
68
+ changed = true
69
+ max_iters = diagram.nodes.length
70
+ iter = 0
71
+ while changed && iter < max_iters
72
+ changed = false
73
+ ei = 0
74
+ while ei < diagram.edges.length
75
+ edge = diagram.edges[ei]
76
+ src = diagram.get_node(edge.source)
77
+ tgt = diagram.get_node(edge.target)
78
+ if src && tgt && src.layer >= 0 && tgt.layer < 0
79
+ tgt.layer = src.layer + 1
80
+ changed = true
81
+ end
82
+ ei = ei + 1
83
+ end
84
+ iter = iter + 1
85
+ end
86
+
87
+ # Set any remaining unvisited nodes to layer 0
88
+ i = 0
89
+ while i < diagram.nodes.length
90
+ if diagram.nodes[i].layer < 0
91
+ diagram.nodes[i].layer = 0
92
+ end
93
+ i = i + 1
94
+ end
95
+ end
96
+
97
+ def calculate_node_sizes(diagram)
98
+ char_width = 8.0
99
+ min_width = 100.0
100
+ node_height = 40.0
101
+
102
+ i = 0
103
+ while i < diagram.nodes.length
104
+ n = diagram.nodes[i]
105
+ label_w = n.label.length * char_width + 24.0
106
+ if label_w < min_width
107
+ label_w = min_width
108
+ end
109
+ n.width = label_w
110
+ n.height = node_height
111
+
112
+ if n.shape == MERMAID_SHAPE_CIRCLE
113
+ max_dim = n.width
114
+ if n.height > max_dim
115
+ max_dim = n.height
116
+ end
117
+ n.width = max_dim
118
+ n.height = max_dim
119
+ elsif n.shape == MERMAID_SHAPE_DIAMOND
120
+ n.width = n.width + 20.0
121
+ n.height = n.width * 0.6
122
+ end
123
+ i = i + 1
124
+ end
125
+ end
126
+
127
+ def max_layer(diagram)
128
+ mx = 0
129
+ i = 0
130
+ while i < diagram.nodes.length
131
+ if diagram.nodes[i].layer > mx
132
+ mx = diagram.nodes[i].layer
133
+ end
134
+ i = i + 1
135
+ end
136
+ mx
137
+ end
138
+
139
+ def position_vertical(diagram, padding, max_width)
140
+ h_spacing = 40.0
141
+ v_spacing = 60.0
142
+ ml = max_layer(diagram)
143
+ reverse = diagram.direction == MERMAID_DIR_BT
144
+
145
+ # First pass: find max total width across all layers
146
+ max_w = find_max_layer_width(diagram, ml, h_spacing)
147
+ if max_w < 1.0
148
+ max_w = max_width
149
+ end
150
+
151
+ # Second pass: position nodes
152
+ y_offset = padding
153
+ layer = 0
154
+ while layer <= ml
155
+ actual = layer
156
+ if reverse
157
+ actual = ml - layer
158
+ end
159
+ position_layer_vertical(diagram, actual, y_offset, padding, max_w, h_spacing)
160
+ tallest = layer_max_height(diagram, actual)
161
+ y_offset = y_offset + tallest + v_spacing
162
+ layer = layer + 1
163
+ end
164
+ end
165
+
166
+ def find_max_layer_width(diagram, ml, spacing)
167
+ max_w = 0.0
168
+ layer = 0
169
+ while layer <= ml
170
+ w = compute_layer_width(diagram, layer, spacing)
171
+ if w > max_w
172
+ max_w = w
173
+ end
174
+ layer = layer + 1
175
+ end
176
+ max_w
177
+ end
178
+
179
+ def compute_layer_width(diagram, layer, spacing)
180
+ total = 0.0
181
+ count = 0
182
+ i = 0
183
+ while i < diagram.nodes.length
184
+ if diagram.nodes[i].layer == layer
185
+ total = total + diagram.nodes[i].width
186
+ count = count + 1
187
+ end
188
+ i = i + 1
189
+ end
190
+ if count > 1
191
+ total = total + (count - 1) * spacing
192
+ end
193
+ total
194
+ end
195
+
196
+ def position_layer_vertical(diagram, layer, y, padding, max_w, spacing)
197
+ lw = compute_layer_width(diagram, layer, spacing)
198
+ start_x = padding + (max_w - lw) / 2.0
199
+ x = start_x
200
+ i = 0
201
+ while i < diagram.nodes.length
202
+ n = diagram.nodes[i]
203
+ if n.layer == layer
204
+ n.x = x
205
+ n.y = y
206
+ x = x + n.width + spacing
207
+ end
208
+ i = i + 1
209
+ end
210
+ end
211
+
212
+ def layer_max_height(diagram, layer)
213
+ mx = 0.0
214
+ i = 0
215
+ while i < diagram.nodes.length
216
+ if diagram.nodes[i].layer == layer && diagram.nodes[i].height > mx
217
+ mx = diagram.nodes[i].height
218
+ end
219
+ i = i + 1
220
+ end
221
+ mx
222
+ end
223
+
224
+ def position_horizontal(diagram, padding)
225
+ h_spacing = 40.0
226
+ v_spacing = 60.0
227
+ ml = max_layer(diagram)
228
+ reverse = diagram.direction == MERMAID_DIR_RL
229
+
230
+ # Find max total height across all layers
231
+ max_h = find_max_layer_height(diagram, ml, h_spacing)
232
+
233
+ # Position nodes
234
+ x_offset = padding
235
+ layer = 0
236
+ while layer <= ml
237
+ actual = layer
238
+ if reverse
239
+ actual = ml - layer
240
+ end
241
+ position_layer_horizontal(diagram, actual, x_offset, padding, max_h, h_spacing)
242
+ widest = layer_max_width(diagram, actual)
243
+ x_offset = x_offset + widest + v_spacing
244
+ layer = layer + 1
245
+ end
246
+ end
247
+
248
+ def find_max_layer_height(diagram, ml, spacing)
249
+ max_h = 0.0
250
+ layer = 0
251
+ while layer <= ml
252
+ h = compute_layer_height(diagram, layer, spacing)
253
+ if h > max_h
254
+ max_h = h
255
+ end
256
+ layer = layer + 1
257
+ end
258
+ max_h
259
+ end
260
+
261
+ def compute_layer_height(diagram, layer, spacing)
262
+ total = 0.0
263
+ count = 0
264
+ i = 0
265
+ while i < diagram.nodes.length
266
+ if diagram.nodes[i].layer == layer
267
+ total = total + diagram.nodes[i].height
268
+ count = count + 1
269
+ end
270
+ i = i + 1
271
+ end
272
+ if count > 1
273
+ total = total + (count - 1) * spacing
274
+ end
275
+ total
276
+ end
277
+
278
+ def position_layer_horizontal(diagram, layer, x, padding, max_h, spacing)
279
+ lh = compute_layer_height(diagram, layer, spacing)
280
+ start_y = padding + (max_h - lh) / 2.0
281
+ y = start_y
282
+ i = 0
283
+ while i < diagram.nodes.length
284
+ n = diagram.nodes[i]
285
+ if n.layer == layer
286
+ n.x = x
287
+ n.y = y
288
+ y = y + n.height + spacing
289
+ end
290
+ i = i + 1
291
+ end
292
+ end
293
+
294
+ def layer_max_width(diagram, layer)
295
+ mx = 0.0
296
+ i = 0
297
+ while i < diagram.nodes.length
298
+ if diagram.nodes[i].layer == layer && diagram.nodes[i].width > mx
299
+ mx = diagram.nodes[i].width
300
+ end
301
+ i = i + 1
302
+ end
303
+ mx
304
+ end
305
+
306
+ def position_subgraphs(diagram)
307
+ sg_padding = 15.0
308
+ title_height = 20.0
309
+
310
+ si = 0
311
+ while si < diagram.subgraphs.length
312
+ sg = diagram.subgraphs[si]
313
+ if sg.node_ids.length > 0
314
+ compute_subgraph_bounds(diagram, sg, sg_padding, title_height)
315
+ end
316
+ si = si + 1
317
+ end
318
+ end
319
+
320
+ def compute_subgraph_bounds(diagram, sg, sg_padding, title_height)
321
+ min_x = 99999.0
322
+ min_y = 99999.0
323
+ max_x = 0.0
324
+ max_y = 0.0
325
+
326
+ ni = 0
327
+ while ni < sg.node_ids.length
328
+ node = diagram.get_node(sg.node_ids[ni])
329
+ if node
330
+ if node.x < min_x
331
+ min_x = node.x
332
+ end
333
+ if node.y < min_y
334
+ min_y = node.y
335
+ end
336
+ right = node.x + node.width
337
+ if right > max_x
338
+ max_x = right
339
+ end
340
+ bottom = node.y + node.height
341
+ if bottom > max_y
342
+ max_y = bottom
343
+ end
344
+ end
345
+ ni = ni + 1
346
+ end
347
+
348
+ sg.x = min_x - sg_padding
349
+ sg.y = min_y - sg_padding - title_height
350
+ sg.width = (max_x - min_x) + sg_padding * 2.0
351
+ sg.height = (max_y - min_y) + sg_padding * 2.0 + title_height
352
+ end
353
+
354
+ def calculate_height(diagram)
355
+ max_y = 0.0
356
+ i = 0
357
+ while i < diagram.nodes.length
358
+ bottom = diagram.nodes[i].y + diagram.nodes[i].height
359
+ if bottom > max_y
360
+ max_y = bottom
361
+ end
362
+ i = i + 1
363
+ end
364
+ i = 0
365
+ while i < diagram.subgraphs.length
366
+ bottom = diagram.subgraphs[i].y + diagram.subgraphs[i].height
367
+ if bottom > max_y
368
+ max_y = bottom
369
+ end
370
+ i = i + 1
371
+ end
372
+ max_y + 20.0
373
+ end
374
+
375
+ def calculate_width(diagram)
376
+ max_x = 0.0
377
+ i = 0
378
+ while i < diagram.nodes.length
379
+ right = diagram.nodes[i].x + diagram.nodes[i].width
380
+ if right > max_x
381
+ max_x = right
382
+ end
383
+ i = i + 1
384
+ end
385
+ max_x + 20.0
386
+ end
387
+ end
@@ -0,0 +1,232 @@
1
+ # Mermaid diagram data models
2
+ # Direction, shape, line type, arrow type constants and node/edge/subgraph classes
3
+
4
+ # Direction constants
5
+ MERMAID_DIR_TB = 0
6
+ MERMAID_DIR_BT = 1
7
+ MERMAID_DIR_LR = 2
8
+ MERMAID_DIR_RL = 3
9
+
10
+ # Node shape constants
11
+ MERMAID_SHAPE_RECT = 0
12
+ MERMAID_SHAPE_ROUNDED = 1
13
+ MERMAID_SHAPE_STADIUM = 2
14
+ MERMAID_SHAPE_CIRCLE = 3
15
+ MERMAID_SHAPE_DIAMOND = 4
16
+ MERMAID_SHAPE_HEXAGON = 5
17
+ MERMAID_SHAPE_SUBROUTINE = 6
18
+
19
+ # Line type constants
20
+ MERMAID_LINE_SOLID = 0
21
+ MERMAID_LINE_DASHED = 1
22
+ MERMAID_LINE_THICK = 2
23
+
24
+ # Arrow type constants
25
+ MERMAID_ARROW_ARROW = 0
26
+ MERMAID_ARROW_OPEN = 1
27
+ MERMAID_ARROW_CIRCLE = 2
28
+ MERMAID_ARROW_CROSS = 3
29
+
30
+ class MermaidNode
31
+ def initialize(id, label, shape)
32
+ @id = id
33
+ @label = label
34
+ @shape = shape
35
+ @x = 0.0
36
+ @y = 0.0
37
+ @width = 0.0
38
+ @height = 0.0
39
+ @layer = 0
40
+ end
41
+
42
+ def id
43
+ @id
44
+ end
45
+
46
+ def label
47
+ @label
48
+ end
49
+
50
+ def label=(v)
51
+ @label = v
52
+ end
53
+
54
+ def shape
55
+ @shape
56
+ end
57
+
58
+ def shape=(v)
59
+ @shape = v
60
+ end
61
+
62
+ def x
63
+ @x
64
+ end
65
+
66
+ def x=(v)
67
+ @x = v
68
+ end
69
+
70
+ def y
71
+ @y
72
+ end
73
+
74
+ def y=(v)
75
+ @y = v
76
+ end
77
+
78
+ def width
79
+ @width
80
+ end
81
+
82
+ def width=(v)
83
+ @width = v
84
+ end
85
+
86
+ def height
87
+ @height
88
+ end
89
+
90
+ def height=(v)
91
+ @height = v
92
+ end
93
+
94
+ def layer
95
+ @layer
96
+ end
97
+
98
+ def layer=(v)
99
+ @layer = v
100
+ end
101
+ end
102
+
103
+ class MermaidEdge
104
+ def initialize(source, target, label, line_type, arrow_type)
105
+ @source = source
106
+ @target = target
107
+ @label = label
108
+ @line_type = line_type
109
+ @arrow_type = arrow_type
110
+ end
111
+
112
+ def source
113
+ @source
114
+ end
115
+
116
+ def target
117
+ @target
118
+ end
119
+
120
+ def label
121
+ @label
122
+ end
123
+
124
+ def line_type
125
+ @line_type
126
+ end
127
+
128
+ def arrow_type
129
+ @arrow_type
130
+ end
131
+ end
132
+
133
+ class MermaidSubgraph
134
+ def initialize(id, title)
135
+ @id = id
136
+ @title = title
137
+ @node_ids = []
138
+ @x = 0.0
139
+ @y = 0.0
140
+ @width = 0.0
141
+ @height = 0.0
142
+ end
143
+
144
+ def id
145
+ @id
146
+ end
147
+
148
+ def title
149
+ @title
150
+ end
151
+
152
+ def node_ids
153
+ @node_ids
154
+ end
155
+
156
+ def x
157
+ @x
158
+ end
159
+
160
+ def x=(v)
161
+ @x = v
162
+ end
163
+
164
+ def y
165
+ @y
166
+ end
167
+
168
+ def y=(v)
169
+ @y = v
170
+ end
171
+
172
+ def width
173
+ @width
174
+ end
175
+
176
+ def width=(v)
177
+ @width = v
178
+ end
179
+
180
+ def height
181
+ @height
182
+ end
183
+
184
+ def height=(v)
185
+ @height = v
186
+ end
187
+ end
188
+
189
+ class MermaidDiagram
190
+ def initialize(direction)
191
+ @direction = direction
192
+ @nodes = []
193
+ @edges = []
194
+ @subgraphs = []
195
+ @node_map = {}
196
+ end
197
+
198
+ def direction
199
+ @direction
200
+ end
201
+
202
+ def nodes
203
+ @nodes
204
+ end
205
+
206
+ def edges
207
+ @edges
208
+ end
209
+
210
+ def subgraphs
211
+ @subgraphs
212
+ end
213
+
214
+ def add_node(node)
215
+ if !@node_map[node.id]
216
+ @nodes.push(node)
217
+ @node_map[node.id] = node
218
+ end
219
+ end
220
+
221
+ def get_node(id)
222
+ @node_map[id]
223
+ end
224
+
225
+ def add_edge(edge)
226
+ @edges.push(edge)
227
+ end
228
+
229
+ def add_subgraph(sg)
230
+ @subgraphs.push(sg)
231
+ end
232
+ end