///|
fn main {
run()
}
///|
fn print_usage() -> Unit {
let usage =
#|Usage:
#| moon run cmd/main -- "graph TD\nA --> B"
#| moon run cmd/main -- --ascii "graph LR\nA --> B"
#| moon run cmd/main -- --unicode "graph LR\nA --> B"
#| moon run cmd/main -- --ascii --ascii-padding-x=8 "graph LR\nA --> B"
#| moon run cmd/main -- --ascii --ascii-padding-y=2 "graph LR\nA --> B"
#| moon run cmd/main -- --ascii --ascii-box-border-padding=2 "graph LR\nA --> B"
#| moon run cmd/main -- --theme=tokyo-night "graph TD\nA --> B"
#| moon run cmd/main -- --theme=default "graph TD\nA --> B"
#| moon run cmd/main -- --font='Roboto Mono' "graph TD\nA --> B"
#| moon run cmd/main -- --bg='#0f172a' "graph TD\nA --> B"
#| moon run cmd/main -- --fg='#e2e8f0' "graph TD\nA --> B"
#| moon run cmd/main -- --line='#64748b' "graph TD\nA --> B"
#| moon run cmd/main -- --accent='#38bdf8' "graph TD\nA --> B"
#| moon run cmd/main -- --muted='#94a3b8' "graph TD\nA --> B"
#| moon run cmd/main -- --surface='#0b1220' "graph TD\nA --> B"
#| moon run cmd/main -- --border='#334155' "graph TD\nA --> B"
#| moon run cmd/main -- --padding=20 "graph TD\nA --> B"
#| moon run cmd/main -- --node-spacing=80 "graph TD\nA --> B"
#| moon run cmd/main -- --layer-spacing=90 "graph TD\nA --> B"
#| moon run cmd/main -- --layout-engine=legacy "graph TD\nA --> B"
#| moon run cmd/main -- --layout-engine=dagre-parity "graph TD\nA --> B"
#| moon run cmd/main -- --layout-engine=elk "graph TD\nA --> B"
#| moon run cmd/main -- --layout-engine=elk-layered "graph TD\nA --> B"
#| moon run cmd/main -- --transparent "graph TD\nA --> B"
#| moon run cmd/main -- --dump-edge-points "graph TD\nA --> B"
#| moon run cmd/main -- --dump-dagre-order-trace "graph TD\nA --> B"
#| moon run cmd/main -- --list-themes
#|Flags:
#| --ascii Render ASCII output
#| --unicode Render Unicode text output
#| --ascii-padding-x ASCII horizontal padding, e.g. 8
#| --ascii-padding-y ASCII vertical padding, e.g. 2
#| --ascii-box-border-padding ASCII box border padding, e.g. 2
#| --theme SVG theme slug, e.g. tokyo-night, github-dark, default
#| --font SVG font family, e.g. Inter, Roboto Mono
#| --bg SVG background color, e.g. #0f172a
#| --fg SVG foreground color, e.g. #e2e8f0
#| --line SVG edge color, e.g. #64748b
#| --accent SVG accent color, e.g. #38bdf8
#| --muted SVG muted text color, e.g. #94a3b8
#| --surface SVG node fill color, e.g. #0b1220
#| --border SVG stroke color, e.g. #334155
#| --padding SVG/layout padding in px, e.g. 20
#| --node-spacing Horizontal node spacing in px, e.g. 80
#| --layer-spacing Vertical layer spacing in px, e.g. 90
#| --layout-engine Graph layout engine: legacy | dagre-parity | elk | elk-layered
#| --transparent Omit SVG background fill
#| --dump-edge-points Print routed edge points instead of rendering SVG
#| --dump-dagre-order-trace Print dagre ordering trace (trace/pass/layer/barycenter)
#| --list-themes Print built-in theme names
#| --help Show this help
#|
println(usage.trim_end().to_owned())
}
///|
fn cli_args_without_program() -> Array[String] {
let all_args = @env.args()
if all_args.length() <= 1 {
[]
} else {
let args : Array[String] = []
for i in 1.. String {
"zinc-light, zinc-dark, tokyo-night, tokyo-night-storm, tokyo-night-light, catppuccin-mocha, catppuccin-latte, nord, nord-light, dracula, github-light, github-dark, solarized-light, solarized-dark, one-dark, default"
}
///|
fn parse_non_negative_int(raw : String) -> Int32? {
let normalized = raw.trim().to_owned()
if normalized == "" {
return None
}
let value = @string.parse_int(normalized) catch { _ => return None }
if value >= 0 {
Some(value)
} else {
None
}
}
///|
fn parse_layout_engine(raw : String) -> @model.LayoutEngine? {
let normalized = raw.trim().to_lower()
if normalized == "legacy" {
return Some(Legacy)
}
if normalized == "elk-layered" || normalized == "elk_layered" {
return Some(ElkLayered)
}
if normalized == "elk" {
return Some(Elk)
}
if normalized == "dagre-parity" ||
normalized == "dagre_parity" ||
normalized == "dagre" ||
normalized == "parity" {
return Some(DagreParity)
}
None
}
///|
fn ascii_spacing_requires_text_mode(
render_text : Bool,
padding_x : Int32,
padding_y : Int32,
box_border_padding : Int32,
) -> Bool {
!render_text && (padding_x != 5 || padding_y != 5 || box_border_padding != 1)
}
///|
fn text_mode_override(arg : String) -> Bool? {
if arg == "--ascii" {
Some(true)
} else if arg == "--unicode" {
Some(false)
} else {
None
}
}
///|
fn svg_options_overridden(
theme_slug : String?,
font_name : String?,
bg_color : String?,
fg_color : String?,
line_color : String?,
accent_color : String?,
muted_color : String?,
surface_color : String?,
border_color : String?,
padding : Int32?,
node_spacing : Int32?,
layer_spacing : Int32?,
layout_engine : @model.LayoutEngine?,
transparent : Bool,
) -> Bool {
theme_slug is Some(_) ||
font_name is Some(_) ||
bg_color is Some(_) ||
fg_color is Some(_) ||
line_color is Some(_) ||
accent_color is Some(_) ||
muted_color is Some(_) ||
surface_color is Some(_) ||
border_color is Some(_) ||
padding is Some(_) ||
node_spacing is Some(_) ||
layer_spacing is Some(_) ||
layout_engine is Some(_) ||
transparent
}
///|
fn print_routed_edge_points(
input : String,
options : @model.RenderOptions,
) -> Unit {
let graph = @parser_header_core.parse_mermaid(input) catch {
err => {
println("Error: \{err}")
return
}
}
let positioned = @layout_engine_graph_core.layout_graph(graph, options)
for edge in positioned.edges {
let points = edge.points
.iter()
.map(point => "\{point.x},\{point.y}")
.join(" ")
println("EDGE\t\{edge.source}\t\{edge.target}\t\{points}")
}
}
///|
fn print_dagre_order_trace(
input : String,
options : @model.RenderOptions,
) -> Unit {
let graph = @parser_header_core.parse_mermaid(input) catch {
err => {
println("Error: \{err}")
return
}
}
let dagre_options : @model.RenderOptions = {
..options,
layout_engine: Some(DagreParity),
}
let setup_state = @layout_engine_graph_legacy_setup_core.build_legacy_layout_setup(
graph, dagre_options, true, false,
)
let lane_state = setup_state.lane_state
let trace = @layout_engine_graph_lane_core.collect_dagre_parity_order_trace(
setup_state.nodes_in_order,
lane_state.flow_rank_by_node_id,
lane_state.flow_max_rank,
graph.edges,
)
for trace_index, rank_nodes in trace.rank_nodes_trace {
for rank, node_ids in rank_nodes {
let joined_node_ids = node_ids.join(",")
println("TRACE\t\{trace_index}\t\{rank}\t\{joined_node_ids}")
}
}
for step in trace.sweep_step_trace {
let incoming_literal = if step.incoming_from_neighbor {
"true"
} else {
"false"
}
let bias_literal = if step.bias_right { "true" } else { "false" }
println(
"PASS\t\{step.pass_index}\t\{incoming_literal}\t\{bias_literal}\t\{step.candidate_crossings}",
)
for rank, node_ids in step.rank_nodes {
let joined_node_ids = node_ids.join(",")
println("PASS_LAYER\t\{step.pass_index}\t\{rank}\t\{joined_node_ids}")
}
let sorted_ranks : Array[Int32] = []
for rank, _ in step.barycenters_by_rank {
sorted_ranks.push(rank)
}
sorted_ranks.sort()
for rank in sorted_ranks {
match step.barycenters_by_rank.get(rank) {
Some(entries) => {
let sorted_node_ids : Array[String] = []
for node_id, _ in entries {
sorted_node_ids.push(node_id)
}
sorted_node_ids.sort()
for node_id in sorted_node_ids {
match entries.get(node_id) {
Some(value) =>
println(
"BARY\t\{step.pass_index}\t\{rank}\t\{node_id}\t\{value}",
)
None => ()
}
}
}
None => ()
}
}
}
}
///|
/// CLI entry point: parses arguments and renders a mermaid diagram.
fn run() -> Unit {
let args = cli_args_without_program()
let mut render_text = false
let mut use_ascii_chars = true
let mut ascii_padding_x = 5
let mut ascii_padding_y = 5
let mut ascii_box_border_padding = 1
let mut theme_slug : String? = None
let mut font_name : String? = None
let mut bg_color : String? = None
let mut fg_color : String? = None
let mut line_color : String? = None
let mut accent_color : String? = None
let mut muted_color : String? = None
let mut surface_color : String? = None
let mut border_color : String? = None
let mut padding : Int32? = None
let mut node_spacing : Int32? = None
let mut layer_spacing : Int32? = None
let mut layout_engine : @model.LayoutEngine? = None
let mut transparent = false
let mut dump_edge_points = false
let mut dump_dagre_order_trace = false
let mut diagram : String? = None
let mut expect_theme_value = false
let mut expect_font_value = false
let mut expect_bg_value = false
let mut expect_fg_value = false
let mut expect_line_value = false
let mut expect_accent_value = false
let mut expect_muted_value = false
let mut expect_surface_value = false
let mut expect_border_value = false
let mut expect_padding_value = false
let mut expect_node_spacing_value = false
let mut expect_layer_spacing_value = false
let mut expect_layout_engine_value = false
let mut expect_ascii_padding_x_value = false
let mut expect_ascii_padding_y_value = false
let mut expect_ascii_box_border_padding_value = false
for arg in args {
if expect_ascii_box_border_padding_value {
if arg is [.. "--", ..] {
println("Error: --ascii-box-border-padding requires a value")
print_usage()
return
}
match parse_non_negative_int(arg) {
Some(value) => ascii_box_border_padding = value
None => {
println(
"Error: --ascii-box-border-padding requires a non-negative integer",
)
print_usage()
return
}
}
expect_ascii_box_border_padding_value = false
continue
}
if expect_ascii_padding_y_value {
if arg is [.. "--", ..] {
println("Error: --ascii-padding-y requires a value")
print_usage()
return
}
match parse_non_negative_int(arg) {
Some(value) => ascii_padding_y = value
None => {
println("Error: --ascii-padding-y requires a non-negative integer")
print_usage()
return
}
}
expect_ascii_padding_y_value = false
continue
}
if expect_ascii_padding_x_value {
if arg is [.. "--", ..] {
println("Error: --ascii-padding-x requires a value")
print_usage()
return
}
match parse_non_negative_int(arg) {
Some(value) => ascii_padding_x = value
None => {
println("Error: --ascii-padding-x requires a non-negative integer")
print_usage()
return
}
}
expect_ascii_padding_x_value = false
continue
}
if expect_layer_spacing_value {
if arg is [.. "--", ..] {
println("Error: --layer-spacing requires a value")
print_usage()
return
}
match parse_non_negative_int(arg) {
Some(value) => layer_spacing = Some(value)
None => {
println("Error: --layer-spacing requires a non-negative integer")
print_usage()
return
}
}
expect_layer_spacing_value = false
continue
}
if expect_layout_engine_value {
if arg is [.. "--", ..] {
println("Error: --layout-engine requires a value")
print_usage()
return
}
match parse_layout_engine(arg) {
Some(engine) => layout_engine = Some(engine)
None => {
println(
"Error: --layout-engine must be one of: legacy, dagre-parity, elk, elk-layered",
)
print_usage()
return
}
}
expect_layout_engine_value = false
continue
}
if expect_node_spacing_value {
if arg is [.. "--", ..] {
println("Error: --node-spacing requires a value")
print_usage()
return
}
match parse_non_negative_int(arg) {
Some(value) => node_spacing = Some(value)
None => {
println("Error: --node-spacing requires a non-negative integer")
print_usage()
return
}
}
expect_node_spacing_value = false
continue
}
if expect_padding_value {
if arg is [.. "--", ..] {
println("Error: --padding requires a value")
print_usage()
return
}
match parse_non_negative_int(arg) {
Some(value) => padding = Some(value)
None => {
println("Error: --padding requires a non-negative integer")
print_usage()
return
}
}
expect_padding_value = false
continue
}
if expect_border_value {
if arg is [.. "--", ..] {
println("Error: --border requires a value")
print_usage()
return
}
border_color = Some(arg)
expect_border_value = false
continue
}
if expect_surface_value {
if arg is [.. "--", ..] {
println("Error: --surface requires a value")
print_usage()
return
}
surface_color = Some(arg)
expect_surface_value = false
continue
}
if expect_muted_value {
if arg is [.. "--", ..] {
println("Error: --muted requires a value")
print_usage()
return
}
muted_color = Some(arg)
expect_muted_value = false
continue
}
if expect_accent_value {
if arg is [.. "--", ..] {
println("Error: --accent requires a value")
print_usage()
return
}
accent_color = Some(arg)
expect_accent_value = false
continue
}
if expect_line_value {
if arg is [.. "--", ..] {
println("Error: --line requires a value")
print_usage()
return
}
line_color = Some(arg)
expect_line_value = false
continue
}
if expect_fg_value {
if arg is [.. "--", ..] {
println("Error: --fg requires a value")
print_usage()
return
}
fg_color = Some(arg)
expect_fg_value = false
continue
}
if expect_bg_value {
if arg is [.. "--", ..] {
println("Error: --bg requires a value")
print_usage()
return
}
bg_color = Some(arg)
expect_bg_value = false
continue
}
if expect_font_value {
if arg is [.. "--", ..] {
println("Error: --font requires a value")
print_usage()
return
}
font_name = Some(arg)
expect_font_value = false
continue
}
if expect_theme_value {
if arg is [.. "--", ..] {
println("Error: --theme requires a value")
print_usage()
return
}
theme_slug = Some(arg)
expect_theme_value = false
continue
}
if arg == "--help" {
print_usage()
return
}
if arg == "--list-themes" {
println(available_theme_list())
return
}
match text_mode_override(arg) {
Some(ascii_mode) => {
render_text = true
use_ascii_chars = ascii_mode
continue
}
None => ()
}
if arg == "--ascii-padding-x" {
expect_ascii_padding_x_value = true
continue
}
if arg == "--ascii-padding-y" {
expect_ascii_padding_y_value = true
continue
}
if arg == "--ascii-box-border-padding" {
expect_ascii_box_border_padding_value = true
continue
}
if arg == "--transparent" {
transparent = true
continue
}
if arg == "--dump-edge-points" {
dump_edge_points = true
continue
}
if arg == "--dump-dagre-order-trace" {
dump_dagre_order_trace = true
continue
}
if arg == "--font" {
expect_font_value = true
continue
}
if arg == "--bg" {
expect_bg_value = true
continue
}
if arg == "--fg" {
expect_fg_value = true
continue
}
if arg == "--line" {
expect_line_value = true
continue
}
if arg == "--accent" {
expect_accent_value = true
continue
}
if arg == "--muted" {
expect_muted_value = true
continue
}
if arg == "--surface" {
expect_surface_value = true
continue
}
if arg == "--border" {
expect_border_value = true
continue
}
if arg == "--padding" {
expect_padding_value = true
continue
}
if arg == "--node-spacing" {
expect_node_spacing_value = true
continue
}
if arg == "--layer-spacing" {
expect_layer_spacing_value = true
continue
}
if arg == "--layout-engine" {
expect_layout_engine_value = true
continue
}
if arg is [.. "--font=", .. raw_font] {
let font = raw_font.to_owned()
if font == "" {
println("Error: --font requires a non-empty value")
print_usage()
return
}
font_name = Some(font)
continue
}
if arg is [.. "--bg=", .. raw_bg] {
let bg = raw_bg.to_owned()
if bg == "" {
println("Error: --bg requires a non-empty value")
print_usage()
return
}
bg_color = Some(bg)
continue
}
if arg is [.. "--fg=", .. raw_fg] {
let fg = raw_fg.to_owned()
if fg == "" {
println("Error: --fg requires a non-empty value")
print_usage()
return
}
fg_color = Some(fg)
continue
}
if arg is [.. "--line=", .. raw_line] {
let line = raw_line.to_owned()
if line == "" {
println("Error: --line requires a non-empty value")
print_usage()
return
}
line_color = Some(line)
continue
}
if arg is [.. "--accent=", .. raw_accent] {
let accent = raw_accent.to_owned()
if accent == "" {
println("Error: --accent requires a non-empty value")
print_usage()
return
}
accent_color = Some(accent)
continue
}
if arg is [.. "--muted=", .. raw_muted] {
let muted = raw_muted.to_owned()
if muted == "" {
println("Error: --muted requires a non-empty value")
print_usage()
return
}
muted_color = Some(muted)
continue
}
if arg is [.. "--surface=", .. raw_surface] {
let surface = raw_surface.to_owned()
if surface == "" {
println("Error: --surface requires a non-empty value")
print_usage()
return
}
surface_color = Some(surface)
continue
}
if arg is [.. "--border=", .. raw_border] {
let border = raw_border.to_owned()
if border == "" {
println("Error: --border requires a non-empty value")
print_usage()
return
}
border_color = Some(border)
continue
}
if arg is [.. "--padding=", .. raw_padding] {
let raw_padding = raw_padding.to_owned()
if raw_padding == "" {
println("Error: --padding requires a non-empty value")
print_usage()
return
}
match parse_non_negative_int(raw_padding) {
Some(value) => padding = Some(value)
None => {
println("Error: --padding requires a non-negative integer")
print_usage()
return
}
}
continue
}
if arg is [.. "--node-spacing=", .. raw_node_spacing] {
let raw_node_spacing = raw_node_spacing.to_owned()
if raw_node_spacing == "" {
println("Error: --node-spacing requires a non-empty value")
print_usage()
return
}
match parse_non_negative_int(raw_node_spacing) {
Some(value) => node_spacing = Some(value)
None => {
println("Error: --node-spacing requires a non-negative integer")
print_usage()
return
}
}
continue
}
if arg is [.. "--layer-spacing=", .. raw_layer_spacing] {
let raw_layer_spacing = raw_layer_spacing.to_owned()
if raw_layer_spacing == "" {
println("Error: --layer-spacing requires a non-empty value")
print_usage()
return
}
match parse_non_negative_int(raw_layer_spacing) {
Some(value) => layer_spacing = Some(value)
None => {
println("Error: --layer-spacing requires a non-negative integer")
print_usage()
return
}
}
continue
}
if arg is [.. "--layout-engine=", .. raw_layout_engine] {
let raw_layout_engine = raw_layout_engine.to_owned()
if raw_layout_engine == "" {
println("Error: --layout-engine requires a non-empty value")
print_usage()
return
}
match parse_layout_engine(raw_layout_engine) {
Some(engine) => layout_engine = Some(engine)
None => {
println(
"Error: --layout-engine must be one of: legacy, dagre-parity, elk, elk-layered",
)
print_usage()
return
}
}
continue
}
if arg is [.. "--ascii-padding-x=", .. raw_ascii_padding_x] {
let raw_ascii_padding_x = raw_ascii_padding_x.to_owned()
if raw_ascii_padding_x == "" {
println("Error: --ascii-padding-x requires a non-empty value")
print_usage()
return
}
match parse_non_negative_int(raw_ascii_padding_x) {
Some(value) => ascii_padding_x = value
None => {
println("Error: --ascii-padding-x requires a non-negative integer")
print_usage()
return
}
}
continue
}
if arg is [.. "--ascii-padding-y=", .. raw_ascii_padding_y] {
let raw_ascii_padding_y = raw_ascii_padding_y.to_owned()
if raw_ascii_padding_y == "" {
println("Error: --ascii-padding-y requires a non-empty value")
print_usage()
return
}
match parse_non_negative_int(raw_ascii_padding_y) {
Some(value) => ascii_padding_y = value
None => {
println("Error: --ascii-padding-y requires a non-negative integer")
print_usage()
return
}
}
continue
}
if arg
is [.. "--ascii-box-border-padding=", .. raw_ascii_box_border_padding] {
let raw_ascii_box_border_padding = raw_ascii_box_border_padding.to_owned()
if raw_ascii_box_border_padding == "" {
println("Error: --ascii-box-border-padding requires a non-empty value")
print_usage()
return
}
match parse_non_negative_int(raw_ascii_box_border_padding) {
Some(value) => ascii_box_border_padding = value
None => {
println(
"Error: --ascii-box-border-padding requires a non-negative integer",
)
print_usage()
return
}
}
continue
}
if arg == "--theme" {
expect_theme_value = true
continue
}
if arg is [.. "--theme=", .. raw_theme] {
let theme = raw_theme.to_owned()
if theme == "" {
println("Error: --theme requires a non-empty value")
print_usage()
return
}
theme_slug = Some(theme)
continue
}
if arg is [.. "--", ..] {
println("Error: unknown flag \{arg}")
print_usage()
return
}
diagram = Some(arg)
}
if expect_theme_value {
println("Error: --theme requires a value")
print_usage()
return
}
if expect_font_value {
println("Error: --font requires a value")
print_usage()
return
}
if expect_bg_value {
println("Error: --bg requires a value")
print_usage()
return
}
if expect_fg_value {
println("Error: --fg requires a value")
print_usage()
return
}
if expect_line_value {
println("Error: --line requires a value")
print_usage()
return
}
if expect_accent_value {
println("Error: --accent requires a value")
print_usage()
return
}
if expect_muted_value {
println("Error: --muted requires a value")
print_usage()
return
}
if expect_surface_value {
println("Error: --surface requires a value")
print_usage()
return
}
if expect_border_value {
println("Error: --border requires a value")
print_usage()
return
}
if expect_padding_value {
println("Error: --padding requires a value")
print_usage()
return
}
if expect_node_spacing_value {
println("Error: --node-spacing requires a value")
print_usage()
return
}
if expect_layer_spacing_value {
println("Error: --layer-spacing requires a value")
print_usage()
return
}
if expect_layout_engine_value {
println("Error: --layout-engine requires a value")
print_usage()
return
}
if expect_ascii_padding_x_value {
println("Error: --ascii-padding-x requires a value")
print_usage()
return
}
if expect_ascii_padding_y_value {
println("Error: --ascii-padding-y requires a value")
print_usage()
return
}
if expect_ascii_box_border_padding_value {
println("Error: --ascii-box-border-padding requires a value")
print_usage()
return
}
if ascii_spacing_requires_text_mode(
render_text, ascii_padding_x, ascii_padding_y, ascii_box_border_padding,
) {
println(
"Error: ASCII spacing flags require --ascii or --unicode text output mode",
)
print_usage()
return
}
if dump_edge_points && render_text {
println("Error: --dump-edge-points requires SVG output mode")
print_usage()
return
}
if dump_dagre_order_trace && render_text {
println("Error: --dump-dagre-order-trace requires SVG output mode")
print_usage()
return
}
if dump_edge_points && dump_dagre_order_trace {
println(
"Error: --dump-edge-points and --dump-dagre-order-trace cannot be combined",
)
print_usage()
return
}
if render_text &&
svg_options_overridden(
theme_slug, font_name, bg_color, fg_color, line_color, accent_color, muted_color,
surface_color, border_color, padding, node_spacing, layer_spacing, layout_engine,
transparent,
) {
println("Error: SVG flags require SVG output mode (omit --ascii/--unicode)")
print_usage()
return
}
let input = match diagram {
Some(found) => found
None =>
(
#|graph TD
#|A[Start] --> B{Decision}
#|B -->|Yes| C[Done]
#|B -->|No| D[Retry]
#|
)
}
if render_text {
let options = @model.AsciiRenderOptions::{
use_ascii: use_ascii_chars,
padding_x: ascii_padding_x,
padding_y: ascii_padding_y,
box_border_padding: ascii_box_border_padding,
}
println(@beautiful_mermaid.render_mermaid_ascii(input, options~)) catch {
err => println("Error: \{err}")
}
return
}
let layout_options = @model.RenderOptions::{
bg: bg_color,
fg: fg_color,
line: line_color,
accent: accent_color,
muted: muted_color,
surface: surface_color,
border: border_color,
font: font_name,
padding,
node_spacing,
layer_spacing,
transparent: Some(transparent),
layout_engine,
}
if dump_edge_points {
print_routed_edge_points(input, layout_options)
return
}
if dump_dagre_order_trace {
print_dagre_order_trace(input, layout_options)
return
}
let svg_options = layout_options
let rendered_svg = try {
match theme_slug {
Some(slug) =>
match @themes.theme_by_name(slug) {
Some(_) =>
@beautiful_mermaid.render_mermaid_with_theme_name(
input,
slug,
options=svg_options,
)
None => {
println("Unknown theme: \{slug}")
println("Available themes: \{available_theme_list()}")
return
}
}
None => @beautiful_mermaid.render_mermaid(input, options=svg_options)
}
} catch {
err => {
println("Error: \{err}")
return
}
}
println(rendered_svg)
}