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,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+ require_relative "common"
5
+
6
+ module Sirena
7
+ module Parser
8
+ module Grammars
9
+ # Grammar for parsing Mermaid radar-beta chart syntax
10
+ class Radar < Common
11
+
12
+ rule(:diagram_type) { str("radar-beta") >> space? }
13
+
14
+ rule(:title_line) do
15
+ str("title") >> space >> (newline.absent? >> any).repeat(1).as(:title) >> eol
16
+ end
17
+
18
+ rule(:acc_title_line) do
19
+ str("accTitle:") >> space >> (newline.absent? >> any).repeat(1).as(:acc_title) >> eol
20
+ end
21
+
22
+ rule(:acc_descr_line) do
23
+ str("accDescr:") >> space >> (newline.absent? >> any).repeat(1).as(:acc_descr) >> eol
24
+ end
25
+
26
+ # Axis definition: axis A,B,C or axis A["Label"], B["Label"]
27
+ rule(:axis_label) do
28
+ str("[") >> str('"') >>
29
+ match('[^"]').repeat(1).as(:label) >>
30
+ str('"') >> str("]")
31
+ end
32
+
33
+ rule(:axis_item) do
34
+ space? >>
35
+ identifier.as(:id) >>
36
+ axis_label.maybe >>
37
+ space?
38
+ end
39
+
40
+ rule(:axis_line) do
41
+ str("axis") >> space >>
42
+ (axis_item >> (str(",") >> axis_item).repeat).as(:axes) >>
43
+ eol
44
+ end
45
+
46
+ # Curve/dataset values
47
+ # Supports: {1,2,3} or { A: 1, B: 2, C: 3 }
48
+ rule(:value_number) { match["0-9"].repeat(1).as(:value) }
49
+
50
+ rule(:positional_value) do
51
+ space? >> value_number >> space?
52
+ end
53
+
54
+ rule(:named_value) do
55
+ space? >>
56
+ identifier.as(:axis) >>
57
+ space? >> str(":") >> space? >>
58
+ value_number >>
59
+ space?
60
+ end
61
+
62
+ rule(:value_list) do
63
+ positional_value >> (str(",") >> positional_value).repeat
64
+ end
65
+
66
+ rule(:named_value_list) do
67
+ named_value >> (str(",") >> named_value).repeat
68
+ end
69
+
70
+ rule(:curve_values) do
71
+ str("{") >>
72
+ (named_value_list | value_list).as(:values) >>
73
+ str("}")
74
+ end
75
+
76
+ rule(:curve_label) do
77
+ str("[") >> str('"') >>
78
+ match('[^"]').repeat(1).as(:label) >>
79
+ str('"') >> str("]")
80
+ end
81
+
82
+ rule(:curve_line) do
83
+ str("curve") >> space >>
84
+ identifier.as(:id) >>
85
+ curve_label.maybe >>
86
+ curve_values >>
87
+ eol
88
+ end
89
+
90
+ # Options
91
+ rule(:ticks_line) do
92
+ str("ticks") >> space >>
93
+ match["0-9"].repeat(1).as(:ticks) >>
94
+ eol
95
+ end
96
+
97
+ rule(:show_legend_line) do
98
+ str("showLegend") >> space >>
99
+ (str("true") | str("false")).as(:show_legend) >>
100
+ eol
101
+ end
102
+
103
+ rule(:graticule_line) do
104
+ str("graticule") >> space >>
105
+ (str("polygon") | str("circular")).as(:graticule) >>
106
+ eol
107
+ end
108
+
109
+ rule(:min_line) do
110
+ str("min") >> space >>
111
+ match["0-9"].repeat(1).as(:min) >>
112
+ eol
113
+ end
114
+
115
+ rule(:max_line) do
116
+ str("max") >> space >>
117
+ match["0-9"].repeat(1).as(:max) >>
118
+ eol
119
+ end
120
+
121
+ rule(:option_line) do
122
+ ticks_line | show_legend_line | graticule_line |
123
+ min_line | max_line
124
+ end
125
+
126
+ rule(:statement) do
127
+ space? >> (
128
+ title_line |
129
+ acc_title_line |
130
+ acc_descr_line |
131
+ axis_line |
132
+ curve_line |
133
+ option_line |
134
+ comment >> eol |
135
+ space? >> newline
136
+ )
137
+ end
138
+
139
+ rule(:body) { statement.repeat }
140
+
141
+ rule(:radar_diagram) do
142
+ diagram_type >> eol >>
143
+ body.as(:statements)
144
+ end
145
+
146
+ root(:radar_diagram)
147
+ end
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for Requirement diagrams.
9
+ #
10
+ # Handles requirement diagram syntax including requirements, elements,
11
+ # relationships, styling, and class assignments.
12
+ class Requirement < Common
13
+ root(:diagram)
14
+
15
+ # Main diagram structure
16
+ rule(:diagram) do
17
+ ws? >>
18
+ header >>
19
+ ws? >>
20
+ statements.maybe >>
21
+ ws?
22
+ end
23
+
24
+ rule(:header) do
25
+ str('requirementDiagram').as(:header) >> ws?
26
+ end
27
+
28
+ rule(:statements) do
29
+ (statement >> ws?).repeat(1)
30
+ end
31
+
32
+ rule(:statement) do
33
+ requirement_statement |
34
+ element_statement |
35
+ relationship_statement |
36
+ style_statement |
37
+ class_definition_statement |
38
+ class_assignment_statement
39
+ end
40
+
41
+ # Requirement: requirement [type] name { properties }
42
+ # or: functionalRequirement name { properties }
43
+ rule(:requirement_statement) do
44
+ requirement_keyword.as(:req_type) >>
45
+ space >>
46
+ identifier.as(:req_name) >>
47
+ (ws? >> class_shorthand.as(:req_classes)).maybe >>
48
+ ws? >>
49
+ lbrace >>
50
+ ws? >>
51
+ properties.maybe.as(:req_properties) >>
52
+ ws? >>
53
+ rbrace >>
54
+ line_end
55
+ end
56
+
57
+ rule(:requirement_keyword) do
58
+ str('functionalRequirement') |
59
+ str('interfaceRequirement') |
60
+ str('performanceRequirement') |
61
+ str('physicalRequirement') |
62
+ str('designConstraint') |
63
+ str('requirement')
64
+ end
65
+
66
+ # Element: element name { properties }
67
+ rule(:element_statement) do
68
+ str('element').as(:elem_keyword) >>
69
+ space >>
70
+ identifier.as(:elem_name) >>
71
+ (ws? >> class_shorthand.as(:elem_classes)).maybe >>
72
+ ws? >>
73
+ lbrace >>
74
+ ws? >>
75
+ properties.maybe.as(:elem_properties) >>
76
+ ws? >>
77
+ rbrace >>
78
+ line_end
79
+ end
80
+
81
+ # Properties: key: value pairs
82
+ rule(:properties) do
83
+ (property >> ws?).repeat(1)
84
+ end
85
+
86
+ rule(:property) do
87
+ property_key.as(:key) >>
88
+ ws? >>
89
+ colon >>
90
+ ws? >>
91
+ property_value.as(:value) >>
92
+ line_end
93
+ end
94
+
95
+ rule(:property_key) do
96
+ (str('id') | str('text') | str('risk') | str('verifymethod') |
97
+ str('type') | str('docref')).as(:prop_key)
98
+ end
99
+
100
+ rule(:property_value) do
101
+ (line_end.absent? >> any).repeat(1)
102
+ end
103
+
104
+ # Relationship: source - type -> target
105
+ rule(:relationship_statement) do
106
+ identifier.as(:rel_source) >>
107
+ ws? >>
108
+ str('-') >>
109
+ ws? >>
110
+ relationship_type.as(:rel_type) >>
111
+ ws? >>
112
+ str('->') >>
113
+ ws? >>
114
+ identifier.as(:rel_target) >>
115
+ line_end
116
+ end
117
+
118
+ rule(:relationship_type) do
119
+ (str('contains') | str('copies') | str('derives') |
120
+ str('satisfies') | str('verifies') | str('refines') |
121
+ str('traces')).as(:type)
122
+ end
123
+
124
+ # Style: style target1 [target2 ...] fill:#f9f,stroke:#333
125
+ rule(:style_statement) do
126
+ str('style').as(:style_keyword) >> space >>
127
+ style_targets.as(:style_targets) >> space >>
128
+ style_properties.as(:style_props) >>
129
+ line_end
130
+ end
131
+
132
+ rule(:style_targets) do
133
+ identifier >> (comma >> ws? >> identifier).repeat
134
+ end
135
+
136
+ rule(:style_properties) do
137
+ style_property >> (comma >> style_property).repeat
138
+ end
139
+
140
+ rule(:style_property) do
141
+ (line_end.absent? >> comma.absent? >> any).repeat(1)
142
+ end
143
+
144
+ # Class definition: classDef className fill:#f9f,stroke:#333
145
+ rule(:class_definition_statement) do
146
+ str('classDef').as(:classdef_keyword) >> space >>
147
+ identifier.as(:class_name) >>
148
+ (space >> class_property).repeat(1).as(:class_props) >>
149
+ line_end
150
+ end
151
+
152
+ rule(:class_property) do
153
+ (line_end.absent? >> comma.absent? >> any).repeat(1)
154
+ end
155
+
156
+ # Class assignment: class target1,target2 className1,className2
157
+ rule(:class_assignment_statement) do
158
+ str('class').as(:class_keyword) >> space >>
159
+ class_assign_targets.as(:class_targets) >> space >>
160
+ class_assign_names.as(:class_names) >>
161
+ line_end
162
+ end
163
+
164
+ rule(:class_assign_targets) do
165
+ identifier >> (comma >> identifier).repeat
166
+ end
167
+
168
+ rule(:class_assign_names) do
169
+ identifier >> (comma >> identifier).repeat
170
+ end
171
+
172
+ # Class shorthand: :::className or :::class1,class2
173
+ rule(:class_shorthand) do
174
+ str(':::') >> class_shorthand_names
175
+ end
176
+
177
+ rule(:class_shorthand_names) do
178
+ identifier >> (comma >> identifier).repeat
179
+ end
180
+
181
+ # Line terminator
182
+ rule(:line_end) do
183
+ space? >> (comment.maybe >> newline | eof)
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "common"
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for Sankey diagrams.
9
+ #
10
+ # Handles Sankey diagram syntax including flows (CSV format) and
11
+ # optional node declarations with labels.
12
+ #
13
+ # @example Simple Sankey
14
+ # sankey-beta
15
+ # A,B,10
16
+ # B,C,20
17
+ #
18
+ # @example Sankey with node labels
19
+ # sankey-beta
20
+ # Source [Energy Source]
21
+ # Process [Processing Plant]
22
+ # Source,Process,100
23
+ # Process,Output,70
24
+ class Sankey < Common
25
+ root(:diagram)
26
+
27
+ # Main diagram structure
28
+ rule(:diagram) do
29
+ ws? >>
30
+ header >>
31
+ ws? >>
32
+ statements.maybe >>
33
+ ws?
34
+ end
35
+
36
+ # Header: sankey-beta
37
+ rule(:header) do
38
+ str("sankey-beta").as(:header) >> ws?
39
+ end
40
+
41
+ # Statements (node declarations and flow entries)
42
+ rule(:statements) do
43
+ (statement >> ws?).repeat(1)
44
+ end
45
+
46
+ rule(:statement) do
47
+ node_declaration |
48
+ flow_entry |
49
+ comment >> line_end
50
+ end
51
+
52
+ # Node declaration with optional label
53
+ # Example: NodeID [Node Label]
54
+ rule(:node_declaration) do
55
+ (space? >>
56
+ node_id.as(:node_id) >>
57
+ space? >>
58
+ lbracket >>
59
+ (rbracket.absent? >> any).repeat(1).as(:node_label) >>
60
+ rbracket >>
61
+ line_end).as(:node_declaration)
62
+ end
63
+
64
+ # Flow entry: source,target,value
65
+ # Example: A,B,10.5
66
+ rule(:flow_entry) do
67
+ (space? >>
68
+ node_id.as(:source) >>
69
+ space? >> comma >> space? >>
70
+ node_id.as(:target) >>
71
+ space? >> comma >> space? >>
72
+ flow_value.as(:value) >>
73
+ line_end).as(:flow_entry)
74
+ end
75
+
76
+ # Node identifier (alphanumeric, underscores, dashes)
77
+ rule(:node_id) do
78
+ match["a-zA-Z0-9_-"].repeat(1)
79
+ end
80
+
81
+ # Flow value (integer or float)
82
+ rule(:flow_value) do
83
+ match["0-9"].repeat(1) >>
84
+ (str(".") >> match["0-9"].repeat(1)).maybe
85
+ end
86
+
87
+ # Comma separator
88
+ rule(:comma) do
89
+ str(",")
90
+ end
91
+
92
+ # Left bracket
93
+ rule(:lbracket) do
94
+ str("[")
95
+ end
96
+
97
+ # Right bracket
98
+ rule(:rbracket) do
99
+ str("]")
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,247 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for sequence diagrams.
9
+ #
10
+ # Handles all sequence diagram syntax including participants, messages,
11
+ # notes, activations, and control structures. The grammar properly handles
12
+ # complex arrow patterns with activation modifiers that cannot be parsed
13
+ # correctly by regex-based lexers.
14
+ class Sequence < Common
15
+ root(:diagram)
16
+
17
+ # Main diagram structure
18
+ rule(:diagram) do
19
+ ws? >>
20
+ header >>
21
+ ws? >>
22
+ statements.maybe >>
23
+ ws?
24
+ end
25
+
26
+ rule(:header) do
27
+ str('sequenceDiagram').as(:header) >> ws?
28
+ end
29
+
30
+ rule(:statements) do
31
+ (statement >> ws?).repeat(1)
32
+ end
33
+
34
+ rule(:statement) do
35
+ participant_declaration |
36
+ actor_declaration |
37
+ note_statement |
38
+ box_statement |
39
+ activation_command |
40
+ deactivation_command |
41
+ control_structure |
42
+ message
43
+ end
44
+
45
+ # Participant declarations
46
+ rule(:participant_declaration) do
47
+ str('participant') >> space.repeat(1) >>
48
+ identifier.as(:id) >> space? >>
49
+ (str('as') >> space.repeat(1) >> label.as(:label)).maybe >>
50
+ line_end.as(:participant)
51
+ end
52
+
53
+ rule(:actor_declaration) do
54
+ str('actor') >> space.repeat(1) >>
55
+ identifier.as(:id) >> space? >>
56
+ (str('as') >> space.repeat(1) >> label.as(:label)).maybe >>
57
+ line_end.as(:actor)
58
+ end
59
+
60
+ # Messages with arrows (order matters: longest patterns first)
61
+ rule(:message) do
62
+ identifier.as(:from) >> space? >>
63
+ arrow.as(:arrow) >> space? >>
64
+ identifier.as(:to) >> space? >>
65
+ message_text.maybe.as(:text) >>
66
+ line_end
67
+ end
68
+
69
+ # Arrow types including activation modifiers
70
+ # Critical: These must be tried in order from longest to shortest
71
+ rule(:arrow) do
72
+ arrow_with_activation | arrow_without_activation
73
+ end
74
+
75
+ rule(:arrow_with_activation) do
76
+ (
77
+ str('->>+') | str('-->>+') |
78
+ str('->>-') | str('-->>-')
79
+ ).as(:arrow_activation)
80
+ end
81
+
82
+ rule(:arrow_without_activation) do
83
+ (
84
+ str('->>') >> str('+').absent? >> str('-').absent? |
85
+ str('-->>') >> str('+').absent? >> str('-').absent? |
86
+ str('->)') | str('-->)') |
87
+ str('->') | str('-->')
88
+ ).as(:arrow_plain)
89
+ end
90
+
91
+ rule(:message_text) do
92
+ colon >> space? >>
93
+ (line_end.absent? >> any).repeat.as(:message_text)
94
+ end
95
+
96
+ # Notes
97
+ rule(:note_statement) do
98
+ (str('note') | str('Note')) >> space.repeat(1) >>
99
+ note_position.as(:position) >> space.repeat(1) >>
100
+ note_participants.as(:participants) >> space? >>
101
+ colon >> space? >>
102
+ (line_end.absent? >> any).repeat.as(:note_text) >>
103
+ line_end
104
+ end
105
+
106
+ rule(:note_position) do
107
+ (str('left') >> space.repeat(1) >> str('of')).as(:left_of) |
108
+ (str('right') >> space.repeat(1) >> str('of')).as(:right_of) |
109
+ str('over').as(:over)
110
+ end
111
+
112
+ rule(:note_participants) do
113
+ identifier.as(:participant) >>
114
+ (space? >> comma >> space? >>
115
+ identifier.as(:participant)).repeat
116
+ end
117
+
118
+ # Activation/Deactivation commands
119
+ rule(:activation_command) do
120
+ str('activate') >> space.repeat(1) >>
121
+ identifier.as(:activate) >>
122
+ line_end
123
+ end
124
+
125
+ rule(:deactivation_command) do
126
+ str('deactivate') >> space.repeat(1) >>
127
+ identifier.as(:deactivate) >>
128
+ line_end
129
+ end
130
+
131
+ # Box grouping
132
+ rule(:box_statement) do
133
+ str('box') >> space.repeat(1) >>
134
+ (line_end.absent? >> any).repeat.as(:box_label) >>
135
+ line_end >>
136
+ ws? >>
137
+ statements.as(:box_statements) >>
138
+ ws? >>
139
+ str('end') >> line_end
140
+ end
141
+
142
+ # Control structures
143
+ rule(:control_structure) do
144
+ loop_structure |
145
+ alt_structure |
146
+ opt_structure |
147
+ par_structure |
148
+ critical_structure |
149
+ break_structure
150
+ end
151
+
152
+ rule(:loop_structure) do
153
+ str('loop') >> space? >>
154
+ (line_end.absent? >> any).repeat.as(:loop_label) >>
155
+ line_end >>
156
+ ws? >>
157
+ statements.as(:loop_statements) >>
158
+ ws? >>
159
+ str('end') >> line_end
160
+ end
161
+
162
+ rule(:alt_structure) do
163
+ str('alt') >> space? >>
164
+ (line_end.absent? >> any).repeat.as(:alt_label) >>
165
+ line_end >>
166
+ ws? >>
167
+ statements.as(:alt_statements) >>
168
+ ws? >>
169
+ (
170
+ str('else') >> space? >>
171
+ (line_end.absent? >> any).repeat.as(:else_label) >>
172
+ line_end >>
173
+ ws? >>
174
+ statements.as(:else_statements) >>
175
+ ws?
176
+ ).repeat.as(:else_blocks) >>
177
+ str('end') >> line_end
178
+ end
179
+
180
+ rule(:opt_structure) do
181
+ str('opt') >> space? >>
182
+ (line_end.absent? >> any).repeat.as(:opt_label) >>
183
+ line_end >>
184
+ ws? >>
185
+ statements.as(:opt_statements) >>
186
+ ws? >>
187
+ str('end') >> line_end
188
+ end
189
+
190
+ rule(:par_structure) do
191
+ str('par') >> space? >>
192
+ (line_end.absent? >> any).repeat.as(:par_label) >>
193
+ line_end >>
194
+ ws? >>
195
+ statements.as(:par_statements) >>
196
+ ws? >>
197
+ (
198
+ str('and') >> space? >>
199
+ (line_end.absent? >> any).repeat.as(:and_label) >>
200
+ line_end >>
201
+ ws? >>
202
+ statements.as(:and_statements) >>
203
+ ws?
204
+ ).repeat.as(:and_blocks) >>
205
+ str('end') >> line_end
206
+ end
207
+
208
+ rule(:critical_structure) do
209
+ str('critical') >> space? >>
210
+ (line_end.absent? >> any).repeat.as(:critical_label) >>
211
+ line_end >>
212
+ ws? >>
213
+ statements.as(:critical_statements) >>
214
+ ws? >>
215
+ (
216
+ str('option') >> space? >>
217
+ (line_end.absent? >> any).repeat.as(:option_label) >>
218
+ line_end >>
219
+ ws? >>
220
+ statements.as(:option_statements) >>
221
+ ws?
222
+ ).repeat.as(:option_blocks) >>
223
+ str('end') >> line_end
224
+ end
225
+
226
+ rule(:break_structure) do
227
+ str('break') >> space? >>
228
+ (line_end.absent? >> any).repeat.as(:break_label) >>
229
+ line_end >>
230
+ ws? >>
231
+ statements.as(:break_statements) >>
232
+ ws? >>
233
+ str('end') >> line_end
234
+ end
235
+
236
+ # Label can be quoted or unquoted text
237
+ rule(:label) do
238
+ string | unquoted_label
239
+ end
240
+
241
+ rule(:unquoted_label) do
242
+ (line_end.absent? >> any).repeat(1)
243
+ end
244
+ end
245
+ end
246
+ end
247
+ end