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
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ gem 'rake'
8
+ gem 'rspec'
9
+ gem "rubocop"
10
+ gem "rubocop-performance", require: false
11
+ gem "rubocop-rake", require: false
12
+ gem "rubocop-rspec", require: false
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2024, Ribose Inc.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.adoc ADDED
@@ -0,0 +1,357 @@
1
+ = Sirena
2
+
3
+ image:https://img.shields.io/gem/v/sirena.svg[RubyGems Version,link=https://rubygems.org/gems/sirena]
4
+ image:https://img.shields.io/github/license/claricle/sirena.svg[License,link=https://github.com/claricle/sirena/blob/main/LICENSE]
5
+ image:https://github.com/claricle/sirena/actions/workflows/rake.yml/badge.svg["Build",link=https://github.com/claricle/sirena/actions/workflows/rake.yml]
6
+
7
+ == Purpose
8
+
9
+ Sirena is a pure Ruby implementation of Mermaid diagram generation that
10
+ transforms Mermaid syntax into SVG output. Unlike the JavaScript-based
11
+ mermaid-js, Sirena operates entirely in Ruby, making it ideal for server-side
12
+ rendering, documentation generation, and integration with Ruby-based tools like
13
+ Metanorma.
14
+
15
+ The library follows strict object-oriented principles with a model-driven
16
+ architecture, using `Lutaml::Model` for all data structures and providing clean
17
+ separation between parsing, transformation, layout, and rendering phases.
18
+
19
+ == Features
20
+
21
+ === Supported diagram types (24/24)
22
+
23
+ Sirena supports all 24 Mermaid diagram types with complete parser, transform,
24
+ and renderer implementations:
25
+
26
+ * **Flowchart** - Directional graphs with various node shapes and edge types
27
+ * **Sequence diagram** - Message flows between participants over time
28
+ * **Class diagram** - UML class relationships and hierarchies
29
+ * **State diagram** - State machine transitions and hierarchies
30
+ * **Entity-relationship diagram** - Database schema relationships
31
+ * **User journey** - User interaction flows with satisfaction levels
32
+ * **Gantt chart** - Project timelines and task dependencies
33
+ * **Pie chart** - Proportional data visualization
34
+ * **Quadrant chart** - 2D data point categorization
35
+ * **Requirement diagram** - Requirements and their relationships
36
+ * **Git graph** - Git branching and commit history
37
+ * **Mindmap** - Hierarchical mind mapping
38
+ * **Timeline** - Event sequences over time
39
+ * **Sankey diagram** - Flow quantities between nodes
40
+ * **XY chart** - Line and bar charts with axes
41
+ * **Block diagram** - Block-based architecture diagrams
42
+ * **Packet diagram** - Network packet structure
43
+ * **C4 diagram** - Software architecture contexts and containers
44
+ * **Architecture diagram** - Service and component architecture
45
+ * **Kanban board** - Workflow status tracking
46
+ * **Radar chart** - Multi-dimensional data comparison
47
+ * **Treemap** - Hierarchical data as nested rectangles
48
+ * **Error diagram** - Error message display
49
+ * **Info diagram** - Information display
50
+
51
+ See link:examples/README.adoc[] for working examples of all diagram types.
52
+
53
+ === Core capabilities
54
+
55
+ * **Pure Ruby implementation** - No JavaScript dependencies
56
+ * **Parslet-based parsing** - Superior error messages and maintainability
57
+ * **SVG output** - Standards-compliant SVG 1.2
58
+ * **Theme support** - 4 built-in themes, custom theme support
59
+ * **Auto-detection** - Automatic diagram type detection
60
+ * **Batch processing** - Process multiple diagrams at once
61
+ * **CLI tool** - Command-line interface for standalone usage
62
+ * **Programmatic API** - Ruby library for custom workflows
63
+ * **Metanorma integration** - Direct embedding in documentation
64
+
65
+ == Architecture
66
+
67
+ === General
68
+
69
+ Sirena implements a pipeline architecture that transforms Mermaid source
70
+ code through distinct processing stages, each with clear responsibilities and
71
+ well-defined interfaces.
72
+
73
+ **All parsers use Parslet**, a powerful PEG (Parsing Expression Grammar) library
74
+ that provides superior error messages, composability, and maintainability
75
+ compared to traditional lexer-based approaches. The 3-layer Parslet architecture
76
+ (Grammar → Transform → Parser) achieved ~80% code reduction during migration.
77
+
78
+ The implementation uses the ELK layout engine via the elkrb gem for
79
+ professional-quality graph layout and positioning. Sirena is a pure Ruby
80
+ implementation with no JavaScript dependencies, generating standards-compliant
81
+ SVG 1.2 output suitable for direct integration with Metanorma documentation
82
+ frameworks.
83
+
84
+ .Sirena processing pipeline
85
+ [source]
86
+ ----
87
+ Mermaid Syntax Input (String)
88
+
89
+
90
+ ┌─────────┐
91
+ │ Parser │ Parslet Grammar → Transform → Parser
92
+ └────┬────┘ (3-layer architecture)
93
+
94
+
95
+ ┌───────────┐
96
+ │ Diagram │ Lutaml::Model AST
97
+ │ Model │ (Flowchart, Sequence, etc.)
98
+ └─────┬─────┘
99
+
100
+
101
+ ┌───────────┐
102
+ │Transform │ Diagram → Graph Conversion
103
+ │ Layer │
104
+ └─────┬─────┘
105
+
106
+
107
+ ┌───────────┐
108
+ │ Layout │ Position Computation
109
+ │ Engine │ (Node positions, edge routes)
110
+ └─────┬─────┘
111
+
112
+
113
+ ┌───────────┐
114
+ │ SVG │ Graph → SVG Conversion
115
+ │ Renderer │
116
+ └─────┬─────┘
117
+
118
+
119
+ ┌───────────┐
120
+ │ SVG │ Lutaml::Model Structure
121
+ │ Builder │
122
+ └─────┬─────┘
123
+
124
+
125
+ SVG XML Output (String)
126
+ ----
127
+
128
+ .Component relationships
129
+ [source]
130
+ ----
131
+ Sirena (Root Module)
132
+
133
+ ├── Engine (Orchestrator)
134
+ │ ├── coordinates overall flow
135
+ │ ├── delegates to Parser
136
+ │ ├── delegates to Transform
137
+ │ └── delegates to Renderer
138
+
139
+ ├── Parser (Parslet-based Syntax Analysis)
140
+ │ ├── Grammars (Parslet rules)
141
+ │ ├── Transforms (tree conversion)
142
+ │ └── produces Diagram Models
143
+
144
+ ├── Diagram (Domain Models)
145
+ │ ├── Architecture
146
+ │ ├── Block
147
+ │ ├── C4
148
+ │ ├── ClassDiagram
149
+ │ ├── ErDiagram
150
+ │ ├── Error
151
+ │ ├── Flowchart
152
+ │ ├── Gantt
153
+ │ ├── GitGraph
154
+ │ ├── Info
155
+ │ ├── Kanban
156
+ │ ├── Mindmap
157
+ │ ├── Packet
158
+ │ ├── Pie
159
+ │ ├── Quadrant
160
+ │ ├── Radar
161
+ │ ├── Requirement
162
+ │ ├── Sankey
163
+ │ ├── Sequence
164
+ │ ├── StateDiagram
165
+ │ ├── Timeline
166
+ │ ├── Treemap
167
+ │ ├── UserJourney
168
+ │ └── XyChart
169
+
170
+ ├── Transform (Model Conversion)
171
+ │ └── diagram-specific converters
172
+
173
+ ├── Renderer (SVG Generation)
174
+ │ └── diagram-specific renderers
175
+
176
+ ├── Svg (SVG Models)
177
+ │ ├── Document, Element, Group
178
+ │ ├── Path, Text, Rect
179
+ │ └── Circle, Line, Polygon
180
+
181
+ └── DiagramRegistry (Type Registration)
182
+ └── maps types to handlers
183
+ ----
184
+
185
+ === Parslet-based parser architecture
186
+
187
+ All 24 implemented diagram types use Parslet exclusively for parsing, following
188
+ a consistent 3-layer pattern:
189
+
190
+ . **Layer 1: Grammar** (Parslet::Parser) - Defines syntax rules using Parslet
191
+ DSL, parses text into intermediate tree structures
192
+ . **Layer 2: Transform** (Parslet::Transform) - Converts intermediate trees to
193
+ typed Diagram models using pattern matching
194
+ . **Layer 3: Parser** - Orchestrates Grammar and Transform, provides public API
195
+
196
+ This architecture provides:
197
+
198
+ * **Superior error messages** with detailed context and line numbers
199
+ * **Composability** through shared grammar rules across diagram types
200
+ * **Maintainability** via declarative, self-documenting syntax rules
201
+ * **Type safety** through strongly-typed Lutaml::Model objects
202
+ * **Code reduction** of ~80% compared to previous lexer-based approach
203
+
204
+ See link:ARCHITECTURE.md[] for detailed architecture documentation.
205
+
206
+ == Installation
207
+
208
+ === Via RubyGems
209
+
210
+ Add Sirena to your Gemfile:
211
+
212
+ [source,ruby]
213
+ ----
214
+ gem 'sirena'
215
+ ----
216
+
217
+ Then execute:
218
+
219
+ [source,shell]
220
+ ----
221
+ bundle install
222
+ ----
223
+
224
+ Or install it directly:
225
+
226
+ [source,shell]
227
+ ----
228
+ gem install sirena
229
+ ----
230
+
231
+ === Requirements
232
+
233
+ * Ruby 2.7 or higher
234
+ * `elkrb` gem (for graph layout)
235
+
236
+ == Quick start
237
+
238
+ === Command-line usage
239
+
240
+ Render a single Mermaid diagram to SVG:
241
+
242
+ [source,shell]
243
+ ----
244
+ sirena render diagram.mmd -o output.svg
245
+ ----
246
+
247
+ Render all Mermaid files in a directory:
248
+
249
+ [source,shell]
250
+ ----
251
+ sirena batch input_dir/ -o output_dir/
252
+ ----
253
+
254
+ List all supported diagram types:
255
+
256
+ [source,shell]
257
+ ----
258
+ sirena types
259
+ ----
260
+
261
+ === Programmatic usage
262
+
263
+ Use Sirena in your Ruby code:
264
+
265
+ [source,ruby]
266
+ ----
267
+ require 'sirena'
268
+
269
+ # Render from a string
270
+ mermaid_code = <<~MERMAID
271
+ graph TD
272
+ A[Start] --> B[Process]
273
+ B --> C[End]
274
+ MERMAID
275
+
276
+ svg = Sirena::Engine.render(mermaid_code)
277
+ File.write('output.svg', svg)
278
+
279
+ # Render from a file
280
+ svg = Sirena::Engine.render_file('diagram.mmd')
281
+ File.write('output.svg', svg)
282
+
283
+ # Specify diagram type explicitly
284
+ svg = Sirena::Engine.render(mermaid_code, type: :flowchart)
285
+ ----
286
+
287
+ === Examples
288
+
289
+ Browse link:examples/README.adoc[] for 37 working examples across all 24
290
+ diagram types, each with corresponding SVG output.
291
+
292
+ == Documentation
293
+
294
+ Comprehensive documentation is available at the https://claricle.github.io/sirena[Sirena Documentation Site].
295
+
296
+ === Quick Links
297
+
298
+ * https://claricle.github.io/sirena/pages/comparison/[Tool Comparison] - Compare Sirena with Mermaid.js, PlantUML, and Graphviz
299
+ * https://claricle.github.io/sirena/pages/compatibility/[Mermaid.js Compatibility] - Detailed syntax compatibility matrix
300
+ * https://claricle.github.io/sirena/diagram_types/[Diagram Types Reference] - Complete syntax reference for all 24 diagram types
301
+ * https://claricle.github.io/sirena/guides/migration-from-mermaid/[Migration Guide] - Step-by-step migration from Mermaid.js
302
+
303
+ === Documentation Structure
304
+
305
+ The documentation uses a 6-collection architecture:
306
+
307
+ . **Core Topics** - Installation, architecture, compatibility, comparison, configuration
308
+ . **Tutorials** - Step-by-step learning paths
309
+ . **Guides** - Task-oriented how-to documentation
310
+ . **Diagram Types** - Complete reference for all 24 diagram types with examples
311
+ . **Features** - Detailed capability documentation
312
+ . **References** - API and CLI reference
313
+
314
+ See the https://claricle.github.io/sirena[documentation site] for the complete guide.
315
+
316
+ == Test coverage
317
+
318
+ === General
319
+
320
+ Sirena implements comprehensive test coverage against the official mermaid-js
321
+ test suite to ensure compatibility and correctness. The test suite validates
322
+ all diagram types and syntax variations against reference outputs generated
323
+ using mermaid-cli v11.12.0.
324
+
325
+ === Mermaid-js compatibility validation
326
+
327
+ Sirena's test suite includes 715 test cases covering all 24 diagram types
328
+ to ensure comprehensive compatibility and correctness:
329
+
330
+ * Flowchart - Comprehensive node shapes and edge types
331
+ * Sequence diagram - Message flows and activations
332
+ * Class diagram - UML relationships and hierarchies
333
+ * State diagram - State transitions and composite states
334
+ * Entity-relationship diagram - Database relationships
335
+ * User journey - User interaction flows
336
+ * Gantt chart - Timeline and dependencies
337
+ * Pie chart - Data proportions
338
+ * Quadrant chart - 2D categorization
339
+ * Requirement diagram - Requirement relationships
340
+ * Git graph - Branching and commits
341
+ * Mindmap - Hierarchical structures
342
+ * Timeline - Event sequences
343
+ * Sankey diagram - Flow visualization
344
+ * XY chart - Line and bar charts
345
+ * Block diagram - Architecture blocks
346
+ * Packet diagram - Network packets
347
+ * C4 diagram - Software architecture
348
+ * Architecture diagram - Service architecture
349
+ * Kanban board - Workflow tracking
350
+ * Radar chart - Multi-dimensional comparison
351
+ * Treemap - Hierarchical data
352
+ * Error diagram - Error display
353
+ * Info diagram - Information display
354
+
355
+ === SVG fixture validation
356
+
357
+ The test suite generates 302 SVG reference fixtures using mermaid-cli v11.12.0
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ # Load custom rake tasks
9
+ Dir.glob('lib/tasks/**/*.rake').each { |r| load r }
10
+
11
+ task default: :spec
data/docs/.gitignore ADDED
@@ -0,0 +1 @@
1
+ _site
data/docs/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'jekyll'
6
+ gem 'jekyll-asciidoc'
7
+ gem 'jekyll-seo-tag'
8
+ gem 'jekyll-sitemap'
9
+ gem 'just-the-docs'
10
+
11
+ group :jekyll_plugins do
12
+ gem 'asciidoctor'
13
+ end
data/docs/_config.yml ADDED
@@ -0,0 +1,182 @@
1
+ # Jekyll configuration for Sirena documentation
2
+ # Uses Just the Docs theme - https://just-the-docs.com/
3
+
4
+ # Site settings
5
+ title: Sirena Documentation
6
+ description: Pure Ruby Mermaid diagram rendering library with 19 diagram types
7
+ url: https://claricle.github.io
8
+ baseurl: /sirena
9
+
10
+ # Theme
11
+ theme: just-the-docs
12
+ remote_theme: just-the-docs/just-the-docs
13
+
14
+ # AsciiDoc support
15
+ asciidoc: {}
16
+ asciidoctor:
17
+ attributes:
18
+ - idprefix=_
19
+ - source-highlighter=rouge
20
+ - icons=font
21
+ - experimental=''
22
+ - idseparator=-
23
+ - sectanchors=''
24
+ - toc=left
25
+ - toclevels=3
26
+
27
+ # Build settings
28
+ plugins:
29
+ - jekyll-asciidoc
30
+ - jekyll-seo-tag
31
+ - jekyll-sitemap
32
+
33
+ # Collections configuration
34
+ collections:
35
+ pages:
36
+ output: true
37
+ permalink: /:collection/:path/
38
+ tutorials:
39
+ output: true
40
+ permalink: /:collection/:path/
41
+ guides:
42
+ output: true
43
+ permalink: /:collection/:path/
44
+ references:
45
+ output: true
46
+ permalink: /:collection/:path/
47
+ features:
48
+ output: true
49
+ permalink: /:collection/:path/
50
+ diagram_types:
51
+ output: true
52
+ permalink: /:collection/:path/
53
+
54
+ # Just the Docs theme configuration
55
+ search_enabled: true
56
+ search:
57
+ heading_level: 2
58
+ previews: 3
59
+ preview_words_before: 5
60
+ preview_words_after: 10
61
+ tokenizer_separator: /[\s/]+/
62
+ rel_url: true
63
+ button: false
64
+
65
+ # Navigation
66
+ nav_sort: case_insensitive
67
+
68
+ # Enable heading anchors
69
+ heading_anchors: true
70
+
71
+ # Back to top link
72
+ back_to_top: true
73
+ back_to_top_text: "Back to top"
74
+
75
+ # Footer content
76
+ footer_content: 'Copyright &copy; 2025 Ribose. Sirena is open source under the MIT license.'
77
+
78
+ # Color scheme
79
+ color_scheme: light
80
+
81
+ # Logo
82
+ logo: false
83
+
84
+ # Aux links for the upper right navigation
85
+ aux_links:
86
+ "Sirena on GitHub":
87
+ - "https://github.com/claricle/sirena"
88
+ "Report Issue":
89
+ - "https://github.com/claricle/sirena/issues"
90
+ "RubyGems":
91
+ - "https://rubygems.org/gems/sirena"
92
+
93
+ # Aux links configuration
94
+ aux_links_new_tab: true
95
+
96
+ # Callouts
97
+ callouts_level: quiet
98
+ callouts:
99
+ note:
100
+ color: blue
101
+ warning:
102
+ color: yellow
103
+ title: Warning
104
+ important:
105
+ color: red
106
+ title: Important
107
+
108
+ # Collection defaults
109
+ defaults:
110
+ - scope:
111
+ path: ""
112
+ values:
113
+ layout: "default"
114
+ - scope:
115
+ path: ""
116
+ type: "pages"
117
+ values:
118
+ layout: "default"
119
+ nav_exclude: false
120
+ - scope:
121
+ path: ""
122
+ type: "tutorials"
123
+ values:
124
+ layout: "default"
125
+ nav_exclude: false
126
+ - scope:
127
+ path: ""
128
+ type: "guides"
129
+ values:
130
+ layout: "default"
131
+ nav_exclude: false
132
+ - scope:
133
+ path: ""
134
+ type: "references"
135
+ values:
136
+ layout: "default"
137
+ nav_exclude: false
138
+ - scope:
139
+ path: ""
140
+ type: "features"
141
+ values:
142
+ layout: "default"
143
+ nav_exclude: false
144
+ - scope:
145
+ path: ""
146
+ type: "diagram_types"
147
+ values:
148
+ layout: "default"
149
+ nav_exclude: false
150
+
151
+ # Only process docs directory
152
+ include:
153
+ - "*.adoc"
154
+ - "*/*.adoc"
155
+ - "_pages"
156
+ - "_tutorials"
157
+ - "_guides"
158
+ - "_references"
159
+ - "_features"
160
+ - "_diagram_types"
161
+
162
+ # Exclude build and config files
163
+ exclude:
164
+ - Gemfile
165
+ - Gemfile.lock
166
+ - README.md
167
+ - vendor/
168
+ - "*.md" # Exclude all .md files (documentation planning docs)
169
+ - DOCUMENTATION_*.md
170
+ - IMPLEMENTATION_*.md
171
+ - INFORMATION_*.md
172
+ - EXAMPLES_*.md
173
+
174
+ # Set permalink structure
175
+ permalink: pretty
176
+
177
+ # Markdown processing (for any .md files)
178
+ markdown: kramdown
179
+ kramdown:
180
+ input: GFM
181
+ hard_wrap: false
182
+ syntax_highlighter: rouge