///|
fn option_string_or(value : String?, fallback : String) -> String {
match value {
Some(found) => found
None => fallback
}
}
///|
fn option_bool_or(value : Bool?, fallback : Bool) -> Bool {
match value {
Some(found) => found
None => fallback
}
}
///|
fn option_color_or(value : String?, fallback : String?) -> String? {
match value {
Some(found) => Some(found)
None => fallback
}
}
///|
/// Resolve a full `DiagramColors` value from `@model.RenderOptions`.
/// Missing `bg`/`fg` values fall back to `@model.DiagramColors::default()`.
fn build_colors(options : @model.RenderOptions) -> @model.DiagramColors {
let defaults = @model.DiagramColors::default()
{
bg: option_string_or(options.bg, defaults.bg),
fg: option_string_or(options.fg, defaults.fg),
line: options.line,
accent: options.accent,
muted: options.muted,
surface: options.surface,
border: options.border,
}
}
///|
/// Merge user `options` with an explicit color palette.
/// Explicit values in `options` win; missing color fields are filled from `colors`.
fn merge_options_with_colors(
options : @model.RenderOptions,
colors : @model.DiagramColors,
) -> @model.RenderOptions {
{
bg: Some(option_string_or(options.bg, colors.bg)),
fg: Some(option_string_or(options.fg, colors.fg)),
line: option_color_or(options.line, colors.line),
accent: option_color_or(options.accent, colors.accent),
muted: option_color_or(options.muted, colors.muted),
surface: option_color_or(options.surface, colors.surface),
border: option_color_or(options.border, colors.border),
font: options.font,
padding: options.padding,
node_spacing: options.node_spacing,
layer_spacing: options.layer_spacing,
transparent: options.transparent,
layout_engine: options.layout_engine,
}
}
///|
/// Parse Mermaid text and render an SVG string.
/// Supports flowchart, state, sequence, class, and ER headers.
///
/// # Example
/// ```mbt check
/// test {
/// let svg = try! render_mermaid(
/// (
/// #|graph TD
/// #|A --> B
/// ),
/// )
/// assert_true(svg.has_prefix("