Skip to main content

merman/
lib.rs

1#![forbid(unsafe_code)]
2
3//! Headless, parity-focused Mermaid parsing and rendering in Rust.
4//!
5//! `merman` is the public Rust facade for the project. It re-exports
6//! [`merman_core`] for detection, parsing, metadata, semantic JSON, and typed
7//! render models, then adds optional convenience modules for SVG, raster, and
8//! terminal text output.
9//!
10//! The compatibility target is Mermaid `@11.15.0`. Upstream Mermaid behavior is
11//! treated as the specification, including cases where the browser implementation
12//! is surprising. The root README and `docs/alignment/STATUS.md` document the
13//! current parity matrix, deferred residuals, and release gates.
14//!
15//! # Choosing an API
16//!
17//! | Goal | Feature | Start with |
18//! | --- | --- | --- |
19//! | Parse Mermaid or produce semantic JSON | none | [`Engine`] and [`ParseOptions`] |
20//! | Render Mermaid-like SVG | `render` | `merman::render::HeadlessRenderer` |
21//! | Prepare SVG for `usvg` / `resvg` / raster export | `render` | `HeadlessRenderer::render_svg_resvg_safe_sync` |
22//! | Render terminal-friendly text | `ascii` | `merman::ascii::HeadlessAsciiRenderer` |
23//! | Render PNG, JPG, or PDF from Rust | `raster` | `HeadlessRenderer::render_png_sync` and `render::raster::RasterOptions` |
24//!
25//! If you already know the diagram type, use the `*_with_type_sync` methods on
26//! [`Engine`] to skip detection. If you need lower-level layout or SVG pipeline
27//! control, use the re-exported types under `merman::render` or depend on
28//! `merman-render` directly.
29//!
30//! # Features
31//!
32//! - `render`: layout plus SVG rendering through `merman::render`.
33//! - `ascii`: ASCII/Unicode text rendering through `merman::ascii`.
34//! - `raster`: PNG/JPG/PDF output through `merman::render::raster`; this implies
35//!   `render`.
36//! - `ratex-math`: pure-Rust math label rendering for the SVG path; this implies
37//!   `render`.
38//!
39//! The default feature set is intentionally empty so parser-only users do not
40//! pull in layout, SVG, raster, or text-output dependencies.
41//!
42//! # SVG quickstart
43//!
44//! ```no_run
45//! # #[cfg(feature = "render")]
46//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
47//! use merman::render::HeadlessRenderer;
48//!
49//! let renderer = HeadlessRenderer::new().with_diagram_id("readme-example");
50//! let svg = renderer
51//!     .render_svg_sync("flowchart TD\nA[Start] --> B[Done]")?
52//!     .expect("diagram detected");
53//!
54//! println!("{svg}");
55//! # Ok(())
56//! # }
57//! # #[cfg(not(feature = "render"))]
58//! # fn main() {}
59//! ```
60//!
61//! A fresh `HeadlessRenderer` keeps the Mermaid parity SVG contract for
62//! `HeadlessRenderer::render_svg_sync`. Calling `with_host_theme` or
63//! `with_svg_pipeline` installs a renderer-owned output pipeline for that
64//! method. Use
65//! `HeadlessRenderer::render_svg_readable_sync` when browser
66//! `<foreignObject>` labels may need readable `<text>` fallbacks, and
67//! `HeadlessRenderer::render_svg_resvg_safe_sync` when the output will
68//! be consumed by `usvg`, `resvg`, or the built-in raster helpers.
69//!
70//! # ASCII quickstart
71//!
72//! ```no_run
73//! # #[cfg(feature = "ascii")]
74//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
75//! use merman::ascii::{AsciiRenderOptions, HeadlessAsciiRenderer};
76//!
77//! let renderer = HeadlessAsciiRenderer::new()
78//!     .with_strict_parsing()
79//!     .with_ascii_options(AsciiRenderOptions::unicode());
80//! let text = renderer
81//!     .render_ascii_sync("sequenceDiagram\nA->>B: Hello")?
82//!     .expect("diagram detected");
83//!
84//! println!("{text}");
85//! # Ok(())
86//! # }
87//! # #[cfg(not(feature = "ascii"))]
88//! # fn main() {}
89//! ```
90//!
91//! Text output is intentionally terminal-native rather than SVG-derived. The
92//! currently supported public subset covers flowchart/graph, sequenceDiagram,
93//! classDiagram, erDiagram, and xychart.
94//!
95//! # Raster output
96//!
97//! The `raster` feature renders SVG through the `resvg`-safe pipeline before
98//! conversion. PNG and JPG use a default pixmap budget to avoid accidental huge
99//! allocations from very large Mermaid `viewBox` values. For UI previews, pass a
100//! visible target box through `RasterOptions::with_fit_to` and use
101//! `RasterOptions::with_scale` for device-pixel ratio.
102
103pub use merman_core::*;
104
105#[cfg(feature = "ascii")]
106pub mod ascii;
107
108#[cfg(feature = "render")]
109pub mod render;
110#[cfg(feature = "render")]
111pub use render::supported_host_theme_presets;