2025-05-18 00:31:20 +03:00
|
|
|
import hljs from "../node_modules/highlight.js/es/core.js";
|
2025-05-18 16:05:50 +03:00
|
|
|
import { normalizeMimeTypeForCKEditor, type MimeType } from "@triliumnext/commons";
|
2025-05-18 17:12:45 +03:00
|
|
|
import syntaxDefinitions from "./syntax_highlighting.js";
|
|
|
|
import { type Theme } from "./themes.js";
|
2025-05-18 15:16:53 +03:00
|
|
|
import { type HighlightOptions } from "highlight.js";
|
2025-05-18 00:31:20 +03:00
|
|
|
|
2025-05-18 17:12:45 +03:00
|
|
|
export { default as Themes } from "./themes.js";
|
|
|
|
|
2025-05-18 15:16:53 +03:00
|
|
|
const registeredMimeTypes = new Set<string>();
|
|
|
|
const unsupportedMimeTypes = new Set<string>();
|
2025-05-18 18:24:35 +03:00
|
|
|
let highlightingThemeEl: HTMLStyleElement | null = null;
|
2025-05-18 15:16:53 +03:00
|
|
|
|
|
|
|
export async function ensureMimeTypes(mimeTypes: MimeType[]) {
|
|
|
|
for (const mimeType of mimeTypes) {
|
|
|
|
if (!mimeType.enabled) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2025-05-18 16:05:50 +03:00
|
|
|
const mime = normalizeMimeTypeForCKEditor(mimeType.mime);
|
2025-05-18 15:16:53 +03:00
|
|
|
if (registeredMimeTypes.has(mime)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
registeredMimeTypes.add(mime);
|
2025-05-18 17:12:45 +03:00
|
|
|
const loader = syntaxDefinitions[mime];
|
2025-05-18 15:16:53 +03:00
|
|
|
if (!loader) {
|
|
|
|
unsupportedMimeTypes.add(mime);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2025-05-18 16:11:40 +03:00
|
|
|
const language = (await loader()).default;
|
2025-05-18 15:16:53 +03:00
|
|
|
hljs.registerLanguage(mime, language);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function highlight(code: string, options: HighlightOptions) {
|
|
|
|
if (unsupportedMimeTypes.has(options.language)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!registeredMimeTypes.has(options.language)) {
|
2025-05-18 16:05:50 +03:00
|
|
|
console.warn(`Unable to find highlighting for ${options.language}.`);
|
2025-05-18 15:16:53 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hljs.highlight(code, options);
|
|
|
|
}
|
|
|
|
|
2025-05-18 18:24:35 +03:00
|
|
|
export async function loadTheme(theme: "none" | Theme) {
|
|
|
|
if (theme === "none") {
|
|
|
|
if (highlightingThemeEl) {
|
|
|
|
highlightingThemeEl.remove();
|
|
|
|
highlightingThemeEl = null;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!highlightingThemeEl) {
|
|
|
|
highlightingThemeEl = document.createElement("style");
|
|
|
|
document.querySelector("head")?.append(highlightingThemeEl);
|
|
|
|
}
|
2025-05-18 17:50:31 +03:00
|
|
|
|
2025-05-18 18:24:35 +03:00
|
|
|
const themeCss = (await theme.load()).default as string;
|
|
|
|
highlightingThemeEl.textContent = themeCss;
|
2025-05-18 17:12:45 +03:00
|
|
|
}
|
|
|
|
|
2025-05-18 15:16:53 +03:00
|
|
|
export const { highlightAuto } = hljs;
|