etassia 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +140 -0
- data/LICENSE +25 -0
- data/README.adoc +436 -0
- data/exe/etassia +7 -0
- data/lib/etassia/cli.rb +187 -0
- data/lib/etassia/commands/batch.rb +210 -0
- data/lib/etassia/commands/notation_loader.rb +22 -0
- data/lib/etassia/commands/render.rb +98 -0
- data/lib/etassia/commands/types.rb +33 -0
- data/lib/etassia/commands/version.rb +24 -0
- data/lib/etassia/corpus_type_names.rb +52 -0
- data/lib/etassia/diagram/architecture.rb +108 -0
- data/lib/etassia/diagram/base.rb +61 -0
- data/lib/etassia/diagram/block.rb +102 -0
- data/lib/etassia/diagram/c4.rb +337 -0
- data/lib/etassia/diagram/class_diagram.rb +466 -0
- data/lib/etassia/diagram/class_namespace.rb +17 -0
- data/lib/etassia/diagram/class_note.rb +17 -0
- data/lib/etassia/diagram/containment.rb +107 -0
- data/lib/etassia/diagram/er_diagram.rb +317 -0
- data/lib/etassia/diagram/error.rb +38 -0
- data/lib/etassia/diagram/flowchart.rb +419 -0
- data/lib/etassia/diagram/flowchart_label_text.rb +63 -0
- data/lib/etassia/diagram/gantt.rb +94 -0
- data/lib/etassia/diagram/generic_text.rb +30 -0
- data/lib/etassia/diagram/git_graph.rb +57 -0
- data/lib/etassia/diagram/info.rb +38 -0
- data/lib/etassia/diagram/kanban.rb +198 -0
- data/lib/etassia/diagram/mindmap.rb +71 -0
- data/lib/etassia/diagram/packet.rb +93 -0
- data/lib/etassia/diagram/pie.rb +115 -0
- data/lib/etassia/diagram/quadrant.rb +135 -0
- data/lib/etassia/diagram/radar.rb +65 -0
- data/lib/etassia/diagram/requirement.rb +168 -0
- data/lib/etassia/diagram/sankey.rb +217 -0
- data/lib/etassia/diagram/sequence.rb +299 -0
- data/lib/etassia/diagram/sequence_box.rb +18 -0
- data/lib/etassia/diagram/sequence_frame.rb +37 -0
- data/lib/etassia/diagram/sequence_frame_section.rb +23 -0
- data/lib/etassia/diagram/sequence_text.rb +69 -0
- data/lib/etassia/diagram/sequence_wrap.rb +23 -0
- data/lib/etassia/diagram/state_diagram.rb +282 -0
- data/lib/etassia/diagram/timeline.rb +183 -0
- data/lib/etassia/diagram/treemap.rb +95 -0
- data/lib/etassia/diagram/user_journey.rb +153 -0
- data/lib/etassia/diagram/xy_chart.rb +90 -0
- data/lib/etassia/diagram.rb +8 -0
- data/lib/etassia/diagram_registry.rb +34 -0
- data/lib/etassia/engine.rb +334 -0
- data/lib/etassia/error/diagram_type_error.rb +10 -0
- data/lib/etassia/error/layout_error.rb +12 -0
- data/lib/etassia/error/notation_registration_error.rb +10 -0
- data/lib/etassia/error/parse_error.rb +11 -0
- data/lib/etassia/error/pipeline_error.rb +10 -0
- data/lib/etassia/error/render_error.rb +12 -0
- data/lib/etassia/error/score_error.rb +12 -0
- data/lib/etassia/error.rb +10 -0
- data/lib/etassia/error_report.rb +69 -0
- data/lib/etassia/ir/data.rb +39 -0
- data/lib/etassia/ir/data_value.rb +35 -0
- data/lib/etassia/ir/dimension.rb +10 -0
- data/lib/etassia/ir/edge.rb +34 -0
- data/lib/etassia/ir/graph.rb +28 -0
- data/lib/etassia/ir/integrity.rb +80 -0
- data/lib/etassia/ir/item.rb +46 -0
- data/lib/etassia/ir/model.rb +56 -0
- data/lib/etassia/ir/node.rb +10 -0
- data/lib/etassia/ir/placement.rb +47 -0
- data/lib/etassia/ir/prepositioned.rb +25 -0
- data/lib/etassia/ir/prepositioned_item.rb +26 -0
- data/lib/etassia/ir/property_set.rb +43 -0
- data/lib/etassia/ir/scalar.rb +25 -0
- data/lib/etassia/ir/series.rb +10 -0
- data/lib/etassia/ir.rb +17 -0
- data/lib/etassia/js_math.rb +511 -0
- data/lib/etassia/js_number.rb +64 -0
- data/lib/etassia/layout/architecture.rb +1472 -0
- data/lib/etassia/layout/base.rb +276 -0
- data/lib/etassia/layout/block.rb +738 -0
- data/lib/etassia/layout/c4.rb +876 -0
- data/lib/etassia/layout/c4_boundary_metrics.rb +35 -0
- data/lib/etassia/layout/c4_bounds.rb +106 -0
- data/lib/etassia/layout/c4_intersection.rb +77 -0
- data/lib/etassia/layout/c4_placement.rb +135 -0
- data/lib/etassia/layout/c4_shape_metrics.rb +97 -0
- data/lib/etassia/layout/c4_shape_outline.rb +67 -0
- data/lib/etassia/layout/c4_stereotype.rb +30 -0
- data/lib/etassia/layout/c4_text.rb +54 -0
- data/lib/etassia/layout/class_cell_placement.rb +148 -0
- data/lib/etassia/layout/class_diagram.rb +1116 -0
- data/lib/etassia/layout/class_diagram_namespaces.rb +26 -0
- data/lib/etassia/layout/class_diagram_notes.rb +26 -0
- data/lib/etassia/layout/class_name_advances.rb +31 -0
- data/lib/etassia/layout/class_namespace_box.rb +21 -0
- data/lib/etassia/layout/class_namespace_nodes.rb +197 -0
- data/lib/etassia/layout/class_namespace_placement.rb +71 -0
- data/lib/etassia/layout/class_note.rb +44 -0
- data/lib/etassia/layout/class_note_nodes.rb +84 -0
- data/lib/etassia/layout/elk_notices.rb +48 -0
- data/lib/etassia/layout/elk_placement.rb +197 -0
- data/lib/etassia/layout/er_diagram.rb +1002 -0
- data/lib/etassia/layout/er_diagram_adjacency.rb +20 -0
- data/lib/etassia/layout/er_diagram_alignment.rb +72 -0
- data/lib/etassia/layout/er_diagram_compaction.rb +85 -0
- data/lib/etassia/layout/er_diagram_conflicts.rb +70 -0
- data/lib/etassia/layout/er_diagram_coordinates.rb +104 -0
- data/lib/etassia/layout/er_diagram_entity_size.rb +82 -0
- data/lib/etassia/layout/er_diagram_layering.rb +109 -0
- data/lib/etassia/layout/er_diagram_ordering.rb +143 -0
- data/lib/etassia/layout/er_diagram_placement.rb +163 -0
- data/lib/etassia/layout/er_diagram_placement_node.rb +22 -0
- data/lib/etassia/layout/error.rb +133 -0
- data/lib/etassia/layout/flowchart/brandes_koepf.rb +208 -0
- data/lib/etassia/layout/flowchart/cluster_reach.rb +70 -0
- data/lib/etassia/layout/flowchart/component_packing.rb +129 -0
- data/lib/etassia/layout/flowchart/directed_placement.rb +428 -0
- data/lib/etassia/layout/flowchart/edge_chains.rb +111 -0
- data/lib/etassia/layout/flowchart/edge_order.rb +34 -0
- data/lib/etassia/layout/flowchart/edge_router.rb +533 -0
- data/lib/etassia/layout/flowchart/label_backdrop_geometry.rb +62 -0
- data/lib/etassia/layout/flowchart/layer_spacing.rb +85 -0
- data/lib/etassia/layout/flowchart/level_edges.rb +74 -0
- data/lib/etassia/layout/flowchart/level_frame.rb +47 -0
- data/lib/etassia/layout/flowchart/minimum_rank_spacing.rb +74 -0
- data/lib/etassia/layout/flowchart/row_centering.rb +229 -0
- data/lib/etassia/layout/flowchart.rb +1290 -0
- data/lib/etassia/layout/gantt.rb +814 -0
- data/lib/etassia/layout/gantt_duration.rb +49 -0
- data/lib/etassia/layout/gantt_exclusions.rb +74 -0
- data/lib/etassia/layout/gantt_ticks.rb +165 -0
- data/lib/etassia/layout/git_graph.rb +1075 -0
- data/lib/etassia/layout/grid.rb +165 -0
- data/lib/etassia/layout/info.rb +113 -0
- data/lib/etassia/layout/kanban.rb +452 -0
- data/lib/etassia/layout/kanban_card_text.rb +95 -0
- data/lib/etassia/layout/mindmap.rb +425 -0
- data/lib/etassia/layout/mindmap_cose.rb +81 -0
- data/lib/etassia/layout/mindmap_cose_body.rb +93 -0
- data/lib/etassia/layout/mindmap_cose_geometry.rb +190 -0
- data/lib/etassia/layout/mindmap_cose_grid.rb +96 -0
- data/lib/etassia/layout/mindmap_cose_link.rb +42 -0
- data/lib/etassia/layout/mindmap_cose_relaxation.rb +166 -0
- data/lib/etassia/layout/mindmap_cose_seed.rb +93 -0
- data/lib/etassia/layout/mindmap_cose_wedge.rb +37 -0
- data/lib/etassia/layout/mindmap_node_size.rb +130 -0
- data/lib/etassia/layout/packet.rb +285 -0
- data/lib/etassia/layout/pie.rb +305 -0
- data/lib/etassia/layout/pie_legend.rb +64 -0
- data/lib/etassia/layout/pie_legend_entry.rb +21 -0
- data/lib/etassia/layout/quadrant.rb +402 -0
- data/lib/etassia/layout/radar.rb +442 -0
- data/lib/etassia/layout/requirement.rb +765 -0
- data/lib/etassia/layout/sankey.rb +501 -0
- data/lib/etassia/layout/scene.rb +18 -0
- data/lib/etassia/layout/sequence/actor_gaps.rb +151 -0
- data/lib/etassia/layout/sequence/box_shape.rb +23 -0
- data/lib/etassia/layout/sequence/creations.rb +73 -0
- data/lib/etassia/layout/sequence/frame_divider.rb +22 -0
- data/lib/etassia/layout/sequence/frame_placement.rb +424 -0
- data/lib/etassia/layout/sequence/frame_reader.rb +75 -0
- data/lib/etassia/layout/sequence/frame_shape.rb +45 -0
- data/lib/etassia/layout/sequence/geometry.rb +24 -0
- data/lib/etassia/layout/sequence/message_rows.rb +165 -0
- data/lib/etassia/layout/sequence/note.rb +16 -0
- data/lib/etassia/layout/sequence/note_box.rb +114 -0
- data/lib/etassia/layout/sequence/note_placement.rb +223 -0
- data/lib/etassia/layout/sequence/text_width.rb +69 -0
- data/lib/etassia/layout/sequence/text_wrap.rb +93 -0
- data/lib/etassia/layout/sequence.rb +936 -0
- data/lib/etassia/layout/state_diagram.rb +1277 -0
- data/lib/etassia/layout/timeline.rb +165 -0
- data/lib/etassia/layout/timeline_card.rb +142 -0
- data/lib/etassia/layout/timeline_flow.rb +164 -0
- data/lib/etassia/layout/timeline_line.rb +33 -0
- data/lib/etassia/layout/timeline_rounding.rb +19 -0
- data/lib/etassia/layout/timeline_text.rb +105 -0
- data/lib/etassia/layout/treemap.rb +303 -0
- data/lib/etassia/layout/treemap_placement.rb +52 -0
- data/lib/etassia/layout/treemap_squarify.rb +108 -0
- data/lib/etassia/layout/user_journey.rb +300 -0
- data/lib/etassia/layout/user_journey_face.rb +33 -0
- data/lib/etassia/layout/user_journey_face_geometry.rb +80 -0
- data/lib/etassia/layout/user_journey_geometry.rb +336 -0
- data/lib/etassia/layout/user_journey_legend.rb +84 -0
- data/lib/etassia/layout/xy_chart.rb +620 -0
- data/lib/etassia/layout.rb +19 -0
- data/lib/etassia/lint_debt_scoreboard.rb +219 -0
- data/lib/etassia/markdown_text/emphasis_simulator.rb +373 -0
- data/lib/etassia/markdown_text.rb +393 -0
- data/lib/etassia/notation/builtin.rb +39 -0
- data/lib/etassia/notation/entry.rb +15 -0
- data/lib/etassia/notation/mermaid/class_diagram_config.rb +42 -0
- data/lib/etassia/notation/mermaid/git_graph_config.rb +46 -0
- data/lib/etassia/notation/mermaid/ir_adapter.rb +27 -0
- data/lib/etassia/notation/mermaid/ir_adapters/architecture.rb +196 -0
- data/lib/etassia/notation/mermaid/ir_adapters/block.rb +138 -0
- data/lib/etassia/notation/mermaid/ir_adapters/c4.rb +258 -0
- data/lib/etassia/notation/mermaid/ir_adapters/class_diagram.rb +257 -0
- data/lib/etassia/notation/mermaid/ir_adapters/er_diagram.rb +220 -0
- data/lib/etassia/notation/mermaid/ir_adapters/error.rb +32 -0
- data/lib/etassia/notation/mermaid/ir_adapters/flowchart.rb +208 -0
- data/lib/etassia/notation/mermaid/ir_adapters/gantt.rb +236 -0
- data/lib/etassia/notation/mermaid/ir_adapters/git_graph.rb +186 -0
- data/lib/etassia/notation/mermaid/ir_adapters/info.rb +34 -0
- data/lib/etassia/notation/mermaid/ir_adapters/kanban.rb +110 -0
- data/lib/etassia/notation/mermaid/ir_adapters/mindmap.rb +76 -0
- data/lib/etassia/notation/mermaid/ir_adapters/packet.rb +51 -0
- data/lib/etassia/notation/mermaid/ir_adapters/pie.rb +71 -0
- data/lib/etassia/notation/mermaid/ir_adapters/quadrant.rb +116 -0
- data/lib/etassia/notation/mermaid/ir_adapters/radar.rb +142 -0
- data/lib/etassia/notation/mermaid/ir_adapters/requirement.rb +237 -0
- data/lib/etassia/notation/mermaid/ir_adapters/sankey.rb +74 -0
- data/lib/etassia/notation/mermaid/ir_adapters/sequence.rb +304 -0
- data/lib/etassia/notation/mermaid/ir_adapters/state_diagram.rb +225 -0
- data/lib/etassia/notation/mermaid/ir_adapters/timeline.rb +93 -0
- data/lib/etassia/notation/mermaid/ir_adapters/treemap.rb +143 -0
- data/lib/etassia/notation/mermaid/ir_adapters/user_journey.rb +127 -0
- data/lib/etassia/notation/mermaid/ir_adapters/xychart.rb +131 -0
- data/lib/etassia/notation/mermaid.rb +399 -0
- data/lib/etassia/notation/parsed.rb +31 -0
- data/lib/etassia/notation/plantuml/activity/arrow_head.rb +45 -0
- data/lib/etassia/notation/plantuml/activity/arrow_style.rb +53 -0
- data/lib/etassia/notation/plantuml/activity/bar_columns.rb +75 -0
- data/lib/etassia/notation/plantuml/activity/box.rb +60 -0
- data/lib/etassia/notation/plantuml/activity/builder.rb +77 -0
- data/lib/etassia/notation/plantuml/activity/canvas.rb +117 -0
- data/lib/etassia/notation/plantuml/activity/column_centres.rb +151 -0
- data/lib/etassia/notation/plantuml/activity/columns.rb +224 -0
- data/lib/etassia/notation/plantuml/activity/diagram.rb +35 -0
- data/lib/etassia/notation/plantuml/activity/edge.rb +35 -0
- data/lib/etassia/notation/plantuml/activity/edge_marks.rb +68 -0
- data/lib/etassia/notation/plantuml/activity/exits.rb +61 -0
- data/lib/etassia/notation/plantuml/activity/frame_marks.rb +116 -0
- data/lib/etassia/notation/plantuml/activity/lane_steps.rb +82 -0
- data/lib/etassia/notation/plantuml/activity/lane_titles.rb +46 -0
- data/lib/etassia/notation/plantuml/activity/layout.rb +50 -0
- data/lib/etassia/notation/plantuml/activity/legacy_parser.rb +181 -0
- data/lib/etassia/notation/plantuml/activity/legacy_row_gaps.rb +65 -0
- data/lib/etassia/notation/plantuml/activity/mark.rb +23 -0
- data/lib/etassia/notation/plantuml/activity/marks.rb +62 -0
- data/lib/etassia/notation/plantuml/activity/metrics.rb +169 -0
- data/lib/etassia/notation/plantuml/activity/new_parser/blocks.rb +166 -0
- data/lib/etassia/notation/plantuml/activity/new_parser.rb +177 -0
- data/lib/etassia/notation/plantuml/activity/node.rb +50 -0
- data/lib/etassia/notation/plantuml/activity/node_marks.rb +174 -0
- data/lib/etassia/notation/plantuml/activity/note.rb +27 -0
- data/lib/etassia/notation/plantuml/activity/parser.rb +51 -0
- data/lib/etassia/notation/plantuml/activity/placement.rb +327 -0
- data/lib/etassia/notation/plantuml/activity/ranking.rb +142 -0
- data/lib/etassia/notation/plantuml/activity/reach.rb +58 -0
- data/lib/etassia/notation/plantuml/activity/renderer.rb +220 -0
- data/lib/etassia/notation/plantuml/activity/route.rb +22 -0
- data/lib/etassia/notation/plantuml/activity/router.rb +308 -0
- data/lib/etassia/notation/plantuml/activity/row_gaps.rb +105 -0
- data/lib/etassia/notation/plantuml/activity/row_spread.rb +59 -0
- data/lib/etassia/notation/plantuml/activity/scene.rb +20 -0
- data/lib/etassia/notation/plantuml/activity/text.rb +36 -0
- data/lib/etassia/notation/plantuml/activity.rb +50 -0
- data/lib/etassia/notation/plantuml/arrow.rb +135 -0
- data/lib/etassia/notation/plantuml/caption.rb +50 -0
- data/lib/etassia/notation/plantuml/caption_layout.rb +97 -0
- data/lib/etassia/notation/plantuml/caption_rows.rb +67 -0
- data/lib/etassia/notation/plantuml/class_header.rb +178 -0
- data/lib/etassia/notation/plantuml/class_name.rb +51 -0
- data/lib/etassia/notation/plantuml/component.rb +37 -0
- data/lib/etassia/notation/plantuml/creole.rb +278 -0
- data/lib/etassia/notation/plantuml/creole_icons.rb +33 -0
- data/lib/etassia/notation/plantuml/diagram.rb +60 -0
- data/lib/etassia/notation/plantuml/diagram_builder.rb +442 -0
- data/lib/etassia/notation/plantuml/diagram_name.rb +51 -0
- data/lib/etassia/notation/plantuml/directives.rb +33 -0
- data/lib/etassia/notation/plantuml/drawing/box.rb +28 -0
- data/lib/etassia/notation/plantuml/drawing/face.rb +39 -0
- data/lib/etassia/notation/plantuml/drawing/pen.rb +105 -0
- data/lib/etassia/notation/plantuml/drawing/renderer.rb +36 -0
- data/lib/etassia/notation/plantuml/drawing/scene.rb +28 -0
- data/lib/etassia/notation/plantuml/drawing.rb +19 -0
- data/lib/etassia/notation/plantuml/ebnf/blocks.rb +272 -0
- data/lib/etassia/notation/plantuml/ebnf/layout.rb +117 -0
- data/lib/etassia/notation/plantuml/ebnf/model.rb +22 -0
- data/lib/etassia/notation/plantuml/ebnf/reader.rb +131 -0
- data/lib/etassia/notation/plantuml/ebnf.rb +34 -0
- data/lib/etassia/notation/plantuml/end_texts.rb +78 -0
- data/lib/etassia/notation/plantuml/entity.rb +54 -0
- data/lib/etassia/notation/plantuml/further.rb +38 -0
- data/lib/etassia/notation/plantuml/gantt/layout.rb +269 -0
- data/lib/etassia/notation/plantuml/gantt/reader.rb +210 -0
- data/lib/etassia/notation/plantuml/gantt/renderer.rb +81 -0
- data/lib/etassia/notation/plantuml/gantt.rb +34 -0
- data/lib/etassia/notation/plantuml/include/blocks.rb +66 -0
- data/lib/etassia/notation/plantuml/include/finder.rb +61 -0
- data/lib/etassia/notation/plantuml/include.rb +78 -0
- data/lib/etassia/notation/plantuml/ir_adapter/annotations.rb +40 -0
- data/lib/etassia/notation/plantuml/ir_adapter/links.rb +91 -0
- data/lib/etassia/notation/plantuml/ir_adapter/sink.rb +49 -0
- data/lib/etassia/notation/plantuml/ir_adapter/structure.rb +86 -0
- data/lib/etassia/notation/plantuml/ir_adapter.rb +32 -0
- data/lib/etassia/notation/plantuml/ir_reader/annotations.rb +51 -0
- data/lib/etassia/notation/plantuml/ir_reader/index.rb +49 -0
- data/lib/etassia/notation/plantuml/ir_reader/links.rb +133 -0
- data/lib/etassia/notation/plantuml/ir_reader/structure.rb +83 -0
- data/lib/etassia/notation/plantuml/ir_reader.rb +42 -0
- data/lib/etassia/notation/plantuml/junction.rb +20 -0
- data/lib/etassia/notation/plantuml/klass.rb +41 -0
- data/lib/etassia/notation/plantuml/label_clearance.rb +67 -0
- data/lib/etassia/notation/plantuml/layout.rb +2806 -0
- data/lib/etassia/notation/plantuml/member.rb +37 -0
- data/lib/etassia/notation/plantuml/member_icon.rb +87 -0
- data/lib/etassia/notation/plantuml/member_icon_elements.rb +91 -0
- data/lib/etassia/notation/plantuml/member_pitch.rb +76 -0
- data/lib/etassia/notation/plantuml/member_rule.rb +48 -0
- data/lib/etassia/notation/plantuml/network/grid.rb +170 -0
- data/lib/etassia/notation/plantuml/network/layout.rb +158 -0
- data/lib/etassia/notation/plantuml/network/model.rb +22 -0
- data/lib/etassia/notation/plantuml/network/placement.rb +64 -0
- data/lib/etassia/notation/plantuml/network/reader.rb +126 -0
- data/lib/etassia/notation/plantuml/network/shapes.rb +109 -0
- data/lib/etassia/notation/plantuml/network.rb +37 -0
- data/lib/etassia/notation/plantuml/node_graph/archimate.rb +49 -0
- data/lib/etassia/notation/plantuml/node_graph/box_reader.rb +86 -0
- data/lib/etassia/notation/plantuml/node_graph/cloud.rb +73 -0
- data/lib/etassia/notation/plantuml/node_graph/crows_foot.rb +85 -0
- data/lib/etassia/notation/plantuml/node_graph/curve.rb +66 -0
- data/lib/etassia/notation/plantuml/node_graph/data_reader.rb +77 -0
- data/lib/etassia/notation/plantuml/node_graph/data_shape.rb +39 -0
- data/lib/etassia/notation/plantuml/node_graph/detour.rb +98 -0
- data/lib/etassia/notation/plantuml/node_graph/edge.rb +26 -0
- data/lib/etassia/notation/plantuml/node_graph/entity_metrics.rb +49 -0
- data/lib/etassia/notation/plantuml/node_graph/entity_reader.rb +65 -0
- data/lib/etassia/notation/plantuml/node_graph/entity_shape.rb +111 -0
- data/lib/etassia/notation/plantuml/node_graph/figures.rb +92 -0
- data/lib/etassia/notation/plantuml/node_graph/frame_ports.rb +73 -0
- data/lib/etassia/notation/plantuml/node_graph/graph.rb +40 -0
- data/lib/etassia/notation/plantuml/node_graph/heads.rb +89 -0
- data/lib/etassia/notation/plantuml/node_graph/label_fan.rb +76 -0
- data/lib/etassia/notation/plantuml/node_graph/label_placer.rb +310 -0
- data/lib/etassia/notation/plantuml/node_graph/label_waypoint.rb +47 -0
- data/lib/etassia/notation/plantuml/node_graph/layout.rb +293 -0
- data/lib/etassia/notation/plantuml/node_graph/link.rb +78 -0
- data/lib/etassia/notation/plantuml/node_graph/macros.rb +39 -0
- data/lib/etassia/notation/plantuml/node_graph/metrics.rb +113 -0
- data/lib/etassia/notation/plantuml/node_graph/node.rb +44 -0
- data/lib/etassia/notation/plantuml/node_graph/note_tail.rb +58 -0
- data/lib/etassia/notation/plantuml/node_graph/packer.rb +126 -0
- data/lib/etassia/notation/plantuml/node_graph/parser.rb +309 -0
- data/lib/etassia/notation/plantuml/node_graph/paths.rb +48 -0
- data/lib/etassia/notation/plantuml/node_graph/ranking.rb +231 -0
- data/lib/etassia/notation/plantuml/node_graph/reader.rb +53 -0
- data/lib/etassia/notation/plantuml/node_graph/references.rb +38 -0
- data/lib/etassia/notation/plantuml/node_graph/renderer.rb +160 -0
- data/lib/etassia/notation/plantuml/node_graph/scene.rb +22 -0
- data/lib/etassia/notation/plantuml/node_graph/shapes.rb +302 -0
- data/lib/etassia/notation/plantuml/node_graph/skipped_ranks.rb +61 -0
- data/lib/etassia/notation/plantuml/node_graph/tab.rb +68 -0
- data/lib/etassia/notation/plantuml/node_graph/usecase_ellipse.rb +100 -0
- data/lib/etassia/notation/plantuml/node_graph.rb +38 -0
- data/lib/etassia/notation/plantuml/note.rb +27 -0
- data/lib/etassia/notation/plantuml/note_layout.rb +257 -0
- data/lib/etassia/notation/plantuml/note_outline.rb +68 -0
- data/lib/etassia/notation/plantuml/objects/map_rows.rb +46 -0
- data/lib/etassia/notation/plantuml/objects/reader.rb +208 -0
- data/lib/etassia/notation/plantuml/objects.rb +39 -0
- data/lib/etassia/notation/plantuml/package.rb +45 -0
- data/lib/etassia/notation/plantuml/package_color.rb +32 -0
- data/lib/etassia/notation/plantuml/package_frames.rb +178 -0
- data/lib/etassia/notation/plantuml/parser.rb +622 -0
- data/lib/etassia/notation/plantuml/portion_visibility.rb +91 -0
- data/lib/etassia/notation/plantuml/qualified_association_layout.rb +332 -0
- data/lib/etassia/notation/plantuml/qualifier_box.rb +78 -0
- data/lib/etassia/notation/plantuml/rank_chain.rb +527 -0
- data/lib/etassia/notation/plantuml/rank_hierarchy.rb +347 -0
- data/lib/etassia/notation/plantuml/relation.rb +103 -0
- data/lib/etassia/notation/plantuml/relation_label_separator.rb +199 -0
- data/lib/etassia/notation/plantuml/relation_path_points.rb +84 -0
- data/lib/etassia/notation/plantuml/renderer.rb +490 -0
- data/lib/etassia/notation/plantuml/scene.rb +134 -0
- data/lib/etassia/notation/plantuml/segment_box.rb +85 -0
- data/lib/etassia/notation/plantuml/sequence/activation.rb +28 -0
- data/lib/etassia/notation/plantuml/sequence/appearance.rb +71 -0
- data/lib/etassia/notation/plantuml/sequence/arrow_end.rb +23 -0
- data/lib/etassia/notation/plantuml/sequence/arrow_marks.rb +111 -0
- data/lib/etassia/notation/plantuml/sequence/arrow_style.rb +42 -0
- data/lib/etassia/notation/plantuml/sequence/arrow_syntax.rb +122 -0
- data/lib/etassia/notation/plantuml/sequence/bar_tracker.rb +59 -0
- data/lib/etassia/notation/plantuml/sequence/box.rb +23 -0
- data/lib/etassia/notation/plantuml/sequence/chrome.rb +60 -0
- data/lib/etassia/notation/plantuml/sequence/chrome_rows.rb +184 -0
- data/lib/etassia/notation/plantuml/sequence/create.rb +34 -0
- data/lib/etassia/notation/plantuml/sequence/delay.rb +19 -0
- data/lib/etassia/notation/plantuml/sequence/destroy.rb +20 -0
- data/lib/etassia/notation/plantuml/sequence/diagram.rb +86 -0
- data/lib/etassia/notation/plantuml/sequence/divider.rb +19 -0
- data/lib/etassia/notation/plantuml/sequence/edge.rb +53 -0
- data/lib/etassia/notation/plantuml/sequence/embedded.rb +77 -0
- data/lib/etassia/notation/plantuml/sequence/fill.rb +56 -0
- data/lib/etassia/notation/plantuml/sequence/fragment.rb +28 -0
- data/lib/etassia/notation/plantuml/sequence/fragment_shape.rb +138 -0
- data/lib/etassia/notation/plantuml/sequence/head_style.rb +43 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/blocks.rb +73 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/fills.rb +24 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/items.rb +48 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/messages.rb +62 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/participants.rb +42 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter/settings.rb +54 -0
- data/lib/etassia/notation/plantuml/sequence/ir_adapter.rb +38 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/blocks.rb +77 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/fills.rb +27 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/index.rb +36 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/items.rb +35 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/messages.rb +70 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/participants.rb +42 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader/settings.rb +74 -0
- data/lib/etassia/notation/plantuml/sequence/ir_reader.rb +38 -0
- data/lib/etassia/notation/plantuml/sequence/keyword_defaults.rb +28 -0
- data/lib/etassia/notation/plantuml/sequence/layout.rb +1567 -0
- data/lib/etassia/notation/plantuml/sequence/message.rb +97 -0
- data/lib/etassia/notation/plantuml/sequence/message_wrap.rb +77 -0
- data/lib/etassia/notation/plantuml/sequence/note.rb +61 -0
- data/lib/etassia/notation/plantuml/sequence/note_fill.rb +35 -0
- data/lib/etassia/notation/plantuml/sequence/note_geometry.rb +126 -0
- data/lib/etassia/notation/plantuml/sequence/note_shape.rb +51 -0
- data/lib/etassia/notation/plantuml/sequence/numbered_label.rb +57 -0
- data/lib/etassia/notation/plantuml/sequence/numbering.rb +49 -0
- data/lib/etassia/notation/plantuml/sequence/outline.rb +204 -0
- data/lib/etassia/notation/plantuml/sequence/page_break.rb +17 -0
- data/lib/etassia/notation/plantuml/sequence/paint.rb +79 -0
- data/lib/etassia/notation/plantuml/sequence/parallel_message.rb +19 -0
- data/lib/etassia/notation/plantuml/sequence/parser.rb +844 -0
- data/lib/etassia/notation/plantuml/sequence/participant.rb +27 -0
- data/lib/etassia/notation/plantuml/sequence/picture.rb +29 -0
- data/lib/etassia/notation/plantuml/sequence/ref.rb +24 -0
- data/lib/etassia/notation/plantuml/sequence/ref_shape.rb +74 -0
- data/lib/etassia/notation/plantuml/sequence/refusals.rb +47 -0
- data/lib/etassia/notation/plantuml/sequence/renderer.rb +501 -0
- data/lib/etassia/notation/plantuml/sequence/scene.rb +200 -0
- data/lib/etassia/notation/plantuml/sequence/skin.rb +76 -0
- data/lib/etassia/notation/plantuml/sequence/spacing.rb +28 -0
- data/lib/etassia/notation/plantuml/sequence/style.rb +151 -0
- data/lib/etassia/notation/plantuml/sequence/tab_size.rb +42 -0
- data/lib/etassia/notation/plantuml/sequence/walker.rb +1190 -0
- data/lib/etassia/notation/plantuml/sequence.rb +47 -0
- data/lib/etassia/notation/plantuml/source_lines.rb +33 -0
- data/lib/etassia/notation/plantuml/state/axis_solver.rb +272 -0
- data/lib/etassia/notation/plantuml/state/cluster_padding.rb +75 -0
- data/lib/etassia/notation/plantuml/state/curve.rb +73 -0
- data/lib/etassia/notation/plantuml/state/dot_axis.rb +248 -0
- data/lib/etassia/notation/plantuml/state/extent.rb +42 -0
- data/lib/etassia/notation/plantuml/state/hierarchy.rb +355 -0
- data/lib/etassia/notation/plantuml/state/label_clearance.rb +148 -0
- data/lib/etassia/notation/plantuml/state/label_reach.rb +139 -0
- data/lib/etassia/notation/plantuml/state/layout.rb +173 -0
- data/lib/etassia/notation/plantuml/state/level_edges.rb +113 -0
- data/lib/etassia/notation/plantuml/state/look.rb +36 -0
- data/lib/etassia/notation/plantuml/state/note_shape.rb +73 -0
- data/lib/etassia/notation/plantuml/state/plane.rb +85 -0
- data/lib/etassia/notation/plantuml/state/ranking.rb +181 -0
- data/lib/etassia/notation/plantuml/state/reader.rb +310 -0
- data/lib/etassia/notation/plantuml/state/renderer.rb +253 -0
- data/lib/etassia/notation/plantuml/state/route_detour.rb +115 -0
- data/lib/etassia/notation/plantuml/state/route_geometry.rb +186 -0
- data/lib/etassia/notation/plantuml/state/routes.rb +196 -0
- data/lib/etassia/notation/plantuml/state/row.rb +88 -0
- data/lib/etassia/notation/plantuml/state/rows.rb +50 -0
- data/lib/etassia/notation/plantuml/state/stretch.rb +71 -0
- data/lib/etassia/notation/plantuml/state.rb +62 -0
- data/lib/etassia/notation/plantuml/stereotype_head.rb +58 -0
- data/lib/etassia/notation/plantuml/style/bound.rb +34 -0
- data/lib/etassia/notation/plantuml/style/colour.rb +41 -0
- data/lib/etassia/notation/plantuml/style/colour_names.rb +89 -0
- data/lib/etassia/notation/plantuml/style/defaults.rb +33 -0
- data/lib/etassia/notation/plantuml/style/inline.rb +56 -0
- data/lib/etassia/notation/plantuml/style/reader.rb +242 -0
- data/lib/etassia/notation/plantuml/style/sheet.rb +103 -0
- data/lib/etassia/notation/plantuml/style.rb +32 -0
- data/lib/etassia/notation/plantuml/style_reader.rb +160 -0
- data/lib/etassia/notation/plantuml/style_sheet.rb +27 -0
- data/lib/etassia/notation/plantuml/styled_relation_curve.rb +71 -0
- data/lib/etassia/notation/plantuml/timing/arrows.rb +81 -0
- data/lib/etassia/notation/plantuml/timing/axis.rb +100 -0
- data/lib/etassia/notation/plantuml/timing/layout.rb +172 -0
- data/lib/etassia/notation/plantuml/timing/model.rb +34 -0
- data/lib/etassia/notation/plantuml/timing/reader.rb +173 -0
- data/lib/etassia/notation/plantuml/timing/signals.rb +328 -0
- data/lib/etassia/notation/plantuml/timing.rb +38 -0
- data/lib/etassia/notation/plantuml/tree/layout.rb +276 -0
- data/lib/etassia/notation/plantuml/tree/mindmap_layout.rb +157 -0
- data/lib/etassia/notation/plantuml/tree/reader.rb +186 -0
- data/lib/etassia/notation/plantuml/tree/renderer.rb +67 -0
- data/lib/etassia/notation/plantuml/tree/role.rb +57 -0
- data/lib/etassia/notation/plantuml/tree/rules.rb +156 -0
- data/lib/etassia/notation/plantuml/tree/wbs_layout.rb +164 -0
- data/lib/etassia/notation/plantuml/tree.rb +41 -0
- data/lib/etassia/notation/plantuml/unsupported_construct_error.rb +39 -0
- data/lib/etassia/notation/plantuml/unsupported_constructs.rb +103 -0
- data/lib/etassia/notation/plantuml/usecase.rb +36 -0
- data/lib/etassia/notation/plantuml.rb +132 -0
- data/lib/etassia/notation/plantuml_data/boxes/frames.rb +101 -0
- data/lib/etassia/notation/plantuml_data/boxes/graph_layout.rb +348 -0
- data/lib/etassia/notation/plantuml_data/boxes/heads.rb +65 -0
- data/lib/etassia/notation/plantuml_data/boxes/highlights.rb +70 -0
- data/lib/etassia/notation/plantuml_data/boxes/inline_rows.rb +99 -0
- data/lib/etassia/notation/plantuml_data/boxes/json_reader.rb +24 -0
- data/lib/etassia/notation/plantuml_data/boxes/link_text.rb +94 -0
- data/lib/etassia/notation/plantuml_data/boxes/marks.rb +76 -0
- data/lib/etassia/notation/plantuml_data/boxes/ornaments.rb +130 -0
- data/lib/etassia/notation/plantuml_data/boxes/renderer.rb +95 -0
- data/lib/etassia/notation/plantuml_data/boxes/row_alignment.rb +58 -0
- data/lib/etassia/notation/plantuml_data/boxes/row_bend.rb +43 -0
- data/lib/etassia/notation/plantuml_data/boxes/scene.rb +27 -0
- data/lib/etassia/notation/plantuml_data/boxes/table.rb +56 -0
- data/lib/etassia/notation/plantuml_data/boxes/table_box.rb +355 -0
- data/lib/etassia/notation/plantuml_data/boxes/text.rb +101 -0
- data/lib/etassia/notation/plantuml_data/boxes/tree_builder.rb +82 -0
- data/lib/etassia/notation/plantuml_data/boxes/tree_layout.rb +82 -0
- data/lib/etassia/notation/plantuml_data/boxes/yaml_reader.rb +105 -0
- data/lib/etassia/notation/plantuml_data/openiconic.LICENSE +6 -0
- data/lib/etassia/notation/plantuml_data/openiconic.json +1 -0
- data/lib/etassia/notation/plantuml_data.rb +84 -0
- data/lib/etassia/notation/plantuml_salt/block.rb +80 -0
- data/lib/etassia/notation/plantuml_salt/box.rb +30 -0
- data/lib/etassia/notation/plantuml_salt/font_metrics.rb +28 -0
- data/lib/etassia/notation/plantuml_salt/grid_marks.rb +66 -0
- data/lib/etassia/notation/plantuml_salt/group_marks.rb +77 -0
- data/lib/etassia/notation/plantuml_salt/layout.rb +206 -0
- data/lib/etassia/notation/plantuml_salt/mark.rb +36 -0
- data/lib/etassia/notation/plantuml_salt/markup.rb +57 -0
- data/lib/etassia/notation/plantuml_salt/parser.rb +239 -0
- data/lib/etassia/notation/plantuml_salt/renderer.rb +138 -0
- data/lib/etassia/notation/plantuml_salt/row.rb +19 -0
- data/lib/etassia/notation/plantuml_salt/run.rb +34 -0
- data/lib/etassia/notation/plantuml_salt/scene.rb +23 -0
- data/lib/etassia/notation/plantuml_salt/scroll_marks.rb +94 -0
- data/lib/etassia/notation/plantuml_salt/tab_marks.rb +74 -0
- data/lib/etassia/notation/plantuml_salt/tree_marks.rb +127 -0
- data/lib/etassia/notation/plantuml_salt/widget.rb +40 -0
- data/lib/etassia/notation/plantuml_salt/widget_marks.rb +319 -0
- data/lib/etassia/notation/plantuml_salt.rb +66 -0
- data/lib/etassia/notation/plugin_failure.rb +42 -0
- data/lib/etassia/notation.rb +289 -0
- data/lib/etassia/parser/architecture.rb +25 -0
- data/lib/etassia/parser/atoms/delimited_run.rb +82 -0
- data/lib/etassia/parser/atoms/greedy_run.rb +116 -0
- data/lib/etassia/parser/atoms/joined.rb +47 -0
- data/lib/etassia/parser/atoms/trimmed_run.rb +47 -0
- data/lib/etassia/parser/base.rb +258 -0
- data/lib/etassia/parser/block.rb +32 -0
- data/lib/etassia/parser/builders/architecture.rb +135 -0
- data/lib/etassia/parser/builders/block.rb +288 -0
- data/lib/etassia/parser/builders/c4.rb +275 -0
- data/lib/etassia/parser/builders/capture_string.rb +17 -0
- data/lib/etassia/parser/builders/class_diagram.rb +539 -0
- data/lib/etassia/parser/builders/er_diagram.rb +308 -0
- data/lib/etassia/parser/builders/error.rb +51 -0
- data/lib/etassia/parser/builders/flowchart.rb +1150 -0
- data/lib/etassia/parser/builders/gantt.rb +267 -0
- data/lib/etassia/parser/builders/git_graph.rb +301 -0
- data/lib/etassia/parser/builders/info.rb +57 -0
- data/lib/etassia/parser/builders/kanban.rb +411 -0
- data/lib/etassia/parser/builders/mindmap.rb +271 -0
- data/lib/etassia/parser/builders/packet.rb +85 -0
- data/lib/etassia/parser/builders/pie.rb +105 -0
- data/lib/etassia/parser/builders/quadrant.rb +165 -0
- data/lib/etassia/parser/builders/radar.rb +157 -0
- data/lib/etassia/parser/builders/requirement.rb +230 -0
- data/lib/etassia/parser/builders/sankey.rb +142 -0
- data/lib/etassia/parser/builders/sequence.rb +431 -0
- data/lib/etassia/parser/builders/sequence_blocks.rb +117 -0
- data/lib/etassia/parser/builders/sequence_box_title.rb +57 -0
- data/lib/etassia/parser/builders/state_diagram.rb +364 -0
- data/lib/etassia/parser/builders/timeline.rb +133 -0
- data/lib/etassia/parser/builders/treemap.rb +138 -0
- data/lib/etassia/parser/builders/xy_chart.rb +148 -0
- data/lib/etassia/parser/c4.rb +37 -0
- data/lib/etassia/parser/class_diagram.rb +58 -0
- data/lib/etassia/parser/class_namespaces.rb +62 -0
- data/lib/etassia/parser/class_notes.rb +54 -0
- data/lib/etassia/parser/er_diagram.rb +28 -0
- data/lib/etassia/parser/error.rb +30 -0
- data/lib/etassia/parser/flowchart.rb +87 -0
- data/lib/etassia/parser/gantt.rb +43 -0
- data/lib/etassia/parser/git_graph.rb +106 -0
- data/lib/etassia/parser/grammars/architecture.rb +165 -0
- data/lib/etassia/parser/grammars/block.rb +190 -0
- data/lib/etassia/parser/grammars/c4.rb +229 -0
- data/lib/etassia/parser/grammars/class_diagram.rb +606 -0
- data/lib/etassia/parser/grammars/common.rb +107 -0
- data/lib/etassia/parser/grammars/er_diagram.rb +232 -0
- data/lib/etassia/parser/grammars/error.rb +32 -0
- data/lib/etassia/parser/grammars/flowchart.rb +1722 -0
- data/lib/etassia/parser/grammars/gantt.rb +198 -0
- data/lib/etassia/parser/grammars/git_graph.rb +234 -0
- data/lib/etassia/parser/grammars/info.rb +53 -0
- data/lib/etassia/parser/grammars/kanban.rb +417 -0
- data/lib/etassia/parser/grammars/mermaid_unicode_text.rb +108 -0
- data/lib/etassia/parser/grammars/mindmap.rb +220 -0
- data/lib/etassia/parser/grammars/packet.rb +71 -0
- data/lib/etassia/parser/grammars/pie.rb +128 -0
- data/lib/etassia/parser/grammars/quadrant.rb +202 -0
- data/lib/etassia/parser/grammars/radar.rb +158 -0
- data/lib/etassia/parser/grammars/requirement.rb +258 -0
- data/lib/etassia/parser/grammars/sankey.rb +104 -0
- data/lib/etassia/parser/grammars/sequence.rb +940 -0
- data/lib/etassia/parser/grammars/state_diagram.rb +382 -0
- data/lib/etassia/parser/grammars/timeline.rb +153 -0
- data/lib/etassia/parser/grammars/treemap.rb +122 -0
- data/lib/etassia/parser/grammars/xy_chart.rb +119 -0
- data/lib/etassia/parser/info.rb +32 -0
- data/lib/etassia/parser/kanban.rb +131 -0
- data/lib/etassia/parser/mermaid_shapes.rb +106 -0
- data/lib/etassia/parser/metadata_yaml.rb +452 -0
- data/lib/etassia/parser/mindmap.rb +92 -0
- data/lib/etassia/parser/native/builders/architecture.rb +103 -0
- data/lib/etassia/parser/native/builders/block.rb +68 -0
- data/lib/etassia/parser/native/builders/c4.rb +16 -0
- data/lib/etassia/parser/native/builders/class_diagram.rb +63 -0
- data/lib/etassia/parser/native/builders/er_diagram.rb +47 -0
- data/lib/etassia/parser/native/builders/flowchart.rb +58 -0
- data/lib/etassia/parser/native/builders/gantt.rb +35 -0
- data/lib/etassia/parser/native/builders/gitgraph.rb +35 -0
- data/lib/etassia/parser/native/builders/info.rb +30 -0
- data/lib/etassia/parser/native/builders/kanban.rb +37 -0
- data/lib/etassia/parser/native/builders/mindmap.rb +26 -0
- data/lib/etassia/parser/native/builders/packet.rb +63 -0
- data/lib/etassia/parser/native/builders/pie.rb +82 -0
- data/lib/etassia/parser/native/builders/quadrant.rb +27 -0
- data/lib/etassia/parser/native/builders/radar.rb +84 -0
- data/lib/etassia/parser/native/builders/requirement.rb +25 -0
- data/lib/etassia/parser/native/builders/sankey.rb +18 -0
- data/lib/etassia/parser/native/builders/sequence.rb +48 -0
- data/lib/etassia/parser/native/builders/state_diagram.rb +61 -0
- data/lib/etassia/parser/native/builders/timeline.rb +46 -0
- data/lib/etassia/parser/native/builders/treemap.rb +60 -0
- data/lib/etassia/parser/native/builders/user_journey.rb +83 -0
- data/lib/etassia/parser/native/builders/xy_chart.rb +94 -0
- data/lib/etassia/parser/native/declined.rb +12 -0
- data/lib/etassia/parser/native/mermaid.json +1 -0
- data/lib/etassia/parser/native/text.rb +31 -0
- data/lib/etassia/parser/native.rb +99 -0
- data/lib/etassia/parser/packet.rb +56 -0
- data/lib/etassia/parser/pie.rb +32 -0
- data/lib/etassia/parser/quadrant.rb +77 -0
- data/lib/etassia/parser/radar.rb +99 -0
- data/lib/etassia/parser/requirement.rb +32 -0
- data/lib/etassia/parser/sankey.rb +47 -0
- data/lib/etassia/parser/sequence.rb +34 -0
- data/lib/etassia/parser/state_diagram.rb +29 -0
- data/lib/etassia/parser/timeline.rb +40 -0
- data/lib/etassia/parser/treemap.rb +25 -0
- data/lib/etassia/parser/user_journey.rb +253 -0
- data/lib/etassia/parser/xy_chart.rb +98 -0
- data/lib/etassia/parser.rb +18 -0
- data/lib/etassia/renderer/architecture.rb +232 -0
- data/lib/etassia/renderer/architecture_edge_router.rb +379 -0
- data/lib/etassia/renderer/base.rb +295 -0
- data/lib/etassia/renderer/block.rb +157 -0
- data/lib/etassia/renderer/c4.rb +294 -0
- data/lib/etassia/renderer/class_diagram.rb +671 -0
- data/lib/etassia/renderer/er_diagram.rb +842 -0
- data/lib/etassia/renderer/error.rb +131 -0
- data/lib/etassia/renderer/flowchart.rb +315 -0
- data/lib/etassia/renderer/gantt.rb +177 -0
- data/lib/etassia/renderer/git_graph.rb +224 -0
- data/lib/etassia/renderer/info.rb +59 -0
- data/lib/etassia/renderer/kanban.rb +157 -0
- data/lib/etassia/renderer/line_break_text.rb +56 -0
- data/lib/etassia/renderer/markdown_text.rb +106 -0
- data/lib/etassia/renderer/mindmap.rb +290 -0
- data/lib/etassia/renderer/packet.rb +87 -0
- data/lib/etassia/renderer/pie.rb +113 -0
- data/lib/etassia/renderer/quadrant.rb +189 -0
- data/lib/etassia/renderer/radar.rb +191 -0
- data/lib/etassia/renderer/requirement.rb +209 -0
- data/lib/etassia/renderer/sankey.rb +114 -0
- data/lib/etassia/renderer/sequence/frame_drawing.rb +169 -0
- data/lib/etassia/renderer/sequence/note_drawing.rb +69 -0
- data/lib/etassia/renderer/sequence.rb +490 -0
- data/lib/etassia/renderer/state_diagram.rb +202 -0
- data/lib/etassia/renderer/timeline.rb +134 -0
- data/lib/etassia/renderer/timeline_palette.rb +18 -0
- data/lib/etassia/renderer/treemap/section_total.rb +33 -0
- data/lib/etassia/renderer/treemap.rb +128 -0
- data/lib/etassia/renderer/user_journey.rb +209 -0
- data/lib/etassia/renderer/xy_chart.rb +180 -0
- data/lib/etassia/renderer.rb +22 -0
- data/lib/etassia/runtime.rb +125 -0
- data/lib/etassia/source/frontmatter.rb +501 -0
- data/lib/etassia/source.rb +224 -0
- data/lib/etassia/svg/arrowhead.rb +205 -0
- data/lib/etassia/svg/circle.rb +19 -0
- data/lib/etassia/svg/document.rb +106 -0
- data/lib/etassia/svg/element.rb +209 -0
- data/lib/etassia/svg/ellipse.rb +23 -0
- data/lib/etassia/svg/escaping.rb +149 -0
- data/lib/etassia/svg/group.rb +64 -0
- data/lib/etassia/svg/line.rb +21 -0
- data/lib/etassia/svg/numbers.rb +53 -0
- data/lib/etassia/svg/path.rb +67 -0
- data/lib/etassia/svg/path_geometry.rb +378 -0
- data/lib/etassia/svg/polygon.rb +25 -0
- data/lib/etassia/svg/polyline.rb +28 -0
- data/lib/etassia/svg/rect.rb +34 -0
- data/lib/etassia/svg/style.rb +50 -0
- data/lib/etassia/svg/text.rb +181 -0
- data/lib/etassia/svg/tspan.rb +48 -0
- data/lib/etassia/svg.rb +38 -0
- data/lib/etassia/text_measurement/arial_advances.rb +122 -0
- data/lib/etassia/text_measurement/dejavu_advances.rb +111 -0
- data/lib/etassia/text_measurement/times_advances.rb +64 -0
- data/lib/etassia/text_measurement/trebuchet_advances.rb +53 -0
- data/lib/etassia/text_measurement/trebuchet_kerning.rb +29 -0
- data/lib/etassia/text_measurement.rb +198 -0
- data/lib/etassia/theme/builtin/dark.yml +229 -0
- data/lib/etassia/theme/builtin/default.yml +239 -0
- data/lib/etassia/theme/builtin/high_contrast.yml +231 -0
- data/lib/etassia/theme/builtin/light.yml +229 -0
- data/lib/etassia/theme/color_palette.rb +97 -0
- data/lib/etassia/theme/completion.rb +50 -0
- data/lib/etassia/theme/effect_styles.rb +34 -0
- data/lib/etassia/theme/registry.rb +45 -0
- data/lib/etassia/theme/shape_styles.rb +34 -0
- data/lib/etassia/theme/spacing_config.rb +30 -0
- data/lib/etassia/theme/typography.rb +40 -0
- data/lib/etassia/theme.rb +73 -0
- data/lib/etassia/version.rb +5 -0
- data/lib/etassia.rb +40 -0
- metadata +865 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Diagram
|
|
8
|
+
# Represents a requirement in the diagram
|
|
9
|
+
class RequirementNode < Lutaml::Model::Serializable
|
|
10
|
+
attribute :name, :string
|
|
11
|
+
attribute :type, :string, default: -> { "requirement" }
|
|
12
|
+
attribute :id, :string
|
|
13
|
+
attribute :text, :string
|
|
14
|
+
attribute :risk, :string # Low, Medium, High
|
|
15
|
+
# Verification methods: Analysis, Inspection, Test, or Demonstration.
|
|
16
|
+
attribute :verifymethod, :string
|
|
17
|
+
attribute :classes, :string, collection: true, default: -> { [] }
|
|
18
|
+
|
|
19
|
+
def add_class(class_name)
|
|
20
|
+
classes << class_name
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Represents an element in the diagram
|
|
25
|
+
class RequirementElement < Lutaml::Model::Serializable
|
|
26
|
+
attribute :name, :string
|
|
27
|
+
attribute :type, :string
|
|
28
|
+
attribute :docref, :string
|
|
29
|
+
attribute :classes, :string, collection: true, default: -> { [] }
|
|
30
|
+
|
|
31
|
+
def add_class(class_name)
|
|
32
|
+
classes << class_name
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Represents a relationship between requirements/elements
|
|
37
|
+
class RequirementRelationship < Lutaml::Model::Serializable
|
|
38
|
+
attribute :source, :string
|
|
39
|
+
attribute :target, :string
|
|
40
|
+
# Relationship types: contains, copies, derives, satisfies, verifies,
|
|
41
|
+
# refines, or traces.
|
|
42
|
+
attribute :type, :string
|
|
43
|
+
|
|
44
|
+
VALID_TYPES = %w[
|
|
45
|
+
contains
|
|
46
|
+
copies
|
|
47
|
+
derives
|
|
48
|
+
satisfies
|
|
49
|
+
verifies
|
|
50
|
+
refines
|
|
51
|
+
traces
|
|
52
|
+
].freeze
|
|
53
|
+
|
|
54
|
+
def valid?
|
|
55
|
+
VALID_TYPES.include?(type)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Represents styling for a requirement or element
|
|
60
|
+
class RequirementStyle < Lutaml::Model::Serializable
|
|
61
|
+
attribute :target_ids, :string, collection: true, default: -> { [] }
|
|
62
|
+
attribute :fill, :string
|
|
63
|
+
attribute :stroke, :string
|
|
64
|
+
attribute :stroke_width, :string
|
|
65
|
+
attribute :properties, :string, collection: true, default: -> { [] }
|
|
66
|
+
|
|
67
|
+
def add_target(id)
|
|
68
|
+
target_ids << id
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def add_property(property)
|
|
72
|
+
properties << property
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Represents a CSS class definition
|
|
77
|
+
class RequirementClass < Lutaml::Model::Serializable
|
|
78
|
+
attribute :name, :string
|
|
79
|
+
attribute :fill, :string
|
|
80
|
+
attribute :stroke, :string
|
|
81
|
+
attribute :stroke_width, :string
|
|
82
|
+
attribute :properties, :string, collection: true, default: -> { [] }
|
|
83
|
+
|
|
84
|
+
def add_property(property)
|
|
85
|
+
properties << property
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Represents a class assignment to requirements/elements
|
|
90
|
+
class RequirementClassAssignment < Lutaml::Model::Serializable
|
|
91
|
+
attribute :target_ids, :string, collection: true, default: -> { [] }
|
|
92
|
+
attribute :class_names, :string, collection: true, default: -> { [] }
|
|
93
|
+
|
|
94
|
+
def add_target(id)
|
|
95
|
+
target_ids << id
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def add_class(class_name)
|
|
99
|
+
class_names << class_name
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Represents a Mermaid requirement diagram
|
|
104
|
+
class Requirement < Base
|
|
105
|
+
attribute :requirements,
|
|
106
|
+
RequirementNode,
|
|
107
|
+
collection: true,
|
|
108
|
+
default: -> { [] }
|
|
109
|
+
attribute :elements,
|
|
110
|
+
RequirementElement,
|
|
111
|
+
collection: true,
|
|
112
|
+
default: -> { [] }
|
|
113
|
+
attribute :relationships,
|
|
114
|
+
RequirementRelationship,
|
|
115
|
+
collection: true,
|
|
116
|
+
default: -> { [] }
|
|
117
|
+
attribute :styles, RequirementStyle, collection: true, default: -> { [] }
|
|
118
|
+
attribute :classes, RequirementClass, collection: true, default: -> { [] }
|
|
119
|
+
attribute :class_assignments,
|
|
120
|
+
RequirementClassAssignment,
|
|
121
|
+
collection: true,
|
|
122
|
+
default: -> { [] }
|
|
123
|
+
attribute :acc_title, :string
|
|
124
|
+
attribute :acc_description, :string
|
|
125
|
+
|
|
126
|
+
def add_requirement(requirement)
|
|
127
|
+
requirements << requirement
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def add_element(element)
|
|
131
|
+
elements << element
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def add_relationship(relationship)
|
|
135
|
+
relationships << relationship
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def add_style(style)
|
|
139
|
+
styles << style
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def add_class(klass)
|
|
143
|
+
classes << klass
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def add_class_assignment(assignment)
|
|
147
|
+
class_assignments << assignment
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Returns the diagram type identifier.
|
|
151
|
+
#
|
|
152
|
+
# @return [Symbol] :requirement
|
|
153
|
+
def diagram_type
|
|
154
|
+
:requirement
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Requirement diagrams have no top-level validation rules yet — the
|
|
158
|
+
# relationship type check lives on RequirementRelationship#valid?
|
|
159
|
+
# above, and nothing here calls it. See TODO.foundation's corpus
|
|
160
|
+
# burndown for real validation; this is deliberately trivial.
|
|
161
|
+
#
|
|
162
|
+
# @return [Boolean] true
|
|
163
|
+
def valid?
|
|
164
|
+
true
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Diagram
|
|
8
|
+
# Represents a node in a Sankey diagram.
|
|
9
|
+
#
|
|
10
|
+
# A node can be a source, target, or intermediate point in the flow.
|
|
11
|
+
# Nodes are automatically discovered from flow definitions.
|
|
12
|
+
class SankeyNode < Lutaml::Model::Serializable
|
|
13
|
+
# Unique identifier for the node
|
|
14
|
+
attribute :id, :string
|
|
15
|
+
|
|
16
|
+
# Display label for the node (defaults to id if not set)
|
|
17
|
+
attribute :label, :string
|
|
18
|
+
|
|
19
|
+
def initialize(id = nil, label = nil)
|
|
20
|
+
super()
|
|
21
|
+
@id = id
|
|
22
|
+
@label = label || id
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Validates the node has required attributes.
|
|
26
|
+
#
|
|
27
|
+
# @return [Boolean] true if node is valid
|
|
28
|
+
def valid?
|
|
29
|
+
!id.nil? && !id.empty?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Get display label, falling back to id.
|
|
33
|
+
#
|
|
34
|
+
# @return [String] the label to display
|
|
35
|
+
def display_label
|
|
36
|
+
label && !label.empty? ? label : id
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Represents a flow/link between two nodes in a Sankey diagram.
|
|
41
|
+
#
|
|
42
|
+
# A flow connects a source node to a target node with a value
|
|
43
|
+
# that determines the width of the flow arrow.
|
|
44
|
+
class SankeyFlow < Lutaml::Model::Serializable
|
|
45
|
+
# Source node identifier
|
|
46
|
+
attribute :source, :string
|
|
47
|
+
|
|
48
|
+
# Target node identifier
|
|
49
|
+
attribute :target, :string
|
|
50
|
+
|
|
51
|
+
# Flow value (determines arrow width)
|
|
52
|
+
attribute :value, :float
|
|
53
|
+
|
|
54
|
+
# Optional label for the flow
|
|
55
|
+
attribute :label, :string
|
|
56
|
+
|
|
57
|
+
def initialize(source = nil, target = nil, value = 0.0)
|
|
58
|
+
super()
|
|
59
|
+
@source = source
|
|
60
|
+
@target = target
|
|
61
|
+
@value = value.to_f
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Validates the flow has required attributes.
|
|
65
|
+
#
|
|
66
|
+
# @return [Boolean] true if flow is valid
|
|
67
|
+
def valid?
|
|
68
|
+
!source.nil? && !source.empty? &&
|
|
69
|
+
!target.nil? && !target.empty? &&
|
|
70
|
+
value.positive?
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Check if this is a self-loop.
|
|
74
|
+
#
|
|
75
|
+
# @return [Boolean] true if source equals target
|
|
76
|
+
def self_loop?
|
|
77
|
+
source == target
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Sankey diagram model.
|
|
82
|
+
#
|
|
83
|
+
# Represents a Sankey diagram showing flows between nodes where
|
|
84
|
+
# the width of arrows is proportional to flow values. Used for
|
|
85
|
+
# visualizing energy flows, material flows, cost distributions, etc.
|
|
86
|
+
#
|
|
87
|
+
# @example Creating a Sankey diagram
|
|
88
|
+
# sankey = Sankey.new
|
|
89
|
+
# sankey.title = 'Energy Flow'
|
|
90
|
+
#
|
|
91
|
+
# flow1 = SankeyFlow.new('Source', 'Process', 100)
|
|
92
|
+
# flow2 = SankeyFlow.new('Process', 'Output', 70)
|
|
93
|
+
# flow3 = SankeyFlow.new('Process', 'Waste', 30)
|
|
94
|
+
# sankey.flows << flow1 << flow2 << flow3
|
|
95
|
+
class Sankey < Base
|
|
96
|
+
# Collection of explicitly defined nodes (optional)
|
|
97
|
+
attribute :nodes, SankeyNode, collection: true,
|
|
98
|
+
default: -> { [] }
|
|
99
|
+
|
|
100
|
+
# Collection of flows between nodes
|
|
101
|
+
attribute :flows, SankeyFlow, collection: true,
|
|
102
|
+
default: -> { [] }
|
|
103
|
+
|
|
104
|
+
# Accessibility title (for screen readers)
|
|
105
|
+
attribute :acc_title, :string
|
|
106
|
+
|
|
107
|
+
# Accessibility description (for screen readers)
|
|
108
|
+
attribute :acc_description, :string
|
|
109
|
+
|
|
110
|
+
def initialize
|
|
111
|
+
@nodes = []
|
|
112
|
+
@flows = []
|
|
113
|
+
super
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Returns the diagram type identifier.
|
|
117
|
+
#
|
|
118
|
+
# @return [Symbol] :sankey
|
|
119
|
+
def diagram_type
|
|
120
|
+
:sankey
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Validates the diagram structure.
|
|
124
|
+
#
|
|
125
|
+
# A Sankey diagram is valid if it has at least one flow.
|
|
126
|
+
#
|
|
127
|
+
# @return [Boolean] true if diagram is valid
|
|
128
|
+
def valid?
|
|
129
|
+
!flows.empty? && flows.all?(&:valid?)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Get all unique node IDs from flows and explicit nodes.
|
|
133
|
+
#
|
|
134
|
+
# @return [Array<String>] array of unique node IDs
|
|
135
|
+
def all_node_ids
|
|
136
|
+
node_ids_from_flows = flows.flat_map { |f| [f.source, f.target] }
|
|
137
|
+
explicit_node_ids = nodes.map(&:id)
|
|
138
|
+
(node_ids_from_flows + explicit_node_ids).uniq
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Get or create node by ID.
|
|
142
|
+
#
|
|
143
|
+
# @param id [String] node identifier
|
|
144
|
+
# @return [SankeyNode] the node
|
|
145
|
+
def node_by_id(id)
|
|
146
|
+
nodes.find { |n| n.id == id } || SankeyNode.new(id)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Get all flows from a specific node.
|
|
150
|
+
#
|
|
151
|
+
# @param node_id [String] the source node ID
|
|
152
|
+
# @return [Array<SankeyFlow>] flows from this node
|
|
153
|
+
def flows_from(node_id)
|
|
154
|
+
flows.select { |f| f.source == node_id }
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Get all flows to a specific node.
|
|
158
|
+
#
|
|
159
|
+
# @param node_id [String] the target node ID
|
|
160
|
+
# @return [Array<SankeyFlow>] flows to this node
|
|
161
|
+
def flows_to(node_id)
|
|
162
|
+
flows.select { |f| f.target == node_id }
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Calculate total outflow from a node.
|
|
166
|
+
#
|
|
167
|
+
# @param node_id [String] the node ID
|
|
168
|
+
# @return [Float] sum of all outgoing flow values
|
|
169
|
+
def total_outflow(node_id)
|
|
170
|
+
flows_from(node_id).sum(&:value)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Calculate total inflow to a node.
|
|
174
|
+
#
|
|
175
|
+
# @param node_id [String] the node ID
|
|
176
|
+
# @return [Float] sum of all incoming flow values
|
|
177
|
+
def total_inflow(node_id)
|
|
178
|
+
flows_to(node_id).sum(&:value)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Get source nodes (nodes with no inflow).
|
|
182
|
+
#
|
|
183
|
+
# @return [Array<String>] source node IDs
|
|
184
|
+
def source_nodes
|
|
185
|
+
all_node_ids.select { |id| total_inflow(id).zero? }
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Get sink nodes (nodes with no outflow).
|
|
189
|
+
#
|
|
190
|
+
# @return [Array<String>] sink node IDs
|
|
191
|
+
def sink_nodes
|
|
192
|
+
all_node_ids.select { |id| total_outflow(id).zero? }
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Get total flow value in the diagram.
|
|
196
|
+
#
|
|
197
|
+
# @return [Float] sum of all flow values
|
|
198
|
+
def total_flow
|
|
199
|
+
flows.sum(&:value)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Get maximum flow value.
|
|
203
|
+
#
|
|
204
|
+
# @return [Float] maximum single flow value
|
|
205
|
+
def max_flow
|
|
206
|
+
flows.map(&:value).max || 0.0
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Get minimum flow value.
|
|
210
|
+
#
|
|
211
|
+
# @return [Float] minimum single flow value
|
|
212
|
+
def min_flow
|
|
213
|
+
flows.map(&:value).min || 0.0
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
require_relative "sequence_frame"
|
|
6
|
+
require_relative "sequence_box"
|
|
7
|
+
|
|
8
|
+
module Etassia
|
|
9
|
+
module Diagram
|
|
10
|
+
# Represents a sequence diagram participant.
|
|
11
|
+
#
|
|
12
|
+
# A participant represents an actor or entity in the sequence diagram
|
|
13
|
+
# that can send and receive messages.
|
|
14
|
+
class SequenceParticipant < Lutaml::Model::Serializable
|
|
15
|
+
# Unique identifier for the participant
|
|
16
|
+
attribute :id, :string
|
|
17
|
+
|
|
18
|
+
# Display text/label for the participant
|
|
19
|
+
attribute :label, :string
|
|
20
|
+
|
|
21
|
+
# Participant type: :participant, :actor
|
|
22
|
+
attribute :actor_type, :string
|
|
23
|
+
|
|
24
|
+
# Declared with `create participant|actor`: the box is drawn at the
|
|
25
|
+
# creating message's row, not at the top of the diagram.
|
|
26
|
+
attribute :created, :boolean, default: -> { false }
|
|
27
|
+
|
|
28
|
+
# Type named by `@{ "type": ... }` (boundary, control, entity,
|
|
29
|
+
# database, collections, queue); nil for a plain box or stick figure.
|
|
30
|
+
attribute :shape_type, :string
|
|
31
|
+
|
|
32
|
+
# Initialize with default actor type
|
|
33
|
+
def initialize(*args)
|
|
34
|
+
super
|
|
35
|
+
self.actor_type ||= "participant"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Validates the participant has required attributes.
|
|
39
|
+
#
|
|
40
|
+
# @return [Boolean] true if participant is valid
|
|
41
|
+
def valid?
|
|
42
|
+
!id.nil? && !id.empty? && !label.nil?
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Represents a sequence diagram message.
|
|
47
|
+
#
|
|
48
|
+
# A message represents communication between participants in a
|
|
49
|
+
# sequence diagram, with various arrow types and optional text.
|
|
50
|
+
class SequenceMessage < Lutaml::Model::Serializable
|
|
51
|
+
# Source participant identifier
|
|
52
|
+
attribute :from_id, :string
|
|
53
|
+
|
|
54
|
+
# Target participant identifier
|
|
55
|
+
attribute :to_id, :string
|
|
56
|
+
|
|
57
|
+
# Message text content
|
|
58
|
+
attribute :message_text, :string
|
|
59
|
+
|
|
60
|
+
# Line style: 'solid' or 'dotted'
|
|
61
|
+
attribute :line_style, :string
|
|
62
|
+
|
|
63
|
+
# Marker shape: 'none', 'filled', 'open', 'cross', 'half_top',
|
|
64
|
+
# 'half_bottom', 'stick_top' or 'stick_bottom'
|
|
65
|
+
attribute :head_style, :string
|
|
66
|
+
|
|
67
|
+
# Which end of the line carries the marker: 'target', 'source', or
|
|
68
|
+
# 'both' for mermaid's <<->> arrows. Mermaid spells the same head at
|
|
69
|
+
# the source end by reversing the arrow: `-\\` against `\\-`.
|
|
70
|
+
attribute :head_side, :string
|
|
71
|
+
|
|
72
|
+
def initialize(*args)
|
|
73
|
+
super
|
|
74
|
+
self.line_style ||= "solid"
|
|
75
|
+
self.head_style ||= "filled"
|
|
76
|
+
self.head_side ||= "target"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# @return [Boolean] true when the marker is drawn at both ends
|
|
80
|
+
def bidirectional?
|
|
81
|
+
head_side == "both"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Validates the message has required attributes.
|
|
85
|
+
#
|
|
86
|
+
# @return [Boolean] true if message is valid
|
|
87
|
+
def valid?
|
|
88
|
+
!from_id.nil? && !from_id.empty? &&
|
|
89
|
+
!to_id.nil? && !to_id.empty?
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Represents an activation box (lifecycle) in a sequence diagram.
|
|
94
|
+
#
|
|
95
|
+
# An activation shows when a participant is active or processing.
|
|
96
|
+
class SequenceActivation < Lutaml::Model::Serializable
|
|
97
|
+
# Participant identifier
|
|
98
|
+
attribute :participant_id, :string
|
|
99
|
+
|
|
100
|
+
# Start message index (position in messages array)
|
|
101
|
+
attribute :start_index, :integer
|
|
102
|
+
|
|
103
|
+
# End message index (position in messages array)
|
|
104
|
+
attribute :end_index, :integer
|
|
105
|
+
|
|
106
|
+
# Validates the activation has required attributes.
|
|
107
|
+
#
|
|
108
|
+
# @return [Boolean] true if activation is valid
|
|
109
|
+
def valid?
|
|
110
|
+
!participant_id.nil? && !participant_id.empty? &&
|
|
111
|
+
!start_index.nil? && !end_index.nil? &&
|
|
112
|
+
start_index <= end_index
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Represents a note in a sequence diagram.
|
|
117
|
+
#
|
|
118
|
+
# A note provides additional context or information in the diagram.
|
|
119
|
+
class SequenceNote < Lutaml::Model::Serializable
|
|
120
|
+
# Note text content
|
|
121
|
+
attribute :text, :string
|
|
122
|
+
|
|
123
|
+
# Position: :left_of, :right_of, :over
|
|
124
|
+
attribute :position, :string
|
|
125
|
+
|
|
126
|
+
# Participant identifier(s) - array for :over with multiple
|
|
127
|
+
attribute :participant_ids, :string, collection: true,
|
|
128
|
+
default: -> { [] }
|
|
129
|
+
|
|
130
|
+
# Message index where the note appears
|
|
131
|
+
attribute :message_index, :integer
|
|
132
|
+
|
|
133
|
+
# Position among the frame edges, dividers and notes, in source
|
|
134
|
+
# order; tells which side of a frame edge at the same message
|
|
135
|
+
# index the note sits on
|
|
136
|
+
attribute :order, :integer
|
|
137
|
+
|
|
138
|
+
# Validates the note has required attributes.
|
|
139
|
+
#
|
|
140
|
+
# Text may be empty — mmdc renders `Note over A:` with no trailing
|
|
141
|
+
# content as an empty label, not a malformed note.
|
|
142
|
+
#
|
|
143
|
+
# @return [Boolean] true if note is valid
|
|
144
|
+
def valid?
|
|
145
|
+
!text.nil? && !position.nil? && !participant_ids.empty?
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Sequence diagram model.
|
|
150
|
+
#
|
|
151
|
+
# Represents a complete sequence diagram with participants, messages,
|
|
152
|
+
# activations, and notes. Sequence diagrams show interactions between
|
|
153
|
+
# participants over time in a vertical timeline format.
|
|
154
|
+
#
|
|
155
|
+
# @example Creating a simple sequence diagram
|
|
156
|
+
# sequence = Sequence.new
|
|
157
|
+
# sequence.participants << SequenceParticipant.new(
|
|
158
|
+
# id: 'Alice',
|
|
159
|
+
# label: 'Alice',
|
|
160
|
+
# actor_type: 'actor'
|
|
161
|
+
# )
|
|
162
|
+
# sequence.participants << SequenceParticipant.new(
|
|
163
|
+
# id: 'Bob',
|
|
164
|
+
# label: 'Bob',
|
|
165
|
+
# actor_type: 'actor'
|
|
166
|
+
# )
|
|
167
|
+
# sequence.messages << SequenceMessage.new(
|
|
168
|
+
# from_id: 'Alice',
|
|
169
|
+
# to_id: 'Bob',
|
|
170
|
+
# message_text: 'Hello Bob',
|
|
171
|
+
# line_style: 'solid',
|
|
172
|
+
# head_style: 'filled'
|
|
173
|
+
# )
|
|
174
|
+
class Sequence < Base
|
|
175
|
+
# Collection of participants in the sequence diagram
|
|
176
|
+
attribute :participants, SequenceParticipant, collection: true,
|
|
177
|
+
default: -> { [] }
|
|
178
|
+
|
|
179
|
+
# Collection of messages between participants
|
|
180
|
+
attribute :messages, SequenceMessage, collection: true,
|
|
181
|
+
default: -> { [] }
|
|
182
|
+
|
|
183
|
+
# Collection of activation boxes
|
|
184
|
+
attribute :activations, SequenceActivation, collection: true,
|
|
185
|
+
default: -> { [] }
|
|
186
|
+
|
|
187
|
+
# Collection of notes
|
|
188
|
+
attribute :notes, SequenceNote, collection: true,
|
|
189
|
+
default: -> { [] }
|
|
190
|
+
|
|
191
|
+
# Whether `%%{wrap}%%` made every message and note wrap
|
|
192
|
+
attribute :wrap, :boolean, default: -> { false }
|
|
193
|
+
|
|
194
|
+
# Control blocks (loop, alt, opt, par, critical, break, rect)
|
|
195
|
+
attribute :frames, SequenceFrame, collection: true,
|
|
196
|
+
default: -> { [] }
|
|
197
|
+
|
|
198
|
+
# `box` groups around participants
|
|
199
|
+
attribute :boxes, SequenceBox, collection: true,
|
|
200
|
+
default: -> { [] }
|
|
201
|
+
|
|
202
|
+
# Returns the diagram type identifier.
|
|
203
|
+
#
|
|
204
|
+
# @return [Symbol] :sequence
|
|
205
|
+
def diagram_type
|
|
206
|
+
:sequence
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Validates the sequence diagram structure.
|
|
210
|
+
#
|
|
211
|
+
# A sequence diagram is valid if:
|
|
212
|
+
# - All participants are valid
|
|
213
|
+
# - All messages are valid
|
|
214
|
+
# - All message references point to existing participants
|
|
215
|
+
# - All activations are valid
|
|
216
|
+
# - All notes are valid
|
|
217
|
+
#
|
|
218
|
+
# Zero participants is valid: `sequenceDiagram` with no body is a
|
|
219
|
+
# diagram mmdc renders (an empty canvas, no lifelines), not a rejection.
|
|
220
|
+
#
|
|
221
|
+
# @return [Boolean] true if sequence diagram is valid
|
|
222
|
+
def valid?
|
|
223
|
+
return false unless components_valid?
|
|
224
|
+
|
|
225
|
+
references_valid?(participants.map(&:id))
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Finds a participant by its identifier.
|
|
229
|
+
#
|
|
230
|
+
# @param id [String] the participant identifier to find
|
|
231
|
+
# @return [SequenceParticipant, nil] the participant or nil if not
|
|
232
|
+
# found
|
|
233
|
+
def find_participant(id)
|
|
234
|
+
participants.find { |p| p.id == id }
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Finds all messages from a specific participant.
|
|
238
|
+
#
|
|
239
|
+
# @param participant_id [String] the source participant identifier
|
|
240
|
+
# @return [Array<SequenceMessage>] messages from the participant
|
|
241
|
+
def messages_from(participant_id)
|
|
242
|
+
messages.select { |m| m.from_id == participant_id }
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Finds all messages to a specific participant.
|
|
246
|
+
#
|
|
247
|
+
# @param participant_id [String] the target participant identifier
|
|
248
|
+
# @return [Array<SequenceMessage>] messages to the participant
|
|
249
|
+
def messages_to(participant_id)
|
|
250
|
+
messages.select { |m| m.to_id == participant_id }
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Finds activations for a specific participant.
|
|
254
|
+
#
|
|
255
|
+
# @param participant_id [String] the participant identifier
|
|
256
|
+
# @return [Array<SequenceActivation>] activations for the participant
|
|
257
|
+
def activations_for(participant_id)
|
|
258
|
+
activations.select { |a| a.participant_id == participant_id }
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
private
|
|
262
|
+
|
|
263
|
+
def components_valid?
|
|
264
|
+
!participants.nil? && participants.all?(&:valid?) &&
|
|
265
|
+
collection_valid?(messages) && collection_valid?(activations) &&
|
|
266
|
+
collection_valid?(notes)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def collection_valid?(collection)
|
|
270
|
+
collection.nil? || collection.all?(&:valid?)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def references_valid?(participant_ids)
|
|
274
|
+
message_references_valid?(participant_ids) &&
|
|
275
|
+
activation_references_valid?(participant_ids) &&
|
|
276
|
+
note_references_valid?(participant_ids)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def message_references_valid?(participant_ids)
|
|
280
|
+
messages.nil? || messages.all? do |message|
|
|
281
|
+
participant_ids.include?(message.from_id) &&
|
|
282
|
+
participant_ids.include?(message.to_id)
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def activation_references_valid?(participant_ids)
|
|
287
|
+
activations.nil? || activations.all? do |activation|
|
|
288
|
+
participant_ids.include?(activation.participant_id)
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def note_references_valid?(participant_ids)
|
|
293
|
+
notes.nil? || notes.all? do |note|
|
|
294
|
+
note.participant_ids.all? { |id| participant_ids.include?(id) }
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Etassia
|
|
6
|
+
module Diagram
|
|
7
|
+
# A `box` group around the participants declared inside it.
|
|
8
|
+
class SequenceBox < Lutaml::Model::Serializable
|
|
9
|
+
# Fill colour; nil when the box has none
|
|
10
|
+
attribute :color, :string
|
|
11
|
+
|
|
12
|
+
attribute :title, :string
|
|
13
|
+
|
|
14
|
+
attribute :participant_ids, :string, collection: true,
|
|
15
|
+
default: -> { [] }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|