mirror of
https://github.com/zadam/trilium.git
synced 2025-10-26 07:46:30 +01:00
feat(export/zip): get same rendering engine as share
This commit is contained in:
@@ -278,6 +278,11 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getParentNote() {
|
||||||
|
return this.parentNote;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default BBranch;
|
export default BBranch;
|
||||||
|
|||||||
@@ -1758,6 +1758,22 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
|||||||
return childBranches;
|
return childBranches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get encodedTitle() {
|
||||||
|
return encodeURIComponent(this.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
getVisibleChildBranches() {
|
||||||
|
return this.getChildBranches().filter((branch) => !branch.getNote().isLabelTruthy("shareHiddenFromTree"));
|
||||||
|
}
|
||||||
|
|
||||||
|
getVisibleChildNotes() {
|
||||||
|
return this.getVisibleChildBranches().map((branch) => branch.getNote());
|
||||||
|
}
|
||||||
|
|
||||||
|
hasVisibleChildren() {
|
||||||
|
return this.getVisibleChildNotes().length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default BNote;
|
export default BNote;
|
||||||
|
|||||||
@@ -19,9 +19,11 @@ import type NoteMeta from "../meta/note_meta.js";
|
|||||||
import type AttachmentMeta from "../meta/attachment_meta.js";
|
import type AttachmentMeta from "../meta/attachment_meta.js";
|
||||||
import type AttributeMeta from "../meta/attribute_meta.js";
|
import type AttributeMeta from "../meta/attribute_meta.js";
|
||||||
import type BBranch from "../../becca/entities/bbranch.js";
|
import type BBranch from "../../becca/entities/bbranch.js";
|
||||||
|
import type BNote from "../../becca/entities/bnote.js";
|
||||||
import type { Response } from "express";
|
import type { Response } from "express";
|
||||||
import type { NoteMetaFile } from "../meta/note_meta.js";
|
import type { NoteMetaFile } from "../meta/note_meta.js";
|
||||||
import cssContent from "@triliumnext/ckeditor5/content.css";
|
import cssContent from "@triliumnext/ckeditor5/content.css";
|
||||||
|
import { renderNoteContent } from "../../share/content_renderer.js";
|
||||||
|
|
||||||
type RewriteLinksFn = (content: string, noteMeta: NoteMeta) => string;
|
type RewriteLinksFn = (content: string, noteMeta: NoteMeta) => string;
|
||||||
|
|
||||||
@@ -314,7 +316,7 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareContent(title: string, content: string | Buffer, noteMeta: NoteMeta): string | Buffer {
|
function prepareContent(note: BNote | undefined, title: string, content: string | Buffer, noteMeta: NoteMeta): string | Buffer {
|
||||||
if (["html", "markdown"].includes(noteMeta?.format || "")) {
|
if (["html", "markdown"].includes(noteMeta?.format || "")) {
|
||||||
content = content.toString();
|
content = content.toString();
|
||||||
content = rewriteFn(content, noteMeta);
|
content = rewriteFn(content, noteMeta);
|
||||||
@@ -329,8 +331,11 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
|
|||||||
const cssUrl = `${"../".repeat(noteMeta.notePath.length - 1)}style.css`;
|
const cssUrl = `${"../".repeat(noteMeta.notePath.length - 1)}style.css`;
|
||||||
const htmlTitle = escapeHtml(title);
|
const htmlTitle = escapeHtml(title);
|
||||||
|
|
||||||
// <base> element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809
|
if (note) {
|
||||||
content = `<html>
|
content = renderNoteContent(note);
|
||||||
|
} else {
|
||||||
|
// <base> element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809
|
||||||
|
content = `<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@@ -346,6 +351,7 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>`;
|
</html>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return content.length < 100_000 ? html.prettyPrint(content, { indent_size: 2 }) : content;
|
return content.length < 100_000 ? html.prettyPrint(content, { indent_size: 2 }) : content;
|
||||||
@@ -375,7 +381,7 @@ ${markdownContent}`;
|
|||||||
|
|
||||||
let content: string | Buffer = `<p>This is a clone of a note. Go to its <a href="${targetUrl}">primary location</a>.</p>`;
|
let content: string | Buffer = `<p>This is a clone of a note. Go to its <a href="${targetUrl}">primary location</a>.</p>`;
|
||||||
|
|
||||||
content = prepareContent(noteMeta.title, content, noteMeta);
|
content = prepareContent(undefined, noteMeta.title, content, noteMeta);
|
||||||
|
|
||||||
archive.append(content, { name: filePathPrefix + noteMeta.dataFileName });
|
archive.append(content, { name: filePathPrefix + noteMeta.dataFileName });
|
||||||
|
|
||||||
@@ -391,7 +397,7 @@ ${markdownContent}`;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (noteMeta.dataFileName) {
|
if (noteMeta.dataFileName) {
|
||||||
const content = prepareContent(noteMeta.title, note.getContent(), noteMeta);
|
const content = prepareContent(note, noteMeta.title, note.getContent(), noteMeta);
|
||||||
|
|
||||||
archive.append(content, {
|
archive.append(content, {
|
||||||
name: filePathPrefix + noteMeta.dataFileName,
|
name: filePathPrefix + noteMeta.dataFileName,
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import assetPath, { assetUrlFragment } from "../services/asset_path.js";
|
|||||||
import shareRoot from "./share_root.js";
|
import shareRoot from "./share_root.js";
|
||||||
import escapeHtml from "escape-html";
|
import escapeHtml from "escape-html";
|
||||||
import type SNote from "./shaca/entities/snote.js";
|
import type SNote from "./shaca/entities/snote.js";
|
||||||
|
import BNote from "../becca/entities/bnote.js";
|
||||||
|
import type BBranch from "../becca/entities/bbranch.js";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import SBranch from "./shaca/entities/sbranch.js";
|
import SBranch from "./shaca/entities/sbranch.js";
|
||||||
import options from "../services/options.js";
|
import options from "../services/options.js";
|
||||||
@@ -24,8 +26,8 @@ export interface Result {
|
|||||||
isEmpty?: boolean;
|
isEmpty?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSharedSubTreeRoot(note: SNote): { note?: SNote; branch?: SBranch } {
|
function getSharedSubTreeRoot(note: SNote | BNote | undefined): { note?: SNote | BNote; branch?: SBranch | BBranch } {
|
||||||
if (note.noteId === shareRoot.SHARE_ROOT_NOTE_ID) {
|
if (!note || note.noteId === shareRoot.SHARE_ROOT_NOTE_ID) {
|
||||||
// share root itself is not shared
|
// share root itself is not shared
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -34,6 +36,13 @@ function getSharedSubTreeRoot(note: SNote): { note?: SNote; branch?: SBranch } {
|
|||||||
// for the sake of simplicity, URLs are not note paths
|
// for the sake of simplicity, URLs are not note paths
|
||||||
const parentBranch = note.getParentBranches()[0];
|
const parentBranch = note.getParentBranches()[0];
|
||||||
|
|
||||||
|
if (note instanceof BNote) {
|
||||||
|
return {
|
||||||
|
note,
|
||||||
|
branch: parentBranch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (parentBranch.parentNoteId === shareRoot.SHARE_ROOT_NOTE_ID) {
|
if (parentBranch.parentNoteId === shareRoot.SHARE_ROOT_NOTE_ID) {
|
||||||
return {
|
return {
|
||||||
note,
|
note,
|
||||||
@@ -44,7 +53,7 @@ function getSharedSubTreeRoot(note: SNote): { note?: SNote; branch?: SBranch } {
|
|||||||
return getSharedSubTreeRoot(parentBranch.getParentNote());
|
return getSharedSubTreeRoot(parentBranch.getParentNote());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderNoteContent(note: SNote) {
|
export function renderNoteContent(note: SNote | BNote) {
|
||||||
const { header, content, isEmpty } = getContent(note);
|
const { header, content, isEmpty } = getContent(note);
|
||||||
const subRoot = getSharedSubTreeRoot(note);
|
const subRoot = getSharedSubTreeRoot(note);
|
||||||
const showLoginInShareTheme = options.getOption("showLoginInShareTheme");
|
const showLoginInShareTheme = options.getOption("showLoginInShareTheme");
|
||||||
@@ -105,7 +114,7 @@ export function renderNoteContent(note: SNote) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getContent(note: SNote) {
|
function getContent(note: SNote | BNote) {
|
||||||
if (note.isProtected) {
|
if (note.isProtected) {
|
||||||
return {
|
return {
|
||||||
header: "",
|
header: "",
|
||||||
@@ -154,7 +163,7 @@ function renderIndex(result: Result) {
|
|||||||
result.content += "</ul>";
|
result.content += "</ul>";
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderText(result: Result, note: SNote) {
|
function renderText(result: Result, note: SNote | BNote) {
|
||||||
const document = new JSDOM(result.content || "").window.document;
|
const document = new JSDOM(result.content || "").window.document;
|
||||||
|
|
||||||
result.isEmpty = document.body.textContent?.trim().length === 0 && document.querySelectorAll("img").length === 0;
|
result.isEmpty = document.body.textContent?.trim().length === 0 && document.querySelectorAll("img").length === 0;
|
||||||
@@ -247,7 +256,7 @@ export function renderCode(result: Result) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderMermaid(result: Result, note: SNote) {
|
function renderMermaid(result: Result, note: SNote | BNote) {
|
||||||
if (typeof result.content !== "string") {
|
if (typeof result.content !== "string") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -261,11 +270,11 @@ function renderMermaid(result: Result, note: SNote) {
|
|||||||
</details>`;
|
</details>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderImage(result: Result, note: SNote) {
|
function renderImage(result: Result, note: SNote | BNote) {
|
||||||
result.content = `<img src="api/images/${note.noteId}/${note.encodedTitle}?${note.utcDateModified}">`;
|
result.content = `<img src="api/images/${note.noteId}/${note.encodedTitle}?${note.utcDateModified}">`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderFile(note: SNote, result: Result) {
|
function renderFile(note: SNote | BNote, result: Result) {
|
||||||
if (note.mime === "application/pdf") {
|
if (note.mime === "application/pdf") {
|
||||||
result.content = `<iframe class="pdf-view" src="api/notes/${note.noteId}/view"></iframe>`;
|
result.content = `<iframe class="pdf-view" src="api/notes/${note.noteId}/view"></iframe>`;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user