Skip to content

Commit c34ddb5

Browse files
fix(markdown): don't strikethrough text wrapped in a single tilde (#154)
remark-gfm treats a single ~ around text (e.g. "~10", "1~3") as strikethrough, unlike VS Code's markdown. Pass { singleTilde: false } so only "~~text~~" renders as strikethrough. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 3bd1a80 commit c34ddb5

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

webview-ui/src/components/common/MarkdownBlock.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,9 @@ const MarkdownBlock = memo(({ markdown }: MarkdownBlockProps) => {
307307
<StyledMarkdown>
308308
<ReactMarkdown
309309
remarkPlugins={[
310-
remarkGfm,
310+
// singleTilde: false so a single "~" around text (e.g. "1~3", "~10") is not
311+
// rendered as strikethrough; only "~~text~~" is. Matches VS Code's markdown. (#154)
312+
[remarkGfm, { singleTilde: false }],
311313
remarkMath,
312314
() => {
313315
return (tree: any) => {

webview-ui/src/components/common/__tests__/MarkdownBlock.spec.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,30 @@ describe("MarkdownBlock", () => {
3636
expect(paragraph?.textContent).toBe("Check out this link: https://example.com.")
3737
}, 10000)
3838

39+
it("should not strikethrough text wrapped in a single tilde (#154)", async () => {
40+
const markdown = "1. Lorem ~10 ipsum dolor sit 1~3 amet."
41+
const { container } = render(<MarkdownBlock markdown={markdown} />)
42+
43+
await screen.findByText(/Lorem/, { exact: false })
44+
45+
// Single tildes around numbers must NOT become strikethrough.
46+
expect(container.querySelectorAll("del").length).toBe(0)
47+
const listItem = container.querySelector("li")
48+
expect(listItem?.textContent).toContain("~10")
49+
expect(listItem?.textContent).toContain("1~3")
50+
}, 10000)
51+
52+
it("should still strikethrough text wrapped in double tildes", async () => {
53+
const markdown = "This is ~~struck~~ text."
54+
const { container } = render(<MarkdownBlock markdown={markdown} />)
55+
56+
await screen.findByText(/struck/, { exact: false })
57+
58+
const del = container.querySelector("del")
59+
expect(del).not.toBeNull()
60+
expect(del?.textContent).toBe("struck")
61+
}, 10000)
62+
3963
it("should render unordered lists with proper styling", async () => {
4064
const markdown = `Here are some items:
4165
- First item

0 commit comments

Comments
 (0)