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,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "sequence_frame_section"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Diagram
|
|
8
|
+
# A control block in a sequence diagram: loop, alt, opt, par, critical,
|
|
9
|
+
# break or rect. It covers the messages whose index is in
|
|
10
|
+
# `start_index...end_index`.
|
|
11
|
+
class SequenceFrame < Lutaml::Model::Serializable
|
|
12
|
+
KINDS = %w[loop alt opt par critical break rect].freeze
|
|
13
|
+
|
|
14
|
+
attribute :kind, :string
|
|
15
|
+
|
|
16
|
+
# Text after the keyword; the colour for a `rect`
|
|
17
|
+
attribute :label, :string
|
|
18
|
+
|
|
19
|
+
# Index of the first message inside the frame
|
|
20
|
+
attribute :start_index, :integer
|
|
21
|
+
|
|
22
|
+
# Index of the first message after the frame
|
|
23
|
+
attribute :end_index, :integer
|
|
24
|
+
|
|
25
|
+
# Number of frames that enclose this one
|
|
26
|
+
attribute :depth, :integer, default: -> { 0 }
|
|
27
|
+
|
|
28
|
+
# Positions of the opening and closing edge among the other frame
|
|
29
|
+
# edges, dividers and notes, in source order
|
|
30
|
+
attribute :open_order, :integer
|
|
31
|
+
attribute :close_order, :integer
|
|
32
|
+
|
|
33
|
+
attribute :sections, SequenceFrameSection, collection: true,
|
|
34
|
+
default: -> { [] }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Etassia
|
|
6
|
+
module Diagram
|
|
7
|
+
# One `else`, `and` or `option` divider inside a sequence frame.
|
|
8
|
+
class SequenceFrameSection < Lutaml::Model::Serializable
|
|
9
|
+
# Divider keyword: else, and or option
|
|
10
|
+
attribute :kind, :string
|
|
11
|
+
|
|
12
|
+
# Text after the keyword
|
|
13
|
+
attribute :label, :string
|
|
14
|
+
|
|
15
|
+
# Index of the first message that follows the divider
|
|
16
|
+
attribute :start_index, :integer
|
|
17
|
+
|
|
18
|
+
# Position of the divider among the frame edges and notes, in
|
|
19
|
+
# source order
|
|
20
|
+
attribute :order, :integer
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Etassia
|
|
4
|
+
module Diagram
|
|
5
|
+
# Mermaid draws a sequence message without its `wrap:`/`nowrap:` prefix
|
|
6
|
+
# and with `<br>` as a line break. `decode` is its character-reference
|
|
7
|
+
# step, which mermaid applies to every piece of sequence text: actor
|
|
8
|
+
# ids, `as` aliases, messages and notes.
|
|
9
|
+
module SequenceText
|
|
10
|
+
WRAP_PREFIX = /\A\s*(?:no)?wrap:\s*/i
|
|
11
|
+
LINE_BREAK = %r{<br\s*/?>}i
|
|
12
|
+
ENTITY = /#(\w+);/
|
|
13
|
+
REPLACEMENT = "�"
|
|
14
|
+
SCALARS = (1..0x10FFFF)
|
|
15
|
+
SURROGATES = (0xD800..0xDFFF)
|
|
16
|
+
C1_CONTROLS = (0x80..0x9F)
|
|
17
|
+
NAMED = {
|
|
18
|
+
"amp" => "&", "AMP" => "&",
|
|
19
|
+
"lt" => "<", "LT" => "<",
|
|
20
|
+
"gt" => ">", "GT" => ">",
|
|
21
|
+
"quot" => '"', "QUOT" => '"',
|
|
22
|
+
"apos" => "'", "nbsp" => "\u00A0",
|
|
23
|
+
"infin" => "∞", "hearts" => "♥",
|
|
24
|
+
"copy" => "©", "reg" => "®", "deg" => "°",
|
|
25
|
+
"trade" => "™", "euro" => "€",
|
|
26
|
+
"mdash" => "—", "ndash" => "–", "hellip" => "…",
|
|
27
|
+
"larr" => "←", "rarr" => "→", "uarr" => "↑", "darr" => "↓",
|
|
28
|
+
"times" => "×", "divide" => "÷", "plusmn" => "±",
|
|
29
|
+
"laquo" => "«", "raquo" => "»", "bull" => "•"
|
|
30
|
+
}.freeze
|
|
31
|
+
|
|
32
|
+
# @param text [String] message text as written in the source
|
|
33
|
+
# @return [String] the text as mermaid draws it
|
|
34
|
+
def self.display(text)
|
|
35
|
+
decode(text.sub(WRAP_PREFIX, "").gsub(LINE_BREAK, " "))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# One pass, like mermaid: `#35;59;` gives `#59;`, never `;`. A
|
|
39
|
+
# numeric reference becomes its character, a known name its
|
|
40
|
+
# character, any other name stays as the literal `&name;` (hex
|
|
41
|
+
# `#x41;` included).
|
|
42
|
+
#
|
|
43
|
+
# @param text [String] text as written in the source
|
|
44
|
+
# @return [String] the text with character references decoded
|
|
45
|
+
def self.decode(text)
|
|
46
|
+
text.gsub(ENTITY) do
|
|
47
|
+
name = Regexp.last_match(1)
|
|
48
|
+
next codepoint(name.to_i) if name.match?(/\A\d+\z/)
|
|
49
|
+
|
|
50
|
+
NAMED.fetch(name) { "&#{name};" }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# HTML numeric rules: NUL, surrogates and out-of-range values are
|
|
55
|
+
# U+FFFD, and 0x80-0x9F read as Windows-1252.
|
|
56
|
+
def self.codepoint(number)
|
|
57
|
+
return REPLACEMENT unless SCALARS.cover?(number)
|
|
58
|
+
return REPLACEMENT if SURROGATES.cover?(number)
|
|
59
|
+
|
|
60
|
+
character = [number].pack("U")
|
|
61
|
+
return character unless C1_CONTROLS.cover?(number)
|
|
62
|
+
|
|
63
|
+
[number].pack("C").force_encoding(Encoding::Windows_1252)
|
|
64
|
+
.encode(Encoding::UTF_8, undef: :replace, replace: character)
|
|
65
|
+
end
|
|
66
|
+
private_class_method :codepoint
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Etassia
|
|
4
|
+
module Diagram
|
|
5
|
+
# Mermaid's global sequence wrap switch: the bare `%%{wrap}%%`
|
|
6
|
+
# directive, or an `init` directive with `wrap: true` at the top level
|
|
7
|
+
# or under `sequence`. The directive may sit before or after the
|
|
8
|
+
# `sequenceDiagram` line.
|
|
9
|
+
module SequenceWrap
|
|
10
|
+
DIRECTIVE = /%%\{(.*?)\}%%/m
|
|
11
|
+
BARE = /\A\s*wrap\s*\z/
|
|
12
|
+
INIT_WRAP = /\A\s*init(?:ialize)?\s*:.*["']?\bwrap["']?\s*:\s*true\b/mi
|
|
13
|
+
|
|
14
|
+
# @param source [String] the whole Mermaid source
|
|
15
|
+
# @return [Boolean] whether every sequence text wraps by default
|
|
16
|
+
def self.on?(source)
|
|
17
|
+
source.scrub.scan(DIRECTIVE).flatten.any? do |body|
|
|
18
|
+
body.match?(BARE) || body.match?(INIT_WRAP)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Diagram
|
|
8
|
+
# Represents a state node in a state diagram.
|
|
9
|
+
#
|
|
10
|
+
# A state node can represent different types of states in a state
|
|
11
|
+
# machine, including normal states, start/end states, choice points,
|
|
12
|
+
# and fork/join nodes.
|
|
13
|
+
class StateNode < Lutaml::Model::Serializable
|
|
14
|
+
# Unique identifier for the state
|
|
15
|
+
attribute :id, :string
|
|
16
|
+
|
|
17
|
+
# Display label for the state
|
|
18
|
+
attribute :label, :string
|
|
19
|
+
|
|
20
|
+
# State type: :normal, :start, :end, :choice, :fork, :join
|
|
21
|
+
attribute :state_type, :string
|
|
22
|
+
|
|
23
|
+
# Most recently declared description for this state, if any
|
|
24
|
+
attribute :description, :string
|
|
25
|
+
|
|
26
|
+
# Ordered display text declared by aliases and descriptions
|
|
27
|
+
attribute :descriptions, :string, collection: true, default: -> { [] }
|
|
28
|
+
|
|
29
|
+
# Child states for composite/nested states
|
|
30
|
+
attribute :children, StateNode, collection: true, default: -> { [] }
|
|
31
|
+
|
|
32
|
+
# A bare `state ID` declaration exists in Mermaid's database but is not
|
|
33
|
+
# drawn until another statement gives it display semantics or uses it.
|
|
34
|
+
attribute :declaration_only, :boolean, default: -> { false }
|
|
35
|
+
|
|
36
|
+
# Initialize with default state type
|
|
37
|
+
def initialize(*args)
|
|
38
|
+
super
|
|
39
|
+
self.state_type ||= "normal"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Validates the state node has required attributes.
|
|
43
|
+
#
|
|
44
|
+
# @return [Boolean] true if state node is valid
|
|
45
|
+
def valid?
|
|
46
|
+
!id.nil? && !id.empty? &&
|
|
47
|
+
!state_type.nil? && !state_type.empty?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Checks if this is a start state.
|
|
51
|
+
#
|
|
52
|
+
# @return [Boolean] true if start state
|
|
53
|
+
def start_state?
|
|
54
|
+
state_type == "start"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Checks if this is an end state.
|
|
58
|
+
#
|
|
59
|
+
# @return [Boolean] true if end state
|
|
60
|
+
def end_state?
|
|
61
|
+
state_type == "end"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Checks if this is a choice state.
|
|
65
|
+
#
|
|
66
|
+
# @return [Boolean] true if choice state
|
|
67
|
+
def choice_state?
|
|
68
|
+
state_type == "choice"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Checks if this is a fork state.
|
|
72
|
+
#
|
|
73
|
+
# @return [Boolean] true if fork state
|
|
74
|
+
def fork_state?
|
|
75
|
+
state_type == "fork"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Checks if this is a join state.
|
|
79
|
+
#
|
|
80
|
+
# @return [Boolean] true if join state
|
|
81
|
+
def join_state?
|
|
82
|
+
state_type == "join"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Checks if this is a composite state.
|
|
86
|
+
#
|
|
87
|
+
# @return [Boolean] true if has child states
|
|
88
|
+
def composite_state?
|
|
89
|
+
!children.nil? && !children.empty?
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Represents a state transition in a state diagram.
|
|
94
|
+
#
|
|
95
|
+
# A transition connects two states with optional trigger event
|
|
96
|
+
# and guard condition.
|
|
97
|
+
class StateTransition < Lutaml::Model::Serializable
|
|
98
|
+
# Source state identifier
|
|
99
|
+
attribute :from_id, :string
|
|
100
|
+
|
|
101
|
+
# Target state identifier
|
|
102
|
+
attribute :to_id, :string
|
|
103
|
+
|
|
104
|
+
# Optional trigger event for the transition
|
|
105
|
+
attribute :trigger, :string
|
|
106
|
+
|
|
107
|
+
# Optional guard condition for the transition
|
|
108
|
+
attribute :guard_condition, :string
|
|
109
|
+
|
|
110
|
+
# Validates the transition has required attributes.
|
|
111
|
+
#
|
|
112
|
+
# @return [Boolean] true if transition is valid
|
|
113
|
+
def valid?
|
|
114
|
+
!from_id.nil? && !from_id.empty? &&
|
|
115
|
+
!to_id.nil? && !to_id.empty?
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Returns the full transition label.
|
|
119
|
+
#
|
|
120
|
+
# @return [String] formatted label with trigger and guard
|
|
121
|
+
def label
|
|
122
|
+
parts = []
|
|
123
|
+
parts << trigger if trigger && !trigger.empty?
|
|
124
|
+
if guard_condition && !guard_condition.empty?
|
|
125
|
+
parts << "[#{guard_condition}]"
|
|
126
|
+
end
|
|
127
|
+
parts.join(" ")
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# A note attached to a state in a state diagram.
|
|
132
|
+
class StateNote < Lutaml::Model::Serializable
|
|
133
|
+
attribute :id, :string
|
|
134
|
+
attribute :text, :string
|
|
135
|
+
attribute :target_id, :string
|
|
136
|
+
attribute :position, :string
|
|
137
|
+
|
|
138
|
+
def valid?
|
|
139
|
+
[id, text, target_id].all? { |value| value && !value.empty? }
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# State diagram model.
|
|
144
|
+
#
|
|
145
|
+
# Represents a complete state machine diagram with states and
|
|
146
|
+
# transitions. State diagrams show the dynamic behavior of a
|
|
147
|
+
# system through states, events, and transitions.
|
|
148
|
+
#
|
|
149
|
+
# @example Creating a simple state diagram
|
|
150
|
+
# diagram = StateDiagram.new(direction: 'TB')
|
|
151
|
+
# diagram.states << StateNode.new(
|
|
152
|
+
# id: 'start',
|
|
153
|
+
# label: '[*]',
|
|
154
|
+
# state_type: 'start'
|
|
155
|
+
# )
|
|
156
|
+
# diagram.states << StateNode.new(
|
|
157
|
+
# id: 'idle',
|
|
158
|
+
# label: 'Idle',
|
|
159
|
+
# state_type: 'normal'
|
|
160
|
+
# )
|
|
161
|
+
# diagram.transitions << StateTransition.new(
|
|
162
|
+
# from_id: 'start',
|
|
163
|
+
# to_id: 'idle'
|
|
164
|
+
# )
|
|
165
|
+
class StateDiagram < Base
|
|
166
|
+
# Collection of states in the diagram
|
|
167
|
+
attribute :states, StateNode, collection: true, default: -> { [] }
|
|
168
|
+
|
|
169
|
+
# Collection of transitions between states
|
|
170
|
+
attribute :transitions, StateTransition, collection: true,
|
|
171
|
+
default: -> { [] }
|
|
172
|
+
|
|
173
|
+
# Collection of notes attached to states
|
|
174
|
+
attribute :notes, StateNote, collection: true, default: -> { [] }
|
|
175
|
+
|
|
176
|
+
# Returns the diagram type identifier.
|
|
177
|
+
#
|
|
178
|
+
# @return [Symbol] :state_diagram
|
|
179
|
+
def diagram_type
|
|
180
|
+
:state_diagram
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Validates the state diagram structure.
|
|
184
|
+
#
|
|
185
|
+
# A state diagram is valid if:
|
|
186
|
+
# - It has a states collection, empty or not
|
|
187
|
+
# - All states are valid
|
|
188
|
+
# - All transitions are valid
|
|
189
|
+
# - All transition references point to existing states
|
|
190
|
+
#
|
|
191
|
+
# An EMPTY collection is fine: mmdc 11.12.0 draws a bare
|
|
192
|
+
# `stateDiagram-v2` as an empty picture rather than refusing it. A
|
|
193
|
+
# MISSING one is not, because the attribute defaults to `[]` and only
|
|
194
|
+
# a caller clearing it can produce nil.
|
|
195
|
+
#
|
|
196
|
+
# @return [Boolean] true if state diagram is valid
|
|
197
|
+
def valid?
|
|
198
|
+
return false if states.nil?
|
|
199
|
+
|
|
200
|
+
all_states.all?(&:valid?) && valid_transitions? && valid_notes?
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Finds a state by its identifier.
|
|
204
|
+
#
|
|
205
|
+
# @param id [String] the state identifier to find
|
|
206
|
+
# @return [StateNode, nil] the state or nil if not found
|
|
207
|
+
def find_state(id)
|
|
208
|
+
all_states.find { |state| state.id == id }
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Finds all transitions originating from a specific state.
|
|
212
|
+
#
|
|
213
|
+
# @param state_id [String] the source state identifier
|
|
214
|
+
# @return [Array<StateTransition>] transitions from the state
|
|
215
|
+
def transitions_from(state_id)
|
|
216
|
+
transitions.select { |t| t.from_id == state_id }
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Finds all transitions targeting a specific state.
|
|
220
|
+
#
|
|
221
|
+
# @param state_id [String] the target state identifier
|
|
222
|
+
# @return [Array<StateTransition>] transitions to the state
|
|
223
|
+
def transitions_to(state_id)
|
|
224
|
+
transitions.select { |t| t.to_id == state_id }
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Finds the start state.
|
|
228
|
+
#
|
|
229
|
+
# @return [StateNode, nil] the start state or nil if not found
|
|
230
|
+
def start_state
|
|
231
|
+
all_states.find(&:start_state?)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Finds all end states.
|
|
235
|
+
#
|
|
236
|
+
# @return [Array<StateNode>] end states
|
|
237
|
+
def end_states
|
|
238
|
+
all_states.select(&:end_state?)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Finds all composite states.
|
|
242
|
+
#
|
|
243
|
+
# @return [Array<StateNode>] composite states
|
|
244
|
+
def composite_states
|
|
245
|
+
all_states.select(&:composite_state?)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Finds all choice states.
|
|
249
|
+
#
|
|
250
|
+
# @return [Array<StateNode>] choice states
|
|
251
|
+
def choice_states
|
|
252
|
+
all_states.select(&:choice_state?)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
private
|
|
256
|
+
|
|
257
|
+
def all_states(collection = states)
|
|
258
|
+
Array(collection).flat_map do |state|
|
|
259
|
+
[state, *all_states(state.children)]
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def valid_transitions?
|
|
264
|
+
transitions.nil? || transitions.all? do |transition|
|
|
265
|
+
transition.valid? && transition_references_resolve?(transition)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def valid_notes?
|
|
270
|
+
notes.nil? || notes.all? do |note|
|
|
271
|
+
note.valid? && !find_state(note.target_id).nil?
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def transition_references_resolve?(transition)
|
|
276
|
+
state_ids = all_states.map(&:id)
|
|
277
|
+
state_ids.include?(transition.from_id) &&
|
|
278
|
+
state_ids.include?(transition.to_id)
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Diagram
|
|
8
|
+
# Represents an event in a timeline.
|
|
9
|
+
#
|
|
10
|
+
# An event represents a point in time with associated description(s).
|
|
11
|
+
# Events can have multiple descriptions (when multiple things happened
|
|
12
|
+
# at the same time).
|
|
13
|
+
class TimelineEvent < Lutaml::Model::Serializable
|
|
14
|
+
# The time/date/year for this event
|
|
15
|
+
attribute :time, :string
|
|
16
|
+
|
|
17
|
+
# Event descriptions (can be multiple for same time)
|
|
18
|
+
attribute :descriptions, :string, collection: true, default: -> { [] }
|
|
19
|
+
|
|
20
|
+
# Validates the event has required attributes.
|
|
21
|
+
#
|
|
22
|
+
# @return [Boolean] true if event is valid
|
|
23
|
+
def valid?
|
|
24
|
+
!time.nil? && !time.empty? && !descriptions.empty?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Get primary description (first one).
|
|
28
|
+
#
|
|
29
|
+
# @return [String, nil] the first description or nil
|
|
30
|
+
def primary_description
|
|
31
|
+
descriptions.first
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# A period written without descriptions (a bare task line).
|
|
35
|
+
#
|
|
36
|
+
# @return [Boolean] true if there are no descriptions
|
|
37
|
+
def bare?
|
|
38
|
+
descriptions.empty?
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Check if event has multiple descriptions.
|
|
42
|
+
#
|
|
43
|
+
# @return [Boolean] true if more than one description
|
|
44
|
+
def multiple_descriptions?
|
|
45
|
+
descriptions.size > 1
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Represents a section/period in a timeline.
|
|
50
|
+
#
|
|
51
|
+
# A section groups related events together, typically representing
|
|
52
|
+
# a period, category, or theme.
|
|
53
|
+
class TimelineSection < Lutaml::Model::Serializable
|
|
54
|
+
# Name/title of this section
|
|
55
|
+
attribute :name, :string
|
|
56
|
+
|
|
57
|
+
# Periods in source order: events and bare tasks interleaved as
|
|
58
|
+
# written. A bare task is an event without descriptions.
|
|
59
|
+
attribute :events, TimelineEvent, collection: true,
|
|
60
|
+
default: -> { [] }
|
|
61
|
+
|
|
62
|
+
def initialize(name = nil)
|
|
63
|
+
super()
|
|
64
|
+
@name = name
|
|
65
|
+
@events = []
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Names of the bare tasks, in source order.
|
|
69
|
+
#
|
|
70
|
+
# @return [Array<String>] task names
|
|
71
|
+
def tasks
|
|
72
|
+
events.select(&:bare?).map(&:time)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Validates the section.
|
|
76
|
+
#
|
|
77
|
+
# @return [Boolean] true if section has a name
|
|
78
|
+
def valid?
|
|
79
|
+
!name.nil? && !name.empty?
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Check if section has events.
|
|
83
|
+
#
|
|
84
|
+
# @return [Boolean] true if section has events with descriptions
|
|
85
|
+
def has_events?
|
|
86
|
+
events.any? { |event| !event.bare? }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Check if section has tasks.
|
|
90
|
+
#
|
|
91
|
+
# @return [Boolean] true if section has tasks
|
|
92
|
+
def has_tasks?
|
|
93
|
+
events.any?(&:bare?)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Timeline diagram model.
|
|
98
|
+
#
|
|
99
|
+
# Represents a timeline showing chronological events, optionally
|
|
100
|
+
# grouped into sections. Timelines are useful for showing historical
|
|
101
|
+
# progression, project milestones, or any time-based sequence.
|
|
102
|
+
#
|
|
103
|
+
# @example Creating a simple timeline
|
|
104
|
+
# timeline = Timeline.new
|
|
105
|
+
# timeline.title = 'History of Computing'
|
|
106
|
+
#
|
|
107
|
+
# section = TimelineSection.new('Early Era')
|
|
108
|
+
# event = TimelineEvent.new
|
|
109
|
+
# event.time = '1936'
|
|
110
|
+
# event.descriptions << 'Turing machine'
|
|
111
|
+
# section.events << event
|
|
112
|
+
#
|
|
113
|
+
# timeline.sections << section
|
|
114
|
+
class Timeline < Base
|
|
115
|
+
# Collection of sections in the timeline
|
|
116
|
+
attribute :sections, TimelineSection, collection: true,
|
|
117
|
+
default: -> { [] }
|
|
118
|
+
|
|
119
|
+
# Periods (events and bare tasks, in source order) written before
|
|
120
|
+
# the first section
|
|
121
|
+
attribute :events, TimelineEvent, collection: true,
|
|
122
|
+
default: -> { [] }
|
|
123
|
+
|
|
124
|
+
# Accessibility title (for screen readers)
|
|
125
|
+
attribute :acc_title, :string
|
|
126
|
+
|
|
127
|
+
# Accessibility description (for screen readers)
|
|
128
|
+
attribute :acc_description, :string
|
|
129
|
+
|
|
130
|
+
def initialize
|
|
131
|
+
@sections = []
|
|
132
|
+
@events = []
|
|
133
|
+
super
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Returns the diagram type identifier.
|
|
137
|
+
#
|
|
138
|
+
# @return [Symbol] :timeline
|
|
139
|
+
def diagram_type
|
|
140
|
+
:timeline
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Validates the timeline structure.
|
|
144
|
+
#
|
|
145
|
+
# A timeline is always valid (can be empty for parsing tests).
|
|
146
|
+
# In practice, useful timelines would have events or sections.
|
|
147
|
+
#
|
|
148
|
+
# @return [Boolean] true if timeline is valid
|
|
149
|
+
def valid?
|
|
150
|
+
true
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Check if timeline has any events.
|
|
154
|
+
#
|
|
155
|
+
# @return [Boolean] true if has events (in sections or standalone)
|
|
156
|
+
def has_events?
|
|
157
|
+
events.any? { |event| !event.bare? } || sections.any?(&:has_events?)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Check if timeline has sections.
|
|
161
|
+
#
|
|
162
|
+
# @return [Boolean] true if has sections
|
|
163
|
+
def has_sections?
|
|
164
|
+
!sections.empty?
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Get all events across all sections and standalone.
|
|
168
|
+
#
|
|
169
|
+
# @return [Array<TimelineEvent>] all events
|
|
170
|
+
def all_events
|
|
171
|
+
section_events = sections.flat_map(&:events)
|
|
172
|
+
events + section_events
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Get all unique time values from events.
|
|
176
|
+
#
|
|
177
|
+
# @return [Array<String>] sorted array of unique times
|
|
178
|
+
def all_times
|
|
179
|
+
all_events.map(&:time).uniq.sort
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|