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,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
require_relative "element"
|
|
5
|
+
|
|
6
|
+
module Etassia
|
|
7
|
+
module Svg
|
|
8
|
+
# SVG Tspan element <tspan>
|
|
9
|
+
#
|
|
10
|
+
# One styled run inside a <text> element: a bold or italic word, or the
|
|
11
|
+
# start of a new line after a hard line break. Only the attributes a
|
|
12
|
+
# markdown run actually needs — position resets (`x`, `y`) and per-run
|
|
13
|
+
# styling (`font-weight`, `font-style`, and for creole runs `font-family`,
|
|
14
|
+
# `font-size` and `text-decoration`; `fill` is a base attribute).
|
|
15
|
+
#
|
|
16
|
+
# `dy` is not an attribute: the :metanorma profile rejects it on a
|
|
17
|
+
# tspan. A run starting a new line sets `line_shift` instead, and the
|
|
18
|
+
# parent Text turns it into an absolute `y` (see Text#place_lines).
|
|
19
|
+
# Everything else (font family/size, fill, text-anchor) is inherited
|
|
20
|
+
# from the parent <text> element and never repeated here.
|
|
21
|
+
class Tspan < Element
|
|
22
|
+
attribute :x, :float
|
|
23
|
+
attribute :y, :float
|
|
24
|
+
# Lines below the previous placed run; never written to the SVG.
|
|
25
|
+
attribute :line_shift, :integer
|
|
26
|
+
attribute :font_weight, :string
|
|
27
|
+
attribute :font_style, :string
|
|
28
|
+
attribute :font_family, :string
|
|
29
|
+
attribute :font_size, :string
|
|
30
|
+
attribute :text_decoration, :string
|
|
31
|
+
attribute :content, :string, collection: true
|
|
32
|
+
|
|
33
|
+
writes_attributes :x, :y, :font_weight, :font_style, :font_family,
|
|
34
|
+
:font_size, :text_decoration
|
|
35
|
+
|
|
36
|
+
protected
|
|
37
|
+
|
|
38
|
+
# `content` is declared `collection: true`, so join rather than
|
|
39
|
+
# interpolate.
|
|
40
|
+
#
|
|
41
|
+
# @return [String] XML string
|
|
42
|
+
def element_markup
|
|
43
|
+
escaped_content = Escaping.escape_text(Array(content).join)
|
|
44
|
+
"<tspan#{build_attributes}>#{escaped_content}</tspan>"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/etassia/svg.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "svg/escaping"
|
|
4
|
+
require_relative "svg/numbers"
|
|
5
|
+
require_relative "svg/path_geometry"
|
|
6
|
+
require_relative "svg/style"
|
|
7
|
+
require_relative "svg/element"
|
|
8
|
+
require_relative "svg/document"
|
|
9
|
+
require_relative "svg/group"
|
|
10
|
+
require_relative "svg/rect"
|
|
11
|
+
require_relative "svg/circle"
|
|
12
|
+
require_relative "svg/line"
|
|
13
|
+
require_relative "svg/polygon"
|
|
14
|
+
require_relative "svg/arrowhead"
|
|
15
|
+
require_relative "svg/path"
|
|
16
|
+
require_relative "svg/polyline"
|
|
17
|
+
require_relative "svg/tspan"
|
|
18
|
+
require_relative "svg/text"
|
|
19
|
+
require_relative "svg/ellipse"
|
|
20
|
+
|
|
21
|
+
module Etassia
|
|
22
|
+
# The SVG document model. Everything Etassia writes into an SVG goes
|
|
23
|
+
# through these classes.
|
|
24
|
+
module Svg
|
|
25
|
+
# The svg_conform profile Etassia's output is built to satisfy.
|
|
26
|
+
#
|
|
27
|
+
# Requires a viewBox, rejects @import/<link>/external images, and
|
|
28
|
+
# enforces the SVG Tiny 1.2 element/attribute table -- but does not
|
|
29
|
+
# by itself guarantee self-containment: an external
|
|
30
|
+
# <?xml-stylesheet?> PI still validates clean under it. Nothing
|
|
31
|
+
# Etassia emits produces one; spec/etassia/svg_conformance_spec.rb holds
|
|
32
|
+
# that line -- don't drop it assuming the profile alone covers it.
|
|
33
|
+
#
|
|
34
|
+
# :svg_1_2_rfc restricts colour/fonts and would erase themes -- not
|
|
35
|
+
# a drop-in equivalent.
|
|
36
|
+
CONFORMANCE_PROFILE = :metanorma
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# GENERATED by scripts/generate_text_advances.rb; do not edit by hand.
|
|
4
|
+
#
|
|
5
|
+
# Horizontal advance widths in per-mille em, read from the hmtx table of
|
|
6
|
+
# Liberation Sans Regular (SIL OFL 1.1), which is metric-compatible with
|
|
7
|
+
# Arial and Helvetica. Cross-checked against Arial where it has the glyph:
|
|
8
|
+
# a codepoint where the two differ by more than 1/1000 em is
|
|
9
|
+
# absent here, not guessed.
|
|
10
|
+
# Advances are numeric facts about a glyph, not a copy of any font.
|
|
11
|
+
module Etassia
|
|
12
|
+
class TextMeasurement
|
|
13
|
+
module ArialAdvances
|
|
14
|
+
# A line "U+XXXX: a b c" starts a run at that codepoint; every number
|
|
15
|
+
# is the advance of the next consecutive codepoint, and a line without
|
|
16
|
+
# a marker continues the previous run.
|
|
17
|
+
DATA = <<~RUNS
|
|
18
|
+
U+0020: 278 278 355 556 556 889 667 191 333 333 389 584 278 333 278 278
|
|
19
|
+
556 556 556 556 556 556 556 556 556 556 278 278 584 584 584 556
|
|
20
|
+
1015 667 667 722 722 667 611 778 722 278 500 667 556 833 722 778
|
|
21
|
+
667 778 722 667 611 722 667 944 667 667 611 278 278 278 469 556
|
|
22
|
+
333 556 556 500 556 556 278 556 556 222 222 500 222 833 556 556
|
|
23
|
+
556 556 333 500 278 556 500 722 500 500 500 334 260 334 584
|
|
24
|
+
U+00A0: 278 333 556 556 556 556 260 556 333 737 370 556 584 333 737 552
|
|
25
|
+
400 549 333 333 333 576 537 333 333 333 365 556 834 834 834 611
|
|
26
|
+
667 667 667 667 667 667 1000 722 667 667 667 667 278 278 278 278
|
|
27
|
+
722 722 778 778 778 778 778 584 778 722 722 722 722 667 667 611
|
|
28
|
+
556 556 556 556 556 556 889 500 556 556 556 556 278 278 278 278
|
|
29
|
+
556 556 556 556 556 556 556 549 611 556 556 556 556 500 556 500
|
|
30
|
+
667 556 667 556 667 556 722 500 722 500 722 500 722 500 722 615
|
|
31
|
+
722 556 667 556 667 556 667 556 667 556 667 556 778 556 778 556
|
|
32
|
+
778 556 778 556 722 556 722 556 278 278 278 278 278 278 278 222
|
|
33
|
+
278 278 735 444 500 222 667 500 500 556 222 556 222 556 292 556
|
|
34
|
+
334 556 222 722 556 722 556 722 556 604 723 556 778 556 778 556
|
|
35
|
+
778 556 1000 944 722 333 722 333 722 333 667 500 667 500 667 500
|
|
36
|
+
667 500 611 278 611 375 611 278 722 556 722 556 722 556 722 556
|
|
37
|
+
722 556 722 556 944 722 667 500 667 611 500 611 500 611 500 222
|
|
38
|
+
556 758 656 556 656 556 722 722 500 722 810 656 556 557 667 752
|
|
39
|
+
604 611 556 778 624 881 222 278 667 500 222 500 891 722 556 778
|
|
40
|
+
857 656 868 667 754 556 667 667 500 618 380 278 611 278 611 854
|
|
41
|
+
669 748 722 772 500 611 500 611 611 545 545 556 556 458 487 556
|
|
42
|
+
260 413 584 278 1333 1222 1049 1062 833 451 1222 944 771 667 556 278
|
|
43
|
+
222 778 556 722 556 722 556 722 556 722 556 722 556 556 667 556
|
|
44
|
+
667 556 1000 889 778 556 778 556 667 500 778 556 778 556 611 545
|
|
45
|
+
222 1333 1222 1049 778 556 1034 618 722 556 667 556 1000 889 778 611
|
|
46
|
+
667 556 667 556 667 556 667 556 278 278 278 278 778 556 778 556
|
|
47
|
+
722 333 722 333 722 556 722 556 667 500 611 278 545 437 722 556
|
|
48
|
+
706 682 604 565 611 500 667 556 667 556 778 556 778 556 778 556
|
|
49
|
+
778 556 667 500 349 685 367 222 887 887 667 722 500 556 611 500
|
|
50
|
+
500 581 453 667 722 668 667 556 500 222 737 556 722 333 667 500
|
|
51
|
+
U+0374: 333 333
|
|
52
|
+
U+037A: 333 500 500 500 278
|
|
53
|
+
U+0384: 333 333 667 278 784 838 384
|
|
54
|
+
U+038C: 774
|
|
55
|
+
U+038E: 855 752 222 667 667 551 668 667 611 722 778 278 667 668 833 722
|
|
56
|
+
650 778 722 667
|
|
57
|
+
U+03A3: 618 611 667 798 667 835 748 278 667 578 446 556 222 547 578 575
|
|
58
|
+
500 557 446 441 556 556 222 500 500 576 500 448 556 690 569 482
|
|
59
|
+
617 395 547 648 525 713 781 222 547 556 547 781
|
|
60
|
+
U+03D0: 575 547 772 958 772 560 781 601 778 556 722 500 611 404 625 529
|
|
61
|
+
756 577 891 833 674 556 674 500 667 667 609 596 737 554 464 410
|
|
62
|
+
601 573 500 222 778 442 442 667 556 722 833 688 569 722 722 722
|
|
63
|
+
667 667 865 542 719 667 278 278 500 1057 1010 854 583 719 635 719
|
|
64
|
+
667 656 667 542 677 667 923 604 719 719 583 656 833 722 778 719
|
|
65
|
+
667 722 611 635 760 667 740 667 917 938 792 885 656 719 1010 722
|
|
66
|
+
556 573 531 365 583 556 669 458 559 559 438 583 688 552 556 542
|
|
67
|
+
556 500 458 500 823 500 573 521 802 823 625 719 521 510 750 542
|
|
68
|
+
556 556 556 365 510 500 222 278 222 906 813 556 438 559 500 552
|
|
69
|
+
1338 624 778 613 950 713 668 500 897 695 829 685 1053 867 604 458
|
|
70
|
+
796 688 778 556 803 631 803 631
|
|
71
|
+
U+047A: 833 612 1191 852 1338 624 722 500 503 0 0 0 0 0 0 0
|
|
72
|
+
719 559 656 521 667 556 489 411 542 365 670 549 923 669 604 458
|
|
73
|
+
583 438 583 438 583 438 742 536 722 552 879 648 1137 870 753 521
|
|
74
|
+
722 500 611 458 556 500 556 500 667 500 925 691 667 521 667 521
|
|
75
|
+
667 556 861 666 861 666 278 923 669 667 551 656 583 722 552 722
|
|
76
|
+
552 667 521 833 688 222 667 556 667 556 1000 889 667 556 752 556
|
|
77
|
+
752 556 923 669 604 458 604 545 719 559 719 559 778 556 778 556
|
|
78
|
+
778 556 719 510 635 500 635 500 635 500 667 521 542 365 885 719
|
|
79
|
+
542 365 667 500 667 500
|
|
80
|
+
U+2000: 500 1000 500 1000 333 250 167 556 278 200 83
|
|
81
|
+
U+2010: 333
|
|
82
|
+
U+2012: 556 556 1000 1000 413 552 222 222 222 222 333 333 333 333 556 556
|
|
83
|
+
350
|
|
84
|
+
U+2026: 1000
|
|
85
|
+
U+202F: 200 1000
|
|
86
|
+
U+2032: 188 354 354
|
|
87
|
+
U+2039: 333 333
|
|
88
|
+
U+203C: 500
|
|
89
|
+
U+203E: 333
|
|
90
|
+
U+2044: 167
|
|
91
|
+
U+205E: 278
|
|
92
|
+
U+20A0: 556 722 722 556 556 833 722 1094 1164 944
|
|
93
|
+
U+20AB: 513 556 667 611 1000 521 667 778 667 556 722
|
|
94
|
+
U+20BF: 740
|
|
95
|
+
U+2105: 885
|
|
96
|
+
U+2113: 323
|
|
97
|
+
U+2116: 1073 737
|
|
98
|
+
U+2122: 1000
|
|
99
|
+
U+2126: 768
|
|
100
|
+
U+212E: 600
|
|
101
|
+
U+214D: 943 490
|
|
102
|
+
U+2190: 1000 500 1000 500 1000 500
|
|
103
|
+
U+21A8: 500
|
|
104
|
+
U+21D4: 1000
|
|
105
|
+
RUNS
|
|
106
|
+
|
|
107
|
+
# codepoint => advance in per-mille em
|
|
108
|
+
TABLE = begin
|
|
109
|
+
codepoint = 0
|
|
110
|
+
DATA.each_line.with_object({}) do |line, table|
|
|
111
|
+
start, advances =
|
|
112
|
+
line.include?(":") ? line.split(":", 2) : [nil, line]
|
|
113
|
+
codepoint = start.delete_prefix("U+").to_i(16) if start
|
|
114
|
+
advances.split.each do |advance|
|
|
115
|
+
table[codepoint] = advance.to_i
|
|
116
|
+
codepoint += 1
|
|
117
|
+
end
|
|
118
|
+
end.freeze
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# GENERATED by scripts/generate_dejavu_advances.rb; do not edit by hand.
|
|
4
|
+
#
|
|
5
|
+
# Horizontal advance widths of DejaVu Sans Regular and Bold, in design
|
|
6
|
+
# units of a 2048-unit em, for Basic Latin and Latin-1 through Latin
|
|
7
|
+
# Extended-B. Advances are numeric facts about a glyph, not a copy of any
|
|
8
|
+
# font. Same layout as ArialAdvances::DATA; REGULAR and BOLD hold them
|
|
9
|
+
# in per-mille em.
|
|
10
|
+
module Etassia
|
|
11
|
+
class TextMeasurement
|
|
12
|
+
module DejaVuAdvances
|
|
13
|
+
REGULAR_DATA = <<~RUNS
|
|
14
|
+
U+0020: 651 821 942 1716 1303 1946 1597 563 799 799 1024 1716 651 739 651 690
|
|
15
|
+
1303 1303 1303 1303 1303 1303 1303 1303 1303 1303 690 690 1716 1716 1716 1087
|
|
16
|
+
2048 1401 1405 1430 1577 1294 1178 1587 1540 604 604 1343 1141 1767 1532 1612
|
|
17
|
+
1235 1612 1423 1300 1251 1499 1401 2025 1403 1251 1403 799 690 799 1716 1024
|
|
18
|
+
1024 1255 1300 1126 1300 1260 721 1300 1298 569 569 1186 569 1995 1298 1253
|
|
19
|
+
1300 1300 842 1067 803 1298 1212 1675 1212 1212 1075 1303 690 1303 1716
|
|
20
|
+
U+00A0: 651 821 1303 1303 1303 1303 690 1024 1024 2048 965 1253 1716 739 2048 1024
|
|
21
|
+
1024 1716 821 821 1024 1303 1303 651 1024 821 965 1253 1985 1985 1985 1087
|
|
22
|
+
1401 1401 1401 1401 1401 1401 1995 1430 1294 1294 1294 1294 604 604 604 604
|
|
23
|
+
1587 1532 1612 1612 1612 1612 1612 1716 1612 1499 1499 1499 1499 1251 1239 1290
|
|
24
|
+
1255 1255 1255 1255 1255 1255 2011 1126 1260 1260 1260 1260 569 569 569 569
|
|
25
|
+
1253 1298 1253 1253 1253 1253 1253 1716 1253 1298 1298 1298 1298 1212 1300 1212
|
|
26
|
+
1401 1255 1401 1255 1401 1255 1430 1126 1430 1126 1430 1126 1430 1126 1577 1300
|
|
27
|
+
1587 1300 1294 1260 1294 1260 1294 1260 1294 1260 1294 1260 1587 1300 1587 1300
|
|
28
|
+
1587 1300 1587 1300 1540 1298 1876 1423 604 569 604 569 604 569 604 569
|
|
29
|
+
604 569 1208 1138 604 569 1343 1186 1186 1141 569 1141 569 1141 768 1141
|
|
30
|
+
700 1151 582 1532 1298 1532 1298 1532 1298 1666 1532 1298 1612 1253 1612 1253
|
|
31
|
+
1612 1253 2191 2095 1423 842 1423 842 1423 842 1300 1067 1300 1067 1300 1067
|
|
32
|
+
1300 1067 1251 803 1251 803 1251 803 1499 1298 1499 1298 1499 1298 1499 1298
|
|
33
|
+
1499 1298 1499 1298 2025 1675 1251 1212 1251 1403 1075 1403 1075 1403 1075 721
|
|
34
|
+
1300 1505 1405 1300 1405 1300 1440 1430 1126 1587 1677 1405 1300 1253 1294 1612
|
|
35
|
+
1258 1178 721 1587 1406 2015 724 604 1527 1186 569 1212 1995 1532 1298 1612
|
|
36
|
+
1870 1253 1943 1555 1335 1300 1423 1300 1067 1294 688 803 1251 803 1251 1757
|
|
37
|
+
1298 1565 1476 1523 1496 1403 1075 1364 1364 1183 1075 1303 1364 1183 1045 1300
|
|
38
|
+
604 1008 940 605 2912 2660 2364 1711 1611 935 1907 1892 1633 1401 1255 604
|
|
39
|
+
569 1612 1253 1499 1298 1499 1298 1499 1298 1499 1298 1499 1298 1260 1401 1255
|
|
40
|
+
1401 1255 1995 2011 1587 1300 1587 1300 1343 1186 1612 1253 1612 1253 1364 1183
|
|
41
|
+
569 2912 2660 2364 1587 1300 2279 1397 1532 1298 1401 1255 1995 2011 1612 1253
|
|
42
|
+
1401 1255 1401 1255 1294 1260 1294 1260 604 569 604 569 1612 1253 1612 1253
|
|
43
|
+
1423 842 1423 842 1499 1298 1499 1298 1300 1067 1251 803 1284 1068 1540 1298
|
|
44
|
+
1506 1716 1430 1250 1403 1075 1401 1255 1294 1260 1612 1253 1612 1253 1612 1253
|
|
45
|
+
1612 1253 1251 1212 972 1726 977 569 2044 2044 1401 1430 1126 1141 1251 1067
|
|
46
|
+
1075 1235 981 1405 1499 1401 1294 1260 604 569 1600 1300 1423 842 1251 1212
|
|
47
|
+
RUNS
|
|
48
|
+
|
|
49
|
+
BOLD_DATA = <<~RUNS
|
|
50
|
+
U+0020: 713 934 1067 1716 1425 2052 1786 627 936 936 1071 1716 778 850 778 748
|
|
51
|
+
1425 1425 1425 1425 1425 1425 1425 1425 1425 1425 819 819 1716 1716 1716 1188
|
|
52
|
+
2048 1585 1561 1503 1700 1399 1399 1681 1714 762 762 1587 1305 2038 1714 1741
|
|
53
|
+
1501 1741 1577 1475 1397 1663 1585 2259 1579 1483 1485 936 748 936 1716 1024
|
|
54
|
+
1024 1382 1466 1214 1466 1389 891 1466 1458 702 702 1362 702 2134 1458 1407
|
|
55
|
+
1466 1466 1010 1219 979 1458 1335 1892 1321 1335 1192 1458 748 1458 1716
|
|
56
|
+
U+00A0: 713 934 1425 1425 1303 1425 748 1024 1024 2048 1155 1323 1716 850 2048 1024
|
|
57
|
+
1024 1716 897 897 1024 1507 1303 778 1024 897 1155 1323 2120 2120 2120 1188
|
|
58
|
+
1585 1585 1585 1585 1585 1585 2222 1503 1399 1399 1399 1399 762 762 762 762
|
|
59
|
+
1716 1714 1741 1741 1741 1741 1741 1716 1741 1663 1663 1663 1663 1483 1511 1473
|
|
60
|
+
1382 1382 1382 1382 1382 1382 2146 1214 1389 1389 1389 1389 702 702 702 702
|
|
61
|
+
1407 1458 1407 1407 1407 1407 1407 1716 1407 1458 1458 1458 1458 1335 1466 1335
|
|
62
|
+
1585 1382 1585 1382 1585 1382 1503 1214 1503 1214 1503 1214 1503 1214 1700 1466
|
|
63
|
+
1716 1466 1399 1389 1399 1389 1399 1389 1399 1389 1399 1389 1681 1466 1681 1466
|
|
64
|
+
1681 1466 1681 1466 1714 1458 1994 1618 762 702 762 702 762 702 762 702
|
|
65
|
+
762 702 1524 1404 762 702 1587 1362 1362 1305 702 1305 702 1305 982 1305
|
|
66
|
+
1140 1315 760 1714 1458 1714 1458 1714 1458 2013 1714 1458 1741 1407 1741 1407
|
|
67
|
+
1741 1407 2390 2241 1577 1010 1577 1010 1577 1010 1475 1219 1475 1219 1475 1219
|
|
68
|
+
1475 1219 1397 979 1397 979 1397 979 1663 1458 1663 1458 1663 1458 1663 1458
|
|
69
|
+
1663 1458 1663 1458 2259 1892 1483 1335 1483 1485 1192 1485 1192 1485 1192 891
|
|
70
|
+
1466 1661 1561 1466 1561 1466 1503 1503 1214 1716 1800 1550 1466 1408 1399 1739
|
|
71
|
+
1425 1399 891 1681 1624 2140 892 797 1587 1362 738 1212 2134 1714 1458 1741
|
|
72
|
+
1789 1407 2217 1868 1601 1466 1577 1475 1219 1399 1130 979 1447 979 1397 1711
|
|
73
|
+
1458 1741 1666 1633 1594 1485 1192 1582 1582 1312 1192 1425 1582 1312 1173 1466
|
|
74
|
+
762 1349 1114 762 3185 2892 2658 2067 2007 1404 2476 2416 2160 1585 1382 762
|
|
75
|
+
702 1741 1407 1663 1458 1663 1458 1663 1458 1663 1458 1663 1458 1389 1585 1382
|
|
76
|
+
1585 1382 2222 2146 1681 1466 1681 1466 1587 1362 1741 1407 1741 1407 1582 1192
|
|
77
|
+
702 3185 2892 2658 1681 1466 2639 1612 1714 1458 1585 1382 2222 2146 1741 1407
|
|
78
|
+
1585 1382 1585 1382 1399 1389 1399 1389 762 702 762 702 1741 1407 1741 1407
|
|
79
|
+
1577 1010 1577 1010 1663 1458 1663 1458 1475 1219 1397 979 1414 1244 1714 1458
|
|
80
|
+
1714 1771 1657 1349 1485 1192 1585 1382 1399 1389 1741 1407 1741 1407 1741 1407
|
|
81
|
+
1741 1407 1483 1335 1007 1775 1048 702 2228 2228 1585 1503 1214 1305 1397 1219
|
|
82
|
+
1192 1601 1258 1561 1663 1585 1399 1389 762 702 1762 1620 1577 1010 1483 1335
|
|
83
|
+
RUNS
|
|
84
|
+
|
|
85
|
+
UNITS_PER_EM = 2048.0
|
|
86
|
+
|
|
87
|
+
# codepoint => advance in per-mille em
|
|
88
|
+
def self.parse(data)
|
|
89
|
+
codepoint = 0
|
|
90
|
+
data.each_line.with_object({}) do |line, table|
|
|
91
|
+
start, values = split(line)
|
|
92
|
+
codepoint = start.delete_prefix("U+").to_i(16) if start
|
|
93
|
+
values.each do |value|
|
|
94
|
+
table[codepoint] = value.to_i * 1000 / UNITS_PER_EM
|
|
95
|
+
codepoint += 1
|
|
96
|
+
end
|
|
97
|
+
end.freeze
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# A run's marker, if the line starts one, and its advances.
|
|
101
|
+
def self.split(line)
|
|
102
|
+
start, values = line.include?(":") ? line.split(":", 2) : [nil, line]
|
|
103
|
+
[start, values.split]
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
REGULAR = parse(REGULAR_DATA)
|
|
107
|
+
BOLD = parse(BOLD_DATA)
|
|
108
|
+
private_class_method :parse, :split
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# GENERATED by scripts/generate_times_advances.rb; do not edit by hand.
|
|
4
|
+
#
|
|
5
|
+
# Horizontal advance widths in per-mille em of Times New Roman Regular,
|
|
6
|
+
# for Basic Latin, Latin-1 through Latin Extended-B and U+FB02. Advances
|
|
7
|
+
# are numeric facts about a glyph, not a copy of any font.
|
|
8
|
+
module Etassia
|
|
9
|
+
class TextMeasurement
|
|
10
|
+
module TimesAdvances
|
|
11
|
+
# Same layout as ArialAdvances::DATA.
|
|
12
|
+
DATA = <<~RUNS
|
|
13
|
+
U+0020: 250 333 408 500 500 833 778 180 333 333 500 564 250 333 250 278
|
|
14
|
+
500 500 500 500 500 500 500 500 500 500 278 278 564 564 564 444
|
|
15
|
+
921 722 667 667 722 611 556 722 722 333 389 722 611 889 722 722
|
|
16
|
+
556 722 667 556 611 722 722 944 722 722 611 333 278 333 469 500
|
|
17
|
+
333 444 500 444 500 444 333 500 500 278 278 500 278 778 500 500
|
|
18
|
+
500 500 333 389 278 500 500 722 500 500 444 480 200 480 541
|
|
19
|
+
U+00A0: 250 333 500 500 500 500 200 500 333 760 276 500 564 333 760 500
|
|
20
|
+
400 549 300 300 333 576 453 333 333 300 310 500 750 750 750 444
|
|
21
|
+
722 722 722 722 722 722 889 667 611 611 611 611 333 333 333 333
|
|
22
|
+
722 722 722 722 722 722 722 564 722 722 722 722 722 722 556 500
|
|
23
|
+
444 444 444 444 444 444 667 444 444 444 444 444 278 278 278 278
|
|
24
|
+
500 500 500 500 500 500 500 549 500 500 500 500 500 500 500 500
|
|
25
|
+
722 444 722 444 722 444 667 444 667 444 667 444 667 444 722 646
|
|
26
|
+
722 500 611 444 611 444 611 444 611 444 611 444 722 500 722 500
|
|
27
|
+
722 500 722 500 722 500 722 500 333 278 333 278 333 278 333 278
|
|
28
|
+
333 278 708 552 389 278 722 500 500 611 278 611 278 611 406 611
|
|
29
|
+
344 611 278 722 500 722 500 722 500 604 702 495 722 500 722 500
|
|
30
|
+
722 500 889 722 667 333 667 333 667 333 556 389 556 389 556 389
|
|
31
|
+
556 389 611 278 611 427 611 278 722 500 722 500 722 500 722 500
|
|
32
|
+
722 500 722 500 944 722 722 500 722 611 444 611 444 611 444 278
|
|
33
|
+
500 760 574 500 574 500 667 667 444 722 815 574 500 471 611 722
|
|
34
|
+
501 556 500 722 722 770 253 333 722 500 278 485 816 722 500 722
|
|
35
|
+
722 529 925 691 650 500 556 556 389 582 344 278 611 278 611 776
|
|
36
|
+
542 743 722 781 500 611 444 539 539 444 444 500 500 443 422 500
|
|
37
|
+
200 281 249 333 1333 1166 944 1000 889 556 1111 1000 778 722 444 333
|
|
38
|
+
278 722 500 722 500 722 500 722 500 722 500 722 500 444 722 444
|
|
39
|
+
722 444 889 667 722 500 722 500 722 500 722 500 722 500 539 444
|
|
40
|
+
278 1333 1166 944 722 500 950 560 722 500 722 444 889 667 722 500
|
|
41
|
+
722 444 722 444 611 444 611 444 333 278 333 278 722 500 722 500
|
|
42
|
+
667 333 667 333 722 500 722 500 556 389 611 278 563 395 722 500
|
|
43
|
+
650 500 604 500 611 444 722 444 611 444 722 500 722 500 722 500
|
|
44
|
+
722 500 722 500 278 500 317 278 774 772 722 667 500 611 611 389
|
|
45
|
+
444 534 397 667 722 725 611 444 389 278 702 500 667 333 722 500
|
|
46
|
+
U+FB02: 556
|
|
47
|
+
RUNS
|
|
48
|
+
|
|
49
|
+
# codepoint => advance in per-mille em
|
|
50
|
+
TABLE = begin
|
|
51
|
+
codepoint = 0
|
|
52
|
+
DATA.each_line.with_object({}) do |line, table|
|
|
53
|
+
start, values =
|
|
54
|
+
line.include?(":") ? line.split(":", 2) : [nil, line]
|
|
55
|
+
codepoint = start.delete_prefix("U+").to_i(16) if start
|
|
56
|
+
values.split.each do |value|
|
|
57
|
+
table[codepoint] = value.to_i
|
|
58
|
+
codepoint += 1
|
|
59
|
+
end
|
|
60
|
+
end.freeze
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# GENERATED by scripts/generate_trebuchet_advances.rb; do not edit by hand.
|
|
4
|
+
#
|
|
5
|
+
# Horizontal advance widths in per-mille em of Trebuchet MS Regular,
|
|
6
|
+
# for Basic Latin and Latin-1 through Latin Extended-B. Advances are
|
|
7
|
+
# numeric facts about a glyph, not a copy of any font.
|
|
8
|
+
module Etassia
|
|
9
|
+
class TextMeasurement
|
|
10
|
+
module TrebuchetAdvances
|
|
11
|
+
# Same layout as ArialAdvances::DATA.
|
|
12
|
+
DATA = <<~RUNS
|
|
13
|
+
U+0020: 301 367 325 524 524 600 706 160 367 367 367 524 367 367 367 524
|
|
14
|
+
524 524 524 524 524 524 524 524 524 524 367 367 524 524 524 367
|
|
15
|
+
771 590 566 598 613 536 525 676 654 278 477 576 506 709 638 674
|
|
16
|
+
558 676 582 481 581 648 587 852 557 570 550 367 355 367 524 524
|
|
17
|
+
524 525 557 495 557 545 370 502 546 285 367 504 295 830 546 537
|
|
18
|
+
557 557 389 405 396 546 490 744 501 493 475 367 524 367 524
|
|
19
|
+
U+00A0: 301 367 524 524 524 570 524 454 524 713 367 524 524 367 713 524
|
|
20
|
+
524 524 451 454 524 546 524 367 524 451 367 524 814 814 814 367
|
|
21
|
+
590 590 590 590 590 590 867 598 536 536 536 536 278 278 278 278
|
|
22
|
+
613 638 674 674 674 674 674 524 657 648 648 648 648 570 556 546
|
|
23
|
+
525 525 525 525 525 525 873 495 545 545 545 545 285 285 285 285
|
|
24
|
+
549 546 537 537 537 537 537 524 545 546 546 546 546 493 553 493
|
|
25
|
+
590 525 590 525 590 525 598 495 598 495 598 495 598 495 613 691
|
|
26
|
+
613 557 536 545 536 545 536 545 536 545 536 545 676 502 676 502
|
|
27
|
+
676 502 676 502 654 546 681 548 278 285 278 285 278 285 278 285
|
|
28
|
+
278 285 727 602 477 367 576 504 545 506 295 506 295 506 295 506
|
|
29
|
+
330 506 298 638 546 638 546 638 546 635 653 546 674 537 674 537
|
|
30
|
+
674 537 993 924 582 389 582 389 582 389 481 405 481 405 481 405
|
|
31
|
+
481 405 581 396 581 496 581 396 648 546 648 546 648 546 648 546
|
|
32
|
+
648 546 648 546 852 744 570 493 570 550 475 550 475 550 475 331
|
|
33
|
+
U+0192: 388
|
|
34
|
+
U+01FA: 590 525 867 873 657 545
|
|
35
|
+
U+0218: 481 405 581 396
|
|
36
|
+
RUNS
|
|
37
|
+
|
|
38
|
+
# codepoint => advance in per-mille em
|
|
39
|
+
TABLE = begin
|
|
40
|
+
codepoint = 0
|
|
41
|
+
DATA.each_line.with_object({}) do |line, table|
|
|
42
|
+
start, values =
|
|
43
|
+
line.include?(":") ? line.split(":", 2) : [nil, line]
|
|
44
|
+
codepoint = start.delete_prefix("U+").to_i(16) if start
|
|
45
|
+
values.split.each do |value|
|
|
46
|
+
table[codepoint] = value.to_i
|
|
47
|
+
codepoint += 1
|
|
48
|
+
end
|
|
49
|
+
end.freeze
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Etassia
|
|
4
|
+
class TextMeasurement
|
|
5
|
+
# Trebuchet MS kern adjustments used by the remaining Mindmap corpus.
|
|
6
|
+
# Values are design units from the regular face's kern table.
|
|
7
|
+
module TrebuchetKerning
|
|
8
|
+
UNITS_PER_EM = 2048.0
|
|
9
|
+
PAIRS = {
|
|
10
|
+
" A" => -113,
|
|
11
|
+
" T" => -37,
|
|
12
|
+
"Pe" => -96,
|
|
13
|
+
"Po" => -96,
|
|
14
|
+
"Re" => -83,
|
|
15
|
+
"Ro" => -83,
|
|
16
|
+
"To" => -255,
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
module_function
|
|
20
|
+
|
|
21
|
+
def adjustment(text, font_size:)
|
|
22
|
+
units = text.each_char.each_cons(2).sum do |pair|
|
|
23
|
+
PAIRS.fetch(pair.join, 0)
|
|
24
|
+
end
|
|
25
|
+
units * font_size / UNITS_PER_EM
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "text_measurement/arial_advances"
|
|
4
|
+
require_relative "text_measurement/dejavu_advances"
|
|
5
|
+
require_relative "text_measurement/trebuchet_advances"
|
|
6
|
+
|
|
7
|
+
module Etassia
|
|
8
|
+
# Estimates text dimensions for layout, in pure Ruby: no font file is read
|
|
9
|
+
# at runtime. Width is the sum of per-glyph advances of the default theme's
|
|
10
|
+
# stack ("Arial, Helvetica, sans-serif"), from the generated ArialAdvances.
|
|
11
|
+
#
|
|
12
|
+
# BOUNDS: every codepoint in ArialAdvances (exact in Liberation Sans, and in
|
|
13
|
+
# Arial wherever Arial has the glyph; macOS Arial lacks U+0487, U+2010,
|
|
14
|
+
# U+202F, U+20BF and U+21D4); CJK and fullwidth at 1.0 em, the four Arabic
|
|
15
|
+
# ligatures in OUTLIERS, and zero-width marks (all measured in Chrome).
|
|
16
|
+
# ESTIMATES: emoji, and any pictographic character followed by U+FE0F, at
|
|
17
|
+
# 1.5 em; everything else at 1.0 em. A ZWJ sequence counts each emoji.
|
|
18
|
+
# DOES NOT BOUND: a font the viewer substitutes for a glyph Arial lacks,
|
|
19
|
+
# other stacks (DejaVu, Verdana run up to 1.19 times wider), bold, italic,
|
|
20
|
+
# kerning (it can widen a pair as well as narrow it), shaping beyond
|
|
21
|
+
# OUTLIERS. Callers that need room use Renderer::Base#reserved_text_width.
|
|
22
|
+
#
|
|
23
|
+
# @example Basic usage
|
|
24
|
+
# TextMeasurement.measure("Hello", font_size: 14)
|
|
25
|
+
# # => { width: 31.892, height: 14.0 }
|
|
26
|
+
#
|
|
27
|
+
# @example With dimension overrides
|
|
28
|
+
# TextMeasurement.measure("Text", font_size: 12, width: 100, height: 20)
|
|
29
|
+
# # => { width: 100, height: 20 }
|
|
30
|
+
class TextMeasurement
|
|
31
|
+
# Text height as ratio of font size
|
|
32
|
+
HEIGHT_RATIO = 1.0
|
|
33
|
+
|
|
34
|
+
# Per-mille em for a codepoint no rule below knows.
|
|
35
|
+
DEFAULT_ADVANCE = 1000
|
|
36
|
+
EMOJI_ADVANCE = 1500
|
|
37
|
+
MONOSPACE_ADVANCE = 600
|
|
38
|
+
# DejaVu Sans Mono: 1233 units of 2048 per glyph.
|
|
39
|
+
DEJAVU_MONO_ADVANCE = 1233 * 1000.0 / 2048
|
|
40
|
+
SPACE_ADVANCE = ArialAdvances::TABLE.fetch(0x20)
|
|
41
|
+
|
|
42
|
+
# SVG draws one <text> as ONE line: a tab, newline or carriage return is
|
|
43
|
+
# collapsed to a space. A CRLF is counted twice (an over-estimate).
|
|
44
|
+
SVG_WHITESPACE = /[\t\n\r]/
|
|
45
|
+
ASCII_WHITESPACE = [9, 10, 13].freeze
|
|
46
|
+
|
|
47
|
+
# Codepoints whose width comes from ligature substitution, so no
|
|
48
|
+
# per-character rule describes them. Chrome measured 1.234, 1.025, 1.221
|
|
49
|
+
# and 6.489 em; these round up.
|
|
50
|
+
OUTLIERS = {
|
|
51
|
+
0xFDFA => 1250, 0xFDFB => 1050, 0xFDFC => 1250, 0xFDFD => 6500
|
|
52
|
+
}.freeze
|
|
53
|
+
|
|
54
|
+
# The faces a caller can ask for. A codepoint a face lacks falls back to
|
|
55
|
+
# the default one.
|
|
56
|
+
FACE_TABLES = {
|
|
57
|
+
arial: ArialAdvances::TABLE,
|
|
58
|
+
trebuchet: TrebuchetAdvances::TABLE,
|
|
59
|
+
dejavu: DejaVuAdvances::REGULAR,
|
|
60
|
+
dejavu_bold: DejaVuAdvances::BOLD,
|
|
61
|
+
}.freeze
|
|
62
|
+
|
|
63
|
+
ZERO_WIDTH = /[\p{Mn}\p{Me}\p{Cf}\p{Cc}]/
|
|
64
|
+
EMOJI = /\p{Extended_Pictographic}/
|
|
65
|
+
# Ruby 4 moved to Unicode 17, where U+266D no longer matches
|
|
66
|
+
# Extended_Pictographic. Keep the measured width independent of the
|
|
67
|
+
# Unicode tables bundled with the running Ruby.
|
|
68
|
+
PINNED_PICTOGRAPHS = [0x266D].freeze
|
|
69
|
+
|
|
70
|
+
# A pictographic character plus U+FE0F asks for the emoji glyph, even for
|
|
71
|
+
# one the table has as text (U+00A9 is 0.737 em as text, 1.0 em as emoji
|
|
72
|
+
# in Chrome). Any other character is a cluster of its own.
|
|
73
|
+
CLUSTER = /#{EMOJI}\uFE0F|./m
|
|
74
|
+
|
|
75
|
+
# Measures the approximate dimensions of text.
|
|
76
|
+
#
|
|
77
|
+
# @param text [String] the text to measure, as one line: a caller that
|
|
78
|
+
# draws several lines measures each line on its own
|
|
79
|
+
# @param font_size [Numeric] the font size in points
|
|
80
|
+
# @param width [Numeric, nil] optional width override
|
|
81
|
+
# @param height [Numeric, nil] optional height override
|
|
82
|
+
# @param monospace [Boolean] measure for a monospace font-family
|
|
83
|
+
# @return [Hash] hash with :width and :height keys
|
|
84
|
+
def self.measure(text, font_size:, width: nil, height: nil,
|
|
85
|
+
monospace: false)
|
|
86
|
+
{
|
|
87
|
+
width: width || calculate_width(text, font_size, monospace, :arial),
|
|
88
|
+
height: height || calculate_height(font_size),
|
|
89
|
+
}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Measures text in a face other than the default, with the default
|
|
93
|
+
# standing in for a codepoint the face lacks.
|
|
94
|
+
#
|
|
95
|
+
# @param text [String] the text to measure, as one line
|
|
96
|
+
# @param font_size [Numeric] the font size in points
|
|
97
|
+
# @param face [Symbol] :arial, :trebuchet, :dejavu or :dejavu_bold
|
|
98
|
+
# @return [Hash] hash with :width and :height keys
|
|
99
|
+
def self.measure_in(face, text, font_size:)
|
|
100
|
+
{
|
|
101
|
+
width: calculate_width(text, font_size, false, face),
|
|
102
|
+
height: calculate_height(font_size),
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Measures text in the `monospace` family PlantUML's JAR resolves to,
|
|
107
|
+
# DejaVu Sans Mono: every glyph advances 1233/2048 em (a combining mark
|
|
108
|
+
# or control character advances nothing).
|
|
109
|
+
#
|
|
110
|
+
# @param text [String] the text to measure, as one line
|
|
111
|
+
# @param font_size [Numeric] the font size in points
|
|
112
|
+
# @return [Hash] hash with :width and :height keys
|
|
113
|
+
def self.measure_mono(text, font_size:)
|
|
114
|
+
cells = normalize(text).scan(CLUSTER).count do |cluster|
|
|
115
|
+
!cluster.match?(ZERO_WIDTH)
|
|
116
|
+
end
|
|
117
|
+
{ width: cells * DEJAVU_MONO_ADVANCE * font_size / 1000.0,
|
|
118
|
+
height: calculate_height(font_size) }
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# @return [Float] the width of the text drawn as one line
|
|
122
|
+
def self.calculate_width(text, font_size, monospace, face)
|
|
123
|
+
normalized = normalize(text)
|
|
124
|
+
if normalized.ascii_only?
|
|
125
|
+
return ascii_width(normalized, monospace, face) * font_size / 1000.0
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
total = normalized.scan(CLUSTER).sum do |cluster|
|
|
129
|
+
cluster.length == 2 ? EMOJI_ADVANCE : advance(cluster, monospace, face)
|
|
130
|
+
end
|
|
131
|
+
total * font_size / 1000.0
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def self.ascii_width(text, monospace, face)
|
|
135
|
+
text.each_byte.sum { |code| ascii_advance(code, monospace, face) }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def self.ascii_advance(code, monospace, face)
|
|
139
|
+
return whitespace_advance(monospace) if ASCII_WHITESPACE.include?(code)
|
|
140
|
+
return 0 if code < 32 || code == 127
|
|
141
|
+
|
|
142
|
+
table = FACE_TABLES.fetch(face)[code] || ArialAdvances::TABLE[code]
|
|
143
|
+
table_advance(table, monospace)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# @return [Integer] the advance of one character in per-mille em
|
|
147
|
+
def self.advance(char, monospace, face)
|
|
148
|
+
return whitespace_advance(monospace) if char.match?(SVG_WHITESPACE)
|
|
149
|
+
return 0 if char.match?(ZERO_WIDTH)
|
|
150
|
+
|
|
151
|
+
code = char.ord
|
|
152
|
+
table = FACE_TABLES.fetch(face)[code] || ArialAdvances::TABLE[code]
|
|
153
|
+
return table_advance(table, monospace) if table
|
|
154
|
+
|
|
155
|
+
OUTLIERS.fetch(code) { fallback_advance(char, monospace) }
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Monospace keeps a zero advance (combining marks) at zero.
|
|
159
|
+
def self.table_advance(table, monospace)
|
|
160
|
+
monospace && table.positive? ? MONOSPACE_ADVANCE : table
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def self.whitespace_advance(monospace)
|
|
164
|
+
monospace ? MONOSPACE_ADVANCE : SPACE_ADVANCE
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def self.fallback_advance(char, monospace)
|
|
168
|
+
return EMOJI_ADVANCE if PINNED_PICTOGRAPHS.include?(char.ord) ||
|
|
169
|
+
char.match?(EMOJI)
|
|
170
|
+
|
|
171
|
+
monospace ? MONOSPACE_ADVANCE : DEFAULT_ADVANCE
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Never raises on an undecodable string: a layout must not fail on bytes.
|
|
175
|
+
# The final re-tag is needed for UTF-8 too: encode from CESU-8 and the
|
|
176
|
+
# UTF8-DoCoMo/KDDI/SoftBank family can leave a stray continuation byte
|
|
177
|
+
# that still reports valid, and only a re-scan of the bytes sees it.
|
|
178
|
+
def self.normalize(text)
|
|
179
|
+
string = text.to_s
|
|
180
|
+
unless string.encoding == Encoding::UTF_8
|
|
181
|
+
string = string.encode(Encoding::UTF_8, invalid: :replace,
|
|
182
|
+
undef: :replace)
|
|
183
|
+
end
|
|
184
|
+
string.b.force_encoding(Encoding::UTF_8).scrub
|
|
185
|
+
rescue EncodingError
|
|
186
|
+
string.b.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# @return [Float] the calculated height
|
|
190
|
+
def self.calculate_height(font_size)
|
|
191
|
+
font_size * HEIGHT_RATIO
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
private_class_method :calculate_width, :calculate_height, :advance,
|
|
195
|
+
:fallback_advance, :table_advance, :whitespace_advance,
|
|
196
|
+
:normalize, :ascii_width, :ascii_advance
|
|
197
|
+
end
|
|
198
|
+
end
|