graphite.md
A Markdown preview for people who read a lot of Markdown: collapsible sections, a git-graph style outline, checklists, math, and diagrams — in a dark, distraction-free theme.
Features
Collapsible sections
Every heading in your document collapses and expands independently. Long specs and READMEs stop being one giant scroll.
A git-graph outline
The right-hand "On this page" pane shows your document's structure as a connected graph — not a flat list — split into three views:
- Content — your heading structure, nested exactly as it is in the doc
- Tables — every table in the document, jump straight to any of them
- Diagrams — every diagram, same idea
Only one view is open at a time. Click any node to soft-scroll to that part of the document; the outline highlights where you are as you scroll.
Checklists
Write - [ ] and - [x] as usual. In the preview they render as real, clickable checkboxes — checking one off edits your markdown file directly, so your task list and your document never drift apart.
Math
Inline ($...$) and block ($$...$$) math, rendered with KaTeX.
Diagrams
Fenced ```mermaid code blocks render as live diagrams.
Callouts
Blockquotes (>) get a distinct treatment so notes and asides stand out from body text.
Rich inline syntax
Superscript (^2^), subscript (~2~), underline (++text++), highlighting (==text==), strikethrough (~~text~~), and footnotes ([^1]) all render natively.
Links that go where you meant them to
A relative link opens the file it points at, resolved against the document you're previewing — the same way VS Code's own Markdown preview resolves it. Absolute URLs open in your browser. And a bare filename stays a filename: README.md in a sentence is not turned into a link to http://README.md, which matters because plenty of country domains (.md, .sh, .rs, .pl, .so, .cc) are also file extensions.
Syntax highlighting
Fenced code blocks are highlighted with highlight.js, tinted to match the graphite theme.
Tunable reading width
Set it once in settings.json — the preview picks the new width up immediately, no reload:
{
"graphiteMd.contentWidth": 60
}
Usage
- Open a
.mdfile. - Run graphite.md: Open Preview to the Side from the Command Palette, or press Ctrl+K V (Cmd+K V on macOS).
- The preview updates live as you type.
Settings
| Setting | Type | Default | Description |
|---|---|---|---|
graphiteMd.contentWidth | number (40–100) | 60 | Width of the reading column, as a percentage of the available preview pane width. |
Requirements
VS Code 1.134.0 or later. No other setup — everything the preview needs (KaTeX, Mermaid) ships bundled with the extension.
Known limitations
- Merged-cell tables (
rowspan/colspan) aren't supported yet — a syntax for them is still being designed. (#8) - The preview doesn't yet follow the editor cursor, or the editor the preview. Re-rendering after an edit does preserve your scroll position, so you aren't thrown back to the top.
- After an extension update, the preview can keep running the previous version's bundle until the panel is reopened. Close and reopen the preview if it looks stale; the durable fix is content-hash busting. (#6)
- The outline panel is a fixed width and can't be collapsed yet. (#3)
Contributing
Build instructions and an overview of how the extension is put together are in DEVELOPMENT.md. Bug reports and pull requests are welcome on GitHub.
License
MIT
Documentation
A closer look at how to use each part of the preview.
Opening the preview
With a Markdown file open, run one of these from the Command Palette (Ctrl+Shift+P / Cmd+Shift+P):
- graphite.md: Open Preview — opens in the current editor group
- graphite.md: Open Preview to the Side — opens beside your editor (bound to Ctrl+K V / Cmd+K V)
The preview re-renders automatically as you edit — no manual refresh.
Collapsing sections
Click any heading (or its chevron, hanging in the left margin) to collapse everything under it. Click again to reopen. This only affects what's shown in the reading pane — it doesn't touch your source file.
The "On this page" outline
Three collapsible groups on the right, at most one open at a time:
- Content — your document's heading structure, drawn as a connected graph so nested sections are visually obvious, not just indented text.
- Tables — a flat list of every table in the document.
- Diagrams — a flat list of every Mermaid diagram.
Clicking any node soft-scrolls the reading pane to that spot, opens any collapsed parent sections needed to reveal it (siblings stay untouched), and briefly pulses the node so you can confirm where you landed.
Checklists
Write these like any GitHub-flavored checklist:
- [ ] Not done yet
- [x] Done
They render as clickable boxes:
- Not done yet
- Done
Clicking a box edits the underlying [ ] / [x] in your markdown file directly — the preview never holds state your file doesn't also have.
Math
Inline math sits in a line of text: $w = c + 2p + 2b$. Block math stands alone:
$$
\text{width} = \text{content} + 2\times\text{padding} + 2\times\text{border}
$$
Diagrams
Fence a Mermaid diagram like any code block, just with mermaid as the language:
```mermaid
graph TD
A[Start] --> B{Decision}
B -->|Yes| C[Do this]
B -->|No| D[Do that]
```
Callouts
A normal blockquote:
> Percentages resolve against the parent's content box.
renders as:
Percentages resolve against the parent's content box.
Rich inline syntax
Beyond the usual emphasis, these all render natively:
| Write | Get |
|---|---|
^2^ | superscript |
~2~ | subscript |
++text++ | underlined text |
==text== | highlighted text |
~~text~~ | strikethrough |
[^1] | a footnote reference |
Footnotes collect at the bottom of the preview as a numbered list. Clicking a reference jumps to its note, and the ↩︎ beside the note brings you back to where you were reading.
Water is H~2~O, and E = mc^2^.
Here's a claim that needs a source.[^1]
[^1]: And here's the source.
Code blocks
Fenced code is highlighted with highlight.js, using the language you name after the backticks:
```ts
const answer: number = 42;
```
An unknown or missing language falls back to plain monospace rather than failing.
Reading width
Set the reading column width once in settings.json:
{
"graphiteMd.contentWidth": 60
}
A percentage of the available pane (40–100). Changing the setting updates an already-open preview immediately — there's no in-panel control.
Keyboard shortcuts
| Action | Windows / Linux | macOS |
|---|---|---|
| Open preview to the side | Ctrl+K V | Cmd+K V |
These are real captures. Every image below is graphite.md itself, rendering a document — nothing is mocked up in HTML. The numbered markers are an overlay, not part of the product; the captures underneath are unedited.
The documents are fictional, but they are written the way their kinds are actually written — an engineering RFC, an operator runbook, a systems paper, and an editor's pass on a launch post. A preview is only as convincing as the text inside it, and a document written for a screenshot reads like one.
A Markdown preview for people who read a lot of Markdown.
RFC 014, opened at the top. The outline panel is fully in frame rather than cropped, because it is the thing most previews do not have.
The outline is a graph, not a list.
Scrolled to a level-four heading inside a level-three inside a level-two. The path down to it is drawn, and so is everything hanging off it.
| 1 | The row you are reading is lit, and so is every section above it — one curve for each level the path passes through, so you can see how deep you are without counting indents. |
|---|---|
| 2 | Tables and diagrams keep their own outlines, folded behind their own headers until you want them. |
Ticking a box edits your file.
The runbook's pre-flight checks, source on the left and preview on the right at the same scroll position. Four ticked, two still open.
| 1 | Click a box in the preview and graphite.md rewrites the - [ ] line in the file on the left. There is no separate task list, so the two cannot drift apart. |
|---|
Rendered where you wrote them.
Two scroll positions of the same paper — $$…$$ at the model, a ```mermaid fence at the testbed.
| 1 | Display math, typeset by KaTeX. The same engine renders the inline $T_f$ and $p$ in the table above it. |
|---|---|
| 2 | A mermaid fence, drawn by Mermaid. Both ship inside the extension, so this is what the preview looks like with no network at all. |
Edits read as edits.
An editor's pass on a launch post: cuts, additions and open questions all marked up in the source, all still legible in the preview.
| 1 | A cut stays visible as strikethrough, so the edit is reviewable in the rendered document rather than only in the diff. |
|---|---|
| 2 | Anything still needing a decision is highlighted, and additions are underlined. Three review states, readable in place. |
| 3 | Footnotes link both ways — the ↩ at the end of a note returns to the sentence that cited it. |
The only capture with the editor in frame. The point is the correspondence between the markup on the left and the rendering on the right, which a preview-only crop would throw away.