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,452 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "psych"
|
|
4
|
+
require_relative "../js_number"
|
|
5
|
+
require_relative "base"
|
|
6
|
+
|
|
7
|
+
module Etassia
|
|
8
|
+
module Parser
|
|
9
|
+
# The value mermaid ends up holding for an `@{ }` metadata body.
|
|
10
|
+
#
|
|
11
|
+
# Mermaid hands the body to js-yaml under its JSON schema, then reads
|
|
12
|
+
# diagram-specific keys from the result. js-yaml is not Psych: `no` stays
|
|
13
|
+
# a string there, a forward alias is an error, and a mapping key is whatever
|
|
14
|
+
# JavaScript makes of it. So the tree is composed here rather than loaded.
|
|
15
|
+
#
|
|
16
|
+
# Nothing calls `Psych.load`, `safe_load` or `to_ruby`. A loader applies
|
|
17
|
+
# Ruby's type table instead of mermaid's, and it runs every converter
|
|
18
|
+
# registered with `Psych.add_domain_type` — a host-global list any other
|
|
19
|
+
# gem can add to. One of those built an object out of a node label.
|
|
20
|
+
class MetadataYaml
|
|
21
|
+
NON_SPECIFIC_TAG = "!"
|
|
22
|
+
STR_TAG = "tag:yaml.org,2002:str"
|
|
23
|
+
INT_TAG = "tag:yaml.org,2002:int"
|
|
24
|
+
FLOAT_TAG = "tag:yaml.org,2002:float"
|
|
25
|
+
BOOL_TAG = "tag:yaml.org,2002:bool"
|
|
26
|
+
NULL_TAG = "tag:yaml.org,2002:null"
|
|
27
|
+
SEQ_TAG = "tag:yaml.org,2002:seq"
|
|
28
|
+
MAP_TAG = "tag:yaml.org,2002:map"
|
|
29
|
+
|
|
30
|
+
TAGGED_SCALAR_READERS = {
|
|
31
|
+
INT_TAG => :tagged_int,
|
|
32
|
+
FLOAT_TAG => :tagged_float,
|
|
33
|
+
BOOL_TAG => :tagged_bool,
|
|
34
|
+
NULL_TAG => :tagged_null,
|
|
35
|
+
}.freeze
|
|
36
|
+
|
|
37
|
+
# What JavaScript writes when it needs a string for a plain object.
|
|
38
|
+
OBJECT_STRING = "[object Object]"
|
|
39
|
+
|
|
40
|
+
PLAIN_SCALAR = Psych::Nodes::Scalar::PLAIN
|
|
41
|
+
|
|
42
|
+
# libyaml ends a line on NEL, LS or PS as well; js-yaml ends one on a
|
|
43
|
+
# line feed or a carriage return and nothing else. A body carrying
|
|
44
|
+
# one of the three cannot mean the same thing to both parsers, so it
|
|
45
|
+
# is refused rather than read the wrong way round.
|
|
46
|
+
FOREIGN_BREAK = /[\u0085\u2028\u2029]/
|
|
47
|
+
|
|
48
|
+
# js-yaml drops a byte-order mark at the very start of the text and
|
|
49
|
+
# leaves every other one alone; libyaml drops one at the start of any
|
|
50
|
+
# line. A mark further in therefore hides a key from mermaid that
|
|
51
|
+
# libyaml hands over as if it were plain — `@{` newline BOM
|
|
52
|
+
# `label: hi }` keeps the node's old label in mmdc.
|
|
53
|
+
BOM = "\uFEFF"
|
|
54
|
+
|
|
55
|
+
# The transform has already turned every carriage return into a line
|
|
56
|
+
# feed, the way mermaid does, and a foreign break is refused below.
|
|
57
|
+
# So a line is whatever sits between two line feeds.
|
|
58
|
+
YAML_BREAK = "\n"
|
|
59
|
+
|
|
60
|
+
# js-yaml takes any 1.x document version and merely warns about the
|
|
61
|
+
# ones it does not know; libyaml refuses everything but 1.1 and 1.2.
|
|
62
|
+
# The version changes nothing either of them does with the tree, so
|
|
63
|
+
# the number is levelled before parsing. Only the number: rewriting
|
|
64
|
+
# the whole line dropped a trailing comment, and `%YAML 1.3 # note`
|
|
65
|
+
# is a document mmdc draws. The number has to be a whole token, or
|
|
66
|
+
# `%YAML 1.3#note` — which js-yaml reads as one unusable version and
|
|
67
|
+
# refuses — became a levelled version with a comment after it.
|
|
68
|
+
# A major other than 1, a second directive and anything else on the
|
|
69
|
+
# line still fail in libyaml, as they do in js-yaml.
|
|
70
|
+
DOCUMENT_VERSION = /^%YAML[ \t]+\K1\.\d+(?=[ \t]|$)/
|
|
71
|
+
LEVELLED_VERSION = "1.2"
|
|
72
|
+
|
|
73
|
+
# A directive only counts ahead of the document, next to the blank
|
|
74
|
+
# lines and comments allowed to sit with it. Past that point a
|
|
75
|
+
# `%YAML 1.3` at column 0 is ordinary text — a single-quoted value
|
|
76
|
+
# carries on there — and levelling it rewrote a label mmdc draws
|
|
77
|
+
# as written.
|
|
78
|
+
DIRECTIVE_HEAD = /\A(?:%|[ \t]*(?:#|\z))/
|
|
79
|
+
|
|
80
|
+
# js-yaml reads an anchor name up to whitespace or a flow indicator,
|
|
81
|
+
# where libyaml stops at the first character an anchor may not hold.
|
|
82
|
+
# `&a:b hi` is the anchor "a:b" holding "hi" there, and the anchor "a"
|
|
83
|
+
# holding ":b hi" here, so the same source names a different label.
|
|
84
|
+
# A tag may sit in front of the anchor, and is stepped over.
|
|
85
|
+
#
|
|
86
|
+
# It cuts the other way too: libyaml's anchor charset is the narrower
|
|
87
|
+
# one, so an anchor holding `.`, `!`, `#` or `%` is refused here and
|
|
88
|
+
# drawn by mermaid. That is a refusal rather than a wrong picture, and
|
|
89
|
+
# reading it would mean giving up libyaml's scanner.
|
|
90
|
+
ANCHOR_PROPERTY = /\A(?:!\S*[ \t]+)?&(?<name>[^\s,\[\]{}]*)/
|
|
91
|
+
|
|
92
|
+
NULL_WORDS = %w[~ null Null NULL].freeze
|
|
93
|
+
|
|
94
|
+
BOOL_WORDS = {
|
|
95
|
+
"true" => true, "True" => true, "TRUE" => true,
|
|
96
|
+
"false" => false, "False" => false, "FALSE" => false
|
|
97
|
+
}.freeze
|
|
98
|
+
|
|
99
|
+
# js-yaml's JSON_SCHEMA is what mermaid parses with, and it is not
|
|
100
|
+
# JSON: the resolvers are YAML 1.1's. Each word has three spellings,
|
|
101
|
+
# so `NULL` is null and mermaid keeps the old label where a JSON
|
|
102
|
+
# reading would have set the string "NULL".
|
|
103
|
+
JSON_WORDS = BOOL_WORDS.merge(
|
|
104
|
+
NULL_WORDS.to_h { |word| [word, nil] },
|
|
105
|
+
).freeze
|
|
106
|
+
|
|
107
|
+
# Numbers carry a sign, group digits with `_`, and come in base 2, 8
|
|
108
|
+
# and 16 as well. JSON reads none of those, so `+1` and `0x1F` were
|
|
109
|
+
# labels here and errors in mmdc.
|
|
110
|
+
#
|
|
111
|
+
# A leading zero is where js-yaml starts looking for a base
|
|
112
|
+
# letter, so the character after it may not be `_`: `0_1` is not
|
|
113
|
+
# an integer there and mmdc refuses `!!int 0_1`. A zero further
|
|
114
|
+
# along is fine, and `00_1` is an integer to both.
|
|
115
|
+
JSON_INT = %r{
|
|
116
|
+
\A[-+]?(
|
|
117
|
+
0b[01_]+ | 0o[0-7_]+ | 0x[0-9a-fA-F_]+
|
|
118
|
+
| 0(?!_)[0-9_]* | [1-9][0-9_]*
|
|
119
|
+
)\z
|
|
120
|
+
}x
|
|
121
|
+
|
|
122
|
+
# js-yaml's own float pattern. The sign is on two of the four
|
|
123
|
+
# branches only: `-1.5` and `-.inf` resolve, `-.5` and `-.nan` stay
|
|
124
|
+
# strings.
|
|
125
|
+
JSON_FLOAT = /
|
|
126
|
+
\A(?:
|
|
127
|
+
[-+]?[0-9][0-9_]*(?:\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?
|
|
128
|
+
|\.[0-9_]+(?:[eE][-+]?[0-9]+)?
|
|
129
|
+
|[-+]?\.(?:inf|Inf|INF)
|
|
130
|
+
|\.(?:nan|NaN|NAN)
|
|
131
|
+
)\z
|
|
132
|
+
/x
|
|
133
|
+
|
|
134
|
+
# The part of js-yaml's scalar table that resolves plain scalar nodes.
|
|
135
|
+
module PlainScalars
|
|
136
|
+
def plain_scalar(text)
|
|
137
|
+
return JSON_WORDS[text] if JSON_WORDS.key?(text)
|
|
138
|
+
return json_int(text.delete("_")) if json_int?(text)
|
|
139
|
+
return json_float(text.delete("_")) if json_float?(text)
|
|
140
|
+
|
|
141
|
+
text
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# js-yaml tries the integer resolver before the float one, and
|
|
145
|
+
# neither takes a trailing `_` — `1_` is a string.
|
|
146
|
+
def json_int?(text)
|
|
147
|
+
!text.end_with?("_") && JSON_INT.match?(text)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def json_float?(text)
|
|
151
|
+
!text.end_with?("_") && JSON_FLOAT.match?(text)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Ruby reads the same three prefixes, but it also reads a bare
|
|
155
|
+
# leading zero as octal, where js-yaml stays in base 10 — and
|
|
156
|
+
# `Integer("08")` raises. So say the base for the plain form.
|
|
157
|
+
def json_int(digits)
|
|
158
|
+
digits.match?(/\A[-+]?0[box]/) ? Integer(digits) : Integer(digits, 10)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# The two words are named, not parsed: mermaid sees NaN, which is
|
|
162
|
+
# falsy and skips the key, and Infinity, which is a number and is
|
|
163
|
+
# refused like any other. `to_f` takes the rest and never raises, so
|
|
164
|
+
# an odd but legal form like `1.` or `.5` stays a number instead of
|
|
165
|
+
# throwing out of the parser.
|
|
166
|
+
def json_float(digits)
|
|
167
|
+
case digits.downcase
|
|
168
|
+
when ".inf", "+.inf" then Float::INFINITY
|
|
169
|
+
when "-.inf" then -Float::INFINITY
|
|
170
|
+
when ".nan" then Float::NAN
|
|
171
|
+
else digits.to_f
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
include PlainScalars
|
|
177
|
+
|
|
178
|
+
# @raise [Parser::ParseError] on YAML mermaid would also refuse
|
|
179
|
+
def self.value(document)
|
|
180
|
+
new(document).value
|
|
181
|
+
rescue SystemStackError
|
|
182
|
+
# Walking the tree is recursive, so a body nested thousands deep
|
|
183
|
+
# runs the stack out. mermaid blows its own browser stack on the
|
|
184
|
+
# same source and refuses it, but SystemStackError is not a
|
|
185
|
+
# StandardError and sailed past every caller on the way up.
|
|
186
|
+
raise ParseError, "Metadata nested too deeply."
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def initialize(document)
|
|
190
|
+
@document = level_versions(document.delete_prefix(BOM))
|
|
191
|
+
@lines = @document.split(YAML_BREAK, -1)
|
|
192
|
+
@anchors = {}
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# nil for a document that came back null: a node refuses it, an
|
|
196
|
+
# edge's block ignores it, so the caller decides.
|
|
197
|
+
def value
|
|
198
|
+
compose(root)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
private
|
|
202
|
+
|
|
203
|
+
def level_versions(text)
|
|
204
|
+
lines = text.split(YAML_BREAK, -1)
|
|
205
|
+
head = lines.take_while { |line| DIRECTIVE_HEAD.match?(line) }
|
|
206
|
+
levelled = head.map do |line|
|
|
207
|
+
line.sub(DOCUMENT_VERSION, LEVELLED_VERSION)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
(levelled + lines.drop(head.size)).join(YAML_BREAK)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# `yaml.load` refuses a stream that is not exactly one document.
|
|
214
|
+
def root
|
|
215
|
+
reject_ambiguous_text
|
|
216
|
+
documents = Psych.parse_stream(@document).children
|
|
217
|
+
raise ParseError, "Malformed metadata." unless documents.one?
|
|
218
|
+
|
|
219
|
+
documents.first.children.first
|
|
220
|
+
rescue Psych::Exception
|
|
221
|
+
raise ParseError, "Malformed metadata."
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Two characters the two parsers read differently, and neither leaves
|
|
225
|
+
# a trace in the tree afterwards. The body is refused rather than
|
|
226
|
+
# read the wrong way round.
|
|
227
|
+
def reject_ambiguous_text
|
|
228
|
+
raise ParseError, "Unreadable line break." if
|
|
229
|
+
FOREIGN_BREAK.match?(@document)
|
|
230
|
+
raise ParseError, "Stray byte-order mark." if
|
|
231
|
+
@lines.any? { |line| line.start_with?(BOM) }
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def compose(node)
|
|
235
|
+
case node
|
|
236
|
+
when Psych::Nodes::Alias then aliased(node)
|
|
237
|
+
when Psych::Nodes::Scalar then scalar(node)
|
|
238
|
+
when Psych::Nodes::Sequence then sequence(node)
|
|
239
|
+
when Psych::Nodes::Mapping then mapping(node)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# An anchor is only visible after the node that defines it, and a
|
|
244
|
+
# redefined one resolves to whichever value came last before the
|
|
245
|
+
# alias. Collecting the whole tree first gave both the wrong answer.
|
|
246
|
+
def aliased(node)
|
|
247
|
+
name = alias_name(node)
|
|
248
|
+
@anchors.fetch(name) do
|
|
249
|
+
raise ParseError, "No anchor for alias: #{name}."
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# js-yaml reads an alias name up to whitespace or a flow indicator,
|
|
254
|
+
# where libyaml stops at the first character an anchor may not hold.
|
|
255
|
+
# `*s: hi` is an alias named "s:" there, and mermaid reports it
|
|
256
|
+
# undefined rather than reading the key.
|
|
257
|
+
def alias_name(node)
|
|
258
|
+
line = @lines[node.start_line]
|
|
259
|
+
line[(node.start_column + 1)..][/\A[^\s,\[\]{}]*/]
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def scalar(node)
|
|
263
|
+
resolved = resolve_scalar(node)
|
|
264
|
+
register_anchor(node, resolved)
|
|
265
|
+
resolved
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# The two parsers read the name differently, and libyaml leaves the
|
|
269
|
+
# rest of it in the value, so the node cannot be read the way mermaid
|
|
270
|
+
# reads it. It is refused instead.
|
|
271
|
+
def register_anchor(node, value)
|
|
272
|
+
name = node.anchor
|
|
273
|
+
return unless name
|
|
274
|
+
|
|
275
|
+
raise ParseError, "Ambiguous anchor: #{name}." unless
|
|
276
|
+
js_anchor_name(node) == name
|
|
277
|
+
|
|
278
|
+
@anchors[name] = value
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def js_anchor_name(node)
|
|
282
|
+
line = @lines[node.start_line]
|
|
283
|
+
ANCHOR_PROPERTY.match(line[node.start_column..])&.[](:name)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def resolve_scalar(node)
|
|
287
|
+
return empty_node(node.tag) if empty_node?(node)
|
|
288
|
+
return tagged_scalar(node.tag, node.value) if explicit_tag?(node)
|
|
289
|
+
return node.value if node.style != PLAIN_SCALAR ||
|
|
290
|
+
node.tag == NON_SPECIFIC_TAG
|
|
291
|
+
|
|
292
|
+
plain_scalar(node.value)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# A plain scalar with nothing in it is no content at all to js-yaml.
|
|
296
|
+
# An empty string had to be written down. Psych reports `quoted` as
|
|
297
|
+
# false for every tagged scalar, so the style is the only thing that
|
|
298
|
+
# tells `!!seq` from `!!seq ""`.
|
|
299
|
+
def empty_node?(node)
|
|
300
|
+
node.style == PLAIN_SCALAR && node.value.empty?
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def explicit_tag?(node)
|
|
304
|
+
!node.tag.nil? && node.tag != NON_SPECIFIC_TAG
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# A node with no content has no kind either, so js-yaml looks its tag
|
|
308
|
+
# up in the whole table rather than the one for its kind, and hands
|
|
309
|
+
# the constructor nothing. `!!seq` builds an empty array that way,
|
|
310
|
+
# and `!!int` throws.
|
|
311
|
+
def empty_node(tag)
|
|
312
|
+
case tag
|
|
313
|
+
when nil, NON_SPECIFIC_TAG, NULL_TAG then nil
|
|
314
|
+
when STR_TAG then ""
|
|
315
|
+
when SEQ_TAG then []
|
|
316
|
+
when MAP_TAG then {}
|
|
317
|
+
when INT_TAG, FLOAT_TAG, BOOL_TAG then unresolvable(tag)
|
|
318
|
+
else unsupported(tag)
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# js-yaml runs the tag's own resolver over the value and refuses the
|
|
323
|
+
# document when it says no, so `!!int nope` is an error rather than
|
|
324
|
+
# the string it looks like.
|
|
325
|
+
def tagged_scalar(tag, text)
|
|
326
|
+
return text if tag == STR_TAG
|
|
327
|
+
|
|
328
|
+
reader = TAGGED_SCALAR_READERS[tag]
|
|
329
|
+
return unsupported(tag) unless reader
|
|
330
|
+
|
|
331
|
+
send(reader, text)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def tagged_int(text)
|
|
335
|
+
json_int?(text) ? json_int(text.delete("_")) : unresolvable(INT_TAG)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def tagged_float(text)
|
|
339
|
+
return json_float(text.delete("_")) if json_float?(text)
|
|
340
|
+
|
|
341
|
+
unresolvable(FLOAT_TAG)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def tagged_bool(text)
|
|
345
|
+
BOOL_WORDS.fetch(text) { unresolvable(BOOL_TAG) }
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def tagged_null(text)
|
|
349
|
+
NULL_WORDS.include?(text) ? nil : unresolvable(NULL_TAG)
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def sequence(node)
|
|
353
|
+
collection_tag(node, SEQ_TAG)
|
|
354
|
+
list = []
|
|
355
|
+
# Registered before the children are read, so `&s [*s]` resolves to
|
|
356
|
+
# the array being built rather than running out of stack.
|
|
357
|
+
register_anchor(node, list)
|
|
358
|
+
node.children.each { |child| list << compose(child) }
|
|
359
|
+
list
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def mapping(node)
|
|
363
|
+
collection_tag(node, MAP_TAG)
|
|
364
|
+
reject_leading_property(node)
|
|
365
|
+
pairs = {}
|
|
366
|
+
register_anchor(node, pairs)
|
|
367
|
+
node.children.each_slice(2) { |key, value| store(pairs, key, value) }
|
|
368
|
+
pairs
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# js-yaml composes the key, then the value, and only then complains
|
|
372
|
+
# about a duplicate.
|
|
373
|
+
def store(pairs, key, value)
|
|
374
|
+
name = key_string(compose(key))
|
|
375
|
+
composed = compose(value)
|
|
376
|
+
raise ParseError, "Duplicate key: #{name}." if pairs.key?(name)
|
|
377
|
+
|
|
378
|
+
pairs[name] = composed
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
# A collection takes its own tag or none. js-yaml looks a tag up in
|
|
382
|
+
# the table for the node's kind, so `!!str [a, b]` finds nothing
|
|
383
|
+
# there and is an unknown tag rather than a string.
|
|
384
|
+
def collection_tag(node, own)
|
|
385
|
+
return if node.tag.nil? || node.tag == NON_SPECIFIC_TAG ||
|
|
386
|
+
node.tag == own
|
|
387
|
+
|
|
388
|
+
unsupported(node.tag)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
# js-yaml stops allowing block collections the moment it reads a node
|
|
392
|
+
# property followed by a space, so `&s shape: rounded` is a parse
|
|
393
|
+
# error there — the anchor lands on a mapping it has not started
|
|
394
|
+
# reading. libyaml takes it as an anchored key, so the mapping has to
|
|
395
|
+
# be refused here instead.
|
|
396
|
+
#
|
|
397
|
+
# Only a property sitting exactly where the mapping starts does this.
|
|
398
|
+
# An explicit `? &s shape` is two columns further in, and a flow
|
|
399
|
+
# mapping's first key is past its brace, so both are left alone.
|
|
400
|
+
def reject_leading_property(node)
|
|
401
|
+
first = node.children.first
|
|
402
|
+
# A body that is nothing but a comment composes as an empty flow
|
|
403
|
+
# mapping, so there may be no first key to look at at all. mmdc
|
|
404
|
+
# draws `A@{#}` with the label the node already had.
|
|
405
|
+
return unless first&.anchor || first&.tag
|
|
406
|
+
return unless first.start_line == node.start_line &&
|
|
407
|
+
first.start_column == node.start_column
|
|
408
|
+
|
|
409
|
+
raise ParseError, "Node property on a block mapping key."
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
# JavaScript stores a mapping key as a string, so `1` and `1.0` are
|
|
413
|
+
# one key and `[shape]` is the key `shape`. js-yaml writes any plain
|
|
414
|
+
# object as "[object Object]" and refuses a nested array outright.
|
|
415
|
+
def key_string(key)
|
|
416
|
+
case key
|
|
417
|
+
when Array then key.map { |item| key_element(item) }.join(",")
|
|
418
|
+
when Hash then OBJECT_STRING
|
|
419
|
+
else js_string(key)
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
def key_element(item)
|
|
424
|
+
case item
|
|
425
|
+
when nil then "" # Array#join writes nothing at all for null.
|
|
426
|
+
when Array then raise ParseError, "Nested array in a metadata key."
|
|
427
|
+
when Hash then OBJECT_STRING
|
|
428
|
+
else js_string(item)
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def js_string(value)
|
|
433
|
+
case value
|
|
434
|
+
when nil then "null"
|
|
435
|
+
when true, false then value.to_s
|
|
436
|
+
when Numeric then Etassia::JsNumber.stringify(value)
|
|
437
|
+
else value
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
def unsupported(tag)
|
|
442
|
+
raise ParseError, "Unsupported tag: #{tag}."
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
def unresolvable(tag)
|
|
446
|
+
raise ParseError, "Value does not fit #{tag}."
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
private_constant :MetadataYaml
|
|
451
|
+
end
|
|
452
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
require_relative "grammars/mindmap"
|
|
5
|
+
require_relative "builders/mindmap"
|
|
6
|
+
require_relative "native/builders/mindmap"
|
|
7
|
+
require_relative "../diagram/mindmap"
|
|
8
|
+
|
|
9
|
+
module Etassia
|
|
10
|
+
module Parser
|
|
11
|
+
# Mindmap parser for Mermaid mindmap diagram syntax.
|
|
12
|
+
#
|
|
13
|
+
# Uses Parslet grammar-based parsing to handle mindmap syntax
|
|
14
|
+
# with hierarchical nodes, shapes, icons, and classes.
|
|
15
|
+
#
|
|
16
|
+
# Parses mindmaps with support for:
|
|
17
|
+
# - Indentation-based hierarchy
|
|
18
|
+
# - Multiple node shapes (circle, cloud, bang, hexagon, square)
|
|
19
|
+
# - Icons (::icon(name))
|
|
20
|
+
# - Classes (:::className)
|
|
21
|
+
#
|
|
22
|
+
# @example Parse a simple mindmap
|
|
23
|
+
# parser = Mindmap.new
|
|
24
|
+
# source = <<~MERMAID
|
|
25
|
+
# mindmap
|
|
26
|
+
# root((Central Idea))
|
|
27
|
+
# Branch 1
|
|
28
|
+
# Sub-item 1.1
|
|
29
|
+
# Branch 2
|
|
30
|
+
# MERMAID
|
|
31
|
+
# diagram = parser.parse(source)
|
|
32
|
+
class Mindmap < Base
|
|
33
|
+
grammar Grammars::Mindmap
|
|
34
|
+
builder Builders::Mindmap
|
|
35
|
+
native :mindmap, builder: Native::Builders::Mindmap
|
|
36
|
+
|
|
37
|
+
# The diagram for a builder's result: the root and every node.
|
|
38
|
+
#
|
|
39
|
+
# @param result [Hash] the builder's +:root+ and +:nodes+
|
|
40
|
+
# @return [Diagram::Mindmap] the mindmap diagram model
|
|
41
|
+
def create_diagram(result)
|
|
42
|
+
diagram = Diagram::Mindmap.new
|
|
43
|
+
add_root(diagram, result[:root])
|
|
44
|
+
add_remaining_nodes(diagram, result)
|
|
45
|
+
diagram
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def add_root(diagram, root_data)
|
|
51
|
+
return unless root_data
|
|
52
|
+
|
|
53
|
+
root = build_node(root_data)
|
|
54
|
+
diagram.root = root
|
|
55
|
+
diagram.add_node(root)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def add_remaining_nodes(diagram, result)
|
|
59
|
+
result[:nodes].each do |node_data|
|
|
60
|
+
next if node_data == result[:root]
|
|
61
|
+
|
|
62
|
+
diagram.add_node(build_node(node_data))
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def build_node(node_data, parent = nil)
|
|
67
|
+
node = create_node(node_data)
|
|
68
|
+
node.parent = parent if parent
|
|
69
|
+
add_children(node, node_data[:children])
|
|
70
|
+
node
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def create_node(node_data)
|
|
74
|
+
Diagram::Mindmap::MindmapNode.new(
|
|
75
|
+
id: node_data[:id],
|
|
76
|
+
content: node_data[:content],
|
|
77
|
+
level: node_data[:level],
|
|
78
|
+
shape: node_data[:shape] || "default",
|
|
79
|
+
icon: node_data[:icon],
|
|
80
|
+
classes: node_data[:classes] || [],
|
|
81
|
+
)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def add_children(node, children)
|
|
85
|
+
children.each do |child_data|
|
|
86
|
+
child = build_node(child_data, node)
|
|
87
|
+
node.add_child(child)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../text"
|
|
4
|
+
require_relative "../../../diagram/architecture"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Parser
|
|
8
|
+
module Native
|
|
9
|
+
module Builders
|
|
10
|
+
# Builds Diagram::Architecture from the native parse tree of the
|
|
11
|
+
# +architecture+ entry.
|
|
12
|
+
class Architecture
|
|
13
|
+
TEXT_ATTRIBUTES = {
|
|
14
|
+
title: :title=,
|
|
15
|
+
acc_title: :acc_title=,
|
|
16
|
+
acc_descr: :acc_descr=,
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
ENTITIES = {
|
|
20
|
+
"group" => %i[groups group_model],
|
|
21
|
+
"service" => %i[services service_model],
|
|
22
|
+
"junction" => %i[junctions junction_model],
|
|
23
|
+
}.freeze
|
|
24
|
+
|
|
25
|
+
EDGE_ATTRIBUTES = {
|
|
26
|
+
from_id: :from, to_id: :to, from_position: :from_pos,
|
|
27
|
+
to_position: :to_pos, label: :label
|
|
28
|
+
}.freeze
|
|
29
|
+
|
|
30
|
+
# @param tree [Hash, Array, Parsanol::Slice] native parse tree
|
|
31
|
+
# @return [Diagram::Architecture]
|
|
32
|
+
def apply(tree)
|
|
33
|
+
Diagram::Architecture.new.tap do |diagram|
|
|
34
|
+
Text.items(tree[:statements]).each do |item|
|
|
35
|
+
apply_statement(diagram, item)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def apply_statement(diagram, item)
|
|
43
|
+
return add_text(diagram, item) if text_statement?(item)
|
|
44
|
+
return diagram.edges << edge_model(item) if item.key?(:from)
|
|
45
|
+
|
|
46
|
+
collection, builder = ENTITIES.fetch(item[:stmt_type].to_s)
|
|
47
|
+
diagram.public_send(collection) << send(builder, item)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def text_statement?(item)
|
|
51
|
+
TEXT_ATTRIBUTES.keys.any? { |name| item.key?(name) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def add_text(diagram, item)
|
|
55
|
+
key = TEXT_ATTRIBUTES.keys.find { |name| item.key?(name) }
|
|
56
|
+
diagram.public_send(TEXT_ATTRIBUTES[key], text(item[key]))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def group_model(data)
|
|
60
|
+
Diagram::Architecture::Group.new.tap do |group|
|
|
61
|
+
assign(group, data, id: :id, label: :label, icon: :icon)
|
|
62
|
+
group.parent_id = text(data[:parent]) if data.key?(:parent)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def service_model(data)
|
|
67
|
+
Diagram::Architecture::Service.new.tap do |service|
|
|
68
|
+
assign(service, data, id: :id, label: :label, icon: :icon)
|
|
69
|
+
service.group_id = text(data[:group]) if data.key?(:group)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def junction_model(data)
|
|
74
|
+
Diagram::Architecture::Junction.new.tap do |junction|
|
|
75
|
+
junction.id = text(data[:id])
|
|
76
|
+
junction.group_id = text(data[:group]) if data.key?(:group)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def edge_model(data)
|
|
81
|
+
Diagram::Architecture::Edge.new.tap do |edge|
|
|
82
|
+
assign(edge, data, EDGE_ATTRIBUTES)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def assign(model, data, attributes)
|
|
87
|
+
attributes.each do |target, source|
|
|
88
|
+
next unless data.key?(source)
|
|
89
|
+
|
|
90
|
+
model.public_send("#{target}=", text(data[source]))
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# A reference or position wraps its capture in a one-key Hash.
|
|
95
|
+
def text(node)
|
|
96
|
+
node = node.values.first if node.is_a?(Hash)
|
|
97
|
+
Text.of(node).strip
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|