From 7505db220eb554da22657ae98638dcf918dccc75 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 27 Oct 2024 11:46:19 +0200 Subject: [PATCH] client: Implement auto syntax highlighting --- src/public/app/services/mime_types.js | 6 +++++ .../type_widgets/ckeditor/syntax_highlight.js | 15 ++++++----- .../app/widgets/type_widgets/editable_text.js | 25 +++++++++++++------ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/public/app/services/mime_types.js b/src/public/app/services/mime_types.js index d448f912d..96f195e0c 100644 --- a/src/public/app/services/mime_types.js +++ b/src/public/app/services/mime_types.js @@ -1,5 +1,10 @@ import options from "./options.js"; +/** + * A pseudo-MIME type which is used in the editor to automatically determine the language used in code blocks via heuristics. + */ +const MIME_TYPE_AUTO = "text-x-trilium-auto"; + const MIME_TYPES_DICT = [ { default: true, title: "Plain text", mime: "text/plain", highlightJs: "plaintext" }, { title: "APL", mime: "text/apl" }, @@ -218,6 +223,7 @@ function normalizeMimeTypeForCKEditor(mimeType) { } export default { + MIME_TYPE_AUTO, getMimeTypes, loadMimeTypes, getHighlightJsNameForMime, diff --git a/src/public/app/widgets/type_widgets/ckeditor/syntax_highlight.js b/src/public/app/widgets/type_widgets/ckeditor/syntax_highlight.js index 90ffefa77..8ccff895c 100644 --- a/src/public/app/widgets/type_widgets/ckeditor/syntax_highlight.js +++ b/src/public/app/widgets/type_widgets/ckeditor/syntax_highlight.js @@ -171,7 +171,7 @@ function highlightCodeBlock(codeBlock, writer) { // Find the corresponding language for the given mimetype. const highlightJsLanguage = mime_types.getHighlightJsNameForMime(mimeType); - if (!highlightJsLanguage) { + if (mimeType !== mime_types.MIME_TYPE_AUTO && !highlightJsLanguage) { console.warn(`Unsupported highlight.js for mime type ${mimeType}.`); return; } @@ -221,13 +221,12 @@ function highlightCodeBlock(codeBlock, writer) { } } - // XXX This auto-detects the language, if we want to honor the language - // attribute we can do - // let html = hljs.highlight(text, {language: 'python'}); - // If that is done, it would also be interesting to have an - // auto-detect option. See language mime types at - // https://github.com/zadam/trilium/blob/dbd312c88db2b000ec0ce18c95bc8a27c0e621a1/src/public/app/widgets/type_widgets/editable_text.js#L104 - let highlightRes = hljs.highlight(text, { language: highlightJsLanguage }); + let highlightRes; + if (mimeType === mime_types.MIME_TYPE_AUTO) { + highlightRes = hljs.highlightAuto(text); + } else { + highlightRes = hljs.highlight(text, { language: highlightJsLanguage }); + } dbg("text\n" + text); dbg("html\n" + highlightRes.value); diff --git a/src/public/app/widgets/type_widgets/editable_text.js b/src/public/app/widgets/type_widgets/editable_text.js index 6f939c801..c39e0a622 100644 --- a/src/public/app/widgets/type_widgets/editable_text.js +++ b/src/public/app/widgets/type_widgets/editable_text.js @@ -88,6 +88,23 @@ const TPL = ` `; +function buildListOfLanguages() { + const userLanguages = (mimeTypesService.getMimeTypes()) + .filter(mt => mt.enabled) + .map(mt => ({ + language: mimeTypesService.normalizeMimeTypeForCKEditor(mt.mime), + label: mt.title + })); + + return [ + { + language: mimeTypesService.MIME_TYPE_AUTO, + label: "Auto" + }, + ...userLanguages + ]; +} + export default class EditableTextTypeWidget extends AbstractTextTypeWidget { static getType() { return "editableText"; } @@ -108,13 +125,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget { await libraryLoader.requireLibrary(libraryLoader.CKEDITOR); await libraryLoader.requireLibrary(libraryLoader.HIGHLIGHT_JS); - const codeBlockLanguages = - (mimeTypesService.getMimeTypes()) - .filter(mt => mt.enabled) - .map(mt => ({ - language: mimeTypesService.normalizeMimeTypeForCKEditor(mt.mime), - label: mt.title - })); + const codeBlockLanguages = buildListOfLanguages(); // CKEditor since version 12 needs the element to be visible before initialization. At the same time, // we want to avoid flicker - i.e., show editor only once everything is ready. That's why we have separate