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,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for info diagrams.
9
+ #
10
+ # Handles simple info diagram syntax with optional showInfo flag.
11
+ #
12
+ # @example Simple info diagram
13
+ # info
14
+ #
15
+ # @example Info diagram with showInfo flag
16
+ # info showInfo
17
+ class Info < Common
18
+ root(:diagram)
19
+
20
+ # Main diagram structure
21
+ rule(:diagram) do
22
+ ws? >>
23
+ header >>
24
+ ws? >>
25
+ body.maybe >>
26
+ ws?
27
+ end
28
+
29
+ # Header: info [showInfo] [additional text...]
30
+ rule(:header) do
31
+ str('info').as(:header) >>
32
+ (space.repeat(1) >> show_info_inline).maybe.as(:show_info_inline) >>
33
+ (space.repeat(1) >> additional_text).maybe >>
34
+ ws?
35
+ end
36
+
37
+ # showInfo on same line as info
38
+ rule(:show_info_inline) do
39
+ str('showInfo').as(:show_info)
40
+ end
41
+
42
+ # Additional text after info keyword (ignored, but not showInfo)
43
+ rule(:additional_text) do
44
+ (str('showInfo').absent? >> line_end.absent? >> any).repeat(1)
45
+ end
46
+
47
+ # Body: showInfo on separate line
48
+ rule(:body) do
49
+ (space.repeat >> show_info_statement >> line_end).repeat(1).as(:show_info_body)
50
+ end
51
+
52
+ rule(:show_info_statement) do
53
+ str('showInfo')
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "common"
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for Kanban diagrams
9
+ class Kanban < Common
10
+ rule(:diagram) do
11
+ space? >>
12
+ header >>
13
+ (content_line).repeat(0).as(:lines) >>
14
+ space?
15
+ end
16
+
17
+ rule(:header) do
18
+ str("kanban") >> (newline | eof)
19
+ end
20
+
21
+ rule(:content_line) do
22
+ empty_line | item_line
23
+ end
24
+
25
+ rule(:empty_line) do
26
+ space? >> newline
27
+ end
28
+
29
+ rule(:item_line) do
30
+ str(' ').repeat.as(:indent) >>
31
+ item >>
32
+ (newline | eof)
33
+ end
34
+
35
+ # An item can be either a column or a card
36
+ rule(:item) do
37
+ identifier.as(:id) >>
38
+ lbracket >>
39
+ match('[^\]]').repeat(1).as(:text) >>
40
+ rbracket >>
41
+ metadata.maybe
42
+ end
43
+
44
+ # Metadata: @{ key: 'value', key2: 'value2' }
45
+ rule(:metadata) do
46
+ str("@") >>
47
+ space? >>
48
+ lbrace >>
49
+ space? >>
50
+ metadata_entries.maybe.as(:metadata) >>
51
+ space? >>
52
+ rbrace
53
+ end
54
+
55
+ rule(:metadata_entries) do
56
+ metadata_entry >> (comma >> space? >> metadata_entry).repeat
57
+ end
58
+
59
+ rule(:metadata_entry) do
60
+ metadata_key.as(:key) >>
61
+ space? >>
62
+ colon >>
63
+ space? >>
64
+ metadata_value.as(:value)
65
+ end
66
+
67
+ rule(:metadata_key) do
68
+ match['a-zA-Z_'] >> match['a-zA-Z0-9_'].repeat
69
+ end
70
+
71
+ rule(:metadata_value) do
72
+ quoted_string | single_quoted_string | unquoted_value
73
+ end
74
+
75
+ rule(:unquoted_value) do
76
+ match['a-zA-Z0-9_\-'].repeat(1).as(:string)
77
+ end
78
+
79
+ root(:diagram)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "common"
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for Mindmap diagrams
9
+ class Mindmap < Common
10
+ rule(:diagram) do
11
+ space? >>
12
+ header >>
13
+ (node_line).repeat(0).as(:nodes) >>
14
+ space?
15
+ end
16
+
17
+ rule(:header) do
18
+ str("mindmap") >> (newline | eof)
19
+ end
20
+
21
+ rule(:node_line) do
22
+ empty_line | node_with_content
23
+ end
24
+
25
+ rule(:empty_line) do
26
+ space? >> newline
27
+ end
28
+
29
+ rule(:node_with_content) do
30
+ str(' ').repeat.as(:indent) >>
31
+ node >>
32
+ (newline | eof)
33
+ end
34
+
35
+ rule(:node) do
36
+ node_with_icon |
37
+ node_with_class |
38
+ node_with_shape |
39
+ node_plain
40
+ end
41
+
42
+ # Node with icon: ::icon(fa fa-book)
43
+ rule(:node_with_icon) do
44
+ str("::icon(") >>
45
+ match('[^)]').repeat(1).as(:icon) >>
46
+ str(")")
47
+ end
48
+
49
+ # Node with class: :::className
50
+ rule(:node_with_class) do
51
+ str(":::") >>
52
+ match('[^\r\n]').repeat(1).as(:classes)
53
+ end
54
+
55
+ # Node with shape (optional identifier prefix)
56
+ rule(:node_with_shape) do
57
+ match['a-zA-Z0-9_'].repeat >>
58
+ (circle_shape | bang_shape | cloud_shape | hexagon_shape | square_shape)
59
+ end
60
+
61
+ # ((text)) - circle
62
+ rule(:circle_shape) do
63
+ str("((") >>
64
+ match('[^)]').repeat(1).as(:content) >>
65
+ str("))") >>
66
+ str("").as(:shape_circle)
67
+ end
68
+
69
+ # ))text(( - bang
70
+ rule(:bang_shape) do
71
+ str("))") >>
72
+ match('[^(]').repeat(1).as(:content) >>
73
+ str("((") >>
74
+ str("").as(:shape_bang)
75
+ end
76
+
77
+ # )text( - cloud
78
+ rule(:cloud_shape) do
79
+ str(")") >>
80
+ match('[^(]').repeat(1).as(:content) >>
81
+ str("(") >>
82
+ str("").as(:shape_cloud)
83
+ end
84
+
85
+ # {{text}} - hexagon
86
+ rule(:hexagon_shape) do
87
+ str("{{") >>
88
+ match('[^}]').repeat(1).as(:content) >>
89
+ str("}}") >>
90
+ str("").as(:shape_hexagon)
91
+ end
92
+
93
+ # [text] - square (handles quoted content like ["text with []"])
94
+ rule(:square_shape) do
95
+ str("[") >>
96
+ (
97
+ # Quoted content: ["text..."]
98
+ (str('"') >> match('[^"]').repeat(1).as(:content) >> str('"')) |
99
+ # Regular content without quotes
100
+ match('[^\]]').repeat(1).as(:content)
101
+ ) >>
102
+ str("]") >>
103
+ str("").as(:shape_square)
104
+ end
105
+
106
+ # Plain text node
107
+ rule(:node_plain) do
108
+ match('[^\r\n:]').repeat(1).as(:content)
109
+ end
110
+
111
+ root(:diagram)
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,73 @@
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 packet-beta diagram syntax
10
+ class Packet < Common
11
+
12
+ rule(:diagram_type) { str("packet-beta") >> space? }
13
+
14
+ rule(:text) { match['^\n'].repeat(1) }
15
+
16
+ rule(:title_line) do
17
+ str("title") >> space >> text.as(:title) >> newline
18
+ end
19
+
20
+ # Field definition: 0-10: "Label"
21
+ rule(:bit_number) do
22
+ match["0-9"].repeat(1)
23
+ end
24
+
25
+ rule(:bit_range) do
26
+ bit_number.as(:bit_start) >>
27
+ str("-") >>
28
+ bit_number.as(:bit_end)
29
+ end
30
+
31
+ rule(:field_label) do
32
+ str('"') >>
33
+ match('[^"]').repeat(0).as(:label) >>
34
+ str('"')
35
+ end
36
+
37
+ rule(:field_line) do
38
+ bit_range >>
39
+ str(":") >> space? >>
40
+ field_label >>
41
+ (newline | eof)
42
+ end
43
+
44
+ rule(:comment_line) do
45
+ comment >> newline
46
+ end
47
+
48
+ rule(:empty_line) do
49
+ space? >> newline
50
+ end
51
+
52
+ rule(:indent?) { space? }
53
+
54
+ rule(:statement) do
55
+ indent? >> (
56
+ title_line |
57
+ field_line |
58
+ comment_line |
59
+ empty_line
60
+ )
61
+ end
62
+
63
+ rule(:body) { statement.repeat(0) }
64
+
65
+ rule(:packet_diagram) do
66
+ diagram_type >> (newline >> body.as(:statements)).maybe >> eof.maybe
67
+ end
68
+
69
+ root(:packet_diagram)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for pie chart diagrams.
9
+ #
10
+ # Handles pie chart syntax including title, data entries with labels
11
+ # and numeric values, and accessibility features.
12
+ #
13
+ # @example Simple pie chart
14
+ # pie
15
+ # "Apples" : 42.5
16
+ # "Oranges" : 30.2
17
+ #
18
+ # @example Pie chart with title and showData
19
+ # pie title "Sales Report" showData
20
+ # "Q1" : 100
21
+ # "Q2" : 150
22
+ class Pie < Common
23
+ root(:diagram)
24
+
25
+ # Main diagram structure
26
+ rule(:diagram) do
27
+ ws? >>
28
+ header >>
29
+ ws? >>
30
+ statements.maybe >>
31
+ ws?
32
+ end
33
+
34
+ # Header: pie|Pie|pie chart|Pie Chart [showData] [title <text>]
35
+ rule(:header) do
36
+ pie_keyword.as(:header) >>
37
+ (space.repeat(1) >> show_data_flag).maybe.as(:show_data) >>
38
+ (space.repeat(1) >> title_declaration).maybe.as(:title) >>
39
+ ws?
40
+ end
41
+
42
+ # Pie keyword - case insensitive with optional "chart" suffix
43
+ rule(:pie_keyword) do
44
+ (match['Pp'] >> str('ie') >> (space.repeat(1) >> match['Cc'] >> str('hart')).maybe)
45
+ end
46
+
47
+ rule(:show_data_flag) do
48
+ str('showData').as(:show_data)
49
+ end
50
+
51
+ rule(:title_declaration) do
52
+ str('title') >> (colon | space.repeat(1)) >>
53
+ title_text.as(:title)
54
+ end
55
+
56
+ rule(:title_text) do
57
+ (line_end.absent? >> any).repeat
58
+ end
59
+
60
+ # Statements (can be data entries or accessibility declarations)
61
+ rule(:statements) do
62
+ (statement >> ws?).repeat(1)
63
+ end
64
+
65
+ rule(:statement) do
66
+ acc_title_declaration |
67
+ acc_descr_declaration |
68
+ standalone_title_declaration |
69
+ data_entry |
70
+ comment >> line_end
71
+ end
72
+
73
+ # Title as a standalone statement (not in header)
74
+ rule(:standalone_title_declaration) do
75
+ # Allow escaped tabs and other whitespace
76
+ (str('\\t') | space).repeat >>
77
+ str('title') >> space.repeat(1) >>
78
+ title_text.as(:standalone_title) >>
79
+ line_end
80
+ end
81
+
82
+ # Accessibility title
83
+ rule(:acc_title_declaration) do
84
+ str('accTitle') >> space? >> colon >> space? >>
85
+ (line_end.absent? >> any).repeat.as(:acc_title) >>
86
+ line_end
87
+ end
88
+
89
+ # Accessibility description (single or multi-line)
90
+ rule(:acc_descr_declaration) do
91
+ acc_descr_single_line | acc_descr_multi_line
92
+ end
93
+
94
+ rule(:acc_descr_single_line) do
95
+ str('accDescr') >> space? >> colon >> space? >>
96
+ (line_end.absent? >> any).repeat.as(:acc_descr) >>
97
+ line_end
98
+ end
99
+
100
+ rule(:acc_descr_multi_line) do
101
+ str('accDescr') >> space? >> lbrace >> ws? >>
102
+ (rbrace.absent? >> any).repeat.as(:acc_descr) >>
103
+ ws? >> rbrace >> line_end
104
+ end
105
+
106
+ # Data entry: "label" : value
107
+ # Allow escaped tabs in data entries
108
+ rule(:data_entry) do
109
+ (str('\\t') | space).repeat >>
110
+ label_text.as(:label) >>
111
+ (str('\\t') | space).repeat >> colon >> (str('\\t') | space).repeat >>
112
+ numeric_value.as(:value) >>
113
+ line_end.as(:data_entry)
114
+ end
115
+
116
+ # Label can be quoted string or unquoted text
117
+ rule(:label_text) do
118
+ quoted_string | single_quoted_string
119
+ end
120
+
121
+ # Numeric value (integer or decimal, can be negative)
122
+ rule(:numeric_value) do
123
+ minus.maybe >> (float | integer)
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for quadrant chart diagrams.
9
+ #
10
+ # Handles quadrant chart syntax including title, axis labels,
11
+ # quadrant labels, and data points with coordinates and styling.
12
+ #
13
+ # @example Simple quadrant chart
14
+ # quadrantChart
15
+ # title Product Analysis
16
+ # x-axis Low Cost --> High Cost
17
+ # y-axis Low Value --> High Value
18
+ # quadrant-1 Invest
19
+ # Product A: [0.3, 0.7]
20
+ #
21
+ # @example With styling
22
+ # quadrantChart
23
+ # Product A: [0.3, 0.7] radius: 10, color: #ff0000
24
+ class Quadrant < 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: quadrantChart
37
+ rule(:header) do
38
+ str('quadrantChart').as(:header) >> ws?
39
+ end
40
+
41
+ # Statements (title, axis labels, quadrant labels, points)
42
+ rule(:statements) do
43
+ (statement >> ws?).repeat(1)
44
+ end
45
+
46
+ rule(:statement) do
47
+ title_declaration |
48
+ x_axis_declaration |
49
+ y_axis_declaration |
50
+ quadrant_label_declaration |
51
+ class_def_declaration |
52
+ data_point |
53
+ comment >> line_end
54
+ end
55
+
56
+ # Title declaration
57
+ rule(:title_declaration) do
58
+ str('title') >> space.repeat(1) >>
59
+ title_text.as(:title) >>
60
+ line_end
61
+ end
62
+
63
+ rule(:title_text) do
64
+ (line_end.absent? >> any).repeat(1)
65
+ end
66
+
67
+ # X-axis: x-axis label1 --> label2
68
+ rule(:x_axis_declaration) do
69
+ str('x-axis') >> space.repeat(1) >>
70
+ axis_label.as(:x_axis_left) >>
71
+ space? >> str('-->') >> space? >>
72
+ axis_label.as(:x_axis_right) >>
73
+ line_end
74
+ end
75
+
76
+ # Y-axis: y-axis label1 --> label2
77
+ rule(:y_axis_declaration) do
78
+ str('y-axis') >> space.repeat(1) >>
79
+ axis_label.as(:y_axis_bottom) >>
80
+ space? >> str('-->') >> space? >>
81
+ axis_label.as(:y_axis_top) >>
82
+ line_end
83
+ end
84
+
85
+ # Axis label (can be quoted or unquoted)
86
+ rule(:axis_label) do
87
+ quoted_string | unquoted_axis_label
88
+ end
89
+
90
+ rule(:unquoted_axis_label) do
91
+ (str('-->').absent? >> line_end.absent? >> any).repeat(1)
92
+ end
93
+
94
+ # Quadrant labels: quadrant-1 through quadrant-4
95
+ rule(:quadrant_label_declaration) do
96
+ str('quadrant-') >>
97
+ match['1-4'].as(:quadrant_number) >>
98
+ space.repeat(1) >>
99
+ quadrant_label_text.as(:quadrant_label) >>
100
+ line_end
101
+ end
102
+
103
+ rule(:quadrant_label_text) do
104
+ (line_end.absent? >> any).repeat(1)
105
+ end
106
+
107
+ # Class definition: classDef name fill:#color
108
+ rule(:class_def_declaration) do
109
+ str('classDef') >> space.repeat(1) >>
110
+ class_name.as(:class_name) >> space.repeat(1) >>
111
+ (line_end.absent? >> any).repeat.as(:class_style) >>
112
+ line_end
113
+ end
114
+
115
+ rule(:class_name) do
116
+ match['a-zA-Z_'].repeat(1) >> match['a-zA-Z0-9_'].repeat
117
+ end
118
+
119
+ # Data point: label[:::class]: [x, y] [styling...]
120
+ rule(:data_point) do
121
+ point_label.as(:label) >>
122
+ class_reference.maybe.as(:class_ref) >>
123
+ space? >> colon >> space? >>
124
+ coordinates.as(:coordinates) >>
125
+ styling_params.maybe.as(:styling) >>
126
+ line_end.as(:data_point)
127
+ end
128
+
129
+ # Point label (text before class reference or colon)
130
+ rule(:point_label) do
131
+ (str(':::').absent? >> colon.absent? >> any).repeat(1)
132
+ end
133
+
134
+ # Class reference: :::className
135
+ rule(:class_reference) do
136
+ str(':::') >> class_name
137
+ end
138
+
139
+ # Coordinates: [x, y]
140
+ rule(:coordinates) do
141
+ lbracket >>
142
+ space? >>
143
+ float.as(:x) >>
144
+ space? >> comma >> space? >>
145
+ float.as(:y) >>
146
+ space? >>
147
+ rbracket
148
+ end
149
+
150
+ # Optional styling parameters (flexible whitespace around commas)
151
+ rule(:styling_params) do
152
+ (space.repeat(1) >> styling_param >> (space? >> comma >> space? >> styling_param).repeat).maybe
153
+ end
154
+
155
+ rule(:styling_param) do
156
+ radius_param |
157
+ color_param |
158
+ stroke_color_param |
159
+ stroke_width_param
160
+ end
161
+
162
+ # radius: value
163
+ rule(:radius_param) do
164
+ str('radius') >> space? >> colon >> space? >>
165
+ (float | integer).as(:radius)
166
+ end
167
+
168
+ # color: #hex
169
+ rule(:color_param) do
170
+ str('color') >> space? >> colon >> space? >>
171
+ color_value.as(:color)
172
+ end
173
+
174
+ # stroke-color: #hex
175
+ rule(:stroke_color_param) do
176
+ str('stroke-color') >> space? >> colon >> space? >>
177
+ color_value.as(:stroke_color)
178
+ end
179
+
180
+ # stroke-width: valuepx
181
+ rule(:stroke_width_param) do
182
+ str('stroke-width') >> space? >> colon >> space? >>
183
+ (float | integer).as(:stroke_width) >>
184
+ str('px').maybe
185
+ end
186
+
187
+ # Color value (#hex or named color)
188
+ rule(:color_value) do
189
+ str('#') >> match['0-9a-fA-F'].repeat(3, 8) |
190
+ match['a-zA-Z'].repeat(1)
191
+ end
192
+
193
+ # Brackets
194
+ rule(:lbracket) { str('[') }
195
+ rule(:rbracket) { str(']') }
196
+ end
197
+ end
198
+ end
199
+ end