diff --git a/apps/server/src/services/export/zip.ts b/apps/server/src/services/export/zip.ts index f6c131d87..84d84871c 100644 --- a/apps/server/src/services/export/zip.ts +++ b/apps/server/src/services/export/zip.ts @@ -1,10 +1,8 @@ "use strict"; -import html from "html"; import dateUtils from "../date_utils.js"; import path from "path"; import mimeTypes from "mime-types"; -import mdService from "./markdown.js"; import packageInfo from "../../../package.json" with { type: "json" }; import { getContentDisposition, escapeHtml } from "../utils.js"; import protectedSessionService from "../protected_session.js"; @@ -22,27 +20,9 @@ import type BBranch from "../../becca/entities/bbranch.js"; import type { Response } from "express"; import type { NoteMetaFile } from "../meta/note_meta.js"; import HtmlExportProvider from "./zip/html.js"; -import { ZipExportProvider, ZipExportProviderData } from "./zip/abstract_provider.js"; +import { AdvancedExportOptions, ZipExportProvider, ZipExportProviderData } from "./zip/abstract_provider.js"; import MarkdownExportProvider from "./zip/markdown.js"; -type RewriteLinksFn = (content: string, noteMeta: NoteMeta) => string; - -export interface AdvancedExportOptions { - /** - * If `true`, then only the note's content will be kept. If `false` (default), then each page will have its own template. - */ - skipHtmlTemplate?: boolean; - - /** - * Provides a custom function to rewrite the links found in HTML or Markdown notes. This method is called for every note imported, if it's of the right type. - * - * @param originalRewriteLinks the original rewrite links function. Can be used to access the default behaviour without having to reimplement it. - * @param getNoteTargetUrl the method to obtain a note's target URL, used internally by `originalRewriteLinks` but can be used here as well. - * @returns a function to rewrite the links in HTML or Markdown notes. - */ - customRewriteLinks?: (originalRewriteLinks: RewriteLinksFn, getNoteTargetUrl: (targetNoteId: string, sourceMeta: NoteMeta) => string | null) => RewriteLinksFn; -} - async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "html" | "markdown", res: Response | fs.WriteStream, setHeaders = true, zipExportOptions?: AdvancedExportOptions) { if (!["html", "markdown"].includes(format)) { throw new ValidationError(`Only 'html' and 'markdown' allowed as export format, '${format}' given`); @@ -322,47 +302,7 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h content = rewriteFn(content, noteMeta); } - if (noteMeta.format === "html" && typeof content === "string") { - if (!content.substr(0, 100).toLowerCase().includes(" element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809 - content = ` - - - - - - ${htmlTitle} - - -
-

${htmlTitle}

- -
${content}
-
- -`; - } - - return content.length < 100_000 ? html.prettyPrint(content, { indent_size: 2 }) : content; - } else if (noteMeta.format === "markdown" && typeof content === "string") { - let markdownContent = mdService.toMarkdown(content); - - if (markdownContent.trim().length > 0 && !markdownContent.startsWith("# ")) { - markdownContent = `# ${title}\r -${markdownContent}`; - } - - return markdownContent; - } else { - return content; - } + return provider.prepareContent(title, content, noteMeta); } function saveNote(noteMeta: NoteMeta, filePathPrefix: string) { diff --git a/apps/server/src/services/export/zip/abstract_provider.ts b/apps/server/src/services/export/zip/abstract_provider.ts index 5f3502107..ceadc0ec1 100644 --- a/apps/server/src/services/export/zip/abstract_provider.ts +++ b/apps/server/src/services/export/zip/abstract_provider.ts @@ -1,11 +1,30 @@ import { Archiver } from "archiver"; import type { default as NoteMeta, NoteMetaFile } from "../../meta/note_meta.js"; +type RewriteLinksFn = (content: string, noteMeta: NoteMeta) => string; + +export interface AdvancedExportOptions { + /** + * If `true`, then only the note's content will be kept. If `false` (default), then each page will have its own template. + */ + skipHtmlTemplate?: boolean; + + /** + * Provides a custom function to rewrite the links found in HTML or Markdown notes. This method is called for every note imported, if it's of the right type. + * + * @param originalRewriteLinks the original rewrite links function. Can be used to access the default behaviour without having to reimplement it. + * @param getNoteTargetUrl the method to obtain a note's target URL, used internally by `originalRewriteLinks` but can be used here as well. + * @returns a function to rewrite the links in HTML or Markdown notes. + */ + customRewriteLinks?: (originalRewriteLinks: RewriteLinksFn, getNoteTargetUrl: (targetNoteId: string, sourceMeta: NoteMeta) => string | null) => RewriteLinksFn; +} + export interface ZipExportProviderData { getNoteTargetUrl: (targetNoteId: string, sourceMeta: NoteMeta) => string | null; metaFile: NoteMetaFile; rootMeta: NoteMeta; archive: Archiver; + zipExportOptions?: AdvancedExportOptions; } export abstract class ZipExportProvider { @@ -14,14 +33,17 @@ export abstract class ZipExportProvider { getNoteTargetUrl: (targetNoteId: string, sourceMeta: NoteMeta) => string | null; rootMeta: NoteMeta; archive: Archiver; + zipExportOptions?: AdvancedExportOptions; constructor(data: ZipExportProviderData) { this.metaFile = data.metaFile; this.getNoteTargetUrl = data.getNoteTargetUrl; this.rootMeta = data.rootMeta; this.archive = data.archive; + this.zipExportOptions = data.zipExportOptions; } abstract prepareMeta(): void; + abstract prepareContent(title: string, content: string | Buffer, noteMeta: NoteMeta): string | Buffer; abstract afterDone(): void; } diff --git a/apps/server/src/services/export/zip/html.ts b/apps/server/src/services/export/zip/html.ts index 517552e1d..0eac07fb8 100644 --- a/apps/server/src/services/export/zip/html.ts +++ b/apps/server/src/services/export/zip/html.ts @@ -33,6 +33,41 @@ export default class HtmlExportProvider extends ZipExportProvider { this.metaFile.files.push(this.cssMeta); } + prepareContent(title: string, content: string | Buffer, noteMeta: NoteMeta): string | Buffer { + if (noteMeta.format === "html" && typeof content === "string") { + if (!content.substr(0, 100).toLowerCase().includes(" element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809 + content = ` + + + + + + ${htmlTitle} + + +
+

${htmlTitle}

+ +
${content}
+
+ +`; + } + + return content.length < 100_000 ? html.prettyPrint(content, { indent_size: 2 }) : content; + } else { + return content; + } + } + afterDone() { if (!this.navigationMeta || !this.indexMeta || !this.cssMeta) { throw new Error("Missing meta."); diff --git a/apps/server/src/services/export/zip/markdown.ts b/apps/server/src/services/export/zip/markdown.ts index 2f8ac13bc..9143e5e1f 100644 --- a/apps/server/src/services/export/zip/markdown.ts +++ b/apps/server/src/services/export/zip/markdown.ts @@ -1,8 +1,26 @@ +import NoteMeta from "../../meta/note_meta" import { ZipExportProvider } from "./abstract_provider" +import mdService from "../markdown.js"; export default class MarkdownExportProvider extends ZipExportProvider { prepareMeta() { } + + prepareContent(title: string, content: string | Buffer, noteMeta: NoteMeta): string | Buffer { + if (noteMeta.format === "markdown" && typeof content === "string") { + let markdownContent = mdService.toMarkdown(content); + + if (markdownContent.trim().length > 0 && !markdownContent.startsWith("# ")) { + markdownContent = `# ${title}\r +${markdownContent}`; + } + + return markdownContent; + } else { + return content; + } + } + afterDone() { } }