client: Implement auto syntax highlighting

This commit is contained in:
Elian Doran 2024-10-27 11:46:19 +02:00
parent a3932376f3
commit 7505db220e
No known key found for this signature in database
3 changed files with 31 additions and 15 deletions

View File

@ -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,

View File

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

View File

@ -88,6 +88,23 @@ const TPL = `
</div>
`;
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