Files

23 lines
6.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Problem
Add Mermaid support to notebook markdown in Warp by recognizing Mermaid fenced blocks, rendering them to SVG asynchronously via the Rust Mermaid renderer, displaying the result in notebook rendering, and gating the behavior behind Warps feature-flag conventions.
## Current state
* Notebook bodies already flow through the shared markdown/buffer pipeline: notebook views call `NotebooksEditorModel::reset_with_markdown` / `update_to_new_markdown`, which delegate to the shared rich-text editor reset/delta path and `Buffer::from_markdown` (`app/src/notebooks/editor/model.rs (236-255)`, `editor/src/model.rs (902-966)`, `editor/src/content/buffer.rs (759-840)`).
* The markdown parser only special-cases embedded objects and table blocks; other fenced blocks remain `FormattedTextLine::CodeBlock` with the original info string preserved (`markdown_parser/src/markdown_parser.rs (39-43)`, `markdown_parser/src/markdown_parser.rs (145-160)`). Code blocks are then normalized into `CodeBlockType` in the editor layer (`editor/src/content/text.rs (534-666)`).
* Shared editor rendering already has reusable async image infrastructure: assets can be `Async` or `Raw`, and SVG bytes are parsed/rendered natively by the image cache (`ui/src/assets/asset_cache.rs (66-84)`, `ui/src/assets/asset_cache.rs (284-352)`, `ui/src/image_cache.rs (215-460)`).
* Plain image blocks are not text-editable in the rich-text model/hit-testing path, so Mermaid should not be persisted as a normal markdown image if we want notebook markdown to keep fenced Mermaid source and round-trip cleanly (`editor/src/content/core.rs (741-940)`, `editor/src/render/model/location.rs (101-252)`).
* Warp feature flags follow the existing `FeatureFlag` + Cargo feature + app registration pattern; `MarkdownTables` is the closest notebook-markdown precedent (`warp_core/src/features.rs (426-532)`, `warp_core/src/features.rs (757-917)`, `app/Cargo.toml (640-776)`, `app/src/lib.rs (2382-2581)`).
* The Mermaid renderer already exists as a standalone pure-Rust repository with a single `render_mermaid_to_svg` API plus theme support. That repository owns its nested `dagre_rust` path dependency, so Warp should consume the renderer as an external Cargo dependency rather than copying either crate into this repo (`https://github.com/warpdotdev/mermaid-to-svg`, `mermaid-to-svg/src/lib.rs (1-159)`, `mermaid-to-svg/src/theme.rs (1-35)`, `mermaid-to-svg/Cargo.toml:1`).
## Proposed changes
* Depend on the standalone `mermaid_to_svg` repository from Cargo.toml using a pinned git revision, and treat that external repo as the single source of truth for both `mermaid_to_svg` and its nested `dagre_rust` fork. Do not copy either crate into the Warp workspace. This keeps Warp reproducible while avoiding duplicated code and letting renderer fixes land upstream first (`Cargo.toml (1-200)`, `app/Cargo.toml (26-225)`, `https://github.com/warpdotdev/mermaid-to-svg`).
* Add Mermaid recognition at the shared markdown/code-block classification layer so notebook code can identify Mermaid fences without scattering raw string checks. The parser already preserves the info string, so this should be a targeted extension around fenced-block classification rather than a full parser rewrite (`markdown_parser/src/markdown_parser.rs (145-160)`, `editor/src/content/text.rs (534-666)`).
* Keep notebook markdown storage/export unchanged and add Mermaid rendering as a notebook render path, not a markdown-to-image rewrite. The render path should derive an async SVG asset from Mermaid source and reuse the existing asset/image cache so diagram generation happens off the UI thread. For this iteration we intentionally hard-code Mermaid light theme output rather than threading terminal/theme-aware variants through asset invalidation.
* Scope the rendering hook to notebook editors by extending notebook render state/configuration, so other markdown consumers are unaffected until explicitly opted in. Theme-aware Mermaid invalidation is deferred for now; notebook appearance changes should continue to trigger normal rich-text relayout, but the Mermaid asset key remains light-theme-specific in this implementation. The editor layout pipeline should branch Mermaid code blocks into a dedicated layout task when diagram rendering is enabled, rather than carrying Mermaid-only state on generic text layout tasks (`editor/src/render/model/mod.rs (231-320)`, `editor/src/render/model/mod.rs (1998-2197)`, `app/src/notebooks/editor/view.rs (1261-1270)`).
* Implement a Mermaid-specific notebook block rendering path that preserves code-block source/offsets while showing the rendered diagram in notebook UI. This can build on the existing notebook code-block model pattern rather than reusing the non-editable plain image block directly (`app/src/notebooks/editor/model.rs (1462-1760)`, `app/src/notebooks/editor/notebook_command.rs (1-260)`, `editor/src/render/element/runnable_command.rs (1-110)`).
* Add a new feature flag following Warp conventions: Cargo feature, `FeatureFlag` enum entry, app registration, rollout list decision, and notebook-side `is_enabled()` guards. The gate should cover both Mermaid parsing/classification and notebook rendering so the feature can be fully disabled. If the flag is off, we should just render the raw Mermaid diagram text; if it's on, render the diagram in the notebook view.
* Keep clipboard support scoped to normal copy behavior for selected Mermaid blocks. In this implementation, copy preserves plain text and may append HTML for Mermaid rendering, but does not place image bytes on the clipboard. Dedicated image-byte clipboard support or a “Copy image” affordance is deferred to a follow-up if we decide the extra cross-platform and async complexity is worthwhile.
* Add focused tests for Mermaid block recognition, notebook markdown round-tripping, feature-flag gating, and async SVG rendering/cache behavior. The most relevant existing suites are `markdown_parser/src/markdown_parser_test.rs`, `editor/src/content/markdown_tests.rs`, and `app/src/notebooks/editor/model_tests.rs`.
## Parallelization
* After the render shape is agreed, Cargo integration of the external `mermaid_to_svg` dependency and feature-flag plumbing can proceed in parallel with notebook render-path work.
* The markdown/code-block classification change should land before final notebook wiring if it introduces new normalized Mermaid handling; otherwise the notebook render work can temporarily key off the preserved fenced language string and converge afterward.
* Validation should happen after both workstreams merge: parser/editor tests, notebook editor tests, and a full build check in this repo.