From 9e6e692d2b7ad1f21b0cd12e2dfae41e94c62ec6 Mon Sep 17 00:00:00 2001 From: Gokul Krishna Date: Thu, 27 Aug 2026 22:28:44 +0530 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8(frontend)=20add=20markdown=20down?= =?UTF-8?q?load=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reuse the editor's Markdown serializer to download document content as a UTF-8 .md file. Add browser coverage for the filename and exported content. Signed-off-by: Gokul Krishna --- .../__tests__/app-impress/doc-export.spec.ts | 28 ++++++++++++++++++- .../doc-export/components/ModalExport.tsx | 15 +++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts index c6dfbb6834..6bf41e732f 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-export.spec.ts @@ -30,7 +30,7 @@ test.describe('Doc Export', () => { await expect(page.getByTestId('modal-export-title')).toBeVisible(); await expect( page.getByText( - 'Export your document to download in .pdf, .docx, .odt or .html(zip) format.', + 'Export your document to download in .pdf, .docx, .odt, .md or .html(zip) format.', ), ).toBeVisible(); await expect(page.getByRole('combobox', { name: 'Format' })).toBeVisible(); @@ -94,6 +94,32 @@ test.describe('Doc Export', () => { expect(download.suggestedFilename()).toBe(`${randomDoc}.odt`); }); + test('it exports the doc to markdown', async ({ page, browserName }) => { + const [randomDoc] = await createDoc( + page, + 'doc-editor-markdown', + browserName, + 1, + ); + + await verifyDocName(page, randomDoc); + await writeInEditor({ page, text: 'Hello Markdown export' }); + + await clickInEditorMenu(page, 'Download'); + + await page.getByRole('combobox', { name: 'Format' }).click(); + await page.getByRole('option', { name: 'Markdown' }).click(); + + const downloadPromise = page.waitForEvent('download'); + await page.getByTestId('doc-export-download-button').click(); + + const download = await downloadPromise; + expect(download.suggestedFilename()).toBe(`${randomDoc}.md`); + + const markdownBuffer = await cs.toBuffer(await download.createReadStream()); + expect(markdownBuffer.toString('utf8')).toContain('Hello Markdown export'); + }); + test('it exports the doc to html zip', async ({ page, browserName }) => { const [randomDoc] = await createDoc( page, diff --git a/src/frontend/apps/impress/src/features/docs/doc-export/components/ModalExport.tsx b/src/frontend/apps/impress/src/features/docs/doc-export/components/ModalExport.tsx index 70a5188981..2ddd8ddc1d 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-export/components/ModalExport.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-export/components/ModalExport.tsx @@ -59,6 +59,11 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => { const formatSelect = useMemo(() => { const formatOptions = (exportAGPL?.formats || []).concat([ + { + label: t('Markdown'), + value: 'markdown', + labelDescription: t('.md'), + }, { label: t('HTML'), value: 'html', @@ -101,6 +106,13 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => { let blobExport = await exportAGPL?.docToBlob(format, documentTitle); + if (!blobExport && format === 'markdown') { + const markdown = await editor.blocksToMarkdownLossy(); + blobExport = new Blob([markdown], { + type: 'text/markdown;charset=utf-8', + }); + } + if (!blobExport && format === 'html') { // Use BlockNote "full HTML" export so that we stay closer to the editor rendering. const fullHtml = await editor.blocksToFullHTML(); @@ -142,7 +154,8 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => { return; } - const downloadExtension = format === 'html' ? 'zip' : format; + const downloadExtension = + format === 'html' ? 'zip' : format === 'markdown' ? 'md' : format; downloadFile(blobExport, `${filename}.${downloadExtension}`); From bcbe755f1be5ab110812e6f47fdb51ee4cb0a8ff Mon Sep 17 00:00:00 2001 From: Gokul Krishna Date: Thu, 27 Aug 2026 22:31:02 +0530 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=93=9D(changelog)=20document=20markdo?= =?UTF-8?q?wn=20download?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the Markdown download option to the unreleased changelog for pull request #2608. Signed-off-by: Gokul Krishna --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4e42d1b58..23a369d52b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to ### Added +- ✨(frontend) add markdown download option #2608 - ✨(frontend) Add "Copy link to block" feature #2547 ### Changed