From 9e3ec88bc1a7cd813bc4d6cf9bbc2904ba919397 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Wed, 30 Sep 2026 01:17:13 +0100 Subject: [PATCH] fix: preserve table header row in markdown export --- .../collaboration/collaboration.util.spec.ts | 54 +++++++++++++++++++ .../src/lib/markdown/utils/turndown.utils.ts | 6 ++- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 apps/server/src/collaboration/collaboration.util.spec.ts diff --git a/apps/server/src/collaboration/collaboration.util.spec.ts b/apps/server/src/collaboration/collaboration.util.spec.ts new file mode 100644 index 000000000..7115e7c10 --- /dev/null +++ b/apps/server/src/collaboration/collaboration.util.spec.ts @@ -0,0 +1,54 @@ +import { jsonToMarkdown } from './collaboration.util'; + +const cell = (type: 'tableHeader' | 'tableCell', text: string) => ({ + type, + content: [ + { + type: 'paragraph', + content: text ? [{ type: 'text', text }] : [], + }, + ], +}); + +const row = (type: 'tableHeader' | 'tableCell', texts: string[]) => ({ + type: 'tableRow', + content: texts.map((text) => cell(type, text)), +}); + +const tableDoc = (rows: ReturnType[]) => ({ + type: 'doc', + content: [{ type: 'table', content: rows }], +}); + +describe('jsonToMarkdown', () => { + it('uses the table header row as the markdown header', () => { + const markdown = jsonToMarkdown( + tableDoc([ + row('tableHeader', ['Name', 'Role']), + row('tableCell', ['Ada', 'Engineer']), + ]), + ); + + expect(markdown.trim().split('\n')).toEqual([ + '| Name | Role |', + '| --- | --- |', + '| Ada | Engineer |', + ]); + }); + + it('adds an empty header when the table has no header row', () => { + const markdown = jsonToMarkdown( + tableDoc([ + row('tableCell', ['Ada', 'Engineer']), + row('tableCell', ['Alan', 'Mathematician']), + ]), + ); + + expect(markdown.trim().split('\n')).toEqual([ + '| | |', + '| --- | --- |', + '| Ada | Engineer |', + '| Alan | Mathematician |', + ]); + }); +}); diff --git a/packages/editor-ext/src/lib/markdown/utils/turndown.utils.ts b/packages/editor-ext/src/lib/markdown/utils/turndown.utils.ts index 55f4afd37..8316c1bf3 100644 --- a/packages/editor-ext/src/lib/markdown/utils/turndown.utils.ts +++ b/packages/editor-ext/src/lib/markdown/utils/turndown.utils.ts @@ -37,7 +37,11 @@ export function htmlToMarkdown(html: string): string { footnoteRef, footnotesList, ]); - return turndownService.turndown(html).replaceAll('
', ' '); + const htmlWithoutColgroups = html.replace( + /]*>[\s\S]*?<\/colgroup>/gi, + '', + ); + return turndownService.turndown(htmlWithoutColgroups).replaceAll('
', ' '); } function listParagraph(turndownService: _TurndownService) {