Skip to content

Feature/export with share theme #2310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/server/src/becca/entities/bbranch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,11 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
});
}
}

getParentNote() {
return this.parentNote;
}

}

export default BBranch;
16 changes: 16 additions & 0 deletions apps/server/src/becca/entities/bnote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1758,6 +1758,22 @@ class BNote extends AbstractBeccaEntity<BNote> {
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;
96 changes: 73 additions & 23 deletions apps/server/src/services/export/zip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import html from "html";
import dateUtils from "../date_utils.js";
import path from "path";
import path, { join } from "path";
import mimeTypes from "mime-types";
import mdService from "./markdown.js";
import packageInfo from "../../../package.json" with { type: "json" };
import { getContentDisposition, escapeHtml, getResourceDir } from "../utils.js";
import { getContentDisposition, escapeHtml, getResourceDir, isDev } from "../utils.js";
import protectedSessionService from "../protected_session.js";
import sanitize from "sanitize-filename";
import fs from "fs";
Expand All @@ -19,9 +19,12 @@ import type NoteMeta from "../meta/note_meta.js";
import type AttachmentMeta from "../meta/attachment_meta.js";
import type AttributeMeta from "../meta/attribute_meta.js";
import type BBranch from "../../becca/entities/bbranch.js";
import type BNote from "../../becca/entities/bnote.js";
import type { Response } from "express";
import type { NoteMetaFile } from "../meta/note_meta.js";
import cssContent from "@triliumnext/ckeditor5/content.css";
//import cssContent from "@triliumnext/ckeditor5/content.css";
import { renderNoteForExport } from "../../share/content_renderer.js";
import { RESOURCE_DIR } from "../resource_dir.js";

type RewriteLinksFn = (content: string, noteMeta: NoteMeta) => string;

Expand Down Expand Up @@ -314,7 +317,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 || "")) {
content = content.toString();
content = rewriteFn(content, noteMeta);
Expand All @@ -326,11 +329,18 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
throw new Error("Missing note path.");
}

const cssUrl = `${"../".repeat(noteMeta.notePath.length - 1)}style.css`;
const basePath = "../".repeat(noteMeta.notePath.length - 1);
const htmlTitle = escapeHtml(title);

// <base> element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809
content = `<html>
if (note) {
content = renderNoteForExport(note, branch, basePath);

// TODO: Fix double rewrite.
content = rewriteFn(content, noteMeta);
} else {
const cssUrl = basePath + "style.css";
// <base> element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809
content = `<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
Expand All @@ -346,6 +356,7 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
</div>
</body>
</html>`;
}
}

return content.length < 100_000 ? html.prettyPrint(content, { indent_size: 2 }) : content;
Expand Down Expand Up @@ -375,7 +386,7 @@ ${markdownContent}`;

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 });

Expand All @@ -391,7 +402,7 @@ ${markdownContent}`;
}

if (noteMeta.dataFileName) {
const content = prepareContent(noteMeta.title, note.getContent(), noteMeta);
const content = prepareContent(note, noteMeta.title, note.getContent(), noteMeta);

archive.append(content, {
name: filePathPrefix + noteMeta.dataFileName,
Expand Down Expand Up @@ -507,12 +518,15 @@ ${markdownContent}`;
archive.append(fullHtml, { name: indexMeta.dataFileName });
}

function saveCss(rootMeta: NoteMeta, cssMeta: NoteMeta) {
if (!cssMeta.dataFileName) {
return;
}
function saveAssets(rootMeta: NoteMeta, assetsMeta: NoteMeta[]) {
for (const assetMeta of assetsMeta) {
if (!assetMeta.dataFileName) {
continue;
}

archive.append(cssContent, { name: cssMeta.dataFileName });
let cssContent = getShareThemeAssets(assetMeta.dataFileName);
archive.append(cssContent, { name: assetMeta.dataFileName });
}
}

const existingFileNames: Record<string, number> = format === "html" ? { navigation: 0, index: 1 } : {};
Expand All @@ -529,7 +543,7 @@ ${markdownContent}`;

let navigationMeta: NoteMeta | null = null;
let indexMeta: NoteMeta | null = null;
let cssMeta: NoteMeta | null = null;
let assetsMeta: NoteMeta[] = [];

if (format === "html") {
navigationMeta = {
Expand All @@ -546,12 +560,26 @@ ${markdownContent}`;

metaFile.files.push(indexMeta);

cssMeta = {
noImport: true,
dataFileName: "style.css"
};

metaFile.files.push(cssMeta);
const assets = [
"style.css",
"script.js",
"boxicons.css",
"boxicons.eot",
"boxicons.woff2",
"boxicons.woff",
"boxicons.ttf",
"boxicons.svg",
"icon-color.svg"
];

for (const asset of assets) {
const assetMeta = {
noImport: true,
dataFileName: asset
};
assetsMeta.push(assetMeta);
metaFile.files.push(assetMeta);
}
}

for (const noteMeta of Object.values(noteIdToMeta)) {
Expand Down Expand Up @@ -585,13 +613,13 @@ ${markdownContent}`;
saveNote(rootMeta, "");

if (format === "html") {
if (!navigationMeta || !indexMeta || !cssMeta) {
if (!navigationMeta || !indexMeta || !assetsMeta) {
throw new Error("Missing meta.");
}

saveNavigation(rootMeta, navigationMeta);
saveIndex(rootMeta, indexMeta);
saveCss(rootMeta, cssMeta);
saveAssets(rootMeta, assetsMeta);
}

const note = branch.getNote();
Expand Down Expand Up @@ -623,6 +651,28 @@ async function exportToZipFile(noteId: string, format: "markdown" | "html", zipF
log.info(`Exported '${noteId}' with format '${format}' to '${zipFilePath}'`);
}

function getShareThemeAssets(nameWithExtension: string) {
// Rename share.css to style.css.
if (nameWithExtension === "style.css") {
nameWithExtension = "share.css";
} else if (nameWithExtension === "script.js") {
nameWithExtension = "share.js";
}

let path: string | undefined;
if (nameWithExtension === "icon-color.svg") {
path = join(RESOURCE_DIR, "images", nameWithExtension);
} else if (isDev) {
path = join(getResourceDir(), "..", "..", "client", "dist", "src", nameWithExtension);
}

if (!path) {
throw new Error("Not yet defined.");
}

return fs.readFileSync(path);
}

export default {
exportToZip,
exportToZipFile
Expand Down
Loading
Loading