sirena 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 (382) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/build_deploy.yml +59 -0
  3. data/.github/workflows/links.yml +85 -0
  4. data/.github/workflows/rake.yml +15 -0
  5. data/.github/workflows/release.yml +27 -0
  6. data/.gitignore +68 -0
  7. data/.rspec +3 -0
  8. data/.rubocop.yml +14 -0
  9. data/.rubocop_todo.yml +70 -0
  10. data/ARCHITECTURE.md +744 -0
  11. data/Gemfile +12 -0
  12. data/LICENSE +25 -0
  13. data/README.adoc +357 -0
  14. data/Rakefile +11 -0
  15. data/docs/.gitignore +1 -0
  16. data/docs/Gemfile +13 -0
  17. data/docs/_config.yml +182 -0
  18. data/docs/_diagram_types/architecture-diagram.adoc +314 -0
  19. data/docs/_diagram_types/block-diagram.adoc +345 -0
  20. data/docs/_diagram_types/c4-diagram.adoc +559 -0
  21. data/docs/_diagram_types/class-diagram.adoc +816 -0
  22. data/docs/_diagram_types/er-diagram.adoc +719 -0
  23. data/docs/_diagram_types/error-diagram.adoc +114 -0
  24. data/docs/_diagram_types/examples/flowchart-examples.adoc +29 -0
  25. data/docs/_diagram_types/flowchart.adoc +488 -0
  26. data/docs/_diagram_types/gantt-chart.adoc +502 -0
  27. data/docs/_diagram_types/git-graph.adoc +600 -0
  28. data/docs/_diagram_types/index.adoc +192 -0
  29. data/docs/_diagram_types/info-diagram.adoc +103 -0
  30. data/docs/_diagram_types/kanban-diagram.adoc +262 -0
  31. data/docs/_diagram_types/mindmap.adoc +603 -0
  32. data/docs/_diagram_types/packet-diagram.adoc +378 -0
  33. data/docs/_diagram_types/pie-chart.adoc +335 -0
  34. data/docs/_diagram_types/quadrant-chart.adoc +406 -0
  35. data/docs/_diagram_types/radar-chart.adoc +528 -0
  36. data/docs/_diagram_types/requirement-diagram.adoc +416 -0
  37. data/docs/_diagram_types/sankey-diagram.adoc +357 -0
  38. data/docs/_diagram_types/sequence-diagram.adoc +664 -0
  39. data/docs/_diagram_types/state-diagram.adoc +658 -0
  40. data/docs/_diagram_types/timeline.adoc +352 -0
  41. data/docs/_diagram_types/treemap-diagram.adoc +462 -0
  42. data/docs/_diagram_types/user-journey.adoc +602 -0
  43. data/docs/_features/index.adoc +129 -0
  44. data/docs/_guides/cli-reference.adoc +203 -0
  45. data/docs/_guides/index.adoc +56 -0
  46. data/docs/_guides/installation.adoc +100 -0
  47. data/docs/_guides/quick-start.adoc +132 -0
  48. data/docs/_pages/comparison.adoc +441 -0
  49. data/docs/_pages/compatibility.adoc +300 -0
  50. data/docs/_pages/index.adoc +39 -0
  51. data/docs/_references/index.adoc +103 -0
  52. data/docs/_tutorials/index.adoc +57 -0
  53. data/docs/index.adoc +166 -0
  54. data/docs/lychee.toml +54 -0
  55. data/examples/.gitignore +10 -0
  56. data/examples/README.adoc +196 -0
  57. data/examples/README.md +64 -0
  58. data/examples/architecture/01-basic-services.mmd +9 -0
  59. data/examples/architecture/01-basic-services.svg +37 -0
  60. data/examples/architecture/02-service-groups.mmd +16 -0
  61. data/examples/architecture/02-service-groups.svg +55 -0
  62. data/examples/architecture/README.adoc +79 -0
  63. data/examples/block/01-basic-blocks.mmd +13 -0
  64. data/examples/block/01-basic-blocks.svg +44 -0
  65. data/examples/block/02-block-shapes.mmd +13 -0
  66. data/examples/block/02-block-shapes.svg +47 -0
  67. data/examples/block/README.adoc +85 -0
  68. data/examples/c4/01-context-diagram.mmd +10 -0
  69. data/examples/c4/01-context-diagram.svg +45 -0
  70. data/examples/c4/02-container-diagram.mmd +24 -0
  71. data/examples/c4/02-container-diagram.svg +105 -0
  72. data/examples/c4/README.adoc +92 -0
  73. data/examples/class_diagram/01-basic-classes.mmd +61 -0
  74. data/examples/class_diagram/01-basic-classes.svg +117 -0
  75. data/examples/class_diagram/02-relationships.mmd +61 -0
  76. data/examples/class_diagram/02-relationships.svg +129 -0
  77. data/examples/class_diagram/README.adoc +93 -0
  78. data/examples/er_diagram/01-basic-entities.mmd +64 -0
  79. data/examples/er_diagram/01-basic-entities.svg +5 -0
  80. data/examples/er_diagram/02-cardinality.mmd +57 -0
  81. data/examples/er_diagram/02-cardinality.svg +125 -0
  82. data/examples/er_diagram/README.adoc +88 -0
  83. data/examples/error/01-basic-error.mmd +1 -0
  84. data/examples/error/01-basic-error.svg +13 -0
  85. data/examples/error/02-error-display.mmd +1 -0
  86. data/examples/error/02-error-display.svg +13 -0
  87. data/examples/error/README.adoc +71 -0
  88. data/examples/error_message_example.svg +13 -0
  89. data/examples/flowchart/00-original.mmd +13 -0
  90. data/examples/flowchart/00-original.svg +5 -0
  91. data/examples/flowchart/01-basic-flow.mmd +7 -0
  92. data/examples/flowchart/01-basic-flow.svg +52 -0
  93. data/examples/flowchart/01-basic-flow.yml +13 -0
  94. data/examples/flowchart/02*.svg +87 -0
  95. data/examples/flowchart/02-node-shapes.mmd +9 -0
  96. data/examples/flowchart/02-node-shapes.svg +33 -0
  97. data/examples/flowchart/03-edge-types.mmd +7 -0
  98. data/examples/flowchart/03-edge-types.svg +53 -0
  99. data/examples/flowchart/04-subgraphs.mmd +9 -0
  100. data/examples/flowchart/04-subgraphs.svg +33 -0
  101. data/examples/flowchart/05-styling.mmd +9 -0
  102. data/examples/flowchart/05-styling.svg +33 -0
  103. data/examples/flowchart/06-complex-flow.mmd +8 -0
  104. data/examples/flowchart/06-complex-flow.svg +59 -0
  105. data/examples/flowchart/README.adoc +167 -0
  106. data/examples/gantt/01-simple-timeline.* +14 -0
  107. data/examples/gantt/01-simple-timeline.mmd +6 -0
  108. data/examples/gantt/01-simple-timeline.svg +26 -0
  109. data/examples/gantt/02-task-dependencies.mmd +6 -0
  110. data/examples/gantt/02-task-dependencies.svg +26 -0
  111. data/examples/gantt/README.adoc +86 -0
  112. data/examples/git_graph/01-linear-history.mmd +12 -0
  113. data/examples/git_graph/01-linear-history.svg +26 -0
  114. data/examples/git_graph/02-branching.mmd +12 -0
  115. data/examples/git_graph/02-branching.svg +26 -0
  116. data/examples/git_graph/README.adoc +73 -0
  117. data/examples/info/02-showinfo.mmd +1 -0
  118. data/examples/info/02-showinfo.svg +10 -0
  119. data/examples/info/README.adoc +58 -0
  120. data/examples/info_showinfo_example.svg +10 -0
  121. data/examples/kanban/01-simple-board.mmd +8 -0
  122. data/examples/kanban/01-simple-board.svg +43 -0
  123. data/examples/kanban/02-workflow.mmd +8 -0
  124. data/examples/kanban/02-workflow.svg +43 -0
  125. data/examples/kanban/README.adoc +79 -0
  126. data/examples/mindmap/01-simple-tree.mmd +19 -0
  127. data/examples/mindmap/01-simple-tree.svg +61 -0
  128. data/examples/mindmap/02-knowledge-map.mmd +19 -0
  129. data/examples/mindmap/02-knowledge-map.svg +61 -0
  130. data/examples/mindmap/README.adoc +77 -0
  131. data/examples/packet/01-basic-packet.* +17 -0
  132. data/examples/packet/01-basic-packet.mmd +4 -0
  133. data/examples/packet/01-basic-packet.svg +82 -0
  134. data/examples/packet/README.adoc +58 -0
  135. data/examples/pie/01-simple-chart.mmd +5 -0
  136. data/examples/pie/01-simple-chart.svg +17 -0
  137. data/examples/pie/02-labeled-slices.mmd +6 -0
  138. data/examples/pie/02-labeled-slices.svg +19 -0
  139. data/examples/pie/README.adoc +75 -0
  140. data/examples/quadrant/01-basic-quadrant.mmd +13 -0
  141. data/examples/quadrant/01-basic-quadrant.svg +33 -0
  142. data/examples/quadrant/02-positioned-items.mmd +14 -0
  143. data/examples/quadrant/02-positioned-items.svg +35 -0
  144. data/examples/quadrant/README.adoc +84 -0
  145. data/examples/radar/01-simple-radar.* +5 -0
  146. data/examples/radar/01-simple-radar.mmd +3 -0
  147. data/examples/radar/01-simple-radar.svg +25 -0
  148. data/examples/radar/02-multiple-curves.mmd +4 -0
  149. data/examples/radar/02-multiple-curves.svg +43 -0
  150. data/examples/radar/README.adoc +75 -0
  151. data/examples/requirement/01-basic-requirements.mmd +23 -0
  152. data/examples/requirement/01-basic-requirements.svg +49 -0
  153. data/examples/requirement/02-risk-levels.mmd +23 -0
  154. data/examples/requirement/02-risk-levels.svg +49 -0
  155. data/examples/requirement/README.adoc +85 -0
  156. data/examples/sankey/01-simple-flow.mmd +7 -0
  157. data/examples/sankey/01-simple-flow.svg +34 -0
  158. data/examples/sankey/02-multi-stage.mmd +11 -0
  159. data/examples/sankey/02-multi-stage.svg +44 -0
  160. data/examples/sankey/README.adoc +74 -0
  161. data/examples/sequence/01-basic-sequence.mmd +27 -0
  162. data/examples/sequence/01-basic-sequence.svg +5 -0
  163. data/examples/sequence/02-activations.mmd +17 -0
  164. data/examples/sequence/02-activations.svg +78 -0
  165. data/examples/sequence/README.adoc +86 -0
  166. data/examples/state_diagram/01-simple-states.mmd +29 -0
  167. data/examples/state_diagram/01-simple-states.svg +5 -0
  168. data/examples/state_diagram/02-composite.mmd +19 -0
  169. data/examples/state_diagram/02-composite.svg +81 -0
  170. data/examples/state_diagram/README.adoc +90 -0
  171. data/examples/timeline/01-simple-timeline.mmd +11 -0
  172. data/examples/timeline/01-simple-timeline.svg +36 -0
  173. data/examples/timeline/02-periods.mmd +15 -0
  174. data/examples/timeline/02-periods.svg +47 -0
  175. data/examples/timeline/README.adoc +78 -0
  176. data/examples/treemap/01-basic-treemap.mmd +12 -0
  177. data/examples/treemap/01-basic-treemap.svg +59 -0
  178. data/examples/treemap/README.adoc +59 -0
  179. data/examples/user_journey/01-simple-journey.mmd +23 -0
  180. data/examples/user_journey/01-simple-journey.svg +5 -0
  181. data/examples/user_journey/02-multi-actor.mmd +18 -0
  182. data/examples/user_journey/02-multi-actor.svg +129 -0
  183. data/examples/user_journey/README.adoc +81 -0
  184. data/examples/xychart/01-line-chart.mmd +5 -0
  185. data/examples/xychart/01-line-chart.svg +43 -0
  186. data/examples/xychart/02-bar-chart.mmd +7 -0
  187. data/examples/xychart/02-bar-chart.svg +48 -0
  188. data/examples/xychart/README.adoc +80 -0
  189. data/exe/sirena +7 -0
  190. data/lib/sirena/cli.rb +138 -0
  191. data/lib/sirena/commands/batch.rb +117 -0
  192. data/lib/sirena/commands/render.rb +80 -0
  193. data/lib/sirena/commands/types.rb +29 -0
  194. data/lib/sirena/commands/version.rb +24 -0
  195. data/lib/sirena/diagram/architecture.rb +46 -0
  196. data/lib/sirena/diagram/base.rb +61 -0
  197. data/lib/sirena/diagram/block.rb +81 -0
  198. data/lib/sirena/diagram/c4.rb +328 -0
  199. data/lib/sirena/diagram/class_diagram.rb +385 -0
  200. data/lib/sirena/diagram/er_diagram.rb +238 -0
  201. data/lib/sirena/diagram/error.rb +38 -0
  202. data/lib/sirena/diagram/flowchart.rb +160 -0
  203. data/lib/sirena/diagram/gantt.rb +71 -0
  204. data/lib/sirena/diagram/git_graph.rb +36 -0
  205. data/lib/sirena/diagram/info.rb +38 -0
  206. data/lib/sirena/diagram/kanban.rb +178 -0
  207. data/lib/sirena/diagram/mindmap.rb +54 -0
  208. data/lib/sirena/diagram/packet.rb +79 -0
  209. data/lib/sirena/diagram/pie.rb +115 -0
  210. data/lib/sirena/diagram/quadrant.rb +138 -0
  211. data/lib/sirena/diagram/radar.rb +52 -0
  212. data/lib/sirena/diagram/requirement.rb +133 -0
  213. data/lib/sirena/diagram/sankey.rb +217 -0
  214. data/lib/sirena/diagram/sequence.rb +242 -0
  215. data/lib/sirena/diagram/state_diagram.rb +237 -0
  216. data/lib/sirena/diagram/timeline.rb +171 -0
  217. data/lib/sirena/diagram/treemap.rb +84 -0
  218. data/lib/sirena/diagram/user_journey.rb +149 -0
  219. data/lib/sirena/diagram/xy_chart.rb +76 -0
  220. data/lib/sirena/diagram.rb +8 -0
  221. data/lib/sirena/diagram_registry.rb +101 -0
  222. data/lib/sirena/engine.rb +292 -0
  223. data/lib/sirena/parser/architecture.rb +41 -0
  224. data/lib/sirena/parser/base.rb +41 -0
  225. data/lib/sirena/parser/block.rb +72 -0
  226. data/lib/sirena/parser/c4.rb +53 -0
  227. data/lib/sirena/parser/class_diagram.rb +63 -0
  228. data/lib/sirena/parser/er_diagram.rb +40 -0
  229. data/lib/sirena/parser/error.rb +49 -0
  230. data/lib/sirena/parser/flowchart.rb +71 -0
  231. data/lib/sirena/parser/gantt.rb +60 -0
  232. data/lib/sirena/parser/git_graph.rb +95 -0
  233. data/lib/sirena/parser/grammars/architecture.rb +145 -0
  234. data/lib/sirena/parser/grammars/block.rb +190 -0
  235. data/lib/sirena/parser/grammars/c4.rb +226 -0
  236. data/lib/sirena/parser/grammars/class_diagram.rb +284 -0
  237. data/lib/sirena/parser/grammars/common.rb +84 -0
  238. data/lib/sirena/parser/grammars/er_diagram.rb +114 -0
  239. data/lib/sirena/parser/grammars/error.rb +40 -0
  240. data/lib/sirena/parser/grammars/flowchart.rb +298 -0
  241. data/lib/sirena/parser/grammars/gantt.rb +252 -0
  242. data/lib/sirena/parser/grammars/git_graph.rb +167 -0
  243. data/lib/sirena/parser/grammars/info.rb +58 -0
  244. data/lib/sirena/parser/grammars/kanban.rb +83 -0
  245. data/lib/sirena/parser/grammars/mindmap.rb +115 -0
  246. data/lib/sirena/parser/grammars/packet.rb +73 -0
  247. data/lib/sirena/parser/grammars/pie.rb +128 -0
  248. data/lib/sirena/parser/grammars/quadrant.rb +199 -0
  249. data/lib/sirena/parser/grammars/radar.rb +150 -0
  250. data/lib/sirena/parser/grammars/requirement.rb +188 -0
  251. data/lib/sirena/parser/grammars/sankey.rb +104 -0
  252. data/lib/sirena/parser/grammars/sequence.rb +247 -0
  253. data/lib/sirena/parser/grammars/state_diagram.rb +172 -0
  254. data/lib/sirena/parser/grammars/timeline.rb +142 -0
  255. data/lib/sirena/parser/grammars/treemap.rb +120 -0
  256. data/lib/sirena/parser/grammars/xy_chart.rb +120 -0
  257. data/lib/sirena/parser/info.rb +49 -0
  258. data/lib/sirena/parser/kanban.rb +97 -0
  259. data/lib/sirena/parser/mindmap.rb +106 -0
  260. data/lib/sirena/parser/packet.rb +76 -0
  261. data/lib/sirena/parser/pie.rb +49 -0
  262. data/lib/sirena/parser/quadrant.rb +57 -0
  263. data/lib/sirena/parser/radar.rb +104 -0
  264. data/lib/sirena/parser/requirement.rb +70 -0
  265. data/lib/sirena/parser/sankey.rb +64 -0
  266. data/lib/sirena/parser/sequence.rb +51 -0
  267. data/lib/sirena/parser/state_diagram.rb +69 -0
  268. data/lib/sirena/parser/timeline.rb +57 -0
  269. data/lib/sirena/parser/transforms/architecture.rb +97 -0
  270. data/lib/sirena/parser/transforms/block.rb +254 -0
  271. data/lib/sirena/parser/transforms/c4.rb +347 -0
  272. data/lib/sirena/parser/transforms/class_diagram.rb +352 -0
  273. data/lib/sirena/parser/transforms/er_diagram.rb +169 -0
  274. data/lib/sirena/parser/transforms/error.rb +58 -0
  275. data/lib/sirena/parser/transforms/flowchart.rb +293 -0
  276. data/lib/sirena/parser/transforms/gantt.rb +215 -0
  277. data/lib/sirena/parser/transforms/git_graph.rb +160 -0
  278. data/lib/sirena/parser/transforms/info.rb +58 -0
  279. data/lib/sirena/parser/transforms/kanban.rb +176 -0
  280. data/lib/sirena/parser/transforms/mindmap.rb +227 -0
  281. data/lib/sirena/parser/transforms/packet.rb +63 -0
  282. data/lib/sirena/parser/transforms/pie.rb +143 -0
  283. data/lib/sirena/parser/transforms/quadrant.rb +177 -0
  284. data/lib/sirena/parser/transforms/radar.rb +126 -0
  285. data/lib/sirena/parser/transforms/requirement.rb +272 -0
  286. data/lib/sirena/parser/transforms/sankey.rb +122 -0
  287. data/lib/sirena/parser/transforms/sequence.rb +342 -0
  288. data/lib/sirena/parser/transforms/state_diagram.rb +292 -0
  289. data/lib/sirena/parser/transforms/timeline.rb +177 -0
  290. data/lib/sirena/parser/transforms/treemap.rb +81 -0
  291. data/lib/sirena/parser/transforms/xy_chart.rb +132 -0
  292. data/lib/sirena/parser/treemap.rb +98 -0
  293. data/lib/sirena/parser/user_journey.rb +120 -0
  294. data/lib/sirena/parser/xy_chart.rb +114 -0
  295. data/lib/sirena/parser.rb +8 -0
  296. data/lib/sirena/renderer/architecture.rb +251 -0
  297. data/lib/sirena/renderer/base.rb +251 -0
  298. data/lib/sirena/renderer/block.rb +286 -0
  299. data/lib/sirena/renderer/c4.rb +490 -0
  300. data/lib/sirena/renderer/class_diagram.rb +499 -0
  301. data/lib/sirena/renderer/er_diagram.rb +417 -0
  302. data/lib/sirena/renderer/error.rb +131 -0
  303. data/lib/sirena/renderer/flowchart.rb +301 -0
  304. data/lib/sirena/renderer/gantt.rb +331 -0
  305. data/lib/sirena/renderer/git_graph.rb +368 -0
  306. data/lib/sirena/renderer/info.rb +93 -0
  307. data/lib/sirena/renderer/kanban.rb +295 -0
  308. data/lib/sirena/renderer/mindmap.rb +396 -0
  309. data/lib/sirena/renderer/packet.rb +239 -0
  310. data/lib/sirena/renderer/pie.rb +235 -0
  311. data/lib/sirena/renderer/quadrant.rb +292 -0
  312. data/lib/sirena/renderer/radar.rb +323 -0
  313. data/lib/sirena/renderer/requirement.rb +371 -0
  314. data/lib/sirena/renderer/sankey.rb +255 -0
  315. data/lib/sirena/renderer/sequence.rb +424 -0
  316. data/lib/sirena/renderer/state_diagram.rb +328 -0
  317. data/lib/sirena/renderer/timeline.rb +304 -0
  318. data/lib/sirena/renderer/treemap.rb +152 -0
  319. data/lib/sirena/renderer/user_journey.rb +331 -0
  320. data/lib/sirena/renderer/xy_chart.rb +452 -0
  321. data/lib/sirena/renderer.rb +8 -0
  322. data/lib/sirena/svg/circle.rb +41 -0
  323. data/lib/sirena/svg/document.rb +103 -0
  324. data/lib/sirena/svg/element.rb +65 -0
  325. data/lib/sirena/svg/ellipse.rb +33 -0
  326. data/lib/sirena/svg/group.rb +71 -0
  327. data/lib/sirena/svg/line.rb +49 -0
  328. data/lib/sirena/svg/path.rb +76 -0
  329. data/lib/sirena/svg/polygon.rb +43 -0
  330. data/lib/sirena/svg/polyline.rb +35 -0
  331. data/lib/sirena/svg/rect.rb +57 -0
  332. data/lib/sirena/svg/style.rb +44 -0
  333. data/lib/sirena/svg/text.rb +72 -0
  334. data/lib/sirena/svg.rb +19 -0
  335. data/lib/sirena/text_measurement.rb +71 -0
  336. data/lib/sirena/theme/builtin/dark.yml +70 -0
  337. data/lib/sirena/theme/builtin/default.yml +80 -0
  338. data/lib/sirena/theme/builtin/high_contrast.yml +70 -0
  339. data/lib/sirena/theme/builtin/light.yml +70 -0
  340. data/lib/sirena/theme/color_palette.rb +48 -0
  341. data/lib/sirena/theme/effect_styles.rb +28 -0
  342. data/lib/sirena/theme/registry.rb +41 -0
  343. data/lib/sirena/theme/shape_styles.rb +28 -0
  344. data/lib/sirena/theme/spacing_config.rb +24 -0
  345. data/lib/sirena/theme/typography.rb +30 -0
  346. data/lib/sirena/theme.rb +69 -0
  347. data/lib/sirena/transform/architecture.rb +273 -0
  348. data/lib/sirena/transform/base.rb +199 -0
  349. data/lib/sirena/transform/block.rb +215 -0
  350. data/lib/sirena/transform/c4.rb +288 -0
  351. data/lib/sirena/transform/class_diagram.rb +296 -0
  352. data/lib/sirena/transform/er_diagram.rb +204 -0
  353. data/lib/sirena/transform/error.rb +39 -0
  354. data/lib/sirena/transform/flowchart.rb +161 -0
  355. data/lib/sirena/transform/gantt.rb +253 -0
  356. data/lib/sirena/transform/git_graph.rb +283 -0
  357. data/lib/sirena/transform/info.rb +39 -0
  358. data/lib/sirena/transform/kanban.rb +180 -0
  359. data/lib/sirena/transform/mindmap.rb +251 -0
  360. data/lib/sirena/transform/packet.rb +185 -0
  361. data/lib/sirena/transform/pie.rb +62 -0
  362. data/lib/sirena/transform/quadrant.rb +167 -0
  363. data/lib/sirena/transform/radar.rb +227 -0
  364. data/lib/sirena/transform/requirement.rb +233 -0
  365. data/lib/sirena/transform/sankey.rb +212 -0
  366. data/lib/sirena/transform/sequence.rb +143 -0
  367. data/lib/sirena/transform/state_diagram.rb +228 -0
  368. data/lib/sirena/transform/timeline.rb +139 -0
  369. data/lib/sirena/transform/treemap.rb +120 -0
  370. data/lib/sirena/transform/user_journey.rb +207 -0
  371. data/lib/sirena/transform/xy_chart.rb +273 -0
  372. data/lib/sirena/transform.rb +8 -0
  373. data/lib/sirena/version.rb +5 -0
  374. data/lib/sirena.rb +328 -0
  375. data/lib/tasks/benchmark.rake +532 -0
  376. data/lib/tasks/examples.rake +468 -0
  377. data/lib/tasks/generate_mermaid_fixtures.rake +363 -0
  378. data/lib/tasks/mermaid_fixtures.rake +46 -0
  379. data/scripts/extract_mermaid_tests.rb +493 -0
  380. data/scripts/rename_to_sirena.rb +73 -0
  381. data/sirena.gemspec +47 -0
  382. metadata +529 -0
@@ -0,0 +1,658 @@
1
+ = State diagrams
2
+ :toc:
3
+ :toclevels: 3
4
+
5
+ == Overview
6
+
7
+ State diagrams in Sirena represent state machines, showing the different states a system can be in and the transitions between those states. They are essential for modeling behavior in reactive systems, workflows, and protocol implementations.
8
+
9
+ State diagrams are useful for:
10
+
11
+ * Modeling user interface workflows
12
+ * Documenting protocol state machines
13
+ * Visualizing application lifecycle states
14
+ * Mapping connection states in networking
15
+ * Planning game state transitions
16
+ * Designing workflow engines
17
+
18
+ == Syntax specification
19
+
20
+ === Diagram declaration
21
+
22
+ State diagrams are declared using the `stateDiagram-v2` keyword:
23
+
24
+ [source,mermaid]
25
+ ----
26
+ stateDiagram-v2
27
+ <diagram-content>
28
+ ----
29
+
30
+ NOTE: Sirena uses the version 2 syntax (`stateDiagram-v2`) which is the current standard.
31
+
32
+ === States
33
+
34
+ ==== Simple states
35
+
36
+ States are declared by their usage in transitions:
37
+
38
+ [source,mermaid]
39
+ ----
40
+ stateDiagram-v2
41
+ State1 --> State2
42
+ ----
43
+
44
+ ==== State with description
45
+
46
+ States can have descriptions that differ from their identifiers:
47
+
48
+ [source,mermaid]
49
+ ----
50
+ stateDiagram-v2
51
+ state1 : This is a description
52
+ state1 --> state2
53
+ ----
54
+
55
+ ==== Start and end states
56
+
57
+ Special states mark the beginning and end:
58
+
59
+ [source,mermaid]
60
+ ----
61
+ stateDiagram-v2
62
+ [*] --> FirstState
63
+ LastState --> [*]
64
+ ----
65
+
66
+ Where `[*]` represents the start or end state.
67
+
68
+ === Transitions
69
+
70
+ Transitions connect states and can have labels:
71
+
72
+ [source,mermaid]
73
+ ----
74
+ stateDiagram-v2
75
+ State1 --> State2
76
+ State2 --> State3 : transition label
77
+ ----
78
+
79
+ === Composite states
80
+
81
+ Composite states contain nested states:
82
+
83
+ [source,mermaid]
84
+ ----
85
+ stateDiagram-v2
86
+ state CompositeState {
87
+ [*] --> InnerState1
88
+ InnerState1 --> InnerState2
89
+ InnerState2 --> [*]
90
+ }
91
+ ----
92
+
93
+ === Concurrent states
94
+
95
+ Concurrent states show parallel state machines:
96
+
97
+ [source,mermaid]
98
+ ----
99
+ stateDiagram-v2
100
+ state Fork <<fork>>
101
+ state Join <<join>>
102
+
103
+ [*] --> Fork
104
+ Fork --> State1
105
+ Fork --> State2
106
+ State1 --> Join
107
+ State2 --> Join
108
+ Join --> [*]
109
+ ----
110
+
111
+ Alternatively, use the `--` separator for concurrent regions:
112
+
113
+ [source,mermaid]
114
+ ----
115
+ stateDiagram-v2
116
+ state Active {
117
+ [*] --> Process1
118
+ --
119
+ [*] --> Process2
120
+ }
121
+ ----
122
+
123
+ === Choice states
124
+
125
+ Choice states represent conditional branches:
126
+
127
+ [source,mermaid]
128
+ ----
129
+ stateDiagram-v2
130
+ state if_state <<choice>>
131
+ [*] --> if_state
132
+ if_state --> State1 : condition1
133
+ if_state --> State2 : condition2
134
+ ----
135
+
136
+ === Notes
137
+
138
+ Notes can be added to states:
139
+
140
+ [source,mermaid]
141
+ ----
142
+ stateDiagram-v2
143
+ State1 --> State2
144
+ note right of State1
145
+ This is a note
146
+ end note
147
+ ----
148
+
149
+ Notes can be positioned:
150
+
151
+ * `note left of StateName`
152
+ * `note right of StateName`
153
+
154
+ === Direction
155
+
156
+ The layout direction can be specified:
157
+
158
+ [source,mermaid]
159
+ ----
160
+ stateDiagram-v2
161
+ direction LR
162
+ State1 --> State2
163
+ ----
164
+
165
+ Options:
166
+
167
+ * `TB` or `TD` - Top to bottom (default)
168
+ * `BT` - Bottom to top
169
+ * `LR` - Left to right
170
+ * `RL` - Right to left
171
+
172
+ === Scale
173
+
174
+ The diagram scale can be adjusted:
175
+
176
+ [source,mermaid]
177
+ ----
178
+ stateDiagram-v2
179
+ scale 350 width
180
+ State1 --> State2
181
+ ----
182
+
183
+ == Examples
184
+
185
+ === Basic state machine
186
+
187
+ .Simple state transitions
188
+ [example]
189
+ ====
190
+ [source,mermaid]
191
+ ----
192
+ stateDiagram-v2
193
+ [*] --> Idle
194
+ Idle --> Active
195
+ Active --> Idle
196
+ Active --> [*]
197
+ ----
198
+
199
+ This creates a simple state machine with:
200
+
201
+ * Start state transitioning to Idle
202
+ * Transitions between Idle and Active
203
+ * Active state can end the machine
204
+ ====
205
+
206
+ === State machine with descriptions
207
+
208
+ .States with descriptive labels
209
+ [example]
210
+ ====
211
+ [source,mermaid]
212
+ ----
213
+ stateDiagram-v2
214
+ [*] --> Idle
215
+
216
+ Idle --> Connecting : connect()
217
+ Connecting --> Connected : success
218
+ Connecting --> Error : failure
219
+
220
+ Connected --> Idle : disconnect()
221
+ Error --> Idle : reset()
222
+ ----
223
+
224
+ This demonstrates:
225
+
226
+ * State transitions with labeled triggers
227
+ * Multiple possible outcomes from a state
228
+ * Return transitions to initial state
229
+ ====
230
+
231
+ === Composite states
232
+
233
+ .Nested state machine
234
+ [example]
235
+ ====
236
+ [source,mermaid]
237
+ ----
238
+ stateDiagram-v2
239
+ [*] --> Idle
240
+
241
+ Idle --> Connecting : connect()
242
+ Connecting --> Connected : success
243
+ Connecting --> Error : failure
244
+
245
+ state Connected {
246
+ [*] --> Authenticated
247
+ Authenticated --> Active
248
+
249
+ state Active {
250
+ [*] --> Reading
251
+ Reading --> Writing : write_request
252
+ Writing --> Reading : write_complete
253
+ Reading --> Processing : process_data
254
+ Processing --> Reading : complete
255
+ }
256
+
257
+ Active --> Suspended : suspend()
258
+ Suspended --> Active : resume()
259
+ }
260
+
261
+ Connected --> Disconnecting : disconnect()
262
+ Error --> Idle : reset()
263
+ Disconnecting --> Idle : complete
264
+ Suspended --> Disconnecting : timeout
265
+
266
+ Idle --> [*] : shutdown()
267
+ ----
268
+
269
+ This example shows:
270
+
271
+ * Multi-level nested composite states
272
+ * State `Connected` contains substates
273
+ * State `Active` is nested within `Connected`
274
+ * Transitions between nested states
275
+ * Transitions from nested states to outer states
276
+ ====
277
+
278
+ === Concurrent states
279
+
280
+ .Parallel state execution
281
+ [example]
282
+ ====
283
+ [source,mermaid]
284
+ ----
285
+ stateDiagram-v2
286
+ [*] --> Active
287
+
288
+ state Active {
289
+ [*] --> ProcessA
290
+ --
291
+ [*] --> ProcessB
292
+
293
+ ProcessA --> DoneA
294
+ ProcessB --> DoneB
295
+ }
296
+
297
+ Active --> [*]
298
+ ----
299
+
300
+ This demonstrates:
301
+
302
+ * Concurrent regions separated by `--`
303
+ * Independent state machines running in parallel
304
+ * Each region has its own start state
305
+ ====
306
+
307
+ === Complex state machine with multiple features
308
+
309
+ .Multi-level recursive states
310
+ [example]
311
+ ====
312
+ [source,mermaid]
313
+ ----
314
+ stateDiagram-v2
315
+ scale 350 width
316
+ [*] --> NotShooting
317
+
318
+ state NotShooting {
319
+ [*] --> Idle
320
+ Idle --> Configuring : EvConfig
321
+ Configuring --> Idle : EvConfig
322
+ }
323
+
324
+ state Configuring {
325
+ [*] --> NewValueSelection
326
+ NewValueSelection --> NewValuePreview : EvNewValue
327
+ NewValuePreview --> NewValueSelection : EvNewValueRejected
328
+ NewValuePreview --> NewValueSelection : EvNewValueSaved
329
+
330
+ state NewValuePreview {
331
+ State1 --> State2
332
+ }
333
+ }
334
+ ----
335
+
336
+ This comprehensive example includes:
337
+
338
+ * Scale directive for width
339
+ * Multiple composite states
340
+ * Recursive nesting (Configuring appears both as substate and composite)
341
+ * Complex transition patterns
342
+ * Real-world camera state machine pattern
343
+ ====
344
+
345
+ === Choice states
346
+
347
+ .Conditional branching
348
+ [example]
349
+ ====
350
+ [source,mermaid]
351
+ ----
352
+ stateDiagram-v2
353
+ state if_state <<choice>>
354
+
355
+ [*] --> CheckValue
356
+ CheckValue --> if_state
357
+
358
+ if_state --> Low : value < 10
359
+ if_state --> Medium : 10 <= value < 50
360
+ if_state --> High : value >= 50
361
+
362
+ Low --> [*]
363
+ Medium --> [*]
364
+ High --> [*]
365
+ ----
366
+
367
+ This shows:
368
+
369
+ * Choice state declaration with `<<choice>>`
370
+ * Multiple conditional branches
371
+ * Condition labels on transitions
372
+ ====
373
+
374
+ === State machine with notes
375
+
376
+ .Documented state transitions
377
+ [example]
378
+ ====
379
+ [source,mermaid]
380
+ ----
381
+ stateDiagram-v2
382
+ [*] --> Idle
383
+
384
+ Idle --> Processing : start
385
+
386
+ note right of Processing
387
+ This state handles all
388
+ data processing operations
389
+ end note
390
+
391
+ Processing --> Complete : success
392
+ Processing --> Error : failure
393
+
394
+ note left of Error
395
+ Error recovery
396
+ is automatic
397
+ end note
398
+
399
+ Error --> Idle : retry
400
+ Complete --> [*]
401
+ ----
402
+
403
+ This demonstrates:
404
+
405
+ * Right-side notes
406
+ * Left-side notes
407
+ * Multi-line note content
408
+ * Documenting state behavior
409
+ ====
410
+
411
+ === Connection lifecycle
412
+
413
+ .Real-world connection state machine
414
+ [example]
415
+ ====
416
+ [source,mermaid]
417
+ ----
418
+ stateDiagram-v2
419
+ [*] --> Disconnected
420
+
421
+ Disconnected --> Connecting : open()
422
+ Connecting --> Connected : handshake_success
423
+ Connecting --> Failed : timeout
424
+ Connecting --> Failed : handshake_error
425
+
426
+ state Connected {
427
+ [*] --> Idle
428
+ Idle --> Transmitting : send()
429
+ Transmitting --> Idle : ack_received
430
+ Idle --> Receiving : data_available
431
+ Receiving --> Idle : data_processed
432
+ }
433
+
434
+ Connected --> Disconnecting : close()
435
+ Connected --> Failed : connection_lost
436
+
437
+ Disconnecting --> Disconnected : cleanup_complete
438
+
439
+ Failed --> Disconnected : reset()
440
+
441
+ Disconnected --> [*]
442
+ ----
443
+
444
+ This real-world example shows:
445
+
446
+ * Connection state lifecycle
447
+ * Error handling paths
448
+ * Nested operational states
449
+ * Recovery transitions
450
+ ====
451
+
452
+ == Features
453
+
454
+ === State identifiers
455
+
456
+ State identifiers can contain letters, numbers, and underscores:
457
+
458
+ [source,mermaid]
459
+ ----
460
+ stateDiagram-v2
461
+ state_1 --> state_2
462
+ state_2 --> state_3
463
+ ----
464
+
465
+ === Multi-word state names
466
+
467
+ State descriptions can contain spaces:
468
+
469
+ [source,mermaid]
470
+ ----
471
+ stateDiagram-v2
472
+ state1 : Waiting for Input
473
+ state2 : Processing Data
474
+ state1 --> state2
475
+ ----
476
+
477
+ === Long descriptions
478
+
479
+ Descriptions can be multiple words:
480
+
481
+ [source,mermaid]
482
+ ----
483
+ stateDiagram-v2
484
+ longStateName : This is a very long state description that explains what happens in this state
485
+ ----
486
+
487
+ === Multiple transitions
488
+
489
+ A state can have multiple incoming and outgoing transitions:
490
+
491
+ [source,mermaid]
492
+ ----
493
+ stateDiagram-v2
494
+ State1 --> State2
495
+ State1 --> State3
496
+ State4 --> State2
497
+ State5 --> State2
498
+ ----
499
+
500
+ === Self-transitions
501
+
502
+ States can transition to themselves:
503
+
504
+ [source,mermaid]
505
+ ----
506
+ stateDiagram-v2
507
+ State1 --> State1 : self_transition
508
+ ----
509
+
510
+ === Nested composite states
511
+
512
+ Composite states can be nested to any depth:
513
+
514
+ [source,mermaid]
515
+ ----
516
+ stateDiagram-v2
517
+ state Outer {
518
+ state Inner {
519
+ state DeepInner {
520
+ [*] --> DeepState
521
+ }
522
+ }
523
+ }
524
+ ----
525
+
526
+ == Limitations
527
+
528
+ === Currently not supported
529
+
530
+ The following Mermaid state diagram features are not yet supported in Sirena:
531
+
532
+ * Fork and join states with `<<fork>>` and `<<join>>` stereotypes
533
+ * Custom styling with CSS classes
534
+ * Click events and links
535
+ * Comments using `%%`
536
+ * Background colors
537
+ * Class styling
538
+
539
+ === Known issues
540
+
541
+ * Very deeply nested states may have layout issues
542
+ * Complex concurrent state diagrams may not space optimally
543
+ * Long state names may overflow boundaries
544
+
545
+ == Best practices
546
+
547
+ === Use meaningful state names
548
+
549
+ Choose descriptive state names:
550
+
551
+ [source,mermaid]
552
+ ----
553
+ %% Good
554
+ stateDiagram-v2
555
+ Idle --> Processing : start_processing
556
+ Processing --> Complete : finished
557
+
558
+ %% Less clear
559
+ stateDiagram-v2
560
+ S1 --> S2
561
+ S2 --> S3
562
+ ----
563
+
564
+ === Label transitions clearly
565
+
566
+ Use descriptive transition labels:
567
+
568
+ [source,mermaid]
569
+ ----
570
+ %% Good
571
+ stateDiagram-v2
572
+ Idle --> Active : user_clicked_start
573
+ Active --> Paused : user_clicked_pause
574
+
575
+ %% Less clear
576
+ stateDiagram-v2
577
+ Idle --> Active
578
+ Active --> Paused
579
+ ----
580
+
581
+ === Group related states
582
+
583
+ Use composite states to organize related substates:
584
+
585
+ [source,mermaid]
586
+ ----
587
+ stateDiagram-v2
588
+ state Active {
589
+ Reading --> Writing
590
+ Writing --> Processing
591
+ Processing --> Reading
592
+ }
593
+ ----
594
+
595
+ === Keep nesting levels manageable
596
+
597
+ Avoid excessive nesting depth:
598
+
599
+ [source,mermaid]
600
+ ----
601
+ %% Good - 2 levels
602
+ stateDiagram-v2
603
+ state Outer {
604
+ state Inner {
605
+ State1 --> State2
606
+ }
607
+ }
608
+
609
+ %% Less maintainable - too deep
610
+ stateDiagram-v2
611
+ state L1 {
612
+ state L2 {
613
+ state L3 {
614
+ state L4 {
615
+ state L5 {
616
+ Deep --> TooDeep
617
+ }
618
+ }
619
+ }
620
+ }
621
+ }
622
+ ----
623
+
624
+ === Use notes for complex logic
625
+
626
+ Add notes to explain complex state behavior:
627
+
628
+ [source,mermaid]
629
+ ----
630
+ stateDiagram-v2
631
+ Processing --> Validated
632
+
633
+ note right of Validated
634
+ Validation includes:
635
+ - Schema check
636
+ - Business rules
637
+ - Data integrity
638
+ end note
639
+ ----
640
+
641
+ === Document error paths
642
+
643
+ Always show error and recovery paths:
644
+
645
+ [source,mermaid]
646
+ ----
647
+ stateDiagram-v2
648
+ Processing --> Success : valid
649
+ Processing --> Error : invalid
650
+ Error --> Retry : recoverable
651
+ Error --> Failed : unrecoverable
652
+ ----
653
+
654
+ == Related documentation
655
+
656
+ * <<index.adoc#,Diagram types overview>>
657
+ * <<flowchart.adoc#,Flowchart diagrams>>
658
+ * link:https://mermaid.js.org/syntax/stateDiagram.html[Official Mermaid state diagram documentation]