From 33dee5f043694d4c42347aa07db49a018114c754 Mon Sep 17 00:00:00 2001 From: vycdev2 Date: Thu, 15 Oct 2026 01:03:30 +0000 Subject: [PATCH 1/2] fix: preserve whitespace-only code spans in Markdown export --- CHANGELOG.md | 1 + src/utils/markdown-export.ts | 7 ++++++- test/markdown-export.spec.ts | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be570f2..0e3192c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ #### Review fixes +- Preserved code spans containing three or more spaces when exporting Todo files to Markdown. - Offered known tag-argument completions inside auto-closed parentheses without inserting a duplicate closing parenthesis. - Preserved punctuation immediately before a completion or elapsed-time tag when reopening a task. - Rejected invalid ISO calendar dates in time estimates instead of silently rolling them into another month. diff --git a/src/utils/markdown-export.ts b/src/utils/markdown-export.ts index 4b9b66c..1e09d35 100644 --- a/src/utils/markdown-export.ts +++ b/src/utils/markdown-export.ts @@ -15,7 +15,12 @@ const escapeMarkdownText = (text: string): string => text.replace(/[!-/:-@[-`{-~ const renderCodeSpan = (content: string): string => { if (!content) return ''; - const needsPadding = (content.startsWith(' ') || content.endsWith(' ')) && !/^ +$/.test(content), + // Markdown trims a space from each end of runs longer than two spaces, + // even when the code span contains nothing but spaces. + const spacesOnly = /^ +$/.test(content), + needsPadding = spacesOnly + ? content.length > 2 + : content.startsWith(' ') || content.endsWith(' '), padding = needsPadding ? ' ' : ''; return `\`${padding}${content}${padding}\``; diff --git a/test/markdown-export.spec.ts b/test/markdown-export.spec.ts index 8dce567..5fcec8f 100644 --- a/test/markdown-export.spec.ts +++ b/test/markdown-export.spec.ts @@ -95,6 +95,15 @@ describe('Todo Markdown export', () => { expect(html).to.include(' code '); }); + it('preserves code spans containing three or more spaces', () => { + const markdown = renderTodoMarkdown('Tasks', [ + { kind: 'comment', level: 0, text: '` ` ` `' }, + ]), + html = new MarkdownIt({ html: true }).render(markdown); + + expect(html).to.include(' '); + }); + it('preserves HTML-like text and entities in rendered Markdown', () => { const markdown = renderTodoMarkdown('Plan ©', [ { kind: 'project', level: 0, text: 'Project ©' }, From 2c0dbe01bc8bd51c2b46f22c183a23bccbad5bf4 Mon Sep 17 00:00:00 2001 From: Victor Sandu Date: Fri, 23 Oct 2026 10:27:07 +0300 Subject: [PATCH 2/2] fix: preserve code spaces across Markdown renderers --- src/utils/markdown-export.ts | 13 +++++-------- test/markdown-export.spec.ts | 20 +++++++++++++------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/utils/markdown-export.ts b/src/utils/markdown-export.ts index 1e09d35..4b9df72 100644 --- a/src/utils/markdown-export.ts +++ b/src/utils/markdown-export.ts @@ -13,14 +13,11 @@ export interface MarkdownExportLine { const escapeMarkdownText = (text: string): string => text.replace(/[!-/:-@[-`{-~]/g, '\\$&'); const renderCodeSpan = (content: string): string => { - if (!content) return ''; - - // Markdown trims a space from each end of runs longer than two spaces, - // even when the code span contains nothing but spaces. - const spacesOnly = /^ +$/.test(content), - needsPadding = spacesOnly - ? content.length > 2 - : content.startsWith(' ') || content.endsWith(' '), + // Renderers disagree on trimming all-space code spans. Inline HTML keeps + // their exact content, including empty spans that backticks cannot express. + if (!content || /^ +$/.test(content)) return `${content}`; + + const needsPadding = content.startsWith(' ') || content.endsWith(' '), padding = needsPadding ? ' ' : ''; return `\`${padding}${content}${padding}\``; diff --git a/test/markdown-export.spec.ts b/test/markdown-export.spec.ts index 5fcec8f..a4936bf 100644 --- a/test/markdown-export.spec.ts +++ b/test/markdown-export.spec.ts @@ -95,13 +95,19 @@ describe('Todo Markdown export', () => { expect(html).to.include(' code '); }); - it('preserves code spans containing three or more spaces', () => { - const markdown = renderTodoMarkdown('Tasks', [ - { kind: 'comment', level: 0, text: '` ` ` `' }, - ]), - html = new MarkdownIt({ html: true }).render(markdown); - - expect(html).to.include(' '); + it('preserves whitespace-only code spans without renderer-specific padding', () => { + for (const length of [1, 2, 3, 4, 8]) { + const spaces = ' '.repeat(length), + markdown = renderTodoMarkdown('Tasks', [ + { kind: 'comment', level: 0, text: `\`${spaces}\`` }, + ]), + html = new MarkdownIt({ html: true }).render(markdown); + + // CommonMark preserves all-space spans, whereas markdown-it 14.1 trims + // runs longer than two spaces. Inline HTML preserves both interpretations. + expect(markdown).to.include(`${spaces}`); + expect(html).to.include(`${spaces}`); + } }); it('preserves HTML-like text and entities in rendered Markdown', () => {