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,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Etassia
|
|
4
|
+
module Notation
|
|
5
|
+
module PlantUMLData
|
|
6
|
+
module Boxes
|
|
7
|
+
# The `#highlight "a" / "b" <<class>>` lines of a JSON or YAML
|
|
8
|
+
# diagram and the `<style>` that colours them.
|
|
9
|
+
class Highlights
|
|
10
|
+
DIRECTIVE = /\A#highlight[ \t]+(.+?)(?:[ \t]+<<(\w+)>>)?\z/i
|
|
11
|
+
STYLE = %r{<style>(.*?)</style>}mi
|
|
12
|
+
RULE = /([.\w]+)[ \t]*\{([^{}]*)\}/
|
|
13
|
+
FIELDS = { "backgroundcolor" => :background, "fontcolor" => :color,
|
|
14
|
+
"fontstyle" => :style }.freeze
|
|
15
|
+
DEFAULT = { background: "#CCFF02", color: "#000000",
|
|
16
|
+
style: nil }.freeze
|
|
17
|
+
private_constant :DIRECTIVE, :STYLE, :RULE, :FIELDS, :DEFAULT
|
|
18
|
+
|
|
19
|
+
# Splits the highlight lines and style off the data.
|
|
20
|
+
#
|
|
21
|
+
# @param text [String] the lines between `@start` and `@end`
|
|
22
|
+
# @return [Array(Highlights, String)] the highlights and the rest
|
|
23
|
+
def self.extract(text)
|
|
24
|
+
styles = text.scan(STYLE).flatten.join("\n")
|
|
25
|
+
rest = text.gsub(STYLE, "")
|
|
26
|
+
lines, data = rest.lines.partition { |l| DIRECTIVE.match?(l.strip) }
|
|
27
|
+
[new(lines.map(&:strip), styles), data.join]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def initialize(directives = [], style_text = "")
|
|
31
|
+
@styles = parse_styles(style_text)
|
|
32
|
+
@paths = directives.map { |line| parse_directive(line) }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @param path [Array<String>] keys from the root to a row
|
|
36
|
+
# @return [Hash, nil] `:background`, `:color` and `:style`
|
|
37
|
+
def style_for(path)
|
|
38
|
+
found = @paths.find { |keys, _| keys == path }
|
|
39
|
+
found && style_of(found.last)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def parse_directive(line)
|
|
45
|
+
body, name = DIRECTIVE.match(line).captures
|
|
46
|
+
[body.scan(/"((?:[^"\\]|\\.)*)"/).flatten, name]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def style_of(name)
|
|
50
|
+
DEFAULT.merge(@styles.fetch(name, @styles.fetch("highlight", {})))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def parse_styles(text)
|
|
54
|
+
text.scan(RULE).to_h do |selector, body|
|
|
55
|
+
[selector.delete_prefix("."), fields(body)]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def fields(body)
|
|
60
|
+
body.lines.filter_map do |line|
|
|
61
|
+
name, value = line.strip.split(/[ \t]+/, 2)
|
|
62
|
+
field = FIELDS[name.to_s.downcase]
|
|
63
|
+
[field, value.strip] if field && value
|
|
64
|
+
end.to_h
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "marks"
|
|
4
|
+
require_relative "text"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Notation
|
|
8
|
+
module PlantUMLData
|
|
9
|
+
module Boxes
|
|
10
|
+
# Measures and draws the rows of a `json` element mixed into another
|
|
11
|
+
# diagram. PlantUML draws such an element as one box: a nested object
|
|
12
|
+
# or array fills the value cell of its row as rows of its own, and
|
|
13
|
+
# an object keeps a key column of its own width.
|
|
14
|
+
module InlineRows
|
|
15
|
+
extend self
|
|
16
|
+
|
|
17
|
+
ROW = 20.4883
|
|
18
|
+
PAD = 5.0
|
|
19
|
+
|
|
20
|
+
# @return [Float] the key column width plus the widest value cell
|
|
21
|
+
def width(rows)
|
|
22
|
+
key_width(rows) + (rows.map { |row| cell_width(row) }.max || 0.0)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @return [Float] what the rows stack to
|
|
26
|
+
def height(rows)
|
|
27
|
+
rows.sum { |row| row.inline ? height(row.inline.rows) : ROW }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @return [Float] the key column's width, 0 when no row is keyed
|
|
31
|
+
def key_width(rows)
|
|
32
|
+
return 0.0 unless rows.any?(&:key)
|
|
33
|
+
|
|
34
|
+
rows.filter_map { |row| Text.width(row.key) if row.key }.max +
|
|
35
|
+
(2 * PAD)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @param width [Float] what the rows fill, at least {#width}
|
|
39
|
+
# @return [Array<Hash>] the marks of rows whose corner is at
|
|
40
|
+
# `left`, `top`
|
|
41
|
+
def draw(rows, left, top, width)
|
|
42
|
+
keys = key_width(rows)
|
|
43
|
+
split = left + keys
|
|
44
|
+
marks = keys.positive? ? divider(split, top, height(rows)) : []
|
|
45
|
+
rows.each_with_index.reduce([top, marks]) do |(y, out), (row, i)|
|
|
46
|
+
out.concat(row_marks(row, [left, y, width], split, i))
|
|
47
|
+
[y + row_height(row), out]
|
|
48
|
+
end.last
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def cell_width(row)
|
|
54
|
+
return width(row.inline.rows) if row.inline
|
|
55
|
+
|
|
56
|
+
Text.width(row.value) + (2 * PAD)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def row_height(row)
|
|
60
|
+
row.inline ? height(row.inline.rows) : ROW
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def divider(split, top, height)
|
|
64
|
+
[Marks.line([split, top], [split, top + height],
|
|
65
|
+
stroke: Marks::INK)]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def row_marks(row, frame, split, index)
|
|
69
|
+
left, top, width = frame
|
|
70
|
+
[*rule(left, top, width, index),
|
|
71
|
+
*key_mark(row, left, top),
|
|
72
|
+
*value_marks(row, [split, top, left + width])]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def rule(left, top, width, index)
|
|
76
|
+
return [] unless index.positive?
|
|
77
|
+
|
|
78
|
+
[Marks.line([left, top], [left + width, top], stroke: Marks::INK)]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def key_mark(row, left, top)
|
|
82
|
+
return [] unless row.key
|
|
83
|
+
|
|
84
|
+
[Marks.text(row.key, left + PAD, top + (ROW / 2))]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def value_marks(row, frame)
|
|
88
|
+
split, top, right = frame
|
|
89
|
+
if row.inline
|
|
90
|
+
return draw(row.inline.rows, split, top, right - split)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
[Marks.text(row.value, split + PAD, top + (ROW / 2))]
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require_relative "../../../error/parse_error"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Notation
|
|
8
|
+
module PlantUMLData
|
|
9
|
+
module Boxes
|
|
10
|
+
# Reads the JSON of a `@startjson` diagram.
|
|
11
|
+
class JsonReader
|
|
12
|
+
# @return [Hash, Array, String, Numeric, true, false, nil]
|
|
13
|
+
# @raise [Etassia::Parser::ParseError] when the text is not JSON
|
|
14
|
+
def call(text)
|
|
15
|
+
JSON.parse(text, max_nesting: 100, allow_nan: false)
|
|
16
|
+
rescue JSON::ParserError => e
|
|
17
|
+
raise Etassia::Parser::ParseError,
|
|
18
|
+
"Parse error: JSON: #{e.message[0, 120]}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "marks"
|
|
4
|
+
require_relative "text"
|
|
5
|
+
require_relative "../../../text_measurement"
|
|
6
|
+
require_relative "../../plantuml/label_clearance"
|
|
7
|
+
|
|
8
|
+
module Etassia
|
|
9
|
+
module Notation
|
|
10
|
+
module PlantUMLData
|
|
11
|
+
module Boxes
|
|
12
|
+
# The texts of a relation, placed as the JAR does: the label of a
|
|
13
|
+
# steep line starts just right of its middle, the label of a flat one
|
|
14
|
+
# is centred on its middle with its foot on the line's highest point
|
|
15
|
+
# under it, the text of an end finishes just left of it, a line's
|
|
16
|
+
# height from that end.
|
|
17
|
+
module LinkText
|
|
18
|
+
extend self
|
|
19
|
+
|
|
20
|
+
LABEL_GAP = 1.0
|
|
21
|
+
LABEL_DROP = 5.2
|
|
22
|
+
END_GAP = 1.4
|
|
23
|
+
TAIL_DROP = 20.2
|
|
24
|
+
HEAD_RISE = 10.4
|
|
25
|
+
# How far right of the middle a flat line's label is centred, and
|
|
26
|
+
# how far its baseline rises over the line (0.264 of the font).
|
|
27
|
+
FLAT_SHIFT = 2.8
|
|
28
|
+
FLAT_RISE = 3.7
|
|
29
|
+
|
|
30
|
+
# @return [Array<Hash>] text marks for `link`, drawn from `start`
|
|
31
|
+
# to `stop`
|
|
32
|
+
def call(link, start, stop)
|
|
33
|
+
[label(link, start, stop), tail(link, start),
|
|
34
|
+
head(link, stop)].compact
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def label(link, start, stop)
|
|
40
|
+
return if link.label.to_s.empty?
|
|
41
|
+
return flat_label(link.label, start, stop) if flat?(start, stop)
|
|
42
|
+
|
|
43
|
+
steep_label(link.label, start, stop)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def flat?(start, stop)
|
|
47
|
+
(stop[0] - start[0]).abs > (stop[1] - start[1]).abs
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def flat_label(content, start, stop)
|
|
51
|
+
centre = ((start[0] + stop[0]) / 2) + FLAT_SHIFT
|
|
52
|
+
half = width_of(content) / 2
|
|
53
|
+
top = PlantUML::LabelClearance.top_between(
|
|
54
|
+
start, stop, centre - half, centre + half
|
|
55
|
+
)
|
|
56
|
+
text(content, centre, top - FLAT_RISE, "middle")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Right of the line, past its furthest point under the text.
|
|
60
|
+
def steep_label(content, start, stop)
|
|
61
|
+
middle = ((start[1] + stop[1]) / 2) + LABEL_DROP
|
|
62
|
+
reach = PlantUML::LabelClearance.right_between(
|
|
63
|
+
start, stop, middle - Text::FONT_SIZE, middle
|
|
64
|
+
)
|
|
65
|
+
text(content, [reach, (start[0] + stop[0]) / 2].max + LABEL_GAP,
|
|
66
|
+
middle)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Measured in DejaVu Sans, the face the picture is drawn in.
|
|
70
|
+
def width_of(content)
|
|
71
|
+
TextMeasurement.measure_in(:dejavu, Text.plain(content),
|
|
72
|
+
font_size: Text::FONT_SIZE)[:width]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def tail(link, start)
|
|
76
|
+
text(link.tail_text, start[0] - END_GAP, start[1] + TAIL_DROP,
|
|
77
|
+
"end")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def head(link, stop)
|
|
81
|
+
text(link.head_text, stop[0] - END_GAP, stop[1] - HEAD_RISE, "end")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def text(content, left, baseline, anchor = nil)
|
|
85
|
+
return if content.to_s.empty?
|
|
86
|
+
|
|
87
|
+
Marks.text(content, left, baseline - Marks::BASELINE,
|
|
88
|
+
anchor: anchor)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "text"
|
|
4
|
+
|
|
5
|
+
module Etassia
|
|
6
|
+
module Notation
|
|
7
|
+
module PlantUMLData
|
|
8
|
+
module Boxes
|
|
9
|
+
# Builds the marks both layouts draw boxes, rules, text and arrows
|
|
10
|
+
# with. PlantUML's palette: grey fill, black ink.
|
|
11
|
+
module Marks
|
|
12
|
+
extend self
|
|
13
|
+
|
|
14
|
+
INK = "#181818"
|
|
15
|
+
BLACK = "#000000"
|
|
16
|
+
PAPER = "#F1F1F1"
|
|
17
|
+
# How far a text's baseline lies below its vertical middle.
|
|
18
|
+
BASELINE = 5.5
|
|
19
|
+
|
|
20
|
+
def rect(left, top, width, height, **style)
|
|
21
|
+
{ kind: :rect, x: left, y: top, width: width, height: height,
|
|
22
|
+
rx: 5, fill: PAPER, stroke: INK, stroke_width: 1.5 }.merge(style)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def line(from, to, stroke: BLACK, width: 1)
|
|
26
|
+
{ kind: :line, x1: from[0], y1: from[1], x2: to[0], y2: to[1],
|
|
27
|
+
stroke: stroke, stroke_width: width }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @param middle [Float] the y of the text's vertical middle
|
|
31
|
+
# @param style [Hash] bold, italic, fill and anchor
|
|
32
|
+
def text(content, left, middle, **style)
|
|
33
|
+
{ kind: :text, content: content, x: left, y: middle + BASELINE,
|
|
34
|
+
bold: false, italic: false, fill: BLACK, anchor: nil }
|
|
35
|
+
.merge(style)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def curve(from, to, dashed: false, stroke: BLACK)
|
|
39
|
+
{ kind: :path, d: bezier(from, to), dashed: dashed,
|
|
40
|
+
stroke: stroke }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def polygon(points, fill: BLACK, stroke: fill)
|
|
44
|
+
{ kind: :polygon, points: points, fill: fill, stroke: stroke }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# The small notched arrow PlantUML ends a tree link with: 7.6 long,
|
|
48
|
+
# 6.1 wide, notched 2.3 in from its base; filled, never outlined.
|
|
49
|
+
def arrowhead(tip)
|
|
50
|
+
x, y = tip
|
|
51
|
+
polygon([[x - 7.6, y - 3.0], [x - 5.3, y], [x - 7.6, y + 3.0], tip],
|
|
52
|
+
fill: BLACK, stroke: "none")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def dot(centre)
|
|
56
|
+
{ kind: :circle, cx: centre[0], cy: centre[1], r: 3, fill: BLACK }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def bezier(from, to)
|
|
62
|
+
start, *rest = [from, *handles(from, to), to].map do |point|
|
|
63
|
+
point.join(" ")
|
|
64
|
+
end
|
|
65
|
+
"M #{start} C #{rest.join(' ')}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def handles(from, to)
|
|
69
|
+
reach = [(to[0] - from[0]).abs / 2.0, 13.0].max
|
|
70
|
+
[[from[0] + reach, from[1]], [to[0] - reach, to[1]]]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "marks"
|
|
4
|
+
require_relative "text"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Notation
|
|
8
|
+
module PlantUMLData
|
|
9
|
+
module Boxes
|
|
10
|
+
# What a cell's markup draws that a text element cannot: the
|
|
11
|
+
# background of `<back:..>`, the coloured line of `<s:..>` and
|
|
12
|
+
# `<u:..>`, an Open Iconic glyph, and a placeholder where an emoji
|
|
13
|
+
# goes (Twemoji is CC-BY 4.0 and its set is too large to bundle).
|
|
14
|
+
module Ornaments
|
|
15
|
+
extend self
|
|
16
|
+
|
|
17
|
+
# Open Iconic outlines sit on an 8 grid; PlantUML scales them by
|
|
18
|
+
# the font size over this.
|
|
19
|
+
ICON_SCALE = 12.0
|
|
20
|
+
ICON_LIFT = 9.88
|
|
21
|
+
ICON_NUDGE = 0.75
|
|
22
|
+
BACK_LIFT = 13.0
|
|
23
|
+
BACK_HEIGHT = 16.5
|
|
24
|
+
STRIKE_LIFT = 3.5
|
|
25
|
+
UNDER_DROP = 1.0
|
|
26
|
+
EMOJI_BOX = 14.0
|
|
27
|
+
DRAWN = %i[back strike_colour underline_colour icon emoji].freeze
|
|
28
|
+
private_constant :DRAWN
|
|
29
|
+
# @return [Array<Hash>] the marks to draw under a text mark
|
|
30
|
+
def behind(mark)
|
|
31
|
+
each_piece(mark).filter_map do |piece, left, right|
|
|
32
|
+
colour = piece.style[:back]
|
|
33
|
+
next unless colour
|
|
34
|
+
|
|
35
|
+
Marks.rect(left, mark[:y] - BACK_LIFT, right - left, BACK_HEIGHT,
|
|
36
|
+
rx: 0, fill: css(colour), stroke: "none",
|
|
37
|
+
stroke_width: 0)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [Array<Hash>] the marks to draw over a text mark
|
|
42
|
+
def over(mark)
|
|
43
|
+
each_piece(mark).flat_map do |piece, left, right|
|
|
44
|
+
[*picture(piece, mark, left, right),
|
|
45
|
+
*rule(piece, :strike_colour, mark[:y] - STRIKE_LIFT,
|
|
46
|
+
[left, right]),
|
|
47
|
+
*rule(piece, :underline_colour, mark[:y] + UNDER_DROP,
|
|
48
|
+
[left, right])]
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def each_piece(mark)
|
|
55
|
+
return [] unless mark[:kind] == :text && mark[:content]
|
|
56
|
+
|
|
57
|
+
runs = Text.runs(mark[:content])
|
|
58
|
+
return [] if runs.all? { |piece| plain?(piece) }
|
|
59
|
+
|
|
60
|
+
spans(runs, mark)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def plain?(piece)
|
|
64
|
+
!piece.style.keys.intersect?(DRAWN)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def spans(runs, mark)
|
|
68
|
+
widths = runs.map { |piece| Text.width(piece.text) }
|
|
69
|
+
left = mark[:x] - anchor_shift(mark[:anchor], widths.sum)
|
|
70
|
+
runs.zip(widths).map do |piece, width|
|
|
71
|
+
span = [piece, left, left + width]
|
|
72
|
+
left += width
|
|
73
|
+
span
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def anchor_shift(anchor, total)
|
|
78
|
+
anchor == "middle" ? total / 2 : 0.0
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def rule(piece, key, height, span)
|
|
82
|
+
return [] unless piece.style[key]
|
|
83
|
+
|
|
84
|
+
[Marks.line([span[0], height], [span[1], height],
|
|
85
|
+
stroke: css(piece.style[key]), width: 0.5)]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def picture(piece, mark, left, right)
|
|
89
|
+
if piece.style[:icon]
|
|
90
|
+
[icon(piece.style[:icon], left, mark[:y], mark[:fill])]
|
|
91
|
+
elsif piece.style[:emoji]
|
|
92
|
+
[placeholder(left, right, mark[:y])]
|
|
93
|
+
else
|
|
94
|
+
[]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def icon(name, left, baseline, fill)
|
|
99
|
+
{ kind: :glyph, d: outline(name),
|
|
100
|
+
fill: fill,
|
|
101
|
+
transform: place(left + ICON_NUDGE, baseline - ICON_LIFT) }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Loaded on first use, like {Text}: `require "etassia"` must not
|
|
105
|
+
# define the PlantUML namespace.
|
|
106
|
+
def outline(name)
|
|
107
|
+
require_relative "../../plantuml/creole_icons"
|
|
108
|
+
Etassia::Notation::PlantUML::Creole::Icons.outline(name)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def place(left, top)
|
|
112
|
+
format("translate(%<x>.4f %<y>.4f) scale(%<k>.4f)",
|
|
113
|
+
x: left, y: top, k: Text::FONT_SIZE / ICON_SCALE)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def placeholder(left, right, baseline)
|
|
117
|
+
side = EMOJI_BOX
|
|
118
|
+
Marks.rect(left + ((right - left - side) / 2), baseline - side,
|
|
119
|
+
side, side, rx: 3, fill: "none", stroke: Marks::INK,
|
|
120
|
+
stroke_width: 0.5)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def css(colour)
|
|
124
|
+
colour.match?(/\A\h{3}(?:\h{3})?\z/) ? "##{colour}" : colour
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../../../renderer/base"
|
|
4
|
+
require_relative "../../../svg"
|
|
5
|
+
require_relative "ornaments"
|
|
6
|
+
require_relative "text"
|
|
7
|
+
|
|
8
|
+
module Etassia
|
|
9
|
+
module Notation
|
|
10
|
+
module PlantUMLData
|
|
11
|
+
module Boxes
|
|
12
|
+
# Draws a {Scene} the way PlantUML does: grey boxes with black
|
|
13
|
+
# rules, dashed links in a JSON or YAML tree.
|
|
14
|
+
class Renderer < Etassia::Renderer::Base
|
|
15
|
+
FONT = "sans-serif"
|
|
16
|
+
private_constant :FONT
|
|
17
|
+
|
|
18
|
+
# @param scene [Scene]
|
|
19
|
+
# @return [Svg::Document]
|
|
20
|
+
def render(scene)
|
|
21
|
+
Svg::Document.new(width: scene.width, height: scene.height,
|
|
22
|
+
view_box: scene.view_box).tap do |document|
|
|
23
|
+
scene.marks.each do |mark|
|
|
24
|
+
[*Ornaments.behind(mark), mark, *Ornaments.over(mark)]
|
|
25
|
+
.each { |piece| document << draw(piece) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def draw(mark)
|
|
33
|
+
send(:"draw_#{mark[:kind]}", mark)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def element(type, **attributes)
|
|
37
|
+
type.new.tap do |node|
|
|
38
|
+
attributes.each do |name, value|
|
|
39
|
+
node.public_send(:"#{name}=", value) unless value.nil?
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def draw_rect(mark)
|
|
45
|
+
element(Svg::Rect, **mark.slice(:x, :y, :width, :height, :rx, :fill,
|
|
46
|
+
:stroke, :stroke_width),
|
|
47
|
+
ry: mark[:rx])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def draw_line(mark)
|
|
51
|
+
element(Svg::Line,
|
|
52
|
+
**mark.slice(:x1, :y1, :x2, :y2, :stroke, :stroke_width))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def draw_text(mark)
|
|
56
|
+
element(Svg::Text, x: mark[:x], y: mark[:y], fill: mark[:fill],
|
|
57
|
+
font_family: FONT, font_size: "14",
|
|
58
|
+
font_weight: ("bold" if mark[:bold]),
|
|
59
|
+
font_style: ("italic" if mark[:italic]),
|
|
60
|
+
text_anchor: mark[:anchor])
|
|
61
|
+
.tap { |text| Text.assign(text, mark[:content]) }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def draw_path(mark)
|
|
65
|
+
element(Svg::Path, d: mark[:d], fill: "none", stroke: mark[:stroke],
|
|
66
|
+
stroke_width: "1",
|
|
67
|
+
stroke_dasharray: dashes(mark))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def dashes(mark)
|
|
71
|
+
mark[:dash] || "3,3" if mark[:dashed]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def draw_glyph(mark)
|
|
75
|
+
element(Svg::Path, d: mark[:d], fill: mark[:fill],
|
|
76
|
+
transform: mark[:transform])
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def draw_polygon(mark)
|
|
80
|
+
element(Svg::Polygon, points: Svg::Polygon.build_points(mark[:points]),
|
|
81
|
+
fill: mark[:fill], stroke: mark[:stroke],
|
|
82
|
+
stroke_width: "1")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def draw_circle(mark)
|
|
86
|
+
element(Svg::Circle, cx: mark[:cx], cy: mark[:cy], r: mark[:r],
|
|
87
|
+
fill: mark[:fill],
|
|
88
|
+
stroke: mark.fetch(:stroke, mark[:fill]),
|
|
89
|
+
stroke_width: "1")
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Etassia
|
|
4
|
+
module Notation
|
|
5
|
+
module PlantUMLData
|
|
6
|
+
module Boxes
|
|
7
|
+
# Where the JAR stands a box that is alone in its rank and linked
|
|
8
|
+
# with a row of a map: beside the side its line leaves by, or, when
|
|
9
|
+
# it is the one linking to the row, over the middle of the map.
|
|
10
|
+
class RowAlignment
|
|
11
|
+
# How far from the side of a map the middle of such a box lies.
|
|
12
|
+
DRIFT = 5.5
|
|
13
|
+
|
|
14
|
+
# @param links [Array<Link>]
|
|
15
|
+
def initialize(links)
|
|
16
|
+
@links = links
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @param rects [Hash{String => Rect}] each box where it stands
|
|
20
|
+
# @param alone [Array<String>] the boxes alone in their rank
|
|
21
|
+
# @return [Hash{String => Rect}] `rects`, the alone boxes moved
|
|
22
|
+
# across
|
|
23
|
+
def call(rects, alone)
|
|
24
|
+
rects.to_h do |id, rect|
|
|
25
|
+
middle = alone.include?(id) && middle_of(id, rects)
|
|
26
|
+
[id, middle ? rect.with(x: middle - (rect.width / 2)) : rect]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def middle_of(id, rects)
|
|
33
|
+
from_row(id, rects) || over_map(id, rects)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def from_row(id, rects)
|
|
37
|
+
link = @links.find { |l| l.to == id && l.from_row.is_a?(String) }
|
|
38
|
+
link && side(link, rects.fetch(link.from))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def over_map(id, rects)
|
|
42
|
+
link = @links.find { |l| l.from == id && l.to_row }
|
|
43
|
+
link && rects.fetch(link.to).centre[0]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Just past the side a map's row leaves by: the left one when
|
|
47
|
+
# another line already ends at the row, otherwise the right.
|
|
48
|
+
def side(link, rect)
|
|
49
|
+
taken = @links.any? do |other|
|
|
50
|
+
other.to == link.from && other.to_row == link.from_row
|
|
51
|
+
end
|
|
52
|
+
taken ? rect.x - DRIFT : rect.right + DRIFT
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Etassia
|
|
4
|
+
module Notation
|
|
5
|
+
module PlantUMLData
|
|
6
|
+
module Boxes
|
|
7
|
+
# The two handles of the spline a link to or from a map row is drawn
|
|
8
|
+
# as: it leaves a row by its side, square to it, and meets a box edge
|
|
9
|
+
# head on.
|
|
10
|
+
module RowBend
|
|
11
|
+
extend self
|
|
12
|
+
|
|
13
|
+
REACH = 30.0
|
|
14
|
+
EASE = 0.35
|
|
15
|
+
|
|
16
|
+
# @param ends [Array<Array<Float>>] where the line starts and stops
|
|
17
|
+
# @param rows [Array<Boolean>] whether each end is a row of its box
|
|
18
|
+
# @param centres [Array<Array<Float>>] the middle of each end's box
|
|
19
|
+
# @return [Array<Array<Float>>] the handle of the start, then of
|
|
20
|
+
# the stop
|
|
21
|
+
def handles(ends, rows, centres)
|
|
22
|
+
[0, 1].map do |at|
|
|
23
|
+
point = ends[at]
|
|
24
|
+
other = ends[1 - at]
|
|
25
|
+
next square(point, other, centres[at]) if rows[at]
|
|
26
|
+
|
|
27
|
+
[point[0], point[1] + ((other[1] - point[1]) * EASE)]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
# A point out from the side of the box `point` is on.
|
|
34
|
+
def square(point, other, centre)
|
|
35
|
+
reach = [(other[0] - point[0]).abs / 2, REACH].max
|
|
36
|
+
side = point[0] >= centre[0] ? 1 : -1
|
|
37
|
+
[point[0] + (side * reach), point[1]]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|