feat(edit-docs): rewrite links to allow navigation in help

This commit is contained in:
Elian Doran
2025-04-09 15:48:03 +03:00
parent 652fc48a86
commit a88a92d490
2 changed files with 68 additions and 6 deletions

View File

@@ -23,7 +23,20 @@ import type { Response } from "express";
import { RESOURCE_DIR } from "../resource_dir.js";
import type { NoteMetaFile } from "../meta/note_meta.js";
async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "html" | "markdown", res: Response | fs.WriteStream, setHeaders = true) {
type RewriteLinksFn = (content: string, noteMeta: NoteMeta) => string;
export interface AdvancedExportOptions {
/**
* 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`);
}
@@ -253,6 +266,8 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
return url;
}
const rewriteFn = (zipExportOptions?.customRewriteLinks ? zipExportOptions?.customRewriteLinks(rewriteLinks, getNoteTargetUrl) : rewriteLinks);
function rewriteLinks(content: string, noteMeta: NoteMeta): string {
content = content.replace(/src="[^"]*api\/images\/([a-zA-Z0-9_]+)\/[^"]*"/g, (match, targetNoteId) => {
const url = getNoteTargetUrl(targetNoteId, noteMeta);
@@ -297,8 +312,7 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
function prepareContent(title: string, content: string | Buffer, noteMeta: NoteMeta): string | Buffer {
if (["html", "markdown"].includes(noteMeta?.format || "")) {
content = content.toString();
content = rewriteLinks(content, noteMeta);
content = rewriteFn(content, noteMeta);
}
if (noteMeta.format === "html" && typeof content === "string") {
@@ -591,7 +605,7 @@ ${markdownContent}`;
taskContext.taskSucceeded();
}
async function exportToZipFile(noteId: string, format: "markdown" | "html", zipFilePath: string) {
async function exportToZipFile(noteId: string, format: "markdown" | "html", zipFilePath: string, zipExportOptions?: AdvancedExportOptions) {
const fileOutputStream = fs.createWriteStream(zipFilePath);
const taskContext = new TaskContext("no-progress-reporting");
@@ -601,7 +615,7 @@ async function exportToZipFile(noteId: string, format: "markdown" | "html", zipF
throw new ValidationError(`Note ${noteId} not found.`);
}
await exportToZip(taskContext, note.getParentBranches()[0], format, fileOutputStream, false);
await exportToZip(taskContext, note.getParentBranches()[0], format, fileOutputStream, false, zipExportOptions);
log.info(`Exported '${noteId}' with format '${format}' to '${zipFilePath}'`);
}