From 14b8d0a47ef0ca0ef25220d10159cd6da1485c86 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 27 Oct 2025 22:18:08 +0200 Subject: [PATCH] chore(share): bring back syntax highlight --- apps/server/package.json | 1 + apps/server/src/share/content_renderer.ts | 18 +++++++++++++++--- packages/share-theme/src/scripts/index.ts | 1 + pnpm-lock.yaml | 9 +++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/apps/server/package.json b/apps/server/package.json index 5cc30b1c9..7f59fe280 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -36,6 +36,7 @@ "@triliumnext/commons": "workspace:*", "@triliumnext/express-partial-content": "workspace:*", "@triliumnext/turndown-plugin-gfm": "workspace:*", + "@triliumnext/highlightjs": "workspace:*", "@types/archiver": "6.0.3", "@types/better-sqlite3": "7.6.13", "@types/cls-hooked": "4.3.9", diff --git a/apps/server/src/share/content_renderer.ts b/apps/server/src/share/content_renderer.ts index 2fd6d55a9..3ab219f26 100644 --- a/apps/server/src/share/content_renderer.ts +++ b/apps/server/src/share/content_renderer.ts @@ -1,4 +1,4 @@ -import { parse, HTMLElement, TextNode } from "node-html-parser"; +import { parse, HTMLElement, TextNode, Options } from "node-html-parser"; import shaca from "./shaca/shaca.js"; import assetPath, { assetUrlFragment } from "../services/asset_path.js"; import shareRoot from "./share_root.js"; @@ -14,6 +14,7 @@ import ejs from "ejs"; import log from "../services/log.js"; import { join } from "path"; import { readFileSync } from "fs"; +import { highlightAuto } from "@triliumnext/highlightjs"; const shareAdjustedAssetPath = isDev ? assetPath : `../${assetPath}`; const templateCache: Map = new Map(); @@ -264,7 +265,10 @@ function renderIndex(result: Result) { function renderText(result: Result, note: SNote | BNote) { if (typeof result.content !== "string") return; - const document = parse(result.content || ""); + const parseOpts: Partial = { + blockTextElements: {} + } + const document = parse(result.content || "", parseOpts); // Process include notes. for (const includeNoteEl of document.querySelectorAll("section.include-note")) { @@ -277,7 +281,7 @@ function renderText(result: Result, note: SNote | BNote) { const includedResult = getContent(note); if (typeof includedResult.content !== "string") continue; - const includedDocument = parse(includedResult.content).childNodes; + const includedDocument = parse(includedResult.content, parseOpts).childNodes; if (includedDocument) { includeNoteEl.replaceWith(...includedDocument); } @@ -286,6 +290,7 @@ function renderText(result: Result, note: SNote | BNote) { result.isEmpty = document.textContent?.trim().length === 0 && document.querySelectorAll("img").length === 0; if (!result.isEmpty) { + // Process attachment links. for (const linkEl of document.querySelectorAll("a")) { const href = linkEl.getAttribute("href"); @@ -299,6 +304,13 @@ function renderText(result: Result, note: SNote | BNote) { } } + // Apply syntax highlight. + for (const codeEl of document.querySelectorAll("pre code")) { + const highlightResult = highlightAuto(codeEl.innerText); + codeEl.innerHTML = highlightResult.value; + codeEl.classList.add("hljs"); + } + result.content = document.innerHTML ?? ""; if (note.hasLabel("shareIndex")) { diff --git a/packages/share-theme/src/scripts/index.ts b/packages/share-theme/src/scripts/index.ts index f076a4bcc..a809962aa 100644 --- a/packages/share-theme/src/scripts/index.ts +++ b/packages/share-theme/src/scripts/index.ts @@ -7,6 +7,7 @@ import setupMermaid from "./modules/mermaid"; import setupMath from "./modules/math"; import api from "./modules/api"; import "boxicons/css/boxicons.min.css"; +import "highlight.js/styles/default.css"; function $try unknown>(func: T, ...args: Parameters) { try { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5f89b028..8b3ab73d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -480,6 +480,9 @@ importers: '@triliumnext/express-partial-content': specifier: workspace:* version: link:../../packages/express-partial-content + '@triliumnext/highlightjs': + specifier: workspace:* + version: link:../../packages/highlightjs '@triliumnext/turndown-plugin-gfm': specifier: workspace:* version: link:../../packages/turndown-plugin-gfm @@ -15103,6 +15106,8 @@ snapshots: '@ckeditor/ckeditor5-core': 47.1.0 '@ckeditor/ckeditor5-utils': 47.1.0 ckeditor5: 47.1.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-code-block@47.1.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)': dependencies: @@ -15355,6 +15360,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 47.1.0 ckeditor5: 47.1.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-editor-multi-root@47.1.0': dependencies: @@ -15377,6 +15384,8 @@ snapshots: '@ckeditor/ckeditor5-table': 47.1.0 '@ckeditor/ckeditor5-utils': 47.1.0 ckeditor5: 47.1.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-emoji@47.1.0': dependencies: