# How the jcode Side Panel Renders Mermaid Diagrams Inline

> Discover how the jcode side panel renders Mermaid diagrams inline. Learn about null-delimited markers, PNG caching, and the jcode-tui-mermaid widget for seamless diagram integration.

- Repository: [Jeremy Huang/jcode](https://github.com/1jehuang/jcode)
- Tags: deep-dive
- Published: 2026-04-30

---

**The jcode side panel renders Mermaid diagrams inline by detecting special null-delimited markers during Markdown parsing, caching the resulting PNGs by content hash, and painting them as `PinnedImagePlacement` instances using the `jcode-tui-mermaid` widget APIs with support for both scale-to-fit and scrollable viewport modes.**

The 1jehuang/jcode repository provides a terminal-based code editor that treats Mermaid diagrams as first-class inline elements within its documentation side panel. Unlike static text, these diagrams render as live images that scroll synchronously with surrounding content and refresh automatically when source files change.

## Markdown Detection and Caching Pipeline

When jcode parses Markdown for the side panel, it identifies Mermaid diagrams through special markers rather than standard code fences. The renderer scans for `\x00MERMAID_IMAGE:…\x00` null-delimited markers (or `JMERMAID:` markers during video export) that embed the diagram's content hash.

In [`src/video_export.rs`](https://github.com/1jehuang/jcode/blob/main/src/video_export.rs), the `find_mermaid_regions` function extracts these hashes and queries the render cache:

```rust
// Simplified lookup during markdown-to-image conversion
let regions = find_mermaid_regions(buffer);
for region in regions {
    if let Some((png_data, width, height)) = crate::tui::mermaid::get_cached_png(region.hash) {
        // Embed the cached PNG into the output
    }
}

```

The caching layer lives in [`crates/jcode-tui-mermaid/src/mermaid_runtime.rs`](https://github.com/1jehuang/jcode/blob/main/crates/jcode-tui-mermaid/src/mermaid_runtime.rs). The `get_cached_png` function provides atomic cache lookups, while `render_mermaid_untracked` handles new renders. When a diagram completes rendering, [`src/tui/mermaid.rs`](https://github.com/1jehuang/jcode/blob/main/src/tui/mermaid.rs) publishes a `BusEvent::MermaidRenderCompleted` event through `install_jcode_mermaid_hooks`, triggering the side panel to repaint with the new cached image.

## Side-Panel Paint Loop Architecture

The core rendering logic resides in [`src/tui/ui_pinned.rs`](https://github.com/1jehuang/jcode/blob/main/src/tui/ui_pinned.rs), specifically within `render_side_panel_markdown_cached` and `render_side_panel_markdown_lines_cached`. During the paint phase (approximately lines 1263–1367), the system iterates over `image_placements` collected during Markdown layout.

Each placement is a `PinnedImagePlacement` struct containing:

- The line number immediately following the marker
- The number of terminal rows the image occupies
- The 64-bit hash identifying the cached PNG
- The `SidePanelImageRenderMode` (`Fit` or `ScrollableViewport`)

The paint loop determines viewport visibility by calculating `y_in_inner` offsets and `avail_rows`. For each visible placement, it retrieves font metrics via `mermaid::get_font_size()` (defaulting to 8×16px) before delegating to the widget layer.

## Render Modes and Widget Implementation

The `jcode-tui-mermaid` crate ([`crates/jcode-tui-mermaid/src/mermaid_widget.rs`](https://github.com/1jehuang/jcode/blob/main/crates/jcode-tui-mermaid/src/mermaid_widget.rs)) provides two primary rendering strategies:

**`render_image_widget_scale`** scales the PNG to fit within the allocated pane area while preserving aspect ratio. This mode respects the `Fit` placement type.

**`render_image_widget_viewport`** creates a scrollable viewport into the full-resolution diagram, controlled by a `zoom_percent` parameter. This implements the `ScrollableViewport` placement type.

When a cached PNG exists, the code calls `plan_fit_image_render` (an internal layout planner) to compute the exact terminal cells available. If the cache misses, the system falls back to `render_image_widget_scale` with a placeholder hash, displaying a loading state until the render completes.

## Debug and Layout Inspection

For diagnostic purposes, [`src/tui/ui_pinned_mermaid_debug.rs`](https://github.com/1jehuang/jcode/blob/main/src/tui/ui_pinned_mermaid_debug.rs) exports `debug_probe_side_panel_mermaid`, which constructs `SidePanelVisibleMermaidDebug` structs for every visible diagram. This function leverages `build_side_panel_mermaid_probe_from_image` to calculate:

- Layout fit rectangles (`layout_fit`)
- Widget fit rectangles (`widget_fit`)
- Area utilization percentages (`area_utilization_percent`)
- Render mode classifications

When users invoke the `client:side-panel:stats` command, the system returns a `SidePanelLiveDebugSnapshot` containing the complete `visible_mermaids` vector with precise layout statistics for each diagram currently displayed in the viewport.

## Practical Implementation Example

To replicate the side-panel rendering pipeline programmatically:

```rust
// 1. Install hooks at application startup
jcode::tui::mermaid::install_jcode_mermaid_hooks();

// 2. Render the side panel (simplified)
let side_panel = app.side_panel();
let pane = side_panel.render(&mut frame, area);

// 3. Generate a debug snapshot for inspection
let snapshot = jcode::tui::ui_pinned_mermaid_debug::debug_probe_side_panel_mermaid(
    "# flowchart TD; A-->B;",

    pane_width_cells,
    pane_height_cells,
    None,        // default font size
    false,       // not centred
)?;
println!("{:#?}", snapshot);

```

This code initializes the Mermaid subsystem, renders the side-panel content, and returns a complete diagnostic snapshot including layout metrics for every visible diagram.

## Summary

- **Marker Detection**: The side panel identifies Mermaid content via `\x00MERMAID_IMAGE:…\x00` markers during Markdown parsing in [`src/tui/ui_pinned.rs`](https://github.com/1jehuang/jcode/blob/main/src/tui/ui_pinned.rs).
- **Cache Integration**: Rendered PNGs are stored in an in-process cache keyed by hash, accessed through `get_cached_png` and updated via `BusEvent::MermaidRenderCompleted`.
- **Placement Strategy**: Diagrams are positioned using `PinnedImagePlacement` records that track line numbers, row spans, and render modes.
- **Widget Rendering**: The `jcode-tui-mermaid` crate provides `render_image_widget_scale` for fit-to-pane viewing and `render_image_widget_viewport` for zoomed scrollable diagrams.
- **Debug Observability**: `SidePanelVisibleMermaidDebug` captures precise layout statistics including cell utilization percentages and fit rectangles.

## Frequently Asked Questions

### What file contains the core side-panel rendering logic for Mermaid diagrams?

The primary implementation lives in [`src/tui/ui_pinned.rs`](https://github.com/1jehuang/jcode/blob/main/src/tui/ui_pinned.rs), specifically within the `render_side_panel_markdown_cached` and `render_side_panel_markdown` functions (around lines 1263–1367). This module coordinates the paint loop, viewport calculations, and delegation to the widget layer.

### How does jcode cache Mermaid diagram renders?

The system caches rendered PNGs in memory using the diagram's content hash as the key. The [`crates/jcode-tui-mermaid/src/mermaid_runtime.rs`](https://github.com/1jehuang/jcode/blob/main/crates/jcode-tui-mermaid/src/mermaid_runtime.rs) file provides `get_cached_png` for lookups and `render_mermaid_untracked` for generating new renders, while [`src/tui/mermaid.rs`](https://github.com/1jehuang/jcode/blob/main/src/tui/mermaid.rs) publishes completion events to trigger UI refreshes.

### What are the two render modes available for Mermaid diagrams in the side panel?

Jcode supports `SidePanelImageRenderMode::Fit`, which scales the diagram to fit the available pane width while maintaining aspect ratio, and `SidePanelImageRenderMode::ScrollableViewport`, which displays the diagram at a configurable zoom level and allows vertical scrolling within the allocated rows.

### How can I debug Mermaid layout issues in the jcode side panel?

Use the `client:side-panel:stats` command, which invokes `debug_probe_side_panel_mermaid` from [`src/tui/ui_pinned_mermaid_debug.rs`](https://github.com/1jehuang/jcode/blob/main/src/tui/ui_pinned_mermaid_debug.rs). This returns a `SidePanelLiveDebugSnapshot` containing `SidePanelVisibleMermaidDebug` entries with detailed metrics including `layout_fit`, `widget_fit`, `area_utilization_percent`, and the exact render mode applied to each visible diagram.