Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@

All notable changes to **Rich Markdown Diff** will be documented in this file.

## [1.5.0] - 2026-08-DD

### Added in 1.5.0

- **Visual Conflict Resolver**: Interactive 3-way merge editor for resolving Git merge conflicts (`<<<<<<<`, `=======`, `>>>>>>>`) directly in rendered Markdown.
- **Semantic Mermaid Diff**: Element-level diff highlighting for Mermaid flowcharts with dynamic color-coding and ghost outlines.
- **HTML Export**: Export rendered side-by-side or inline diffs to standalone HTML files via the `Export Rendered Diff to HTML` command.
- **Custom Diff Colors & View Preferences**: Added settings for custom insertion/deletion highlight colors and default view/folding modes.
- **Committed Revision Diffs**: Render visual diffs for committed revisions from Git history and the editor context menu.

### Fixed in 1.5.0

- **Stability & Edge Cases**:
- Fixed frontmatter parser error when metadata keys include `hasOwnProperty`.
- Fixed MDX `<TabItem>` tag counting inside `<Tabs>` blocks.
- Resolved table diff `TypeError` on rows with fewer columns than the header.
- Added support for 64-character SHA-256 commit hashes in Git Blame.
- Fixed line number data-attribute injection when HTML tags contain `>`.
- Hardened validation for webview edit message payloads.

## [1.4.0] - 2026-07-19

### Added in 1.4.0
Expand Down
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ A professional VS Code extension for visual Markdown comparison. Compare rendere
## Key Features

- **Visual Diff**: Compare rendered HTML side-by-side or inline instead of raw source code.
- ⚔️ **Visual Conflict Resolver**: Resolve Git merge conflicts (`<<<<<<<`, `|||||||`, `=======`, `>>>>>>>`) in rendered Markdown with an interactive 3-Way Merge View (`Accept Mine`, `Accept Theirs`, `Accept Both`).
- 📊 **Semantic Mermaid Diff**: Element-level diff highlighting for Mermaid flowcharts. Added, deleted, and modified nodes and edges are dynamically color-coded with ghost outlines for deleted elements.
- **Git Integration**: Compare changes directly from the VS Code Source Control view (Workspace, Staged, or HEAD).
- **Git Blame**: Hover over any line in the diff view to instantly see its commit author and history.
- **Interactive Image Diff**: Compare visual changes in images using "Swipe" and "Onion Skin" comparison modes.
Expand All @@ -21,14 +23,15 @@ A professional VS Code extension for visual Markdown comparison. Compare rendere
| **MDX / Custom** | Native diffing for MDX, Docusaurus, and Astro Starlight components (Tabs, Steps, Badges, Cards, and Admonitions). |
| **Marp** | Render and diff slide decks with full theme support. |
| **Math** | High-quality KaTeX rendering for formulas. |
| **Mermaid** | Flowcharts, sequence diagrams, and Gantt charts with VS Code theme-aware rendering. |
| **Mermaid** | Flowcharts with element-level diff highlighting, plus sequence diagrams and Gantt charts with VS Code theme-aware rendering. |
| **Obsidian** | Native support for Tags (`#tag`) and Transclusions (`![[link]]`). |
| **Alerts** | GitHub-style `[!NOTE]`, `[!WARNING]`, etc. |
| **Structure** | Robust diffing for Tables, Nested Lists, Footnotes, and block-level math/code changes. |
| **Misc** | Wikilinks, Emoji, Sub/Superscript, and Definition Lists. |

## Use Cases

- ⚔️ **Merge Conflicts**: Resolve Git merge conflicts in Markdown docs visually rather than inspecting raw syntax markers.
- 🖼️ **Marp Presentations**: Verify slide layout and theme changes visually.
- 📚 **Knowledge Bases**: Review changes in foam/wiki notes with wikilinks and footnotes.
- 🌐 **Modern Tech Docs**: Catch rendering issues in MDX, Docusaurus, and Astro Starlight components.
Expand All @@ -42,12 +45,30 @@ A professional VS Code extension for visual Markdown comparison. Compare rendere
Select two `.md` files in the Explorer, right-click, and select **Show Markdown Diff**.

### 2. Git & SCM
Click the **Show Markdown Diff** icon next to any modified Markdown file in the Source Control view.
- **Working Tree & Staged**: Click the **Show Markdown Diff** icon next to any modified Markdown file in the Source Control view.
- **Committed Revisions**: When viewing committed file diffs from Git history or the Git Graph, click the **Show Markdown Diff** icon in the editor title bar or right-click inside the diff editor and choose **Show Rich Markdown Diff**.

![SCM Diff](https://raw.githubusercontent.com/phine-apps/rich-markdown-diff/main/images/scm-diff.gif)

### 3. Clipboard Comparison
Right-click in any Markdown editor and choose **Compare with Clipboard**.
Right-click in any Markdown editor and choose **Compare with Clipboard** (or press `Cmd+Shift+C` / `Ctrl+Shift+C`).

### 4. Visual Conflict Resolver
Right-click any Markdown file containing Git conflict markers, choose **Open With...**, and select **Markdown Visual Conflict Resolver**. Click **Accept Mine**, **Accept Theirs**, or **Accept Both** on any conflict block to resolve it directly.

### 5. Export to HTML
Click the **Export to HTML** icon in the diff view toolbar, or run **Export Rendered Diff to HTML** from the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`) to generate a standalone HTML document.

## Keyboard Shortcuts

The following default shortcuts are available when the visual diff panel is active:

| Shortcut (Mac) | Shortcut (Windows/Linux) | Command | Description |
| --- | --- | --- | --- |
| `F7` / `Shift+F7` | `F7` / `Shift+F7` | Next / Previous Change | Jump to the next or previous diff highlight. |
| `Alt+F7` | `Alt+F7` | Toggle Inline View | Toggle between Side-by-Side and Inline diff layouts. |
| `Alt+F8` | `Alt+F8` | Toggle Fold Unchanged | Fold or unfold unchanged Markdown blocks. |
| `Cmd+Shift+C` | `Ctrl+Shift+C` | Compare with Clipboard | Compare active Markdown document with clipboard content. |

## Technical Details

Expand Down
42 changes: 28 additions & 14 deletions fixtures/expected/comprehensive.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,7 @@ <h2 data-line="64" data-line-end="65">Math (KaTeX)</h2>
M834 80h400000v40h-400000z"></path></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.190845em"><span></span></span></span></span></span></span></span></span></span></p>
<ins class="diffins diff-block"><p data-line="74" data-line-end="75">New equation added:</p></ins><ins class="diffins diff-block"><p class="katex-block" data-line="76" data-line-end="79"><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>n</mi></munderover><mi>i</mi><mo>=</mo><mfrac><mrow><mi>n</mi><mo>(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo>)</mo></mrow><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.929066em;vertical-align:-1.277669em"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.6513970000000002em"><span style="top:-1.872331em;margin-left:0em"><span class="pstrut" style="height:3.05em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class="mrel mtight">=</span><span class="mord mtight">1</span></span></span></span><span style="top:-3.050005em"><span class="pstrut" style="height:3.05em"></span><span><span class="mop op-symbol large-op">∑</span></span></span><span style="top:-4.3000050000000005em;margin-left:0em"><span class="pstrut" style="height:3.05em"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.277669em"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em"></span><span class="mord mathnormal">i</span><span class="mspace" style="margin-right:0.2777777777777778em"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em"></span></span><span class="base"><span class="strut" style="height:2.113em;vertical-align:-0.686em"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em"><span style="top:-2.314em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.23em"><span class="pstrut" style="height:3em"></span><span class="frac-line" style="border-bottom-width:0.04em"></span></span><span style="top:-3.677em"><span class="pstrut" style="height:3em"></span><span class="mord"><span class="mord mathnormal">n</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p></ins><h2 data-line="80" data-line-end="81">Mermaid Diagrams</h2>
<del class="diffmod diff-block"><div class="mermaid" data-line="72" data-line-end="78" data-original-content="graph TD;
A--&gt;B;
B--&gt;C;
C--&gt;D;
">
graph TD;
A--&gt;B;
B--&gt;C;
C--&gt;D;

</div></del><ins class="diffmod diff-block"><div class="mermaid" data-line="82" data-line-end="94" data-original-content="graph TD
<div class="mermaid" data-line="82" data-line-end="94" data-original-content="graph TD
A[Start] --&gt; B{Decision}
B -- Yes --&gt; C[Process One]
B -- No --&gt; D[Process Two]
Expand All @@ -106,8 +96,7 @@ <h2 data-line="64" data-line-end="65">Math (KaTeX)</h2>
E --&gt; H[End]
F --&gt; H
G --&gt; H
">
graph TD
">graph TD
A[Start] --&gt; B{Decision}
B -- Yes --&gt; C[Process One]
B -- No --&gt; D[Process Two]
Expand All @@ -118,7 +107,32 @@ <h2 data-line="64" data-line-end="65">Math (KaTeX)</h2>
F --&gt; H
G --&gt; H

</div></ins><h2 data-line="95" data-line-end="96">GitHub Alerts</h2>
%% Ghost definitions for deleted elements
A--[&quot;A--&quot;]
B--[&quot;B--&quot;]
C--[&quot;C--&quot;]
C -.-&gt; D

%% Dynamic Diff Styles
style A fill:#e6ffec,stroke:#22863a,stroke-width:2px;
style E fill:#e6ffec,stroke:#22863a,stroke-width:2px;
style F fill:#e6ffec,stroke:#22863a,stroke-width:2px;
style G fill:#e6ffec,stroke:#22863a,stroke-width:2px;
style H fill:#e6ffec,stroke:#22863a,stroke-width:2px;
style A-- fill:#ffeef0,stroke:#d73a49,stroke-width:1px,stroke-dasharray:5 5,opacity:0.75;
style B-- fill:#ffeef0,stroke:#d73a49,stroke-width:1px,stroke-dasharray:5 5,opacity:0.75;
style C-- fill:#ffeef0,stroke:#d73a49,stroke-width:1px,stroke-dasharray:5 5,opacity:0.75;
style B fill:#fffdef,stroke:#b08800,stroke-width:2px;
style C fill:#fffdef,stroke:#b08800,stroke-width:2px;
style D fill:#fffdef,stroke:#b08800,stroke-width:2px;
linkStyle 2 stroke:#22863a,stroke-width:2px;
linkStyle 3 stroke:#22863a,stroke-width:2px;
linkStyle 4 stroke:#22863a,stroke-width:2px;
linkStyle 5 stroke:#22863a,stroke-width:2px;
linkStyle 6 stroke:#22863a,stroke-width:2px;
linkStyle 7 stroke:#22863a,stroke-width:2px;
linkStyle 8 stroke:#22863a,stroke-width:2px;
linkStyle 9 stroke:#d73a49,stroke-width:1px,stroke-dasharray:3 3,opacity:0.75;</div><h2 data-line="95" data-line-end="96">GitHub Alerts</h2>
<div class="markdown-alert markdown-alert-note" data-line="97" data-line-end="99"><p class="markdown-alert-title"><svg class="octicon octicon-info mr-2" width="16" height="16" aria-hidden="true"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>Note</p>
<p data-line="97" data-line-end="99">This is a note alert<ins class="diffins">&nbsp;with updated content</ins>.</p></div>
<div class="markdown-alert markdown-alert-warning" data-line="100" data-line-end="102"><p class="markdown-alert-title"><svg class="octicon octicon-alert mr-2" width="16" height="16" aria-hidden="true"><path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path></svg>Warning</p><p data-line="100" data-line-end="102">This is a warning alert.</p>
Expand Down
14 changes: 12 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"publisher": "phine-apps",
"displayName": "Rich Markdown Diff",
"description": "Professional visual Markdown diff with Math, Mermaid, and Git integration for better document reviews.",
"version": "1.4.0",
"version": "1.5.0",
"icon": "images/icon.png",
"author": "phine-apps",
"license": "MIT",
Expand Down Expand Up @@ -313,6 +313,16 @@
}
],
"priority": "option"
},
{
"viewType": "rich-markdown-diff.conflictResolver",
"displayName": "Markdown Visual Conflict Resolver",
"selector": [
{
"filenamePattern": "*.md"
}
],
"priority": "option"
}
]
},
Expand Down Expand Up @@ -348,7 +358,7 @@
"@typescript-eslint/eslint-plugin": "^8.63.0",
"@typescript-eslint/parser": "^8.63.0",
"@vscode/l10n-dev": "^0.0.35",
"@vscode/test-electron": "^3.0.0",
"@vscode/test-electron": "^3.1.0",
"@vscode/vsce": "^3.9.2",
"esbuild": "^0.28.1",
"eslint": "^10.7.0",
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading