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,284 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for Class diagrams.
9
+ #
10
+ # Handles UML class diagram syntax including classes, attributes,
11
+ # methods, relationships with various types (inheritance, composition,
12
+ # aggregation, association, dependency, realization), stereotypes,
13
+ # generic types, namespaces, and cardinality labels.
14
+ class ClassDiagram < 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('classDiagram').as(:header) >>
28
+ ws? >>
29
+ direction.maybe.as(:direction)
30
+ end
31
+
32
+ rule(:direction) do
33
+ (str('TD') | str('TB') | str('LR') | str('RL') | str('BT')).as(:dir_value) >> ws?
34
+ end
35
+
36
+ rule(:statements) do
37
+ (statement >> ws?).repeat(1)
38
+ end
39
+
40
+ rule(:statement) do
41
+ namespace_block |
42
+ class_declaration |
43
+ standalone_stereotype |
44
+ colon_member_definition |
45
+ relationship |
46
+ link_statement |
47
+ callback_statement |
48
+ standalone_class
49
+ end
50
+
51
+ # Namespace block: namespace Name { ... }
52
+ rule(:namespace_block) do
53
+ str('namespace').as(:namespace_keyword) >> space >>
54
+ namespace_name.as(:namespace_name) >> space? >>
55
+ lbrace >> ws? >>
56
+ namespace_statements.maybe.as(:namespace_body) >>
57
+ ws? >> rbrace >>
58
+ line_end
59
+ end
60
+
61
+ rule(:namespace_name) do
62
+ (match['a-zA-Z0-9_.'] | str('-')).repeat(1)
63
+ end
64
+
65
+ rule(:namespace_statements) do
66
+ (namespace_statement >> ws?).repeat(1)
67
+ end
68
+
69
+ rule(:namespace_statement) do
70
+ class_declaration |
71
+ standalone_stereotype |
72
+ colon_member_definition |
73
+ relationship |
74
+ standalone_class
75
+ end
76
+
77
+ # Class declaration: class ClassName <<stereotype>> { body }
78
+ rule(:class_declaration) do
79
+ str('class').as(:keyword) >> space >>
80
+ class_name.as(:class_id) >> space? >>
81
+ stereotype.maybe.as(:stereotype) >> space? >>
82
+ generic_params.maybe.as(:generic) >> space? >>
83
+ class_body.maybe.as(:body) >>
84
+ line_end
85
+ end
86
+
87
+ # Standalone stereotype: <<interface>> ClassName
88
+ rule(:standalone_stereotype) do
89
+ stereotype.as(:stereotype) >> space >>
90
+ class_name.as(:class_id) >>
91
+ line_end
92
+ end
93
+
94
+ # Colon member definition: ClassName : +member or ClassName : +method()
95
+ rule(:colon_member_definition) do
96
+ class_name.as(:class_id) >> space? >>
97
+ colon >> space? >>
98
+ visibility_modifier.maybe.as(:visibility) >>
99
+ member_definition.as(:member) >>
100
+ line_end
101
+ end
102
+
103
+ # Link statement: link ClassName "url" "tooltip"
104
+ rule(:link_statement) do
105
+ str('link').as(:link_keyword) >> space >>
106
+ class_name.as(:class_id) >> space >>
107
+ string.as(:url) >>
108
+ (space >> string.as(:tooltip)).maybe >>
109
+ line_end
110
+ end
111
+
112
+ # Callback statement: callback ClassName "function" "tooltip"
113
+ rule(:callback_statement) do
114
+ str('callback').as(:callback_keyword) >> space >>
115
+ class_name.as(:class_id) >> space >>
116
+ string.as(:callback_fn) >>
117
+ (space >> string.as(:tooltip)).maybe >>
118
+ line_end
119
+ end
120
+
121
+ # Standalone class (just an identifier)
122
+ rule(:standalone_class) do
123
+ class_name.as(:class_id) >> line_end
124
+ end
125
+
126
+ # Class name (identifier or dotted identifier)
127
+ rule(:class_name) do
128
+ (match['a-zA-Z_'] >> match['a-zA-Z0-9_.'].repeat)
129
+ end
130
+
131
+ # Stereotype: <<interface>>, <<abstract>>, etc.
132
+ rule(:stereotype) do
133
+ str('<<') >>
134
+ (str('>>').absent? >> any).repeat(1).as(:stereotype_value) >>
135
+ str('>>')
136
+ end
137
+
138
+ # Generic parameters: ~T~ or ~Type~
139
+ rule(:generic_params) do
140
+ tilde >>
141
+ (tilde.absent? >> any).repeat(1).as(:generic_type) >>
142
+ tilde
143
+ end
144
+
145
+ # Class body: { members }
146
+ rule(:class_body) do
147
+ lbrace >> ws? >>
148
+ class_members.maybe >>
149
+ ws? >> rbrace
150
+ end
151
+
152
+ rule(:class_members) do
153
+ (class_member >> ws?).repeat(1)
154
+ end
155
+
156
+ rule(:class_member) do
157
+ visibility_modifier.maybe.as(:visibility) >>
158
+ member_definition.as(:member)
159
+ end
160
+
161
+ # Member definition (attribute or method)
162
+ rule(:member_definition) do
163
+ method_definition | attribute_definition
164
+ end
165
+
166
+ # Method: name(params) or name(params): returnType
167
+ rule(:method_definition) do
168
+ method_name.as(:method_name) >>
169
+ lparen >>
170
+ method_params.maybe.as(:parameters) >>
171
+ rparen >>
172
+ method_return_type.maybe.as(:return_type)
173
+ end
174
+
175
+ rule(:method_name) do
176
+ identifier
177
+ end
178
+
179
+ rule(:method_params) do
180
+ (rparen.absent? >> any).repeat(1)
181
+ end
182
+
183
+ rule(:method_return_type) do
184
+ space? >> colon >> space? >>
185
+ type_expression.as(:type)
186
+ end
187
+
188
+ # Attribute: type name or name: type
189
+ rule(:attribute_definition) do
190
+ # Try type-first format: type name
191
+ (type_expression.as(:type) >> space >> identifier.as(:attr_name)) |
192
+ # Try name-first with optional type: name or name: type
193
+ (identifier.as(:attr_name) >>
194
+ (space? >> colon >> space? >> type_expression.as(:type)).maybe)
195
+ end
196
+
197
+ # Type expression (handles generics like List~String~)
198
+ rule(:type_expression) do
199
+ (
200
+ match['a-zA-Z_'] >> match['a-zA-Z0-9_<>'].repeat >>
201
+ (tilde >> (tilde.absent? >> any).repeat >> tilde).maybe
202
+ )
203
+ end
204
+
205
+ # Visibility modifiers
206
+ rule(:visibility_modifier) do
207
+ (plus | minus | hash | tilde).as(:vis_symbol)
208
+ end
209
+
210
+ # Relationship: A relationship_operator B
211
+ rule(:relationship) do
212
+ class_name.as(:from_id) >> space? >>
213
+ source_cardinality.maybe.as(:source_card) >> space? >>
214
+ relationship_operator.as(:operator) >> space? >>
215
+ pipe_label.maybe.as(:pipe_label) >> space? >>
216
+ target_cardinality.maybe.as(:target_card) >> space? >>
217
+ class_name.as(:to_id) >>
218
+ colon_label.maybe.as(:colon_label) >>
219
+ line_end
220
+ end
221
+
222
+ # Cardinality: "1", "*", "0..1", "1..*", etc.
223
+ rule(:source_cardinality) do
224
+ string
225
+ end
226
+
227
+ rule(:target_cardinality) do
228
+ string
229
+ end
230
+
231
+ # Relationship operators (8 types)
232
+ rule(:relationship_operator) do
233
+ inheritance_operator |
234
+ composition_operator |
235
+ aggregation_operator |
236
+ realization_operator |
237
+ dependency_operator |
238
+ association_operator
239
+ end
240
+
241
+ rule(:inheritance_operator) do
242
+ (str('<|--') | str('--|>')).as(:arrow)
243
+ end
244
+
245
+ rule(:composition_operator) do
246
+ (str('*--') | str('--*')).as(:arrow)
247
+ end
248
+
249
+ rule(:aggregation_operator) do
250
+ (str('o--') | str('--o')).as(:arrow)
251
+ end
252
+
253
+ rule(:realization_operator) do
254
+ (str('..|>') | str('<|..')).as(:arrow)
255
+ end
256
+
257
+ rule(:dependency_operator) do
258
+ (str('..>') | str('<..')).as(:arrow)
259
+ end
260
+
261
+ rule(:association_operator) do
262
+ (str('-->') | str('<--') | str('--') | str('..')).as(:arrow)
263
+ end
264
+
265
+ # Labels
266
+ rule(:pipe_label) do
267
+ pipe >>
268
+ (pipe.absent? >> any).repeat(1).as(:label_text) >>
269
+ pipe
270
+ end
271
+
272
+ rule(:colon_label) do
273
+ space? >> colon >> space? >>
274
+ (line_end.absent? >> any).repeat(1).as(:label_text)
275
+ end
276
+
277
+ # Line terminators for class diagrams
278
+ rule(:line_end) do
279
+ semicolon.maybe >> space? >> (comment.maybe >> newline | eof)
280
+ end
281
+ end
282
+ end
283
+ end
284
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parslet'
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Common grammar rules for Mermaid diagrams.
9
+ #
10
+ # Provides shared parsing patterns used across all diagram types,
11
+ # including whitespace handling, comments, identifiers, strings,
12
+ # and common punctuation.
13
+ class Common < Parslet::Parser
14
+ # Whitespace patterns
15
+ rule(:space) { match[' \t'] }
16
+ rule(:space?) { space.repeat }
17
+ rule(:newline) { str("\n") | str("\r\n") }
18
+ rule(:whitespace) { (space | newline).repeat(1) }
19
+ rule(:whitespace?) { (space | newline).repeat }
20
+
21
+ # Comments
22
+ rule(:comment) { str('%%') >> (newline.absent? >> any).repeat }
23
+
24
+ # Identifiers and keywords
25
+ rule(:identifier) do
26
+ match['a-zA-Z_'] >> match['a-zA-Z0-9_'].repeat
27
+ end
28
+
29
+ rule(:quoted_string) do
30
+ str('"') >> (
31
+ str('\\') >> any | str('"').absent? >> any
32
+ ).repeat.as(:string) >> str('"')
33
+ end
34
+
35
+ rule(:single_quoted_string) do
36
+ str("'") >> (
37
+ str('\\') >> any | str("'").absent? >> any
38
+ ).repeat.as(:string) >> str("'")
39
+ end
40
+
41
+ rule(:string) { quoted_string | single_quoted_string }
42
+
43
+ # Numbers
44
+ rule(:integer) { match['0-9'].repeat(1) }
45
+ rule(:float) do
46
+ integer >> str('.') >> integer
47
+ end
48
+ rule(:number) { float | integer }
49
+
50
+ # Common punctuation
51
+ rule(:colon) { str(':') }
52
+ rule(:semicolon) { str(';') }
53
+ rule(:comma) { str(',') }
54
+ rule(:lparen) { str('(') }
55
+ rule(:rparen) { str(')') }
56
+ rule(:lbracket) { str('[') }
57
+ rule(:rbracket) { str(']') }
58
+ rule(:lbrace) { str('{') }
59
+ rule(:rbrace) { str('}') }
60
+ rule(:pipe) { str('|') }
61
+ rule(:equals) { str('=') }
62
+ rule(:plus) { str('+') }
63
+ rule(:minus) { str('-') }
64
+ rule(:asterisk) { str('*') }
65
+ rule(:tilde) { str('~') }
66
+ rule(:hash) { str('#') }
67
+
68
+ # Line terminators
69
+ rule(:line_end) do
70
+ semicolon.maybe >> space? >> (comment.maybe >> newline | eof)
71
+ end
72
+
73
+ # Alias for end-of-line (used by some grammars)
74
+ rule(:eol) { line_end }
75
+
76
+ rule(:eof) { any.absent? }
77
+
78
+ # Utility: skip whitespace and comments
79
+ rule(:ws) { (space | newline | comment).repeat }
80
+ rule(:ws?) { ws.maybe }
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for ER diagrams.
9
+ #
10
+ # Handles Entity-Relationship diagram syntax including entities,
11
+ # attributes, relationships with cardinality notation, and both
12
+ # identifying and non-identifying relationships.
13
+ class ErDiagram < Common
14
+ root(:diagram)
15
+
16
+ # Main diagram structure
17
+ rule(:diagram) do
18
+ ws? >>
19
+ header >>
20
+ ws? >>
21
+ statements.maybe >>
22
+ ws?
23
+ end
24
+
25
+ rule(:header) do
26
+ str('erDiagram').as(:header) >> ws?
27
+ end
28
+
29
+ rule(:statements) do
30
+ (statement >> ws?).repeat(1)
31
+ end
32
+
33
+ rule(:statement) do
34
+ entity_definition |
35
+ relationship |
36
+ entity_declaration
37
+ end
38
+
39
+ # Entity with attribute block
40
+ rule(:entity_definition) do
41
+ identifier.as(:entity_id) >> space? >>
42
+ lbrace >> ws? >>
43
+ attributes.maybe.as(:attributes) >>
44
+ ws? >> rbrace >>
45
+ line_end
46
+ end
47
+
48
+ # Relationship between entities
49
+ rule(:relationship) do
50
+ identifier.as(:from_id) >> space? >>
51
+ relationship_pattern.as(:pattern) >> space? >>
52
+ identifier.as(:to_id) >> space? >>
53
+ relationship_label.maybe.as(:label) >>
54
+ line_end
55
+ end
56
+
57
+ # Stand-alone entity (no body, no relationship)
58
+ rule(:entity_declaration) do
59
+ identifier.as(:entity_id) >> line_end
60
+ end
61
+
62
+ # Attributes within entity block
63
+ rule(:attributes) do
64
+ (attribute >> ws?).repeat(1)
65
+ end
66
+
67
+ rule(:attribute) do
68
+ attribute_type.maybe.as(:type) >> space? >>
69
+ identifier.as(:name) >> space? >>
70
+ key_type.maybe.as(:key) >>
71
+ (space? >> comment).maybe
72
+ end
73
+
74
+ rule(:attribute_type) do
75
+ identifier
76
+ end
77
+
78
+ rule(:key_type) do
79
+ (str('PK') | str('FK') | str('UK')).as(:key_type)
80
+ end
81
+
82
+ # Relationship pattern: cardinality(2) + operator(2) + cardinality(2)
83
+ # Examples: ||--o{, ||==|{, }o..||
84
+ rule(:relationship_pattern) do
85
+ cardinality.as(:card_from) >>
86
+ operator.as(:operator) >>
87
+ cardinality.as(:card_to)
88
+ end
89
+
90
+ # Cardinality symbols (2 characters)
91
+ rule(:cardinality) do
92
+ str('||') | str('o{') | str('|{') | str('}o') |
93
+ str('{o') | str('{|') | str('}{') | str('{}')
94
+ end
95
+
96
+ # Relationship operators (2 characters)
97
+ rule(:operator) do
98
+ str('==') | str('--') | str('..')
99
+ end
100
+
101
+ # Relationship label (after colon)
102
+ rule(:relationship_label) do
103
+ colon >> space? >>
104
+ (line_end.absent? >> any).repeat(1).as(:label_text)
105
+ end
106
+
107
+ # Line terminators for ER diagrams
108
+ rule(:line_end) do
109
+ semicolon.maybe >> space? >> (comment.maybe >> newline | eof)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module Sirena
6
+ module Parser
7
+ module Grammars
8
+ # Parslet grammar for error diagrams.
9
+ #
10
+ # Handles simple error diagram syntax with optional error message.
11
+ #
12
+ # @example Simple error diagram
13
+ # error
14
+ #
15
+ # @example Error diagram with message
16
+ # Error Diagrams
17
+ class Error < Common
18
+ root(:diagram)
19
+
20
+ # Main diagram structure
21
+ rule(:diagram) do
22
+ ws? >>
23
+ header >>
24
+ ws?
25
+ end
26
+
27
+ # Header: error [message text] or Error [message text]
28
+ rule(:header) do
29
+ (str('Error') | str('error')).as(:header) >>
30
+ (space.repeat(1) >> message_text).maybe.as(:message) >>
31
+ ws?
32
+ end
33
+
34
+ rule(:message_text) do
35
+ (line_end.absent? >> any).repeat(1)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end