From 411e3dfa0eb73c7b3430dedf22f3a1e0d328808c Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 22 Feb 2025 12:45:21 +0200 Subject: [PATCH] server(export): export Markdown using ATX heading syntax (closes #1251) --- spec/support/utils.ts | 32 ++++++++++++++++++++++++++++++++ src/services/export/md.spec.ts | 24 ++++++++++++++++++++++++ src/services/export/md.ts | 5 ++++- 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/spec/support/utils.ts b/spec/support/utils.ts index 8735c9651..a616c0078 100644 --- a/spec/support/utils.ts +++ b/spec/support/utils.ts @@ -1,3 +1,35 @@ +/** + * Reads the level of indentation of the first line and trims the identation for all the text by that amount. + * + * For example, for: + * + * ```json + * { + * "hello": "world" + * } + * ``` + * + * it results in: + * + * ```json + * { + * "hello": "world" + * } + * ``` + * + * This is meant to be used as a template string, where it allows the indentation of the template without affecting whitespace changes. + * + * @example const html = trimIndentation`\ + *

Heading 1

+ *

Heading 2

+ *

Heading 3

+ *

Heading 4

+ *
Heading 5
+ *
Heading 6
+ * `; + * @param strings + * @returns + */ export function trimIndentation(strings: TemplateStringsArray) { const str = strings.toString(); diff --git a/src/services/export/md.spec.ts b/src/services/export/md.spec.ts index 6facdcba2..400ddd4cc 100644 --- a/src/services/export/md.spec.ts +++ b/src/services/export/md.spec.ts @@ -74,4 +74,28 @@ describe("Markdown export", () => { const expected = "~~hello~~Hello ~~world~~"; expect(markdownExportService.toMarkdown(html)).toBe(expected); }); + + it("exports headings properly", () => { + const html = trimIndentation`\ +

Heading 1

+

Heading 2

+

Heading 3

+

Heading 4

+
Heading 5
+
Heading 6
+ `; + const expected = trimIndentation`\ + # Heading 1 + + ## Heading 2 + + ### Heading 3 + + #### Heading 4 + + ##### Heading 5 + + ###### Heading 6`; + expect(markdownExportService.toMarkdown(html)).toBe(expected); + }); }); diff --git a/src/services/export/md.ts b/src/services/export/md.ts index 5ba3d6e03..669871ff9 100644 --- a/src/services/export/md.ts +++ b/src/services/export/md.ts @@ -24,7 +24,10 @@ const fencedCodeBlockFilter: TurndownService.Rule = { function toMarkdown(content: string) { if (instance === null) { - instance = new TurndownService({ codeBlockStyle: "fenced" }); + instance = new TurndownService({ + headingStyle: "atx", + codeBlockStyle: "fenced" + }); // Filter is heavily based on: https://github.com/mixmark-io/turndown/issues/274#issuecomment-458730974 instance.addRule("fencedCodeBlock", fencedCodeBlockFilter); instance.use(turndownPluginGfm.gfm);