How Diagram Design Handles Importing Mermaid Diagrams: Architecture and Implementation

Diagram Design imports Mermaid diagrams through a dedicated Python extractor that performs fully-sandboxed parsing without JavaScript execution, converting source files into a normalized intermediate representation (IR) for Markdown or JSON output.

The cathrynlavery/diagram-design repository provides a robust pipeline for importing Mermaid diagrams that prioritizes security and programmability. Unlike browser-based renderers, this implementation parses Mermaid syntax directly in Python according to a strictly bounded 12-step architecture, enabling automated analysis of diagram structures in CI/CD workflows.

The Import Pipeline Architecture

The Mermaid import process follows a deterministic pipeline orchestrated by skills/diagram-design/scripts/mermaid_extract.py. This extractor operates without ever invoking Mermaid's JavaScript engine or performing network fetches, satisfying strict security requirements for processing untrusted diagram sources.

Command Invocation and Entry Point

When a user executes diagram-design import-mermaid <file>, the command definition in commands/import-mermaid.md forwards arguments to the Python extractor. The main() function (lines 9-14) parses CLI flags, validates the input path, and calls load_blocks() to locate Mermaid content within the source file.

Block Extraction and Preprocessing

The load_blocks() function (lines 28-60) handles three input variants:

  • Raw .mmd or .mermaid files
  • Markdown files containing fenced Mermaid blocks (```mermaid)
  • Multi-diagram documents with front-matter

This function discards YAML front-matter delimited by --- and ignores Mermaid directives (%%{…}%%). Errors are raised for missing fences, unsupported extensions, or oversized files. Subsequently, _prepared_lines() (lines 81-108) strips remaining comments and directives, returning a list of (source_line, text) tuples ready for grammar parsing.

Diagram Type Detection

The _kind_and_direction() function in skills/diagram-design/scripts/mermaid_input.py (lines 11-33) inspects the first non-empty line to classify the diagram into one of four supported types:

  • flowchart
  • sequenceDiagram
  • stateDiagram-v2
  • erDiagram

Unsupported diagram kinds (pie, gantt, etc.) trigger graceful failures with descriptive error messages.

Grammar-Specific Parsing

Depending on the detected type, the extractor invokes one of four specialized parsers within mermaid_extract.py:

  • _parse_flowchart() (lines 703-773): Handles node definitions, edge operators (-->, -.->, ==>), and subgraphs
  • _parse_sequence() (lines 774-843): Parses actors, messages, loops, and alt blocks
  • _parse_state() (lines 998-1056): Processes state transitions and composite states
  • _parse_er() (lines 1059-1084): Extracts entity relationships and cardinality notation

Each parser constructs a Diagram object populated with Node and Edge dataclasses, representing the normalized IR independent of Mermaid's native format.

Safety Measures and Resource Limits

The extractor implements defense-in-depth sanitization:

  • clean_label() (lines 94-108): Removes HTML tags, resolves HTML entities, strips Markdown emphasis, and normalizes line-breaks
  • _strip_class_suffix() (lines 114-124): Removes CSS class annotations (:::className) from node definitions
  • _parse_expanded_attributes() (lines 126-155): Parses extended attribute syntax @{ shape: ..., label: ... } while discarding URLs or icon references to prevent injection attacks

Hard resource caps prevent denial-of-service:

  • MAX_SOURCE_BYTES = 4 MiB
  • MAX_NODES = 2000
  • MAX_EDGES = 5000

Violations abort processing with exit code 2 before parsing consumes excessive memory.

Analysis and Output Generation

After parsing, _finalize_degrees() computes in-degree and out-degree metrics for each node. The analyze() function (lines 665-735) derives structural metadata including cycle detection, hub ranking using centrality algorithms, collapsible group identification, and complexity budget checks.

The pipeline supports two output modes:

  1. JSON serialization: to_json() (lines 1320-1389) exports the complete IR including nodes, edges, and analysis metadata
  2. Markdown digest: digest() (lines 1446-1608) generates human-readable tables with escaped markup to prevent rendering side effects

Using the Import Command

Import a raw Mermaid file and view the digest:

diagram-design import-mermaid examples/flowchart.mmd

Extract a specific diagram from a Markdown file containing multiple fenced blocks, outputting JSON:

diagram-design import-mermaid docs/multi-diagram.md --diagram 2 --json > ir.json

Limit output rows for large diagrams:

diagram-design import-mermaid examples/large.mmd --max-rows 10

Programmatic usage in Python:

from pathlib import Path
from skills.diagram_design.scripts.mermaid_extract import load_blocks, parse_block, digest

path = Path("examples/flowchart.mmd")
blocks = load_blocks(path)
diagrams = [parse_block(b) for b in blocks]
print(digest(path, diagrams, diagrams[:1], max_rows=30))

Verification and Documentation Integrity

The scripts/verify-mermaid-import.py test suite validates the extractor through structural and adversarial testing, covering shape vocabulary validation, edge form verification, front-matter handling, UTF-8 safety, and malformed edge detection.

The check_docs_and_wiring() function (lines 773-826) within the verification script ensures synchronization between:

  • SKILL.md (skill metadata)
  • commands/import-mermaid.md (CLI definition)
  • prompts/import-mermaid.md (AI assistant discovery)
  • references/import-mermaid.md (human documentation)

This prevents documentation drift and guarantees that the command, prompt, and skill description all reference the same extractor implementation.

Summary

  • Diagram Design imports Mermaid diagrams through a Python-based extractor in mermaid_extract.py invoked via the import-mermaid command.
  • The pipeline handles raw .mmd files or fenced blocks in Markdown, supporting flowchart, sequenceDiagram, stateDiagram-v2, and erDiagram types.
  • Security is enforced through HTML sanitization, class suffix stripping, resource limits (4 MiB source, 2000 nodes, 5000 edges), and zero JavaScript execution.
  • Output formats include human-readable Markdown digests via digest() or machine-readable JSON via to_json().
  • Validation occurs through scripts/verify-mermaid-import.py, which tests structural integrity and maintains documentation consistency via check_docs_and_wiring().

Frequently Asked Questions

Which Mermaid diagram types can Diagram Design import?

Diagram Design supports flowchart, sequenceDiagram, stateDiagram-v2, and erDiagram types through dedicated parsers in mermaid_extract.py. The _kind_and_direction() function detects the diagram type by inspecting the first non-empty line; unsupported types like pie charts or Gantt charts result in graceful failures with exit code 2.

How does the extractor handle large or complex diagrams?

The implementation enforces hard resource caps defined in mermaid_extract.py: MAX_SOURCE_BYTES (4 MiB), MAX_NODES (2000), and MAX_EDGES (5000). Files exceeding these limits abort immediately with exit code 2, preventing memory exhaustion and ensuring predictable performance in automated pipelines.

Can I import Mermaid diagrams embedded within Markdown files?

Yes. The load_blocks() function automatically detects whether the input is a raw .mmd file or a Markdown document containing fenced Mermaid blocks (```mermaid). It extracts all diagram blocks while discarding surrounding Markdown content and YAML front-matter, enabling batch processing of documentation repositories.

Is the import process secure for untrusted diagram sources?

Yes. The extractor operates in a fully sandboxed Python environment without executing Mermaid's JavaScript engine or performing network fetches. Security layers include clean_label() for HTML entity sanitization, _strip_class_suffix() for CSS class removal, and _parse_expanded_attributes() for URL filtering, making it safe for processing arbitrary user-submitted diagrams.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →