etassia 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 (727) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +140 -0
  3. data/LICENSE +25 -0
  4. data/README.adoc +436 -0
  5. data/exe/etassia +7 -0
  6. data/lib/etassia/cli.rb +187 -0
  7. data/lib/etassia/commands/batch.rb +210 -0
  8. data/lib/etassia/commands/notation_loader.rb +22 -0
  9. data/lib/etassia/commands/render.rb +98 -0
  10. data/lib/etassia/commands/types.rb +33 -0
  11. data/lib/etassia/commands/version.rb +24 -0
  12. data/lib/etassia/corpus_type_names.rb +52 -0
  13. data/lib/etassia/diagram/architecture.rb +108 -0
  14. data/lib/etassia/diagram/base.rb +61 -0
  15. data/lib/etassia/diagram/block.rb +102 -0
  16. data/lib/etassia/diagram/c4.rb +337 -0
  17. data/lib/etassia/diagram/class_diagram.rb +466 -0
  18. data/lib/etassia/diagram/class_namespace.rb +17 -0
  19. data/lib/etassia/diagram/class_note.rb +17 -0
  20. data/lib/etassia/diagram/containment.rb +107 -0
  21. data/lib/etassia/diagram/er_diagram.rb +317 -0
  22. data/lib/etassia/diagram/error.rb +38 -0
  23. data/lib/etassia/diagram/flowchart.rb +419 -0
  24. data/lib/etassia/diagram/flowchart_label_text.rb +63 -0
  25. data/lib/etassia/diagram/gantt.rb +94 -0
  26. data/lib/etassia/diagram/generic_text.rb +30 -0
  27. data/lib/etassia/diagram/git_graph.rb +57 -0
  28. data/lib/etassia/diagram/info.rb +38 -0
  29. data/lib/etassia/diagram/kanban.rb +198 -0
  30. data/lib/etassia/diagram/mindmap.rb +71 -0
  31. data/lib/etassia/diagram/packet.rb +93 -0
  32. data/lib/etassia/diagram/pie.rb +115 -0
  33. data/lib/etassia/diagram/quadrant.rb +135 -0
  34. data/lib/etassia/diagram/radar.rb +65 -0
  35. data/lib/etassia/diagram/requirement.rb +168 -0
  36. data/lib/etassia/diagram/sankey.rb +217 -0
  37. data/lib/etassia/diagram/sequence.rb +299 -0
  38. data/lib/etassia/diagram/sequence_box.rb +18 -0
  39. data/lib/etassia/diagram/sequence_frame.rb +37 -0
  40. data/lib/etassia/diagram/sequence_frame_section.rb +23 -0
  41. data/lib/etassia/diagram/sequence_text.rb +69 -0
  42. data/lib/etassia/diagram/sequence_wrap.rb +23 -0
  43. data/lib/etassia/diagram/state_diagram.rb +282 -0
  44. data/lib/etassia/diagram/timeline.rb +183 -0
  45. data/lib/etassia/diagram/treemap.rb +95 -0
  46. data/lib/etassia/diagram/user_journey.rb +153 -0
  47. data/lib/etassia/diagram/xy_chart.rb +90 -0
  48. data/lib/etassia/diagram.rb +8 -0
  49. data/lib/etassia/diagram_registry.rb +34 -0
  50. data/lib/etassia/engine.rb +334 -0
  51. data/lib/etassia/error/diagram_type_error.rb +10 -0
  52. data/lib/etassia/error/layout_error.rb +12 -0
  53. data/lib/etassia/error/notation_registration_error.rb +10 -0
  54. data/lib/etassia/error/parse_error.rb +11 -0
  55. data/lib/etassia/error/pipeline_error.rb +10 -0
  56. data/lib/etassia/error/render_error.rb +12 -0
  57. data/lib/etassia/error/score_error.rb +12 -0
  58. data/lib/etassia/error.rb +10 -0
  59. data/lib/etassia/error_report.rb +69 -0
  60. data/lib/etassia/ir/data.rb +39 -0
  61. data/lib/etassia/ir/data_value.rb +35 -0
  62. data/lib/etassia/ir/dimension.rb +10 -0
  63. data/lib/etassia/ir/edge.rb +34 -0
  64. data/lib/etassia/ir/graph.rb +28 -0
  65. data/lib/etassia/ir/integrity.rb +80 -0
  66. data/lib/etassia/ir/item.rb +46 -0
  67. data/lib/etassia/ir/model.rb +56 -0
  68. data/lib/etassia/ir/node.rb +10 -0
  69. data/lib/etassia/ir/placement.rb +47 -0
  70. data/lib/etassia/ir/prepositioned.rb +25 -0
  71. data/lib/etassia/ir/prepositioned_item.rb +26 -0
  72. data/lib/etassia/ir/property_set.rb +43 -0
  73. data/lib/etassia/ir/scalar.rb +25 -0
  74. data/lib/etassia/ir/series.rb +10 -0
  75. data/lib/etassia/ir.rb +17 -0
  76. data/lib/etassia/js_math.rb +511 -0
  77. data/lib/etassia/js_number.rb +64 -0
  78. data/lib/etassia/layout/architecture.rb +1472 -0
  79. data/lib/etassia/layout/base.rb +276 -0
  80. data/lib/etassia/layout/block.rb +738 -0
  81. data/lib/etassia/layout/c4.rb +876 -0
  82. data/lib/etassia/layout/c4_boundary_metrics.rb +35 -0
  83. data/lib/etassia/layout/c4_bounds.rb +106 -0
  84. data/lib/etassia/layout/c4_intersection.rb +77 -0
  85. data/lib/etassia/layout/c4_placement.rb +135 -0
  86. data/lib/etassia/layout/c4_shape_metrics.rb +97 -0
  87. data/lib/etassia/layout/c4_shape_outline.rb +67 -0
  88. data/lib/etassia/layout/c4_stereotype.rb +30 -0
  89. data/lib/etassia/layout/c4_text.rb +54 -0
  90. data/lib/etassia/layout/class_cell_placement.rb +148 -0
  91. data/lib/etassia/layout/class_diagram.rb +1116 -0
  92. data/lib/etassia/layout/class_diagram_namespaces.rb +26 -0
  93. data/lib/etassia/layout/class_diagram_notes.rb +26 -0
  94. data/lib/etassia/layout/class_name_advances.rb +31 -0
  95. data/lib/etassia/layout/class_namespace_box.rb +21 -0
  96. data/lib/etassia/layout/class_namespace_nodes.rb +197 -0
  97. data/lib/etassia/layout/class_namespace_placement.rb +71 -0
  98. data/lib/etassia/layout/class_note.rb +44 -0
  99. data/lib/etassia/layout/class_note_nodes.rb +84 -0
  100. data/lib/etassia/layout/elk_notices.rb +48 -0
  101. data/lib/etassia/layout/elk_placement.rb +197 -0
  102. data/lib/etassia/layout/er_diagram.rb +1002 -0
  103. data/lib/etassia/layout/er_diagram_adjacency.rb +20 -0
  104. data/lib/etassia/layout/er_diagram_alignment.rb +72 -0
  105. data/lib/etassia/layout/er_diagram_compaction.rb +85 -0
  106. data/lib/etassia/layout/er_diagram_conflicts.rb +70 -0
  107. data/lib/etassia/layout/er_diagram_coordinates.rb +104 -0
  108. data/lib/etassia/layout/er_diagram_entity_size.rb +82 -0
  109. data/lib/etassia/layout/er_diagram_layering.rb +109 -0
  110. data/lib/etassia/layout/er_diagram_ordering.rb +143 -0
  111. data/lib/etassia/layout/er_diagram_placement.rb +163 -0
  112. data/lib/etassia/layout/er_diagram_placement_node.rb +22 -0
  113. data/lib/etassia/layout/error.rb +133 -0
  114. data/lib/etassia/layout/flowchart/brandes_koepf.rb +208 -0
  115. data/lib/etassia/layout/flowchart/cluster_reach.rb +70 -0
  116. data/lib/etassia/layout/flowchart/component_packing.rb +129 -0
  117. data/lib/etassia/layout/flowchart/directed_placement.rb +428 -0
  118. data/lib/etassia/layout/flowchart/edge_chains.rb +111 -0
  119. data/lib/etassia/layout/flowchart/edge_order.rb +34 -0
  120. data/lib/etassia/layout/flowchart/edge_router.rb +533 -0
  121. data/lib/etassia/layout/flowchart/label_backdrop_geometry.rb +62 -0
  122. data/lib/etassia/layout/flowchart/layer_spacing.rb +85 -0
  123. data/lib/etassia/layout/flowchart/level_edges.rb +74 -0
  124. data/lib/etassia/layout/flowchart/level_frame.rb +47 -0
  125. data/lib/etassia/layout/flowchart/minimum_rank_spacing.rb +74 -0
  126. data/lib/etassia/layout/flowchart/row_centering.rb +229 -0
  127. data/lib/etassia/layout/flowchart.rb +1290 -0
  128. data/lib/etassia/layout/gantt.rb +814 -0
  129. data/lib/etassia/layout/gantt_duration.rb +49 -0
  130. data/lib/etassia/layout/gantt_exclusions.rb +74 -0
  131. data/lib/etassia/layout/gantt_ticks.rb +165 -0
  132. data/lib/etassia/layout/git_graph.rb +1075 -0
  133. data/lib/etassia/layout/grid.rb +165 -0
  134. data/lib/etassia/layout/info.rb +113 -0
  135. data/lib/etassia/layout/kanban.rb +452 -0
  136. data/lib/etassia/layout/kanban_card_text.rb +95 -0
  137. data/lib/etassia/layout/mindmap.rb +425 -0
  138. data/lib/etassia/layout/mindmap_cose.rb +81 -0
  139. data/lib/etassia/layout/mindmap_cose_body.rb +93 -0
  140. data/lib/etassia/layout/mindmap_cose_geometry.rb +190 -0
  141. data/lib/etassia/layout/mindmap_cose_grid.rb +96 -0
  142. data/lib/etassia/layout/mindmap_cose_link.rb +42 -0
  143. data/lib/etassia/layout/mindmap_cose_relaxation.rb +166 -0
  144. data/lib/etassia/layout/mindmap_cose_seed.rb +93 -0
  145. data/lib/etassia/layout/mindmap_cose_wedge.rb +37 -0
  146. data/lib/etassia/layout/mindmap_node_size.rb +130 -0
  147. data/lib/etassia/layout/packet.rb +285 -0
  148. data/lib/etassia/layout/pie.rb +305 -0
  149. data/lib/etassia/layout/pie_legend.rb +64 -0
  150. data/lib/etassia/layout/pie_legend_entry.rb +21 -0
  151. data/lib/etassia/layout/quadrant.rb +402 -0
  152. data/lib/etassia/layout/radar.rb +442 -0
  153. data/lib/etassia/layout/requirement.rb +765 -0
  154. data/lib/etassia/layout/sankey.rb +501 -0
  155. data/lib/etassia/layout/scene.rb +18 -0
  156. data/lib/etassia/layout/sequence/actor_gaps.rb +151 -0
  157. data/lib/etassia/layout/sequence/box_shape.rb +23 -0
  158. data/lib/etassia/layout/sequence/creations.rb +73 -0
  159. data/lib/etassia/layout/sequence/frame_divider.rb +22 -0
  160. data/lib/etassia/layout/sequence/frame_placement.rb +424 -0
  161. data/lib/etassia/layout/sequence/frame_reader.rb +75 -0
  162. data/lib/etassia/layout/sequence/frame_shape.rb +45 -0
  163. data/lib/etassia/layout/sequence/geometry.rb +24 -0
  164. data/lib/etassia/layout/sequence/message_rows.rb +165 -0
  165. data/lib/etassia/layout/sequence/note.rb +16 -0
  166. data/lib/etassia/layout/sequence/note_box.rb +114 -0
  167. data/lib/etassia/layout/sequence/note_placement.rb +223 -0
  168. data/lib/etassia/layout/sequence/text_width.rb +69 -0
  169. data/lib/etassia/layout/sequence/text_wrap.rb +93 -0
  170. data/lib/etassia/layout/sequence.rb +936 -0
  171. data/lib/etassia/layout/state_diagram.rb +1277 -0
  172. data/lib/etassia/layout/timeline.rb +165 -0
  173. data/lib/etassia/layout/timeline_card.rb +142 -0
  174. data/lib/etassia/layout/timeline_flow.rb +164 -0
  175. data/lib/etassia/layout/timeline_line.rb +33 -0
  176. data/lib/etassia/layout/timeline_rounding.rb +19 -0
  177. data/lib/etassia/layout/timeline_text.rb +105 -0
  178. data/lib/etassia/layout/treemap.rb +303 -0
  179. data/lib/etassia/layout/treemap_placement.rb +52 -0
  180. data/lib/etassia/layout/treemap_squarify.rb +108 -0
  181. data/lib/etassia/layout/user_journey.rb +300 -0
  182. data/lib/etassia/layout/user_journey_face.rb +33 -0
  183. data/lib/etassia/layout/user_journey_face_geometry.rb +80 -0
  184. data/lib/etassia/layout/user_journey_geometry.rb +336 -0
  185. data/lib/etassia/layout/user_journey_legend.rb +84 -0
  186. data/lib/etassia/layout/xy_chart.rb +620 -0
  187. data/lib/etassia/layout.rb +19 -0
  188. data/lib/etassia/lint_debt_scoreboard.rb +219 -0
  189. data/lib/etassia/markdown_text/emphasis_simulator.rb +373 -0
  190. data/lib/etassia/markdown_text.rb +393 -0
  191. data/lib/etassia/notation/builtin.rb +39 -0
  192. data/lib/etassia/notation/entry.rb +15 -0
  193. data/lib/etassia/notation/mermaid/class_diagram_config.rb +42 -0
  194. data/lib/etassia/notation/mermaid/git_graph_config.rb +46 -0
  195. data/lib/etassia/notation/mermaid/ir_adapter.rb +27 -0
  196. data/lib/etassia/notation/mermaid/ir_adapters/architecture.rb +196 -0
  197. data/lib/etassia/notation/mermaid/ir_adapters/block.rb +138 -0
  198. data/lib/etassia/notation/mermaid/ir_adapters/c4.rb +258 -0
  199. data/lib/etassia/notation/mermaid/ir_adapters/class_diagram.rb +257 -0
  200. data/lib/etassia/notation/mermaid/ir_adapters/er_diagram.rb +220 -0
  201. data/lib/etassia/notation/mermaid/ir_adapters/error.rb +32 -0
  202. data/lib/etassia/notation/mermaid/ir_adapters/flowchart.rb +208 -0
  203. data/lib/etassia/notation/mermaid/ir_adapters/gantt.rb +236 -0
  204. data/lib/etassia/notation/mermaid/ir_adapters/git_graph.rb +186 -0
  205. data/lib/etassia/notation/mermaid/ir_adapters/info.rb +34 -0
  206. data/lib/etassia/notation/mermaid/ir_adapters/kanban.rb +110 -0
  207. data/lib/etassia/notation/mermaid/ir_adapters/mindmap.rb +76 -0
  208. data/lib/etassia/notation/mermaid/ir_adapters/packet.rb +51 -0
  209. data/lib/etassia/notation/mermaid/ir_adapters/pie.rb +71 -0
  210. data/lib/etassia/notation/mermaid/ir_adapters/quadrant.rb +116 -0
  211. data/lib/etassia/notation/mermaid/ir_adapters/radar.rb +142 -0
  212. data/lib/etassia/notation/mermaid/ir_adapters/requirement.rb +237 -0
  213. data/lib/etassia/notation/mermaid/ir_adapters/sankey.rb +74 -0
  214. data/lib/etassia/notation/mermaid/ir_adapters/sequence.rb +304 -0
  215. data/lib/etassia/notation/mermaid/ir_adapters/state_diagram.rb +225 -0
  216. data/lib/etassia/notation/mermaid/ir_adapters/timeline.rb +93 -0
  217. data/lib/etassia/notation/mermaid/ir_adapters/treemap.rb +143 -0
  218. data/lib/etassia/notation/mermaid/ir_adapters/user_journey.rb +127 -0
  219. data/lib/etassia/notation/mermaid/ir_adapters/xychart.rb +131 -0
  220. data/lib/etassia/notation/mermaid.rb +399 -0
  221. data/lib/etassia/notation/parsed.rb +31 -0
  222. data/lib/etassia/notation/plantuml/activity/arrow_head.rb +45 -0
  223. data/lib/etassia/notation/plantuml/activity/arrow_style.rb +53 -0
  224. data/lib/etassia/notation/plantuml/activity/bar_columns.rb +75 -0
  225. data/lib/etassia/notation/plantuml/activity/box.rb +60 -0
  226. data/lib/etassia/notation/plantuml/activity/builder.rb +77 -0
  227. data/lib/etassia/notation/plantuml/activity/canvas.rb +117 -0
  228. data/lib/etassia/notation/plantuml/activity/column_centres.rb +151 -0
  229. data/lib/etassia/notation/plantuml/activity/columns.rb +224 -0
  230. data/lib/etassia/notation/plantuml/activity/diagram.rb +35 -0
  231. data/lib/etassia/notation/plantuml/activity/edge.rb +35 -0
  232. data/lib/etassia/notation/plantuml/activity/edge_marks.rb +68 -0
  233. data/lib/etassia/notation/plantuml/activity/exits.rb +61 -0
  234. data/lib/etassia/notation/plantuml/activity/frame_marks.rb +116 -0
  235. data/lib/etassia/notation/plantuml/activity/lane_steps.rb +82 -0
  236. data/lib/etassia/notation/plantuml/activity/lane_titles.rb +46 -0
  237. data/lib/etassia/notation/plantuml/activity/layout.rb +50 -0
  238. data/lib/etassia/notation/plantuml/activity/legacy_parser.rb +181 -0
  239. data/lib/etassia/notation/plantuml/activity/legacy_row_gaps.rb +65 -0
  240. data/lib/etassia/notation/plantuml/activity/mark.rb +23 -0
  241. data/lib/etassia/notation/plantuml/activity/marks.rb +62 -0
  242. data/lib/etassia/notation/plantuml/activity/metrics.rb +169 -0
  243. data/lib/etassia/notation/plantuml/activity/new_parser/blocks.rb +166 -0
  244. data/lib/etassia/notation/plantuml/activity/new_parser.rb +177 -0
  245. data/lib/etassia/notation/plantuml/activity/node.rb +50 -0
  246. data/lib/etassia/notation/plantuml/activity/node_marks.rb +174 -0
  247. data/lib/etassia/notation/plantuml/activity/note.rb +27 -0
  248. data/lib/etassia/notation/plantuml/activity/parser.rb +51 -0
  249. data/lib/etassia/notation/plantuml/activity/placement.rb +327 -0
  250. data/lib/etassia/notation/plantuml/activity/ranking.rb +142 -0
  251. data/lib/etassia/notation/plantuml/activity/reach.rb +58 -0
  252. data/lib/etassia/notation/plantuml/activity/renderer.rb +220 -0
  253. data/lib/etassia/notation/plantuml/activity/route.rb +22 -0
  254. data/lib/etassia/notation/plantuml/activity/router.rb +308 -0
  255. data/lib/etassia/notation/plantuml/activity/row_gaps.rb +105 -0
  256. data/lib/etassia/notation/plantuml/activity/row_spread.rb +59 -0
  257. data/lib/etassia/notation/plantuml/activity/scene.rb +20 -0
  258. data/lib/etassia/notation/plantuml/activity/text.rb +36 -0
  259. data/lib/etassia/notation/plantuml/activity.rb +50 -0
  260. data/lib/etassia/notation/plantuml/arrow.rb +135 -0
  261. data/lib/etassia/notation/plantuml/caption.rb +50 -0
  262. data/lib/etassia/notation/plantuml/caption_layout.rb +97 -0
  263. data/lib/etassia/notation/plantuml/caption_rows.rb +67 -0
  264. data/lib/etassia/notation/plantuml/class_header.rb +178 -0
  265. data/lib/etassia/notation/plantuml/class_name.rb +51 -0
  266. data/lib/etassia/notation/plantuml/component.rb +37 -0
  267. data/lib/etassia/notation/plantuml/creole.rb +278 -0
  268. data/lib/etassia/notation/plantuml/creole_icons.rb +33 -0
  269. data/lib/etassia/notation/plantuml/diagram.rb +60 -0
  270. data/lib/etassia/notation/plantuml/diagram_builder.rb +442 -0
  271. data/lib/etassia/notation/plantuml/diagram_name.rb +51 -0
  272. data/lib/etassia/notation/plantuml/directives.rb +33 -0
  273. data/lib/etassia/notation/plantuml/drawing/box.rb +28 -0
  274. data/lib/etassia/notation/plantuml/drawing/face.rb +39 -0
  275. data/lib/etassia/notation/plantuml/drawing/pen.rb +105 -0
  276. data/lib/etassia/notation/plantuml/drawing/renderer.rb +36 -0
  277. data/lib/etassia/notation/plantuml/drawing/scene.rb +28 -0
  278. data/lib/etassia/notation/plantuml/drawing.rb +19 -0
  279. data/lib/etassia/notation/plantuml/ebnf/blocks.rb +272 -0
  280. data/lib/etassia/notation/plantuml/ebnf/layout.rb +117 -0
  281. data/lib/etassia/notation/plantuml/ebnf/model.rb +22 -0
  282. data/lib/etassia/notation/plantuml/ebnf/reader.rb +131 -0
  283. data/lib/etassia/notation/plantuml/ebnf.rb +34 -0
  284. data/lib/etassia/notation/plantuml/end_texts.rb +78 -0
  285. data/lib/etassia/notation/plantuml/entity.rb +54 -0
  286. data/lib/etassia/notation/plantuml/further.rb +38 -0
  287. data/lib/etassia/notation/plantuml/gantt/layout.rb +269 -0
  288. data/lib/etassia/notation/plantuml/gantt/reader.rb +210 -0
  289. data/lib/etassia/notation/plantuml/gantt/renderer.rb +81 -0
  290. data/lib/etassia/notation/plantuml/gantt.rb +34 -0
  291. data/lib/etassia/notation/plantuml/include/blocks.rb +66 -0
  292. data/lib/etassia/notation/plantuml/include/finder.rb +61 -0
  293. data/lib/etassia/notation/plantuml/include.rb +78 -0
  294. data/lib/etassia/notation/plantuml/ir_adapter/annotations.rb +40 -0
  295. data/lib/etassia/notation/plantuml/ir_adapter/links.rb +91 -0
  296. data/lib/etassia/notation/plantuml/ir_adapter/sink.rb +49 -0
  297. data/lib/etassia/notation/plantuml/ir_adapter/structure.rb +86 -0
  298. data/lib/etassia/notation/plantuml/ir_adapter.rb +32 -0
  299. data/lib/etassia/notation/plantuml/ir_reader/annotations.rb +51 -0
  300. data/lib/etassia/notation/plantuml/ir_reader/index.rb +49 -0
  301. data/lib/etassia/notation/plantuml/ir_reader/links.rb +133 -0
  302. data/lib/etassia/notation/plantuml/ir_reader/structure.rb +83 -0
  303. data/lib/etassia/notation/plantuml/ir_reader.rb +42 -0
  304. data/lib/etassia/notation/plantuml/junction.rb +20 -0
  305. data/lib/etassia/notation/plantuml/klass.rb +41 -0
  306. data/lib/etassia/notation/plantuml/label_clearance.rb +67 -0
  307. data/lib/etassia/notation/plantuml/layout.rb +2806 -0
  308. data/lib/etassia/notation/plantuml/member.rb +37 -0
  309. data/lib/etassia/notation/plantuml/member_icon.rb +87 -0
  310. data/lib/etassia/notation/plantuml/member_icon_elements.rb +91 -0
  311. data/lib/etassia/notation/plantuml/member_pitch.rb +76 -0
  312. data/lib/etassia/notation/plantuml/member_rule.rb +48 -0
  313. data/lib/etassia/notation/plantuml/network/grid.rb +170 -0
  314. data/lib/etassia/notation/plantuml/network/layout.rb +158 -0
  315. data/lib/etassia/notation/plantuml/network/model.rb +22 -0
  316. data/lib/etassia/notation/plantuml/network/placement.rb +64 -0
  317. data/lib/etassia/notation/plantuml/network/reader.rb +126 -0
  318. data/lib/etassia/notation/plantuml/network/shapes.rb +109 -0
  319. data/lib/etassia/notation/plantuml/network.rb +37 -0
  320. data/lib/etassia/notation/plantuml/node_graph/archimate.rb +49 -0
  321. data/lib/etassia/notation/plantuml/node_graph/box_reader.rb +86 -0
  322. data/lib/etassia/notation/plantuml/node_graph/cloud.rb +73 -0
  323. data/lib/etassia/notation/plantuml/node_graph/crows_foot.rb +85 -0
  324. data/lib/etassia/notation/plantuml/node_graph/curve.rb +66 -0
  325. data/lib/etassia/notation/plantuml/node_graph/data_reader.rb +77 -0
  326. data/lib/etassia/notation/plantuml/node_graph/data_shape.rb +39 -0
  327. data/lib/etassia/notation/plantuml/node_graph/detour.rb +98 -0
  328. data/lib/etassia/notation/plantuml/node_graph/edge.rb +26 -0
  329. data/lib/etassia/notation/plantuml/node_graph/entity_metrics.rb +49 -0
  330. data/lib/etassia/notation/plantuml/node_graph/entity_reader.rb +65 -0
  331. data/lib/etassia/notation/plantuml/node_graph/entity_shape.rb +111 -0
  332. data/lib/etassia/notation/plantuml/node_graph/figures.rb +92 -0
  333. data/lib/etassia/notation/plantuml/node_graph/frame_ports.rb +73 -0
  334. data/lib/etassia/notation/plantuml/node_graph/graph.rb +40 -0
  335. data/lib/etassia/notation/plantuml/node_graph/heads.rb +89 -0
  336. data/lib/etassia/notation/plantuml/node_graph/label_fan.rb +76 -0
  337. data/lib/etassia/notation/plantuml/node_graph/label_placer.rb +310 -0
  338. data/lib/etassia/notation/plantuml/node_graph/label_waypoint.rb +47 -0
  339. data/lib/etassia/notation/plantuml/node_graph/layout.rb +293 -0
  340. data/lib/etassia/notation/plantuml/node_graph/link.rb +78 -0
  341. data/lib/etassia/notation/plantuml/node_graph/macros.rb +39 -0
  342. data/lib/etassia/notation/plantuml/node_graph/metrics.rb +113 -0
  343. data/lib/etassia/notation/plantuml/node_graph/node.rb +44 -0
  344. data/lib/etassia/notation/plantuml/node_graph/note_tail.rb +58 -0
  345. data/lib/etassia/notation/plantuml/node_graph/packer.rb +126 -0
  346. data/lib/etassia/notation/plantuml/node_graph/parser.rb +309 -0
  347. data/lib/etassia/notation/plantuml/node_graph/paths.rb +48 -0
  348. data/lib/etassia/notation/plantuml/node_graph/ranking.rb +231 -0
  349. data/lib/etassia/notation/plantuml/node_graph/reader.rb +53 -0
  350. data/lib/etassia/notation/plantuml/node_graph/references.rb +38 -0
  351. data/lib/etassia/notation/plantuml/node_graph/renderer.rb +160 -0
  352. data/lib/etassia/notation/plantuml/node_graph/scene.rb +22 -0
  353. data/lib/etassia/notation/plantuml/node_graph/shapes.rb +302 -0
  354. data/lib/etassia/notation/plantuml/node_graph/skipped_ranks.rb +61 -0
  355. data/lib/etassia/notation/plantuml/node_graph/tab.rb +68 -0
  356. data/lib/etassia/notation/plantuml/node_graph/usecase_ellipse.rb +100 -0
  357. data/lib/etassia/notation/plantuml/node_graph.rb +38 -0
  358. data/lib/etassia/notation/plantuml/note.rb +27 -0
  359. data/lib/etassia/notation/plantuml/note_layout.rb +257 -0
  360. data/lib/etassia/notation/plantuml/note_outline.rb +68 -0
  361. data/lib/etassia/notation/plantuml/objects/map_rows.rb +46 -0
  362. data/lib/etassia/notation/plantuml/objects/reader.rb +208 -0
  363. data/lib/etassia/notation/plantuml/objects.rb +39 -0
  364. data/lib/etassia/notation/plantuml/package.rb +45 -0
  365. data/lib/etassia/notation/plantuml/package_color.rb +32 -0
  366. data/lib/etassia/notation/plantuml/package_frames.rb +178 -0
  367. data/lib/etassia/notation/plantuml/parser.rb +622 -0
  368. data/lib/etassia/notation/plantuml/portion_visibility.rb +91 -0
  369. data/lib/etassia/notation/plantuml/qualified_association_layout.rb +332 -0
  370. data/lib/etassia/notation/plantuml/qualifier_box.rb +78 -0
  371. data/lib/etassia/notation/plantuml/rank_chain.rb +527 -0
  372. data/lib/etassia/notation/plantuml/rank_hierarchy.rb +347 -0
  373. data/lib/etassia/notation/plantuml/relation.rb +103 -0
  374. data/lib/etassia/notation/plantuml/relation_label_separator.rb +199 -0
  375. data/lib/etassia/notation/plantuml/relation_path_points.rb +84 -0
  376. data/lib/etassia/notation/plantuml/renderer.rb +490 -0
  377. data/lib/etassia/notation/plantuml/scene.rb +134 -0
  378. data/lib/etassia/notation/plantuml/segment_box.rb +85 -0
  379. data/lib/etassia/notation/plantuml/sequence/activation.rb +28 -0
  380. data/lib/etassia/notation/plantuml/sequence/appearance.rb +71 -0
  381. data/lib/etassia/notation/plantuml/sequence/arrow_end.rb +23 -0
  382. data/lib/etassia/notation/plantuml/sequence/arrow_marks.rb +111 -0
  383. data/lib/etassia/notation/plantuml/sequence/arrow_style.rb +42 -0
  384. data/lib/etassia/notation/plantuml/sequence/arrow_syntax.rb +122 -0
  385. data/lib/etassia/notation/plantuml/sequence/bar_tracker.rb +59 -0
  386. data/lib/etassia/notation/plantuml/sequence/box.rb +23 -0
  387. data/lib/etassia/notation/plantuml/sequence/chrome.rb +60 -0
  388. data/lib/etassia/notation/plantuml/sequence/chrome_rows.rb +184 -0
  389. data/lib/etassia/notation/plantuml/sequence/create.rb +34 -0
  390. data/lib/etassia/notation/plantuml/sequence/delay.rb +19 -0
  391. data/lib/etassia/notation/plantuml/sequence/destroy.rb +20 -0
  392. data/lib/etassia/notation/plantuml/sequence/diagram.rb +86 -0
  393. data/lib/etassia/notation/plantuml/sequence/divider.rb +19 -0
  394. data/lib/etassia/notation/plantuml/sequence/edge.rb +53 -0
  395. data/lib/etassia/notation/plantuml/sequence/embedded.rb +77 -0
  396. data/lib/etassia/notation/plantuml/sequence/fill.rb +56 -0
  397. data/lib/etassia/notation/plantuml/sequence/fragment.rb +28 -0
  398. data/lib/etassia/notation/plantuml/sequence/fragment_shape.rb +138 -0
  399. data/lib/etassia/notation/plantuml/sequence/head_style.rb +43 -0
  400. data/lib/etassia/notation/plantuml/sequence/ir_adapter/blocks.rb +73 -0
  401. data/lib/etassia/notation/plantuml/sequence/ir_adapter/fills.rb +24 -0
  402. data/lib/etassia/notation/plantuml/sequence/ir_adapter/items.rb +48 -0
  403. data/lib/etassia/notation/plantuml/sequence/ir_adapter/messages.rb +62 -0
  404. data/lib/etassia/notation/plantuml/sequence/ir_adapter/participants.rb +42 -0
  405. data/lib/etassia/notation/plantuml/sequence/ir_adapter/settings.rb +54 -0
  406. data/lib/etassia/notation/plantuml/sequence/ir_adapter.rb +38 -0
  407. data/lib/etassia/notation/plantuml/sequence/ir_reader/blocks.rb +77 -0
  408. data/lib/etassia/notation/plantuml/sequence/ir_reader/fills.rb +27 -0
  409. data/lib/etassia/notation/plantuml/sequence/ir_reader/index.rb +36 -0
  410. data/lib/etassia/notation/plantuml/sequence/ir_reader/items.rb +35 -0
  411. data/lib/etassia/notation/plantuml/sequence/ir_reader/messages.rb +70 -0
  412. data/lib/etassia/notation/plantuml/sequence/ir_reader/participants.rb +42 -0
  413. data/lib/etassia/notation/plantuml/sequence/ir_reader/settings.rb +74 -0
  414. data/lib/etassia/notation/plantuml/sequence/ir_reader.rb +38 -0
  415. data/lib/etassia/notation/plantuml/sequence/keyword_defaults.rb +28 -0
  416. data/lib/etassia/notation/plantuml/sequence/layout.rb +1567 -0
  417. data/lib/etassia/notation/plantuml/sequence/message.rb +97 -0
  418. data/lib/etassia/notation/plantuml/sequence/message_wrap.rb +77 -0
  419. data/lib/etassia/notation/plantuml/sequence/note.rb +61 -0
  420. data/lib/etassia/notation/plantuml/sequence/note_fill.rb +35 -0
  421. data/lib/etassia/notation/plantuml/sequence/note_geometry.rb +126 -0
  422. data/lib/etassia/notation/plantuml/sequence/note_shape.rb +51 -0
  423. data/lib/etassia/notation/plantuml/sequence/numbered_label.rb +57 -0
  424. data/lib/etassia/notation/plantuml/sequence/numbering.rb +49 -0
  425. data/lib/etassia/notation/plantuml/sequence/outline.rb +204 -0
  426. data/lib/etassia/notation/plantuml/sequence/page_break.rb +17 -0
  427. data/lib/etassia/notation/plantuml/sequence/paint.rb +79 -0
  428. data/lib/etassia/notation/plantuml/sequence/parallel_message.rb +19 -0
  429. data/lib/etassia/notation/plantuml/sequence/parser.rb +844 -0
  430. data/lib/etassia/notation/plantuml/sequence/participant.rb +27 -0
  431. data/lib/etassia/notation/plantuml/sequence/picture.rb +29 -0
  432. data/lib/etassia/notation/plantuml/sequence/ref.rb +24 -0
  433. data/lib/etassia/notation/plantuml/sequence/ref_shape.rb +74 -0
  434. data/lib/etassia/notation/plantuml/sequence/refusals.rb +47 -0
  435. data/lib/etassia/notation/plantuml/sequence/renderer.rb +501 -0
  436. data/lib/etassia/notation/plantuml/sequence/scene.rb +200 -0
  437. data/lib/etassia/notation/plantuml/sequence/skin.rb +76 -0
  438. data/lib/etassia/notation/plantuml/sequence/spacing.rb +28 -0
  439. data/lib/etassia/notation/plantuml/sequence/style.rb +151 -0
  440. data/lib/etassia/notation/plantuml/sequence/tab_size.rb +42 -0
  441. data/lib/etassia/notation/plantuml/sequence/walker.rb +1190 -0
  442. data/lib/etassia/notation/plantuml/sequence.rb +47 -0
  443. data/lib/etassia/notation/plantuml/source_lines.rb +33 -0
  444. data/lib/etassia/notation/plantuml/state/axis_solver.rb +272 -0
  445. data/lib/etassia/notation/plantuml/state/cluster_padding.rb +75 -0
  446. data/lib/etassia/notation/plantuml/state/curve.rb +73 -0
  447. data/lib/etassia/notation/plantuml/state/dot_axis.rb +248 -0
  448. data/lib/etassia/notation/plantuml/state/extent.rb +42 -0
  449. data/lib/etassia/notation/plantuml/state/hierarchy.rb +355 -0
  450. data/lib/etassia/notation/plantuml/state/label_clearance.rb +148 -0
  451. data/lib/etassia/notation/plantuml/state/label_reach.rb +139 -0
  452. data/lib/etassia/notation/plantuml/state/layout.rb +173 -0
  453. data/lib/etassia/notation/plantuml/state/level_edges.rb +113 -0
  454. data/lib/etassia/notation/plantuml/state/look.rb +36 -0
  455. data/lib/etassia/notation/plantuml/state/note_shape.rb +73 -0
  456. data/lib/etassia/notation/plantuml/state/plane.rb +85 -0
  457. data/lib/etassia/notation/plantuml/state/ranking.rb +181 -0
  458. data/lib/etassia/notation/plantuml/state/reader.rb +310 -0
  459. data/lib/etassia/notation/plantuml/state/renderer.rb +253 -0
  460. data/lib/etassia/notation/plantuml/state/route_detour.rb +115 -0
  461. data/lib/etassia/notation/plantuml/state/route_geometry.rb +186 -0
  462. data/lib/etassia/notation/plantuml/state/routes.rb +196 -0
  463. data/lib/etassia/notation/plantuml/state/row.rb +88 -0
  464. data/lib/etassia/notation/plantuml/state/rows.rb +50 -0
  465. data/lib/etassia/notation/plantuml/state/stretch.rb +71 -0
  466. data/lib/etassia/notation/plantuml/state.rb +62 -0
  467. data/lib/etassia/notation/plantuml/stereotype_head.rb +58 -0
  468. data/lib/etassia/notation/plantuml/style/bound.rb +34 -0
  469. data/lib/etassia/notation/plantuml/style/colour.rb +41 -0
  470. data/lib/etassia/notation/plantuml/style/colour_names.rb +89 -0
  471. data/lib/etassia/notation/plantuml/style/defaults.rb +33 -0
  472. data/lib/etassia/notation/plantuml/style/inline.rb +56 -0
  473. data/lib/etassia/notation/plantuml/style/reader.rb +242 -0
  474. data/lib/etassia/notation/plantuml/style/sheet.rb +103 -0
  475. data/lib/etassia/notation/plantuml/style.rb +32 -0
  476. data/lib/etassia/notation/plantuml/style_reader.rb +160 -0
  477. data/lib/etassia/notation/plantuml/style_sheet.rb +27 -0
  478. data/lib/etassia/notation/plantuml/styled_relation_curve.rb +71 -0
  479. data/lib/etassia/notation/plantuml/timing/arrows.rb +81 -0
  480. data/lib/etassia/notation/plantuml/timing/axis.rb +100 -0
  481. data/lib/etassia/notation/plantuml/timing/layout.rb +172 -0
  482. data/lib/etassia/notation/plantuml/timing/model.rb +34 -0
  483. data/lib/etassia/notation/plantuml/timing/reader.rb +173 -0
  484. data/lib/etassia/notation/plantuml/timing/signals.rb +328 -0
  485. data/lib/etassia/notation/plantuml/timing.rb +38 -0
  486. data/lib/etassia/notation/plantuml/tree/layout.rb +276 -0
  487. data/lib/etassia/notation/plantuml/tree/mindmap_layout.rb +157 -0
  488. data/lib/etassia/notation/plantuml/tree/reader.rb +186 -0
  489. data/lib/etassia/notation/plantuml/tree/renderer.rb +67 -0
  490. data/lib/etassia/notation/plantuml/tree/role.rb +57 -0
  491. data/lib/etassia/notation/plantuml/tree/rules.rb +156 -0
  492. data/lib/etassia/notation/plantuml/tree/wbs_layout.rb +164 -0
  493. data/lib/etassia/notation/plantuml/tree.rb +41 -0
  494. data/lib/etassia/notation/plantuml/unsupported_construct_error.rb +39 -0
  495. data/lib/etassia/notation/plantuml/unsupported_constructs.rb +103 -0
  496. data/lib/etassia/notation/plantuml/usecase.rb +36 -0
  497. data/lib/etassia/notation/plantuml.rb +132 -0
  498. data/lib/etassia/notation/plantuml_data/boxes/frames.rb +101 -0
  499. data/lib/etassia/notation/plantuml_data/boxes/graph_layout.rb +348 -0
  500. data/lib/etassia/notation/plantuml_data/boxes/heads.rb +65 -0
  501. data/lib/etassia/notation/plantuml_data/boxes/highlights.rb +70 -0
  502. data/lib/etassia/notation/plantuml_data/boxes/inline_rows.rb +99 -0
  503. data/lib/etassia/notation/plantuml_data/boxes/json_reader.rb +24 -0
  504. data/lib/etassia/notation/plantuml_data/boxes/link_text.rb +94 -0
  505. data/lib/etassia/notation/plantuml_data/boxes/marks.rb +76 -0
  506. data/lib/etassia/notation/plantuml_data/boxes/ornaments.rb +130 -0
  507. data/lib/etassia/notation/plantuml_data/boxes/renderer.rb +95 -0
  508. data/lib/etassia/notation/plantuml_data/boxes/row_alignment.rb +58 -0
  509. data/lib/etassia/notation/plantuml_data/boxes/row_bend.rb +43 -0
  510. data/lib/etassia/notation/plantuml_data/boxes/scene.rb +27 -0
  511. data/lib/etassia/notation/plantuml_data/boxes/table.rb +56 -0
  512. data/lib/etassia/notation/plantuml_data/boxes/table_box.rb +355 -0
  513. data/lib/etassia/notation/plantuml_data/boxes/text.rb +101 -0
  514. data/lib/etassia/notation/plantuml_data/boxes/tree_builder.rb +82 -0
  515. data/lib/etassia/notation/plantuml_data/boxes/tree_layout.rb +82 -0
  516. data/lib/etassia/notation/plantuml_data/boxes/yaml_reader.rb +105 -0
  517. data/lib/etassia/notation/plantuml_data/openiconic.LICENSE +6 -0
  518. data/lib/etassia/notation/plantuml_data/openiconic.json +1 -0
  519. data/lib/etassia/notation/plantuml_data.rb +84 -0
  520. data/lib/etassia/notation/plantuml_salt/block.rb +80 -0
  521. data/lib/etassia/notation/plantuml_salt/box.rb +30 -0
  522. data/lib/etassia/notation/plantuml_salt/font_metrics.rb +28 -0
  523. data/lib/etassia/notation/plantuml_salt/grid_marks.rb +66 -0
  524. data/lib/etassia/notation/plantuml_salt/group_marks.rb +77 -0
  525. data/lib/etassia/notation/plantuml_salt/layout.rb +206 -0
  526. data/lib/etassia/notation/plantuml_salt/mark.rb +36 -0
  527. data/lib/etassia/notation/plantuml_salt/markup.rb +57 -0
  528. data/lib/etassia/notation/plantuml_salt/parser.rb +239 -0
  529. data/lib/etassia/notation/plantuml_salt/renderer.rb +138 -0
  530. data/lib/etassia/notation/plantuml_salt/row.rb +19 -0
  531. data/lib/etassia/notation/plantuml_salt/run.rb +34 -0
  532. data/lib/etassia/notation/plantuml_salt/scene.rb +23 -0
  533. data/lib/etassia/notation/plantuml_salt/scroll_marks.rb +94 -0
  534. data/lib/etassia/notation/plantuml_salt/tab_marks.rb +74 -0
  535. data/lib/etassia/notation/plantuml_salt/tree_marks.rb +127 -0
  536. data/lib/etassia/notation/plantuml_salt/widget.rb +40 -0
  537. data/lib/etassia/notation/plantuml_salt/widget_marks.rb +319 -0
  538. data/lib/etassia/notation/plantuml_salt.rb +66 -0
  539. data/lib/etassia/notation/plugin_failure.rb +42 -0
  540. data/lib/etassia/notation.rb +289 -0
  541. data/lib/etassia/parser/architecture.rb +25 -0
  542. data/lib/etassia/parser/atoms/delimited_run.rb +82 -0
  543. data/lib/etassia/parser/atoms/greedy_run.rb +116 -0
  544. data/lib/etassia/parser/atoms/joined.rb +47 -0
  545. data/lib/etassia/parser/atoms/trimmed_run.rb +47 -0
  546. data/lib/etassia/parser/base.rb +258 -0
  547. data/lib/etassia/parser/block.rb +32 -0
  548. data/lib/etassia/parser/builders/architecture.rb +135 -0
  549. data/lib/etassia/parser/builders/block.rb +288 -0
  550. data/lib/etassia/parser/builders/c4.rb +275 -0
  551. data/lib/etassia/parser/builders/capture_string.rb +17 -0
  552. data/lib/etassia/parser/builders/class_diagram.rb +539 -0
  553. data/lib/etassia/parser/builders/er_diagram.rb +308 -0
  554. data/lib/etassia/parser/builders/error.rb +51 -0
  555. data/lib/etassia/parser/builders/flowchart.rb +1150 -0
  556. data/lib/etassia/parser/builders/gantt.rb +267 -0
  557. data/lib/etassia/parser/builders/git_graph.rb +301 -0
  558. data/lib/etassia/parser/builders/info.rb +57 -0
  559. data/lib/etassia/parser/builders/kanban.rb +411 -0
  560. data/lib/etassia/parser/builders/mindmap.rb +271 -0
  561. data/lib/etassia/parser/builders/packet.rb +85 -0
  562. data/lib/etassia/parser/builders/pie.rb +105 -0
  563. data/lib/etassia/parser/builders/quadrant.rb +165 -0
  564. data/lib/etassia/parser/builders/radar.rb +157 -0
  565. data/lib/etassia/parser/builders/requirement.rb +230 -0
  566. data/lib/etassia/parser/builders/sankey.rb +142 -0
  567. data/lib/etassia/parser/builders/sequence.rb +431 -0
  568. data/lib/etassia/parser/builders/sequence_blocks.rb +117 -0
  569. data/lib/etassia/parser/builders/sequence_box_title.rb +57 -0
  570. data/lib/etassia/parser/builders/state_diagram.rb +364 -0
  571. data/lib/etassia/parser/builders/timeline.rb +133 -0
  572. data/lib/etassia/parser/builders/treemap.rb +138 -0
  573. data/lib/etassia/parser/builders/xy_chart.rb +148 -0
  574. data/lib/etassia/parser/c4.rb +37 -0
  575. data/lib/etassia/parser/class_diagram.rb +58 -0
  576. data/lib/etassia/parser/class_namespaces.rb +62 -0
  577. data/lib/etassia/parser/class_notes.rb +54 -0
  578. data/lib/etassia/parser/er_diagram.rb +28 -0
  579. data/lib/etassia/parser/error.rb +30 -0
  580. data/lib/etassia/parser/flowchart.rb +87 -0
  581. data/lib/etassia/parser/gantt.rb +43 -0
  582. data/lib/etassia/parser/git_graph.rb +106 -0
  583. data/lib/etassia/parser/grammars/architecture.rb +165 -0
  584. data/lib/etassia/parser/grammars/block.rb +190 -0
  585. data/lib/etassia/parser/grammars/c4.rb +229 -0
  586. data/lib/etassia/parser/grammars/class_diagram.rb +606 -0
  587. data/lib/etassia/parser/grammars/common.rb +107 -0
  588. data/lib/etassia/parser/grammars/er_diagram.rb +232 -0
  589. data/lib/etassia/parser/grammars/error.rb +32 -0
  590. data/lib/etassia/parser/grammars/flowchart.rb +1722 -0
  591. data/lib/etassia/parser/grammars/gantt.rb +198 -0
  592. data/lib/etassia/parser/grammars/git_graph.rb +234 -0
  593. data/lib/etassia/parser/grammars/info.rb +53 -0
  594. data/lib/etassia/parser/grammars/kanban.rb +417 -0
  595. data/lib/etassia/parser/grammars/mermaid_unicode_text.rb +108 -0
  596. data/lib/etassia/parser/grammars/mindmap.rb +220 -0
  597. data/lib/etassia/parser/grammars/packet.rb +71 -0
  598. data/lib/etassia/parser/grammars/pie.rb +128 -0
  599. data/lib/etassia/parser/grammars/quadrant.rb +202 -0
  600. data/lib/etassia/parser/grammars/radar.rb +158 -0
  601. data/lib/etassia/parser/grammars/requirement.rb +258 -0
  602. data/lib/etassia/parser/grammars/sankey.rb +104 -0
  603. data/lib/etassia/parser/grammars/sequence.rb +940 -0
  604. data/lib/etassia/parser/grammars/state_diagram.rb +382 -0
  605. data/lib/etassia/parser/grammars/timeline.rb +153 -0
  606. data/lib/etassia/parser/grammars/treemap.rb +122 -0
  607. data/lib/etassia/parser/grammars/xy_chart.rb +119 -0
  608. data/lib/etassia/parser/info.rb +32 -0
  609. data/lib/etassia/parser/kanban.rb +131 -0
  610. data/lib/etassia/parser/mermaid_shapes.rb +106 -0
  611. data/lib/etassia/parser/metadata_yaml.rb +452 -0
  612. data/lib/etassia/parser/mindmap.rb +92 -0
  613. data/lib/etassia/parser/native/builders/architecture.rb +103 -0
  614. data/lib/etassia/parser/native/builders/block.rb +68 -0
  615. data/lib/etassia/parser/native/builders/c4.rb +16 -0
  616. data/lib/etassia/parser/native/builders/class_diagram.rb +63 -0
  617. data/lib/etassia/parser/native/builders/er_diagram.rb +47 -0
  618. data/lib/etassia/parser/native/builders/flowchart.rb +58 -0
  619. data/lib/etassia/parser/native/builders/gantt.rb +35 -0
  620. data/lib/etassia/parser/native/builders/gitgraph.rb +35 -0
  621. data/lib/etassia/parser/native/builders/info.rb +30 -0
  622. data/lib/etassia/parser/native/builders/kanban.rb +37 -0
  623. data/lib/etassia/parser/native/builders/mindmap.rb +26 -0
  624. data/lib/etassia/parser/native/builders/packet.rb +63 -0
  625. data/lib/etassia/parser/native/builders/pie.rb +82 -0
  626. data/lib/etassia/parser/native/builders/quadrant.rb +27 -0
  627. data/lib/etassia/parser/native/builders/radar.rb +84 -0
  628. data/lib/etassia/parser/native/builders/requirement.rb +25 -0
  629. data/lib/etassia/parser/native/builders/sankey.rb +18 -0
  630. data/lib/etassia/parser/native/builders/sequence.rb +48 -0
  631. data/lib/etassia/parser/native/builders/state_diagram.rb +61 -0
  632. data/lib/etassia/parser/native/builders/timeline.rb +46 -0
  633. data/lib/etassia/parser/native/builders/treemap.rb +60 -0
  634. data/lib/etassia/parser/native/builders/user_journey.rb +83 -0
  635. data/lib/etassia/parser/native/builders/xy_chart.rb +94 -0
  636. data/lib/etassia/parser/native/declined.rb +12 -0
  637. data/lib/etassia/parser/native/mermaid.json +1 -0
  638. data/lib/etassia/parser/native/text.rb +31 -0
  639. data/lib/etassia/parser/native.rb +99 -0
  640. data/lib/etassia/parser/packet.rb +56 -0
  641. data/lib/etassia/parser/pie.rb +32 -0
  642. data/lib/etassia/parser/quadrant.rb +77 -0
  643. data/lib/etassia/parser/radar.rb +99 -0
  644. data/lib/etassia/parser/requirement.rb +32 -0
  645. data/lib/etassia/parser/sankey.rb +47 -0
  646. data/lib/etassia/parser/sequence.rb +34 -0
  647. data/lib/etassia/parser/state_diagram.rb +29 -0
  648. data/lib/etassia/parser/timeline.rb +40 -0
  649. data/lib/etassia/parser/treemap.rb +25 -0
  650. data/lib/etassia/parser/user_journey.rb +253 -0
  651. data/lib/etassia/parser/xy_chart.rb +98 -0
  652. data/lib/etassia/parser.rb +18 -0
  653. data/lib/etassia/renderer/architecture.rb +232 -0
  654. data/lib/etassia/renderer/architecture_edge_router.rb +379 -0
  655. data/lib/etassia/renderer/base.rb +295 -0
  656. data/lib/etassia/renderer/block.rb +157 -0
  657. data/lib/etassia/renderer/c4.rb +294 -0
  658. data/lib/etassia/renderer/class_diagram.rb +671 -0
  659. data/lib/etassia/renderer/er_diagram.rb +842 -0
  660. data/lib/etassia/renderer/error.rb +131 -0
  661. data/lib/etassia/renderer/flowchart.rb +315 -0
  662. data/lib/etassia/renderer/gantt.rb +177 -0
  663. data/lib/etassia/renderer/git_graph.rb +224 -0
  664. data/lib/etassia/renderer/info.rb +59 -0
  665. data/lib/etassia/renderer/kanban.rb +157 -0
  666. data/lib/etassia/renderer/line_break_text.rb +56 -0
  667. data/lib/etassia/renderer/markdown_text.rb +106 -0
  668. data/lib/etassia/renderer/mindmap.rb +290 -0
  669. data/lib/etassia/renderer/packet.rb +87 -0
  670. data/lib/etassia/renderer/pie.rb +113 -0
  671. data/lib/etassia/renderer/quadrant.rb +189 -0
  672. data/lib/etassia/renderer/radar.rb +191 -0
  673. data/lib/etassia/renderer/requirement.rb +209 -0
  674. data/lib/etassia/renderer/sankey.rb +114 -0
  675. data/lib/etassia/renderer/sequence/frame_drawing.rb +169 -0
  676. data/lib/etassia/renderer/sequence/note_drawing.rb +69 -0
  677. data/lib/etassia/renderer/sequence.rb +490 -0
  678. data/lib/etassia/renderer/state_diagram.rb +202 -0
  679. data/lib/etassia/renderer/timeline.rb +134 -0
  680. data/lib/etassia/renderer/timeline_palette.rb +18 -0
  681. data/lib/etassia/renderer/treemap/section_total.rb +33 -0
  682. data/lib/etassia/renderer/treemap.rb +128 -0
  683. data/lib/etassia/renderer/user_journey.rb +209 -0
  684. data/lib/etassia/renderer/xy_chart.rb +180 -0
  685. data/lib/etassia/renderer.rb +22 -0
  686. data/lib/etassia/runtime.rb +125 -0
  687. data/lib/etassia/source/frontmatter.rb +501 -0
  688. data/lib/etassia/source.rb +224 -0
  689. data/lib/etassia/svg/arrowhead.rb +205 -0
  690. data/lib/etassia/svg/circle.rb +19 -0
  691. data/lib/etassia/svg/document.rb +106 -0
  692. data/lib/etassia/svg/element.rb +209 -0
  693. data/lib/etassia/svg/ellipse.rb +23 -0
  694. data/lib/etassia/svg/escaping.rb +149 -0
  695. data/lib/etassia/svg/group.rb +64 -0
  696. data/lib/etassia/svg/line.rb +21 -0
  697. data/lib/etassia/svg/numbers.rb +53 -0
  698. data/lib/etassia/svg/path.rb +67 -0
  699. data/lib/etassia/svg/path_geometry.rb +378 -0
  700. data/lib/etassia/svg/polygon.rb +25 -0
  701. data/lib/etassia/svg/polyline.rb +28 -0
  702. data/lib/etassia/svg/rect.rb +34 -0
  703. data/lib/etassia/svg/style.rb +50 -0
  704. data/lib/etassia/svg/text.rb +181 -0
  705. data/lib/etassia/svg/tspan.rb +48 -0
  706. data/lib/etassia/svg.rb +38 -0
  707. data/lib/etassia/text_measurement/arial_advances.rb +122 -0
  708. data/lib/etassia/text_measurement/dejavu_advances.rb +111 -0
  709. data/lib/etassia/text_measurement/times_advances.rb +64 -0
  710. data/lib/etassia/text_measurement/trebuchet_advances.rb +53 -0
  711. data/lib/etassia/text_measurement/trebuchet_kerning.rb +29 -0
  712. data/lib/etassia/text_measurement.rb +198 -0
  713. data/lib/etassia/theme/builtin/dark.yml +229 -0
  714. data/lib/etassia/theme/builtin/default.yml +239 -0
  715. data/lib/etassia/theme/builtin/high_contrast.yml +231 -0
  716. data/lib/etassia/theme/builtin/light.yml +229 -0
  717. data/lib/etassia/theme/color_palette.rb +97 -0
  718. data/lib/etassia/theme/completion.rb +50 -0
  719. data/lib/etassia/theme/effect_styles.rb +34 -0
  720. data/lib/etassia/theme/registry.rb +45 -0
  721. data/lib/etassia/theme/shape_styles.rb +34 -0
  722. data/lib/etassia/theme/spacing_config.rb +30 -0
  723. data/lib/etassia/theme/typography.rb +40 -0
  724. data/lib/etassia/theme.rb +73 -0
  725. data/lib/etassia/version.rb +5 -0
  726. data/lib/etassia.rb +40 -0
  727. metadata +865 -0
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "arrow_style"
4
+ require_relative "edge"
5
+
6
+ module Etassia
7
+ module Notation
8
+ module PlantUML
9
+ module Sequence
10
+ # One arrow, normalised so `from` is always the sender: `B <- A` and
11
+ # `A -> B` read the same. `style` is an {ArrowStyle}. `label` is the
12
+ # source text. `from` or `to` is an {Edge} when the message has no
13
+ # participant at that end. `number` is the `autonumber` {Number}, or
14
+ # nil.
15
+ class Message
16
+ Label = Struct.new(:content, :font_family, keyword_init: true)
17
+
18
+ # The text `autonumber` draws before a label, and whether it is bold.
19
+ Number = Struct.new(:text, :bold, keyword_init: true) do
20
+ def to_s
21
+ text
22
+ end
23
+ end
24
+
25
+ attr_reader :from, :to, :label, :style, :number, :label_family
26
+
27
+ def initialize(from:, to:, label:, style:, number: nil)
28
+ @from = from
29
+ @to = to
30
+ @label = label.is_a?(Label) ? label.content : label
31
+ @label_family = label.is_a?(Label) ? label.font_family : nil
32
+ @style = style
33
+ @number = number_of(number)
34
+ freeze
35
+ end
36
+
37
+ # @return [Message] the same message, drawn with `number`
38
+ def numbered(text, bold: true)
39
+ display = Label.new(content: label, font_family: label_family)
40
+ self.class.new(from: from, to: to, label: display, style: style,
41
+ number: text && Number.new(text: text, bold: bold))
42
+ end
43
+
44
+ # @return [String, nil] the weight of the number
45
+ def number_weight
46
+ "bold" if number&.bold
47
+ end
48
+
49
+ def head
50
+ style.head.glyph
51
+ end
52
+
53
+ def dashed
54
+ style.dashed
55
+ end
56
+
57
+ # Written `<-`: a message to its own sender loops out on the left.
58
+ def leftward?
59
+ style.leftward
60
+ end
61
+
62
+ # True for a message written after `&`; see {ParallelMessage}.
63
+ def parallel?
64
+ false
65
+ end
66
+
67
+ def self_message?
68
+ from == to
69
+ end
70
+
71
+ # @return [Edge, nil] the end with no participant
72
+ def edge
73
+ [from, to].grep(Edge).first
74
+ end
75
+
76
+ # @return [Array<String>] the participants the message touches
77
+ def participants
78
+ [from, to].grep_v(Edge)
79
+ end
80
+
81
+ # What is drawn at the {#edge} end.
82
+ def edge_end
83
+ from.is_a?(Edge) ? style.tail : style.head
84
+ end
85
+
86
+ private
87
+
88
+ def number_of(number)
89
+ return number if number.nil? || number.is_a?(Number)
90
+
91
+ Number.new(text: number.to_s, bold: true)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Etassia
4
+ module Notation
5
+ module PlantUML
6
+ module Sequence
7
+ # Splits explicit message lines and wraps each to `Maxmessagesize`.
8
+ # Words fill a line until the next one would pass the limit; a word
9
+ # wider than the limit keeps a line.
10
+ class MessageWrap
11
+ # @param limit [Numeric, nil] widest line, in pixels; nil never wraps
12
+ # @param measure [#call] text width in pixels
13
+ def initialize(limit, measure)
14
+ @limit = limit
15
+ @measure = measure
16
+ end
17
+
18
+ # @return [Array<String>] the lines of `label`
19
+ def lines(label)
20
+ explicit_lines(label).flat_map { |line| wrapped_line(line) }
21
+ end
22
+
23
+ # @return [Float] the width of the widest line of `label`
24
+ def width(label)
25
+ lines(label).map { |line| @measure.call(line) }.max.to_f
26
+ end
27
+
28
+ private
29
+
30
+ def explicit_lines(label)
31
+ decoded = decode_line_breaks(label)
32
+ decoded = decode_quote_escapes(decoded) if doubled_quotes?(label)
33
+ if !decoded.include?("\n") && doubled_quotes?(decoded)
34
+ decoded = decoded[2...-2].strip
35
+ end
36
+ decoded.empty? ? [""] : decoded.split(/\r\n|\r|\n/, -1)
37
+ end
38
+
39
+ def decode_line_breaks(label)
40
+ label.gsub(/(\\+)n/) do
41
+ slashes = Regexp.last_match(1).size
42
+ ("\\" * (slashes / 2)) + (slashes.odd? ? "\n" : "n")
43
+ end
44
+ end
45
+
46
+ def decode_quote_escapes(label)
47
+ label.gsub(/\\+(?![\\n])/) do |slashes|
48
+ "\\" * ((slashes.size + 1) / 2)
49
+ end
50
+ end
51
+
52
+ def doubled_quotes?(label)
53
+ label.start_with?('""') && label.end_with?('""')
54
+ end
55
+
56
+ def wrapped_line(line)
57
+ return [line] unless @limit
58
+
59
+ words = line.split(/[ \t]+/)
60
+ return [""] if words.empty?
61
+
62
+ words.each_with_object([]) { |word, lines| add(lines, word) }
63
+ end
64
+
65
+ def add(lines, word)
66
+ joined = "#{lines.last} #{word}"
67
+ if lines.empty? || @measure.call(joined) > @limit
68
+ lines << word
69
+ else
70
+ lines[-1] = joined
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "embedded"
4
+ require_relative "keyword_defaults"
5
+
6
+ module Etassia
7
+ module Notation
8
+ module PlantUML
9
+ module Sequence
10
+ # A `note`, `hnote` or `rnote`. `side` is :left, :right, :over or
11
+ # :across. `targets` are participant ids; empty for :across and for a
12
+ # left/right note that hangs off the message before it. `parallel` is
13
+ # true when the note began with `&`. `fill` is a {Fill}, or nil for
14
+ # the default note colour. `picture` is the laid-out embedded diagram.
15
+ class Note
16
+ EXTRAS = { parallel: false, fill: nil, picture: nil }.freeze
17
+ private_constant :EXTRAS
18
+
19
+ attr_reader :shape, :side, :targets, :text, :fill, :picture
20
+
21
+ def initialize(shape:, side:, targets:, text:, **extras)
22
+ extras = KeywordDefaults.resolve(extras, EXTRAS)
23
+ @shape = shape
24
+ @side = side
25
+ @targets = targets.freeze
26
+ @text = text
27
+ @parallel = extras[:parallel]
28
+ @fill = extras[:fill]
29
+ @picture = extras[:picture]
30
+ freeze
31
+ end
32
+
33
+ def parallel?
34
+ @parallel
35
+ end
36
+
37
+ # PlantUML also reads the two characters `\n` as a line break.
38
+ def lines
39
+ text.split(/\\n|\n/, -1)
40
+ end
41
+
42
+ # @return [Embedded, nil] the diagram this note holds
43
+ def embedded
44
+ Embedded.read(text)
45
+ end
46
+
47
+ # @param picture [Picture] the embedded diagram, laid out
48
+ # @return [Note] this note with its picture
49
+ def with_picture(picture)
50
+ Note.new(shape: shape, side: side, targets: targets, text: text,
51
+ parallel: parallel?, fill: fill, picture: picture)
52
+ end
53
+
54
+ def attached?
55
+ targets.empty? && %i[left right].include?(side)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "fill"
4
+
5
+ module Etassia
6
+ module Notation
7
+ module PlantUML
8
+ module Sequence
9
+ # The colour written after `note right`: a hex colour in the forms
10
+ # {Fill} reads, or one of the names below, which PlantUML draws as
11
+ # these hex values. Any other name is not read.
12
+ module NoteFill
13
+ extend self
14
+
15
+ NAMES = {
16
+ "red" => "#FF0000", "blue" => "#0000FF", "green" => "#008000",
17
+ "yellow" => "#FFFF00", "orange" => "#FFA500",
18
+ "pink" => "#FFC0CB", "lightblue" => "#ADD8E6",
19
+ "lightgreen" => "#90EE90", "lightgray" => "#D3D3D3",
20
+ "white" => "#FFFFFF", "black" => "#000000", "gray" => "#808080",
21
+ "cyan" => "#00FFFF", "magenta" => "#FF00FF",
22
+ "purple" => "#800080", "aqua" => "#00FFFF"
23
+ }.freeze
24
+
25
+ # @param token [String] such as `#red` or `#ff8800`
26
+ # @return [Fill, nil] nil when the token is not one of the forms
27
+ def read(token)
28
+ hex = NAMES[token.to_s.delete_prefix("#").downcase]
29
+ hex ? Fill.new(hex) : Fill.read(token)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../creole"
4
+ require_relative "../drawing"
5
+
6
+ module Etassia
7
+ module Notation
8
+ module PlantUML
9
+ module Sequence
10
+ # Size and horizontal place of a note, shared by the layout (which
11
+ # widens gaps for it) and the walker (which draws it).
12
+ module NoteGeometry
13
+ extend self
14
+
15
+ PAD = 8.0
16
+ SKIN_FONT_SIZE = 13.0
17
+ OFFSET = 6.0
18
+ OVER_MARGIN = 10.0
19
+ BLOCK_GAP = 5.0
20
+ PICTURE_CHROME = 15.0
21
+ LINE_LEADING = 1.1776
22
+ # PlantUML 1.2026.6 sizes a note box as 10 + 15 per line, though
23
+ # the text inside steps by the font's own leading.
24
+ LINE_PITCH = 15.0
25
+ CHROME = 10.0
26
+ FIRST_BASELINE = 17.568
27
+ private_constant :LINE_PITCH, :CHROME
28
+
29
+ # Width the text needs, without regard to the participants.
30
+ def natural_width(note, font_size)
31
+ return picture_width(note.picture) + (2 * PAD) if note.picture
32
+
33
+ widest = note.lines.map { |line| line_width(line, font_size) }
34
+ widest.max + (2 * PAD)
35
+ end
36
+
37
+ # A line is as wide as it is drawn, in the face the other sequence
38
+ # text is measured in: creole markers and tags take no room, a bold
39
+ # run is measured bold, a `<size:N>` run at its own size, and a
40
+ # monospace run (`""..""`, an undecoded image) in the mono face.
41
+ def line_width(line, font_size, bold: false)
42
+ Creole.parse(line).sum { |run| run_width(run, font_size, bold) }
43
+ end
44
+
45
+ # The widest line of a multi-line label (a newline or a literal
46
+ # backslash-n splits it), each line measured as drawn.
47
+ def widest_line(text, font_size, bold: false)
48
+ lines = text.to_s.split(/\\n|\n/, -1)
49
+ lines.map { |l| line_width(l, font_size, bold: bold) }.max.to_f
50
+ end
51
+
52
+ def line_height(font_size)
53
+ font_size * LINE_LEADING
54
+ end
55
+
56
+ def height(note)
57
+ return picture_height(note.picture) + 14 if note.picture
58
+
59
+ (note.lines.size * LINE_PITCH) + CHROME
60
+ end
61
+
62
+ def picture_inset(picture)
63
+ nested = picture.scene.notes.any?(&:picture)
64
+ nested ? PICTURE_CHROME * picture.scale : 0.0
65
+ end
66
+
67
+ def picture_width(picture)
68
+ picture.width - (2 * picture_inset(picture))
69
+ end
70
+
71
+ def picture_height(picture)
72
+ picture.height - (2 * picture_inset(picture))
73
+ end
74
+
75
+ # @return [Array<Integer>] first and last participant index the
76
+ # note refers to
77
+ def span(note, previous, ids)
78
+ return [0, ids.size - 1] if note.side == :across
79
+ return message_span(previous, ids) if note.attached?
80
+
81
+ note.targets.map { |id| ids.index(id) }.minmax
82
+ end
83
+
84
+ # Where a note on a closed block goes: right of the block, whichever
85
+ # side the source names, level with its top. `block` is the
86
+ # {FragmentShape}.
87
+ #
88
+ # @return [Array<Float>] left edge and width
89
+ def beside(block, natural)
90
+ [block.x + block.width + BLOCK_GAP, natural]
91
+ end
92
+
93
+ # @return [Array<Float>] left edge and width
94
+ def box(note, centers, natural)
95
+ low, high = centers
96
+ case note.side
97
+ when :left then [low - OFFSET - natural, natural]
98
+ when :right then [high + OFFSET, natural]
99
+ else
100
+ width = [natural, high - low + (2 * OVER_MARGIN)].max
101
+ [((low + high) / 2) - (width / 2), width]
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def run_width(run, font_size, bold)
108
+ size = run.style[:size].to_f
109
+ size = font_size unless size.positive?
110
+ if run.style[:mono]
111
+ return TextMeasurement.measure_mono(run.text,
112
+ font_size: size)[:width]
113
+ end
114
+
115
+ Drawing::Face.width(run.text, size: size,
116
+ bold: bold || run.style[:bold])
117
+ end
118
+
119
+ def message_span(message, ids)
120
+ message.participants.map { |id| ids.index(id) }.minmax
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Etassia
4
+ module Notation
5
+ module PlantUML
6
+ module Sequence
7
+ # SVG path data for the three note shapes: a folded corner for
8
+ # `note`, a hexagon for `hnote` and a plain rectangle for `rnote`.
9
+ module NoteShape
10
+ extend self
11
+
12
+ FOLD = 10.0
13
+
14
+ def outline(shape, left, top, width, height)
15
+ right = left + width
16
+ bottom = top + height
17
+ points = case shape
18
+ when :hnote then hexagon(left, top, right, bottom)
19
+ when :rnote then [[left, top], [right, top],
20
+ [right, bottom], [left, bottom]]
21
+ else folded(left, top, right, bottom)
22
+ end
23
+ "M #{points.map { |x, y| "#{x} #{y}" }.join(' L ')} Z"
24
+ end
25
+
26
+ # @return [String, nil] the crease of a folded corner
27
+ def fold(shape, left, top, width)
28
+ return unless shape == :note
29
+
30
+ right = left + width
31
+ "M #{right - FOLD} #{top} L #{right - FOLD} #{top + FOLD} " \
32
+ "L #{right} #{top + FOLD}"
33
+ end
34
+
35
+ private
36
+
37
+ def folded(left, top, right, bottom)
38
+ [[left, top], [right - FOLD, top], [right, top + FOLD],
39
+ [right, bottom], [left, bottom]]
40
+ end
41
+
42
+ def hexagon(left, top, right, bottom)
43
+ middle = (top + bottom) / 2
44
+ [[left + FOLD, top], [right - FOLD, top], [right, middle],
45
+ [right - FOLD, bottom], [left + FOLD, bottom], [left, middle]]
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "scene"
4
+
5
+ module Etassia
6
+ module Notation
7
+ module PlantUML
8
+ module Sequence
9
+ # The label of a message under `autonumber`: its number in bold,
10
+ # then the label, four pixels on. The pair is placed as one unit
11
+ # where the plain label would have been.
12
+ class NumberedLabel
13
+ GAP = 4.0
14
+
15
+ # @param measure [#call] text width in pixels
16
+ def initialize(measure, size: nil, family: nil)
17
+ @measure = measure
18
+ @size = size
19
+ @family = family
20
+ end
21
+
22
+ # @return [Float] the width the number adds to the label
23
+ def extra(message)
24
+ return 0.0 unless message.number
25
+
26
+ @measure.call(message.number.to_s) + GAP
27
+ end
28
+
29
+ # @param anchor [String] where the unit sits at `at_x`: "start",
30
+ # "middle" or "end"
31
+ # @return [Array<Scene::Text>] the number, then the label
32
+ def texts(message, at_x, at_y, anchor)
33
+ left = left_of(message, at_x, anchor)
34
+ [piece(message.number.to_s, left, at_y, "message_number",
35
+ message.number_weight),
36
+ piece(message.label, left + extra(message), at_y, "message_label")]
37
+ end
38
+
39
+ private
40
+
41
+ def left_of(message, at_x, anchor)
42
+ total = extra(message) + @measure.call(message.label)
43
+ { "middle" => at_x - (total / 2), "end" => at_x - total }
44
+ .fetch(anchor, at_x)
45
+ end
46
+
47
+ def piece(content, at_x, at_y, role, weight = nil)
48
+ PlantUML::Scene::Text.new(content: content, x: at_x, y: at_y,
49
+ role: role, anchor: "start",
50
+ weight: weight, size: @size,
51
+ family: @family)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Etassia
4
+ module Notation
5
+ module PlantUML
6
+ module Sequence
7
+ # What an `autonumber` line sets: the first number, the step between
8
+ # numbers and the format. A format is literal text around one run of
9
+ # zeros, which pads the number to that width; a leading `<b>` makes it
10
+ # bold. Without a format the number is bold and unpadded.
11
+ class Numbering
12
+ FORMAT = /\A(?<bold><b>)?(?<before>[^0<>#.]*)(?<zeros>0+)
13
+ (?<after>[^0<>#.]*)\z/x
14
+ private_constant :FORMAT
15
+
16
+ attr_reader :start, :step
17
+
18
+ # @param format [String, nil] the text between the quotes
19
+ # @return [Numbering, nil] nil when the format is not one read
20
+ def self.read(start: 1, step: 1, format: nil)
21
+ return new(start, step) unless format
22
+
23
+ parts = FORMAT.match(format) or return
24
+ new(start, step, parts)
25
+ end
26
+
27
+ def initialize(start, step, parts = nil)
28
+ @start = start
29
+ @step = step
30
+ @parts = parts
31
+ freeze
32
+ end
33
+
34
+ def bold?
35
+ @parts.nil? || !@parts[:bold].nil?
36
+ end
37
+
38
+ # @return [String] the text drawn for the `count`th number
39
+ def text(count)
40
+ return count.to_s unless @parts
41
+
42
+ digits = count.to_s.rjust(@parts[:zeros].length, "0")
43
+ "#{@parts[:before]}#{digits}#{@parts[:after]}"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end