From c8d0a319bcefa533249bbbabaf9243df7fd8f164 Mon Sep 17 00:00:00 2001 From: guopenghui Date: Thu, 23 May 2024 20:21:27 +0800 Subject: [PATCH 1/3] feat: add syntax highlight in edit mode --- esbuild.config.mjs | 3 ++- main.ts | 5 +++- mode.ts | 65 ++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 20 ++++++++++---- package.json | 1 + 5 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 mode.ts diff --git a/esbuild.config.mjs b/esbuild.config.mjs index b13282b..94b5ecb 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -20,6 +20,7 @@ const context = await esbuild.context({ external: [ "obsidian", "electron", + "codemirror", "@codemirror/autocomplete", "@codemirror/collab", "@codemirror/commands", @@ -45,4 +46,4 @@ if (prod) { process.exit(0); } else { await context.watch(); -} \ No newline at end of file +} diff --git a/main.ts b/main.ts index a3b0ab4..fbedc1c 100644 --- a/main.ts +++ b/main.ts @@ -1,4 +1,5 @@ -import { Plugin } from "obsidian"; +import { MarkdownView, Plugin } from "obsidian"; +import { SwarnamMode } from "./mode"; const PREFIX = "swarnam"; @@ -49,6 +50,8 @@ function showError(msg: string, root: HTMLElement) { export default class SwarnamPlugin extends Plugin { async onload() { + this.register(SwarnamMode()) + this.registerMarkdownCodeBlockProcessor( "swarnam", (source, el, ctx) => { diff --git a/mode.ts b/mode.ts new file mode 100644 index 0000000..333b8ef --- /dev/null +++ b/mode.ts @@ -0,0 +1,65 @@ +import type * as CODE_MIRROR from "codemirror" + +declare const CodeMirror: typeof CODE_MIRROR + +type State = { + curSegment: "html" | "css" | "js" + htmlState: any, + cssState: any, + jsState: any +} + +function advance(state: State) { + if(state.curSegment === "html") { + state.curSegment = "css" + } else if(state.curSegment === "css") { + state.curSegment = "js" + } +} + +export function SwarnamMode() { + CodeMirror.defineMode("swarnam", (config) => { + const htmlMode = CodeMirror.getMode(config, "htmlmixed") + const cssMode = CodeMirror.getMode(config, "css") + const jsMode = CodeMirror.getMode(config, "javascript") + + return { + startState(): State { + const htmlState = CodeMirror.startState(htmlMode) + const cssState = CodeMirror.startState(cssMode) + const jsState = CodeMirror.startState(jsMode) + + return { + curSegment: "html", + htmlState, + cssState, + jsState + } + }, + + token(stream, state: State): string | null { + let style = null; + + if(stream.string.trim() === "---*---") { + stream.skipToEnd() + advance(state) + }else if(state.curSegment === "html") { + style = htmlMode.token(stream, state.htmlState) + }else if(state.curSegment === "css") { + style = cssMode.token(stream, state.cssState) + }else if(state.curSegment === "js") { + style = jsMode.token(stream, state.jsState) + } + + return style + }, + } + }, + //@ts-ignore + "html", "css", "javascript" + ) + + return () => { + delete CodeMirror.modes.swarnam + } +} diff --git a/package-lock.json b/package-lock.json index b6cfa54..392c6fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { "name": "obsidian-sample-plugin", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "obsidian-sample-plugin", - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "devDependencies": { + "@types/codemirror": "^5.60.15", "@types/node": "^16.11.6", "@typescript-eslint/eslint-plugin": "5.29.0", "@typescript-eslint/parser": "5.29.0", @@ -532,9 +533,9 @@ } }, "node_modules/@types/codemirror": { - "version": "5.60.8", - "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.8.tgz", - "integrity": "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==", + "version": "5.60.15", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", + "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", "dev": true, "dependencies": { "@types/tern": "*" @@ -1753,6 +1754,15 @@ "@codemirror/view": "^6.0.0" } }, + "node_modules/obsidian/node_modules/@types/codemirror": { + "version": "5.60.8", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.8.tgz", + "integrity": "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==", + "dev": true, + "dependencies": { + "@types/tern": "*" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", diff --git a/package.json b/package.json index a9f81ef..1733d10 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "author": "", "license": "MIT", "devDependencies": { + "@types/codemirror": "^5.60.15", "@types/node": "^16.11.6", "@typescript-eslint/eslint-plugin": "5.29.0", "@typescript-eslint/parser": "5.29.0", From 877c9d7877c224a80676d48e9c5d02766b17d128 Mon Sep 17 00:00:00 2001 From: guopenghui Date: Thu, 23 May 2024 20:43:30 +0800 Subject: [PATCH 2/3] feat: add syntax highlight in preview mode --- main.ts | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/main.ts b/main.ts index fbedc1c..b4385f2 100644 --- a/main.ts +++ b/main.ts @@ -1,4 +1,4 @@ -import { MarkdownView, Plugin } from "obsidian"; +import { Plugin, loadPrism } from "obsidian"; import { SwarnamMode } from "./mode"; const PREFIX = "swarnam"; @@ -49,12 +49,21 @@ function showError(msg: string, root: HTMLElement) { } export default class SwarnamPlugin extends Plugin { - async onload() { - this.register(SwarnamMode()) + private prismLoaded = false + async onload() { + // add highlight in edit mode + this.register(SwarnamMode()) + this.registerMarkdownCodeBlockProcessor( "swarnam", - (source, el, ctx) => { + async (source, el, ctx) => { + // load Prism.js to add highlight in preview mode + if(!this.prismLoaded) { + await loadPrism() + this.prismLoaded = true + } + const root = el.createDiv({ cls: `${PREFIX}-root` }); let [ @@ -99,7 +108,7 @@ export default class SwarnamPlugin extends Plugin { text: "HTML", cls: `${PREFIX}-badge ${PREFIX}-html-badge`, }); - htmlEl.setText(htmlSource); + htmlEl.innerHTML = h(htmlSource, "html"); if (cssSource) { const cssContainer = sourceRoot.createDiv({ @@ -112,7 +121,7 @@ export default class SwarnamPlugin extends Plugin { text: "CSS", cls: `${PREFIX}-badge ${PREFIX}-css-badge`, }); - cssEl.setText(cssSource); + cssEl.innerHTML = h(cssSource, "css"); } if (jsSource) { @@ -128,7 +137,7 @@ export default class SwarnamPlugin extends Plugin { text: "JS", cls: `${PREFIX}-badge ${PREFIX}-js-badge`, }); - jsEl.setText(jsSource); + jsEl.innerHTML = h(jsSource, "javascript"); } const iframeEl = root.createEl("iframe", { @@ -142,3 +151,8 @@ export default class SwarnamPlugin extends Plugin { ); } } + +function h(code: string, mode: string) { + // @ts-ignore + return Prism.highlight(code, Prism.languages[mode], mode); +} From e56afd3a5854333099615c9b260f39cba07f8895 Mon Sep 17 00:00:00 2001 From: guopenghui Date: Thu, 23 May 2024 20:57:40 +0800 Subject: [PATCH 3/3] fix: remove undesirable padding --- styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles.css b/styles.css index c187810..a0b6379 100644 --- a/styles.css +++ b/styles.css @@ -27,7 +27,7 @@ .swarnam-source-root { flex: 1 1 0; - overflow-x: scroll; + overflow-x: auto; display: flex; align-items: stretch; flex-direction: column;