From 5153fb8aff3420350e43700cb28d05e928dd2e8a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Mon, 23 Dec 2024 22:42:18 +0200 Subject: [PATCH] feat(client/code-note): add support for batch files --- libraries/codemirror/batch.js | 51 +++++++++++++++++++++++ src/public/app/services/library_loader.ts | 51 ++++++++++++++--------- src/public/app/services/mime_types.ts | 11 +++-- 3 files changed, 89 insertions(+), 24 deletions(-) create mode 100644 libraries/codemirror/batch.js diff --git a/libraries/codemirror/batch.js b/libraries/codemirror/batch.js new file mode 100644 index 000000000..cd52aa2ba --- /dev/null +++ b/libraries/codemirror/batch.js @@ -0,0 +1,51 @@ +// Source: https://github.com/deathau/cm-editor-syntax-highlight-obsidian/issues/27#issuecomment-1340586596 +(() => { + var varsAndArgsRegex = /(%[0-9]|%~\S+|%\S+%)/; + + CodeMirror.defineSimpleMode("batch", { + start: [ + { //comment + regex: /(rem|::)(?:\s.*|$)/i, + token: "comment", + sol: true + }, + { //echo + regex: /(@echo|echo)/i, + token: "builtin", + sol: true, + next: "echo" + }, + { //commands + regex: /(?:\s|^)(assoc|aux|break|call|cd|chcp|chdir|choice|cls|cmdextversion|color|com1|com2|com3|com4|com|con|copy|country|ctty|date|defined|del|dir|do|dpath|else|endlocal|erase|errorlevel|exist|exit|for|ftype|goto|if|in|loadfix|loadhigh|lpt|lpt1|lpt2|lpt3|lpt4|md|mkdir|move|not|nul|path|pause|popd|prn|prompt|pushd|rd|rename|ren|rmdir|setlocal|set|shift|start|time|title|type|verify|ver|vol)(?:\s|$)/i, + token: "builtin" + }, + { //variables and arguments + regex: varsAndArgsRegex, + token: "variable-2" + }, + { //label + regex: /\s*:.*/, + token: "string", + sol: true + } + ], + echo: [ + { //highlight variables and arguments in echo command + regex: varsAndArgsRegex, + token: "variable-2" + }, + { //go back to start state at end of line + regex: /.$/, + next: "start" + } + ] + }); + + CodeMirror.defineMIME("application/x-bat", "batch"); + CodeMirror.modeInfo.push({ + ext: [ "bat", "cmd" ], + mime: "application/x-bat", + mode: "batch", + name: "Batch file" + }); +})(); diff --git a/src/public/app/services/library_loader.ts b/src/public/app/services/library_loader.ts index a3e79e8c9..e7d448820 100644 --- a/src/public/app/services/library_loader.ts +++ b/src/public/app/services/library_loader.ts @@ -12,21 +12,32 @@ const CKEDITOR: Library = { }; const CODE_MIRROR: Library = { - js: [ - "node_modules/codemirror/lib/codemirror.js", - "node_modules/codemirror/addon/display/placeholder.js", - "node_modules/codemirror/addon/edit/matchbrackets.js", - "node_modules/codemirror/addon/edit/matchtags.js", - "node_modules/codemirror/addon/fold/xml-fold.js", - "node_modules/codemirror/addon/lint/lint.js", - "node_modules/codemirror/addon/mode/loadmode.js", - "node_modules/codemirror/addon/mode/multiplex.js", - "node_modules/codemirror/addon/mode/overlay.js", - "node_modules/codemirror/addon/mode/simple.js", - "node_modules/codemirror/addon/search/match-highlighter.js", - "node_modules/codemirror/mode/meta.js", - "node_modules/codemirror/keymap/vim.js" - ], + js: () => { + const scriptsToLoad = [ + "node_modules/codemirror/lib/codemirror.js", + "node_modules/codemirror/addon/display/placeholder.js", + "node_modules/codemirror/addon/edit/matchbrackets.js", + "node_modules/codemirror/addon/edit/matchtags.js", + "node_modules/codemirror/addon/fold/xml-fold.js", + "node_modules/codemirror/addon/lint/lint.js", + "node_modules/codemirror/addon/mode/loadmode.js", + "node_modules/codemirror/addon/mode/multiplex.js", + "node_modules/codemirror/addon/mode/overlay.js", + "node_modules/codemirror/addon/mode/simple.js", + "node_modules/codemirror/addon/search/match-highlighter.js", + "node_modules/codemirror/mode/meta.js", + "node_modules/codemirror/keymap/vim.js" + ]; + + const mimeTypes = mimeTypesService.getMimeTypes(); + for (const mimeType of mimeTypes) { + if (mimeType.codeMirrorSource) { + scriptsToLoad.push(mimeType.codeMirrorSource); + } + } + + return scriptsToLoad; + }, css: [ "node_modules/codemirror/lib/codemirror.css", "node_modules/codemirror/addon/lint/lint.css" @@ -74,7 +85,7 @@ const FORCE_GRAPH: Library = { const MERMAID: Library = { js: [ - "node_modules/mermaid/dist/mermaid.min.js" + "node_modules/mermaid/dist/mermaid.min.js" ] } @@ -134,7 +145,7 @@ const HIGHLIGHT_JS: Library = { scriptsToLoad.add(`node_modules/@highlightjs/cdn-assets/languages/${id}.min.js`); } } - + const currentTheme = String(optionsService.get("codeBlockTheme")); loadHighlightingTheme(currentTheme); @@ -195,7 +206,7 @@ async function requireCss(url: string, prependAssetPath = true) { let highlightingThemeEl: JQuery | null = null; function loadHighlightingTheme(theme: string) { - if (!theme) { + if (!theme) { return; } @@ -207,12 +218,12 @@ function loadHighlightingTheme(theme: string) { } return; } - + if (!highlightingThemeEl) { highlightingThemeEl = $(``); $("head").append(highlightingThemeEl); } - + const url = getStylesheetUrl(theme); if (url) { highlightingThemeEl.attr("href", url); diff --git a/src/public/app/services/mime_types.ts b/src/public/app/services/mime_types.ts index 44e3e72d8..524bb3020 100644 --- a/src/public/app/services/mime_types.ts +++ b/src/public/app/services/mime_types.ts @@ -17,6 +17,8 @@ interface MimeTypeDefinition { highlightJs?: string; /** If specified, will load the corresponding highlight.js file from the `libraries/highlightjs/${id}.js` instead of `node_modules/@highlightjs/cdn-assets/languages/${id}.min.js`. */ highlightJsSource?: "libraries"; + /** If specified, will load the corresponding highlight file from the given path instead of `node_modules`. */ + codeMirrorSource?: string; } interface MimeType extends MimeTypeDefinition { @@ -29,6 +31,7 @@ const MIME_TYPES_DICT: MimeTypeDefinition[] = [ { title: "ASN.1", mime: "text/x-ttcn-asn" }, { title: "ASP.NET", mime: "application/x-aspx" }, { title: "Asterisk", mime: "text/x-asterisk" }, + { title: "Batch file (DOS)", mime: "application/x-bat", codeMirrorSource: "libraries/codemirror/batch.js" }, { title: "Brainfuck", mime: "text/x-brainfuck", highlightJs: "brainfuck" }, { default: true, title: "C", mime: "text/x-csrc", highlightJs: "c" }, { default: true, title: "C#", mime: "text/x-csharp", highlightJs: "csharp" }, @@ -209,13 +212,13 @@ let mimeToHighlightJsMapping: Record | null = null; /** * Obtains the corresponding language tag for highlight.js for a given MIME type. - * + * * The mapping is built the first time this method is built and then the results are cached for better performance. - * + * * @param mimeType The MIME type of the code block, in the CKEditor-normalized format (e.g. `text-c-src` instead of `text/c-src`). * @returns the corresponding highlight.js tag, for example `c` for `text-c-src`. */ -function getHighlightJsNameForMime(mimeType: string) { +function getHighlightJsNameForMime(mimeType: string) { if (!mimeToHighlightJsMapping) { const mimeTypes = getMimeTypes(); mimeToHighlightJsMapping = {}; @@ -234,7 +237,7 @@ function getHighlightJsNameForMime(mimeType: string) { /** * Given a MIME type in the usual format (e.g. `text/csrc`), it returns a MIME type that can be passed down to the CKEditor * code plugin. - * + * * @param mimeType The MIME type to normalize, in the usual format (e.g. `text/c-src`). * @returns the normalized MIME type (e.g. `text-c-src`). */