Skip to content

fix(mermaid): strip Mermaid frontmatter before rendering (#10676)#11249

Open
maxmilian wants to merge 1 commit into
warpdotdev:masterfrom
maxmilian:fix/10676-mermaid-frontmatter
Open

fix(mermaid): strip Mermaid frontmatter before rendering (#10676)#11249
maxmilian wants to merge 1 commit into
warpdotdev:masterfrom
maxmilian:fix/10676-mermaid-frontmatter

Conversation

@maxmilian
Copy link
Copy Markdown
Contributor

@maxmilian maxmilian commented May 19, 2026

Summary

Fixes #10676. Mermaid diagrams that start with a YAML frontmatter / config block (a --- ... --- block at the very top, supported by Mermaid 11+) never render in Warp — the UI stays on "Rendering Mermaid diagram" indefinitely on older builds, and shows the generic failure callout on newer ones. Issue's exact sample:

---
config:
  theme: default
---
xychart-beta
  title "Évolution des prix des appartements à Versailles"
  ...
Loading

Visual evidence

Built WarpOss from this branch, opened a Personal Notebook, and pasted the issue's mermaid-with-frontmatter source. Same notebook, same markdown — just toggling the Mermaid block's view mode.

warp-pr11249-ui-comparison
  • Raw view (left)---\nconfig:\n theme: default\n--- frontmatter is preserved in the source (this is what was breaking master).
  • Diagram view (right)strip_mermaid_frontmatter strips the leading block before mermaid_to_svg, the flowchart renders.

Pipeline-level proof using the same mermaid_to_svg rev pinned in this repo:

warp-pr11249-pipeline-proof
  • Before — raw source with frontmatter → Parse error at line 1: Expected 'graph' or 'flowchart' declaration.
  • After — stripped source → SVG rendered.

Root cause

The pinned mermaid_to_svg renderer's first_diagram_type_token treats the first non-empty, non-%%-prefixed line as the diagram token. With frontmatter present that token is --- rather than xychart-beta / flowchart / etc., so the renderer fails to dispatch to the right parser and never produces a usable SVG.

Both call sites — crates/editor/src/content/mermaid_diagram.rs:39 (mermaid_asset_source, used by markdown notebook layout) and app/src/notebooks/editor/model.rs:157 (render_mermaid_clipboard_html, the clipboard SVG embed) — pass the raw source through unmodified.

Fix

Introduce strip_mermaid_frontmatter in crates/editor/src/content/mermaid_diagram.rs (returns Cow<'_, str>Borrowed when no frontmatter, Owned otherwise) and apply it at both call sites. The asset cache key is derived from the post-strip source, so the same logical diagram with and without frontmatter shares a cache entry.

Strip is lossless: Warp passes a hardcoded MermaidTheme::light() to render_mermaid_to_svg and does not consult any of the frontmatter config keys, so nothing about today's rendered output changes when the leading --- block is removed.

Line trimming before delimiter comparison intentionally mirrors mermaid_to_svg's own first_diagram_type_token behavior — being stricter (e.g. requiring --- at column 0) would leave a class of broken sources still broken on the renderer side.

Tests

13 new unit tests in crates/editor/src/content/mermaid_diagram_tests.rs:

  • strip_frontmatter_removes_leading_config_block — the issue's exact xychart sample.
  • strip_frontmatter_preserves_source_without_frontmatter — no-op path returns Cow::Borrowed (no spurious allocation).
  • strip_frontmatter_skips_leading_blank_lines_before_open_delimiter — blanks/whitespace before --- are not load-bearing.
  • strip_frontmatter_handles_crlf_line_endings — Windows line endings.
  • strip_frontmatter_leaves_text_starting_with_three_dashes_then_content--- title-like lines are not delimiters.
  • strip_frontmatter_leaves_unterminated_block_for_renderer_to_surface — missing close --- → leave intact so the renderer's own error surfaces.
  • strip_frontmatter_handles_empty_input — empty string.
  • strip_frontmatter_handles_only_frontmatter_no_body — frontmatter with no body.
  • strip_frontmatter_handles_frontmatter_without_trailing_newline — closing --- on final line.
  • strip_frontmatter_handles_open_delimiter_only_with_newline---\n alone.
  • strip_frontmatter_handles_open_delimiter_only_without_newline--- alone (no trailing newline).
  • strip_frontmatter_treats_indented_dashes_as_delimiter — documented intentional choice that mirrors the renderer's line-trim behavior.
  • strip_frontmatter_does_not_treat_inner_dashes_line_as_delimiter--- lines mid-diagram are not delimiters.
  • mermaid_asset_source_hashes_post_strip_for_cache_key_stability — same cache key with/without frontmatter.

All 16 module tests pass locally (cargo test -p warp_editor --lib content::mermaid_diagram::). cargo fmt --check, cargo clippy -p warp_editor --lib, cargo clippy -p warp --lib are clean.

Scope

Deliberately not changed:

  • mermaid_to_svg (the warpdotdev fork) is not patched. Fixing the renderer to recognize frontmatter would be more general but requires a separate PR to that repo plus a dep bump. The Warp-side strip is a single PR that fully solves the user-visible bug with minimal blast radius.
  • Frontmatter theme / config.* keys remain ignored. Honoring them would mean parsing YAML and overriding the hardcoded light theme — a feature, not a fix. The current behavior matches what shipped before frontmatter was attempted at all.

Follow-up

  • Patch the mermaid_to_svg fork to recognize --- frontmatter natively, then remove this Warp-side helper. Would also fix the bug for any other consumer of that crate.
  • Honor frontmatter theme: dark / theme: forest etc. by parsing the YAML and passing the appropriate MermaidTheme instead of hardcoded light().
  • The MermaidTheme::light() hardcode itself is worth revisiting — it doesn't honor Warp's app theme.

@cla-bot cla-bot Bot added the cla-signed label May 19, 2026
@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 19, 2026
…with config blocks display (warpdotdev#10676)

Root cause: `mermaid_to_svg`'s diagram-type detection treats the first
non-empty, non-`%%`-prefixed line as the diagram token. When the source
opens with a YAML frontmatter block

    ---
    config:
      theme: default
    ---
    xychart-beta
      ...

the token becomes `---` instead of `xychart-beta`, so the renderer fails
to dispatch to the right parser and the asset never resolves into a
displayable SVG — the UI sits on "Rendering Mermaid diagram" indefinitely
on older builds, or shows a generic failure on newer ones.

Fix: introduce `strip_mermaid_frontmatter` in
`crates/editor/src/content/mermaid_diagram.rs` and apply it at both call
sites that feed `render_mermaid_to_svg`:

- `mermaid_asset_source` (the renderer used by markdown notebook layout)
- `render_mermaid_clipboard_html` (the clipboard SVG embed)

Warp passes a hardcoded `MermaidTheme::light()` and does not consult any
of the frontmatter config keys, so stripping is lossless. The asset cache
key is now derived from the post-strip source, so the same logical
diagram with and without frontmatter shares a cache entry.

13 new unit tests cover: the issue's exact xychart sample, a
no-frontmatter no-op path (verifying `Cow::Borrowed` to avoid spurious
allocation), leading blank lines before the open delimiter, CRLF endings,
"--- title-like" lines that should NOT be treated as a delimiter,
unterminated frontmatter, empty input, frontmatter without a body,
frontmatter without a trailing newline, inner `---` lines after real
content, open delimiter only (with and without trailing newline),
indented `---` lines as a documented intentional choice that mirrors the
renderer's own line-trimming behavior, and a parity check that confirms
the cache key matches the no-frontmatter version.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@maxmilian maxmilian force-pushed the fix/10676-mermaid-frontmatter branch from 3c7e47e to 35db65e Compare May 19, 2026 00:27
@maxmilian maxmilian marked this pull request as ready for review May 19, 2026 00:27
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 19, 2026

@maxmilian

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR strips leading Mermaid --- frontmatter before sending diagram sources to the existing renderer, applies the helper to both notebook rendering/cache keys and clipboard HTML rendering, and adds focused unit coverage for the frontmatter edge cases.

Concerns

  • This is a user-facing rendering fix, but the supplied PR description does not include screenshots or a screen recording showing Mermaid frontmatter rendering successfully end to end. Per the repository review guidance, please attach visual evidence for this behavior change before merge.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

@maxmilian
Copy link
Copy Markdown
Contributor Author

Visual evidence (per Oz review request)

Built WarpOss from this branch, opened a Personal Notebook, and pasted the
issue's mermaid-with-frontmatter source. Same notebook, same markdown — just
toggling the Mermaid block's view mode.

warp-pr11249-ui-comparison

  • Raw view (left)---\nconfig:\n theme: default\n--- frontmatter is preserved in the
    source (this is what was breaking master).
  • Diagram view (right)strip_mermaid_frontmatter strips the leading block before
    mermaid_to_svg, the flowchart renders.

Pipeline-level proof using the same mermaid_to_svg rev pinned in this repo:

warp-pr11249-pipeline-proof

  • Before — raw source with frontmatter → Parse error at line 1: Expected 'graph' or 'flowchart' declaration.
  • After — stripped source → SVG rendered.

@maxmilian
Copy link
Copy Markdown
Contributor Author

/oz-review

@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 19, 2026

@maxmilian

I'm re-reviewing this pull request in response to a review request.

You can view the conversation on Warp.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR strips leading Mermaid YAML frontmatter before rendering diagrams and when producing clipboard SVG HTML, with unit coverage for delimiter handling and cache-key stability.

Concerns

  • For this user-facing Mermaid rendering change, please include screenshots or a short screen recording demonstrating a Mermaid diagram with leading frontmatter rendering end to end. Repo review guidance requires visual evidence for user-visible behavior changes.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mermaid diagram is always stuck at "Rendering Mermaid diagram" on MacOS

1 participant