merman-render
merman-render is the low-level layout and SVG crate behind merman. It consumes typed merman-core family semantics and produces compatibility layout JSON or Mermaid-like SVG through one family artifact.
Implementation crate: this crate is published to support Merman's Cargo dependency chain, not as the normal product entry point. Applications should depend on
mermanand usemerman::svg::HeadlessRenderer.
Direct use is reserved for Merman maintainers and advanced integrations that deliberately own the typed core model, render session, text measurement, layout, and SVG postprocessing lifecycle.
What It Provides
- Headless layout for parsed Mermaid diagrams.
- Mermaid-parity SVG emission.
FamilyRenderArtifact, which keeps one matching built-in semantic/layout pair opaque and projects layout JSON or consuming SVG output.LayoutOptions::headless_svg_defaults()for editor/export use cases.- Text measurement hooks through
TextMeasurer. - Math rendering hooks through
MathRenderer. - Shared Root Viewport policy for computed sizing, accessibility chrome, and root SVG emission.
SvgPipelinepresets and postprocessors for readable or rasterizer-friendly SVG.
Feature Selection
The base crate provides SVG and the shared Mermaid/Dagre rendering path with no Cargo features. Optional features add only distinct backends or system adapters:
| Feature | Adds |
|---|---|
layout-cytoscape |
Architecture FCoSE and non-tidy-tree Mindmap COSE-Bilkent layout through manatee. |
layout-elk |
Source-backed ELK layered layout for Flowchart ELK, Class, and ER. |
math |
RaTeX parsing, layout, SVG output, and embedded math fonts. |
system-clock, system-timezone, system-random, system-timing |
Explicit host runtime adapters; none are selected by default. |
Omitting an optional layout or math backend preserves parsing and semantic support. Rendering a diagram that needs the missing backend returns a typed capability error instead of silently choosing a different layout.
Render Environment
RenderEnvironment owns adapters and policy for one operation: named text-measurement routes, math rendering, icons, time, randomness, and resource limits. Call begin_session() once before layout and retain that RenderSession through SVG and any raster postprocessing so those phases observe the same snapshot and provenance. The higher-level HeadlessRenderer also applies the frozen session date and timezone to date-sensitive parsing; direct low-level callers are responsible for configuring the core Engine consistently.
TextMeasurer keeps browser DOM primitives distinct. In particular, measure_svg_create_text_bbox_y_offset_px measures ordinary Mermaid createText, while measure_svg_create_text_middle_bbox_y_offset_px measures Architecture's formatted text under an inherited middle baseline. The latter is font- and x-height-dependent and cannot reuse the former. The vendored profile's pinned middle-baseline shift is a deterministic fallback, not a general system-font formula; an authoritative host measurement bypasses it.
This is a breaking replacement for independently configured layout and SVG services. Text and math adapters no longer live in LayoutOptions, and render code does not read process-global policy. Production request values stay in SvgRenderOptions; diagnostics, including timing output, live in SvgDebugOptions and are accepted only by the explicit *_with_debug entry points.
Low-Level Pipeline Example
use ;
use ;
use ;
SVG Output Pipelines
The default SVG renderer aims for Mermaid DOM parity. Host applications can opt into an output pipeline after rendering:
SvgPipeline::parity()leaves the SVG unchanged.SvgPipeline::readable()keeps fallback text for<foreignObject>labels.SvgPipeline::resvg_safe()prepares SVG for commonusvg/resvgrasterization paths.ScopedCssPostprocessor,CssOverridePostprocessor, and customSvgPostprocessorimplementations let applications inject host-specific styling without forking the renderer.
See docs/rendering/SVG_OUTPUT_PIPELINE.md for the higher-level integration guide.
Relationship To merman
merman re-exports the common render APIs behind its svg feature and adds HeadlessRenderer, consuming prepare_render_sync stages, SVG id sanitization helpers, and optional raster helpers. Direct merman-render users call family::prepare and retain its RenderSession; the old public layout_parsed*, render_layouted_svg, raw model/layout SVG helpers, and per-family pass-through wrappers are not retained as compatibility paths.