diff --git a/manifest.json b/manifest.json index 4dab95e..c4cddfa 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "2.1.0", + "version": "2.1.1", "minAppVersion": "1.1.6", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", diff --git a/package.json b/package.json index 59fb072..33ee190 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,12 @@ "rollup-plugin-web-worker-loader": "^1.6.1", "tslib": "^2.6.1", "ttypescript": "^1.5.15", - "typescript": "^5.2.2" + "typescript": "^5.2.2", + "@codemirror/commands": "^6.3.3", + "@codemirror/language": "^6.10.0", + "@codemirror/search": "^6.5.5", + "@codemirror/state": "^6.4.0", + "@codemirror/view": "^6.23.0" }, "resolutions": { "@typescript-eslint/typescript-estree": "5.3.0" diff --git a/rollup.config.js b/rollup.config.js index ab09f9e..701eac8 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -26,6 +26,7 @@ const react_pkg = isLib ? "" : isProd const reactdom_pkg = isLib ? "" : isProd ? fs.readFileSync("./node_modules/react-dom/umd/react-dom.production.min.js", "utf8") : fs.readFileSync("./node_modules/react-dom/umd/react-dom.development.js", "utf8"); + const lzstring_pkg = isLib ? "" : fs.readFileSync("./node_modules/lz-string/libs/lz-string.min.js", "utf8"); if(!isLib) { const excalidraw_styles = isProd @@ -58,7 +59,23 @@ const packageString = isLib const BASE_CONFIG = { input: 'src/main.ts', - external: ['obsidian', '@zsviczian/excalidraw', 'react', 'react-dom'], + external: [ + '@codemirror/autocomplete', + '@codemirror/collab', + '@codemirror/commands', + '@codemirror/language', + '@codemirror/lint', + '@codemirror/search', + '@codemirror/state', + '@codemirror/view', + '@lezer/common', + '@lezer/highlight', + '@lezer/lr', + 'obsidian', + '@zsviczian/excalidraw', + 'react', + 'react-dom' + ], } const getRollupPlugins = (tsconfig, ...plugins) => @@ -107,7 +124,9 @@ const BUILD_CONFIG = { // npm install brettz9/rollup-plugin-postprocess#update --save-dev // https://github.com/developit/rollup-plugin-postprocess/issues/10 postprocess([ - [/,React=require\("react"\);/, packageString], + //[/,React=require\("react"\);/, packageString], + [/React=require\("react"\),state=require\("@codemirror\/state"\),view=require\("@codemirror\/view"\)/, + `state=require("@codemirror/state"),view=require("@codemirror/view")` + packageString] ]) ] : [ diff --git a/src/CodeMirrorExtension/EditorHandler.ts b/src/CodeMirrorExtension/EditorHandler.ts new file mode 100644 index 0000000..85eca0d --- /dev/null +++ b/src/CodeMirrorExtension/EditorHandler.ts @@ -0,0 +1,49 @@ +import { Extension } from "@codemirror/state"; +import ExcalidrawPlugin from "src/main"; +import { HideTextBetweenCommentsExtension } from "./Fadeout"; +export const EDITOR_FADEOUT = "fadeOutExcalidrawMarkup"; + +export let excalidrawPlugin: ExcalidrawPlugin = null; + +const editorExtensions: {[key:string]:Extension}= { + [EDITOR_FADEOUT]: HideTextBetweenCommentsExtension, +} + +export class EditorHandler { + private activeEditorExtensions: Extension[] = []; + + constructor(private plugin: ExcalidrawPlugin) { + excalidrawPlugin = plugin; + } + + setup(): void { + this.plugin.registerEditorExtension(this.activeEditorExtensions); + this.updateCMExtensionState(EDITOR_FADEOUT, this.plugin.settings.fadeOutExcalidrawMarkup); + } + + updateCMExtensionState( + extensionIdentifier: string, + extensionState: boolean, + ) { + const extension = editorExtensions[extensionIdentifier]; + if(!extension) return; + if (extensionState == true) { + this.activeEditorExtensions.push(extension); + // @ts-ignore + this.activeEditorExtensions[this.activeEditorExtensions.length - 1].exID = extensionIdentifier; + } else { + for (let i = 0; i < this.activeEditorExtensions.length; i++) { + const ext = this.activeEditorExtensions[i]; + // @ts-ignore + if (ext.exID === extensionIdentifier) { + this.activeEditorExtensions.splice(i, 1); + break; + } + } + } + this.plugin.app.workspace.updateOptions(); + } + update(): void { + this.plugin.app.workspace.updateOptions(); + } +} \ No newline at end of file diff --git a/src/CodeMirrorExtension/Fadeout.ts b/src/CodeMirrorExtension/Fadeout.ts new file mode 100644 index 0000000..d64fd8a --- /dev/null +++ b/src/CodeMirrorExtension/Fadeout.ts @@ -0,0 +1,61 @@ +import { RangeSetBuilder } from "@codemirror/state"; +import { Decoration, DecorationSet, EditorView, ViewPlugin, ViewUpdate } from "@codemirror/view"; + +const o30 = Decoration.line({ attributes: {class: "ex-opacity-30"} }); +const o15 = Decoration.line({ attributes: {class: "ex-opacity-15"} }); +const o8 = Decoration.line({ attributes: {class: "ex-opacity-8"} }); +const o5 = Decoration.line({ attributes: {class: "ex-opacity-5"} }); +const o0 = Decoration.line({ attributes: {class: "ex-opacity-0"} }); + +export const HideTextBetweenCommentsExtension = ViewPlugin.fromClass( + class { + view: EditorView; + decorations: DecorationSet; + reTextElements = /^%%(?:\r\n|\r|\n)# Text Elements$/gm; + reDrawing = /^%%(?:\r\n|\r|\n)# Drawing$/gm; + linecount = 0; + isExcalidraw = false; + + constructor(view: EditorView) { + this.view = view; + this.isExcalidraw = view.state.doc.toString().search(/^excalidraw-plugin: /m) > 0; + if(!this.isExcalidraw) { + this.decorations = Decoration.none; + return; + } + this.decorations = this.updateDecorations(view); + } + + updateDecorations (view: EditorView) { + const { state } = view; + const { doc } = state; + + const text = doc.toString(); + + let start = text.search(this.reTextElements); + if(start == -1) { + start = text.search(this.reDrawing); + if(start == -1) return Decoration.none; + } + const startLine = doc.lineAt(start).number; + const endLine = doc.lines; + let builder = new RangeSetBuilder() + for (let l = startLine; l <= endLine; l++) { + const line = doc.line(l); + const pos = l-startLine; + builder.add(line.from, line.from, + pos == 0 ? o30 : (pos == 1) ? o15 : (pos < 6) ? o8 : (pos < 12) ? o5 : o0); + } + return builder.finish() + } + + update(update: ViewUpdate) { + if (this.isExcalidraw && update.docChanged) { + this.decorations = this.updateDecorations(update.view) + } + } + }, + { + decorations: (x) => x.decorations, + } +); \ No newline at end of file diff --git a/src/dialogs/Messages.ts b/src/dialogs/Messages.ts index 69c9d15..e58f046 100644 --- a/src/dialogs/Messages.ts +++ b/src/dialogs/Messages.ts @@ -17,6 +17,16 @@ I develop this plugin as a hobby, spending my free time doing this. If you find
`, +"2.1.1":` +## Fixed +- Printing a markdown page that has an Excalidraw drawing on the back side, resulted in an empty PDF. This is now resolved. + +## New +- Reduce the visual clutter by fading out the Excalidraw markup in markdown view mode. This feature needs to be enabled in plugin settings. You'll find the setting under ${String.fromCharCode(96)}Miscellaneous features${String.fromCharCode(96)}. Look for ${String.fromCharCode(96)}Fade out Excalidraw markup${String.fromCharCode(96)}. Depending on the location of the markdown comment ${String.fromCharCode(96)}%%${String.fromCharCode(96)}, if the comment starts before ${String.fromCharCode(96)}# Text Elements${String.fromCharCode(96)} then the fading will start from ${String.fromCharCode(96)}# Text Elements${String.fromCharCode(96)}, if the comment is before ${String.fromCharCode(96)}# Drawing${String.fromCharCode(96)} then the fading will only start with "drawing". If you delete the opening ${String.fromCharCode(96)}%%${String.fromCharCode(96)} the markup will be visible. Note, that if you place the comment before ${String.fromCharCode(96)}#Text Elements${String.fromCharCode(96)}, you will not be able to reference blocks in the ${String.fromCharCode(96)}# Text Elements${String.fromCharCode(96)} section, because Obsidian does not index blocks within comment blocks. Image references are not effective, they will work. + + + +`, "2.1.0":` Bumping the version to 2.1.0 due to minor file format changes that aren't backward compatible. Essentially, 2.0.26 is already not backward compatible, but I forgot to update the version number. diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index ace80b5..670435e 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -283,7 +283,8 @@ FILENAME_HEAD: "Filename", "Should pen mode be automatically enabled when opening Excalidraw?", SHOW_PEN_MODE_FREEDRAW_CROSSHAIR_NAME: "Show (+) crosshair in pen mode", SHOW_PEN_MODE_FREEDRAW_CROSSHAIR_DESC: - "Show crosshair in pen mode when using the freedraw tool. Toggle ON:SHOW Toggle OFF:HIDE", + "Show crosshair in pen mode when using the freedraw tool. Toggle ON: SHOW Toggle OFF: HIDE
"+ + "The effect depends on the device. Crosshair is typically visible on drawing tablets, MS Surface, but not on iOS.", THEME_HEAD: "Theme and styling", ZOOM_HEAD: "Zoom", DEFAULT_PINCHZOOM_NAME: "Allow pinch zoom in pen mode", @@ -611,6 +612,9 @@ FILENAME_HEAD: "Filename", "Turn this on to support image embedding styles such as ![[drawing|width|style]] in live preview editing mode. " + "The setting will not affect the currently open documents. You need close the open documents and re-open them for the change " + "to take effect.", + FADE_OUT_EXCALIDRAW_MARKUP_NAME: "Fade out Excalidraw markup", + FADE_OUT_EXCALIDRAW_MARKUP_DESC: "In Markdown view mode, the section after the markdown comment %% " + + "fades out. The text is still there, but the visual clutter is reduced", CUSTOM_FONT_HEAD: "Fourth font", ENABLE_FOURTH_FONT_NAME: "Enable fourth font option", ENABLE_FOURTH_FONT_DESC: diff --git a/src/main.ts b/src/main.ts index 9afd589..9f065bb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -133,6 +133,7 @@ import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types"; import { CustomMutationObserver, durationTreshold, isDebugMode } from "./utils/DebugHelper"; import { carveOutImage, carveOutPDF, createImageCropperFile, CROPPED_PREFIX } from "./utils/CarveOut"; import { ExcalidrawConfig } from "./utils/ExcalidrawConfig"; +import { EditorHandler } from "./CodeMirrorExtension/EditorHandler"; declare const EXCALIDRAW_PACKAGES:string; declare const react:any; @@ -181,6 +182,7 @@ export default class ExcalidrawPlugin extends Plugin { private removeEventLisnters:(()=>void)[] = []; private stylesManager:StylesManager; private textMeasureDiv:HTMLDivElement = null; + public editorHandler: EditorHandler; constructor(app: App, manifest: PluginManifest) { super(app, manifest); @@ -262,6 +264,8 @@ export default class ExcalidrawPlugin extends Plugin { await this.loadSettings({reEnableAutosave:true}); this.excalidrawConfig = new ExcalidrawConfig(this); await loadMermaid(); + this.editorHandler = new EditorHandler(this); + this.editorHandler.setup(); this.addSettingTab(new ExcalidrawSettingTab(this.app, this)); this.ea = await initExcalidrawAutomate(this); diff --git a/src/settings.ts b/src/settings.ts index e4e77e9..b04540d 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -34,6 +34,7 @@ import { startupScript } from "./constants/starutpscript"; import { ModifierKeySet, ModifierSetType } from "./utils/ModifierkeyHelper"; import { ModifierKeySettingsComponent } from "./dialogs/ModifierKeySettings"; import { ANNOTATED_PREFIX, CROPPED_PREFIX } from "./utils/CarveOut"; +import { EDITOR_FADEOUT } from "./CodeMirrorExtension/EditorHandler"; export interface ExcalidrawSettings { folder: string; @@ -110,6 +111,7 @@ export interface ExcalidrawSettings { experimentalFileType: boolean; experimentalFileTag: string; experimentalLivePreview: boolean; + fadeOutExcalidrawMarkup: boolean; experimentalEnableFourthFont: boolean; experimantalFourthFont: string; fieldSuggester: boolean; @@ -260,6 +262,7 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = { experimentalFileType: false, experimentalFileTag: "✏️", experimentalLivePreview: true, + fadeOutExcalidrawMarkup: false, experimentalEnableFourthFont: false, experimantalFourthFont: "Virgil", fieldSuggester: true, @@ -2260,6 +2263,19 @@ export class ExcalidrawSettingTab extends PluginSettingTab { }), ); + new Setting(detailsEl) + .setName(t("FADE_OUT_EXCALIDRAW_MARKUP_NAME")) + .setDesc(fragWithHTML(t("FADE_OUT_EXCALIDRAW_MARKUP_DESC"))) + .addToggle((toggle) => + toggle + .setValue(this.plugin.settings.fadeOutExcalidrawMarkup) + .onChange(async (value) => { + this.plugin.settings.fadeOutExcalidrawMarkup = value; + this.plugin.editorHandler.updateCMExtensionState(EDITOR_FADEOUT, value) + this.applySettingsUpdate(); + }), + ); + detailsEl = experimentalDetailsEl.createEl("details"); detailsEl.createEl("summary", { text: t("TASKBONE_HEAD"), diff --git a/styles.css b/styles.css index 391948a..a64b4b7 100644 --- a/styles.css +++ b/styles.css @@ -559,4 +559,24 @@ img.excalidraw-cropped-pdfpage, .excalidraw .pdf-toolbar, .excalidraw .pdf-container { width: 100%; +} + +.ex-opacity-30 { + opacity: 0.3; +} + +.ex-opacity-15 { + opacity: 0.15; +} + +.ex-opacity-8 { + opacity: 0.08; +} + +.ex-opacity-5 { + opacity: 0.05; +} + +.ex-opacity-0 { + opacity: 0; } \ No newline at end of file