Skip to content

feat: render dot and graphviz fences as ascii diagrams - #48

Merged
denolfe merged 1 commit into
mainfrom
feat/digraph
Aug 8, 2026
Merged

feat: render dot and graphviz fences as ascii diagrams#48
denolfe merged 1 commit into
mainfrom
feat/digraph

Conversation

@denolfe

@denolfe denolfe commented Aug 8, 2026

Copy link
Copy Markdown
Owner

viewmd now renders dot and graphviz fenced code blocks as ASCII diagrams. A new translator converts a subset of DOT into a Mermaid flowchart, which the existing ASCII renderer paints.

DOT diagrams are common in READMEs and skill files, and until now they rendered as raw source inside a framed code block. Mermaid fences already rendered as ASCII, so DOT was the remaining gap.

Before: the fence renders as source text inside a box.

```dot
digraph g { parse -> ast [label="tokens"]; }
```

After: the same fence renders as a diagram.

┌───────┐
│ parse │
└───┬───┘
    │
 tokens
    │
    ▼
┌───────┐
│  ast  │
└───────┘

Key Changes

  • DOT translator
    • dotToMermaid parses DOT and emits a Mermaid flowchart. It is a hand written lexer and parser, so no dependency is added.
    • Covered: graph direction, node and edge labels, edge chains, shapes, default node attributes, cluster subgraphs, and comments.
    • Constructs with no flowchart equivalent throw UnsupportedDotError. These are record shapes, ports, and HTML labels.
  • Fence handling
    • replaceDotBlocks renders dot and graphviz fences through the Mermaid ASCII renderer.
    • Untranslatable DOT falls through to a framed code block. The renderer never throws on bad input.
    • The shared render and fallback path is factored out of replaceMermaidBlocks so both fence types behave the same.
  • Context aware label escaping
    • Labels are emitted unquoted, because the ASCII renderer prints quotation marks literally.
    • Only the character that closes the surrounding wrapper is stripped. A stray closer silently truncates the rest of the graph rather than just the label.
  • Known fidelity limits
    • Shape is carried through the translation, but the renderer paints every node as a rectangle.
    • Line breaks in DOT labels become spaces, because the renderer prints <br/> literally. Undirected edges become arrows, because a flowchart has no undirected edge.
  • Test fixture
    • test/graph-digraph.md exercises each supported construct plus the fallback cases.
    • Equivalence tests assert that a DOT graph and its hand written Mermaid twin paint identical output.

Overall Flow

flowchart TD
  A[markdown source] --> B[replaceMermaidBlocks]
  B --> C[replaceDotBlocks]
  C --> D{dot or graphviz fence?}
  D -->|no| G[buildTree]
  D -->|yes| E[dotToMermaid]
  E -->|translated| F[renderMermaidAscii]
  E -->|UnsupportedDotError| H[leave fence unchanged]
  F -->|rendered| I[mermaidascii fence]
  F -->|throws| H
  I --> G
  H --> G
Loading

The preprocess stage previously ran only the Mermaid pass. DOT now runs as a second pass over the same output.

References / Links

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

Startup benchmark (--render test/exhaustive.md, linux-x64)

build mean ratio verdict
baseline (main@5b74c1e) 722.1ms ± 31.2ms
PR 696.7ms ± 13.0ms 0.96× ✅ ok

Thresholds: warn ≥ 1.1×, fail ≥ 1.25×. Baseline built from main.

@denolfe denolfe changed the title feat(dot): render dot and graphviz fences as ascii diagrams feat: render dot and graphviz fences as ascii diagrams Aug 8, 2026
Translate a subset of DOT into a mermaid flowchart and reuse the existing
ascii renderer. Constructs with no flowchart equivalent (records, ports,
HTML labels) fall through to a framed code block.
@denolfe
denolfe merged commit 416931a into main Aug 8, 2026
8 checks passed
@denolfe
denolfe deleted the feat/digraph branch August 8, 2026 19:28
denolfe added a commit that referenced this pull request Aug 15, 2026
- feat(sidebar): widen content when the toc is hidden (#50) (6cce955)
- feat(sidebar): drag-resize content width with a mouse handle (#49) (daae0b5)
- feat: render dot and graphviz fences as ascii diagrams (#48) (416931a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant