diff --git a/manifest.json b/manifest.json index 6b58536..cc58eb3 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "1.6.16", + "version": "1.6.17", "minAppVersion": "0.12.16", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", diff --git a/src/EmbeddedFileLoader.ts b/src/EmbeddedFileLoader.ts index a291520..c9fc38a 100644 --- a/src/EmbeddedFileLoader.ts +++ b/src/EmbeddedFileLoader.ts @@ -3,7 +3,9 @@ import { BinaryFileData, DataURL } from "@zsviczian/excalidraw/types/types"; import { App, MarkdownRenderer, Notice, TFile } from "obsidian"; import { CASCADIA_FONT, + DEFAULT_MD_EMBED_CSS, fileid, + FRONTMATTER_KEY_BORDERCOLOR, FRONTMATTER_KEY_FONT, FRONTMATTER_KEY_FONTCOLOR, FRONTMATTER_KEY_MD_STYLE, @@ -430,20 +432,29 @@ const convertMarkdownToSVG = async ( frontmatterCSSisAfile = true; } } - if ( - !frontmatterCSSisAfile && - plugin.settings.mdCSS && - plugin.settings.mdCSS != "" - ) { - const f = plugin.app.metadataCache.getFirstLinkpathDest( - plugin.settings.mdCSS, - file.path, - ); - if (f) { - style += `\n${await plugin.app.vault.read(f)}`; + if(!frontmatterCSSisAfile) { + if (plugin.settings.mdCSS && plugin.settings.mdCSS !== "") { + const f = plugin.app.metadataCache.getFirstLinkpathDest( + plugin.settings.mdCSS, + file.path, + ); + style += f + ? `\n${await plugin.app.vault.read(f)}` + : DEFAULT_MD_EMBED_CSS; + } else { + style += DEFAULT_MD_EMBED_CSS; } } + const borderColor = fileCache?.frontmatter + ? fileCache.frontmatter[FRONTMATTER_KEY_BORDERCOLOR] ?? + plugin.settings.mdBorderColor + : plugin.settings.mdBorderColor; + + if(borderColor && borderColor !== "" && !style.match(/svg/i)) { + style += `svg{border:2px solid;color:${borderColor};transform:scale(.95)}`; + } + //3. //SVG helper functions //the SVG will first have ~infinite height. After sizing this will be reduced @@ -470,9 +481,8 @@ const convertMarkdownToSVG = async ( } mdDIV.style.overflow = "auto"; mdDIV.style.display = "block"; - if (fontColor && fontColor != "") { - mdDIV.style.color = fontColor; - } + mdDIV.style.color = (fontColor && fontColor !== "") + ? fontColor : "initial"; await MarkdownRenderer.renderMarkdown(text, mdDIV, file.path, plugin); mdDIV diff --git a/src/ExcalidrawView.ts b/src/ExcalidrawView.ts index d874447..edcd70b 100644 --- a/src/ExcalidrawView.ts +++ b/src/ExcalidrawView.ts @@ -7,7 +7,6 @@ import { Notice, Menu, MarkdownView, - ViewStateResult, } from "obsidian"; import * as React from "react"; import * as ReactDOM from "react-dom"; @@ -52,7 +51,7 @@ import { import { checkAndCreateFolder, checkExcalidrawVersion, - debug, + //debug, download, embedFontsInSVG, errorlog, @@ -374,8 +373,7 @@ export default class ExcalidrawView extends TextFileView { if (allowSave) { await super.save(); - this.semaphores.dirty = null; - this.diskIcon.querySelector("svg").removeClass("excalidraw-dirty"); + this.clearDirty(); } if (!this.semaphores.autosaving) { @@ -623,7 +621,7 @@ export default class ExcalidrawView extends TextFileView { ).latex; const prompt = new Prompt(this.app, t("ENTER_LATEX"), equation, ""); prompt.openAndGetValue(async (formula: string) => { - if (!formula) { + if (!formula || formula === equation) { return; } this.excalidrawData.setEquation(selectedImage.fileId, { @@ -638,6 +636,7 @@ export default class ExcalidrawView extends TextFileView { addFiles, this.plugin, ); + this.setDirty(); }); return; } @@ -657,12 +656,13 @@ export default class ExcalidrawView extends TextFileView { "Do not add [[square brackets]] around the filename!
Follow this format when editing your link:
filename#^blockref|WIDTHxMAXHEIGHT", ); prompt.openAndGetValue(async (link: string) => { - if (!link) { + if (!link || ef.linkParts.original === link) { return; } ef.resetImage(this.file.path, link); await this.save(true); await this.loadSceneFiles(); + this.setDirty(); }); return; } @@ -881,7 +881,7 @@ export default class ExcalidrawView extends TextFileView { } this.diskIcon.querySelector("svg").removeClass("excalidraw-dirty"); if (this.compatibilityMode) { - this.semaphores.dirty = null; + this.clearDirty(); return; } if (!this.excalidrawRef) { @@ -903,7 +903,7 @@ export default class ExcalidrawView extends TextFileView { this.excalidrawData.scene.appState.theme = this.excalidrawAPI.getAppState().theme; await this.loadDrawing(loadOnModifyTrigger); - this.semaphores.dirty = null; + this.clearDirty(); } zoomToElementId(id:string) { @@ -1093,8 +1093,7 @@ export default class ExcalidrawView extends TextFileView { const excalidrawData = this.excalidrawData.scene; this.semaphores.justLoaded = justloaded; this.initialContainerSizeUpdate = justloaded; - this.semaphores.dirty = null; - this.diskIcon.querySelector("svg").removeClass("excalidraw-dirty"); + this.clearDirty(); const om = this.excalidrawData.getOpenMode(); this.semaphores.preventReload = false; if (this.excalidrawRef) { @@ -1154,8 +1153,7 @@ export default class ExcalidrawView extends TextFileView { this.plugin.settings.compress !== isCompressed && !this.isEditedAsMarkdownInOtherView() ) { - this.semaphores.dirty = this.file?.path; - this.diskIcon.querySelector("svg").addClass("excalidraw-dirty"); + this.setDirty(); } } @@ -1168,6 +1166,16 @@ export default class ExcalidrawView extends TextFileView { ); } + public setDirty() { + this.semaphores.dirty = this.file?.path; + this.diskIcon.querySelector("svg").addClass("excalidraw-dirty"); + } + + public clearDirty() { + this.semaphores.dirty = null; + this.diskIcon.querySelector("svg").removeClass("excalidraw-dirty"); + } + public initializeToolsIconPanelAfterLoading() { const st = this.excalidrawAPI?.getAppState(); const panel = this.toolsPanelRef?.current; @@ -1334,8 +1342,7 @@ export default class ExcalidrawView extends TextFileView { private previousBackgroundColor = ""; private instantiateExcalidraw(initdata: any) { //console.log("ExcalidrawView.instantiateExcalidraw()"); - this.semaphores.dirty = null; - this.diskIcon.querySelector("svg").removeClass("excalidraw-dirty"); + this.clearDirty(); const reactElement = React.createElement(() => { let currentPosition = { x: 0, y: 0 }; const excalidrawWrapperRef = React.useRef(null); @@ -1665,8 +1672,7 @@ export default class ExcalidrawView extends TextFileView { if (save) { await this.save(false); //preventReload=false will ensure that markdown links are paresed and displayed correctly } else { - this.semaphores.dirty = this.file?.path; - this.diskIcon.querySelector("svg").addClass("excalidraw-dirty"); + this.setDirty(); } return true; }; @@ -2088,8 +2094,7 @@ export default class ExcalidrawView extends TextFileView { ) { this.previousSceneVersion = sceneVersion; this.previousBackgroundColor = st.viewBackgroundColor; - this.semaphores.dirty = this.file?.path; - this.diskIcon.querySelector("svg").addClass("excalidraw-dirty"); + this.setDirty(); } } }, @@ -2300,8 +2305,7 @@ export default class ExcalidrawView extends TextFileView { if (isDeleted) { this.excalidrawData.deleteTextElement(textElement.id); - this.semaphores.dirty = this.file?.path; - this.diskIcon.querySelector("svg").addClass("excalidraw-dirty"); + this.setDirty(); return [null, null, null]; } @@ -2324,8 +2328,7 @@ export default class ExcalidrawView extends TextFileView { ) { //the user made changes to the text or the text is missing from Excalidraw Data (recently copy/pasted) //setTextElement will attempt a quick parse (without processing transclusions) - this.semaphores.dirty = this.file?.path; - this.diskIcon.querySelector("svg").addClass("excalidraw-dirty"); + this.setDirty(); const [parseResultWrapped, parseResultOriginal, link] = this.excalidrawData.setTextElement( textElement.id, diff --git a/src/Messages.ts b/src/Messages.ts index eb305cb..6f664b4 100644 --- a/src/Messages.ts +++ b/src/Messages.ts @@ -6,23 +6,63 @@ If you'd like to learn more, please subscribe to my YouTube channel: [Visual PKM Thank you & Enjoy!
- +
`; export const RELEASE_NOTES: { [k: string]: string } = { Intro: `I want to make it easier for you to keep up with all the updates. Going forward, after installing each release, you'll be prompted with a message summarizing the key new features and fixes. -You can disable this in plugin-settings. The release change log is also available on [GitHub](https://github.com/zsviczian/obsidian-excalidraw-plugin/releases). +You can disable this in plugin-settings. The release change-log is also available on [GitHub](https://github.com/zsviczian/obsidian-excalidraw-plugin/releases). Since March 2021, I've spent most of my free time building this plugin. By now, this means well over 100 workdays worth of my time (assuming 8-hour days). I am grateful to all of you who have already bought me a coffee. THANK YOU! This means a lot to me! I still have many-many ideas for making Obsidian Excalidraw better. -I will continue to keep all the features of the plugin free. If, however, you'd like to contribute to the on-going development of the plugin, I am introducing a simple membership scheme, with Bronze, Silver and Gold tiers. -If you find this plugin valuable, please consider clicking the button below. +I will continue to keep all the features of the plugin free. If, however, you'd like to contribute to the on-going development of the plugin, I am introducing a simple membership scheme with Bronze, Silver and Gold tiers. +If you find this plugin valuable, please consider supporting.
+`, +"1.6.17": ` +
+ +
+ +# Fixed +- Freedraw shape's background color was missing in the SVG export. [#443](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/443) +- In rare cases, when you only changed the background color of the drawing or edited the dimensions of an embedded markdown document, or changed an existing LaTeX formula, and then moved to another document in the vault, these changes did not get saved. [#503](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/503) +- I resolved an Excalidraw Automate glitch with word wrapping in containers. EA generated containers with fixed line breaks. The same error also affected the conversion of drawings from the "legacy" Excalidraw.com file format. +- When you allow/disable autosave in settings, this change will immediately take effect for all open Excalidraw workspace leaves. Until now autosave was activated only after you closed and reopened the Excalidraw view. [#502](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/502) +- When you create a text element containing a ${String.fromCharCode(96,96,96)}[[markdown link]]${String.fromCharCode(96,96,96)} in raw mode, the new link was parsed nonetheless, and sometimes the link disappeared, leaving only the parsed text without the actual link. Creating links in raw-mode now works correctly. + +# New Features +- The most recent 5 custom colors from the canvas are now added as color options to the element stroke and element background palette. [#4843](https://github.com/excalidraw/excalidraw/pull/4843) +- Vertical text alignment for text in sticky notes [#4852](https://github.com/excalidraw/excalidraw/pull/4852) +- Markdown embeds into Excalidraw now receive default styling, including that of tables, blockquotes, and code blocks. I also added a new setting and corresponding frontmatter-key to set the border-color for the embedded markdown document. You can override plugin settings at the document level by adding ${String.fromCharCode(96,96,96)}excalidraw-border-color: steelblue${String.fromCharCode(96,96,96)} to the markdown document you want to embed into your drawing. Valid values are css-color-name|#HEXcolor|any-other-html-standard-format. +- In Obsidian search, when the text you were searching for is found in an Excalidraw document, clicking the link in search-results will open the drawing with the matching text element selected and zoomed. +- Excalidraw now supports linking to text elements on the canvas and linking to non-text objects. +1) You can reference text headings just the same as markdown headings in a document +i.e. you have a text element that includes a valid markdown heading: +${String.fromCharCode(96,96,96)}markdown +# My Heading +details... +${String.fromCharCode(96,96,96)} +or +${String.fromCharCode(96,96,96)}markdown +text element text +# my reference +${String.fromCharCode(96,96,96)} +You can reference these like this respectively: ${String.fromCharCode(96,96,96)}[[#My Heading|display alias]]${String.fromCharCode(96,96,96)} and ${String.fromCharCode(96,96,96)}[[#my reference|alias]]${String.fromCharCode(96,96,96)} + +![image](https://user-images.githubusercontent.com/14358394/156890231-5a23bcb3-40a4-4ad7-b366-74c328620159.png) + +2) You can also reference element ids similar to block references +- Links take this form ${String.fromCharCode(96,96,96)}[[#^elementID|alias]]${String.fromCharCode(96,96,96)} +- Linking is supported by a new action on the Obsidian Tools Panel +![image](https://user-images.githubusercontent.com/14358394/156894011-6442c3d6-aaff-43a8-bd77-513e450484ba.png) + +[Release Notes on GitHub](https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/1.6.17) `, "1.6.16": `
diff --git a/src/ReleaseNotes.ts b/src/ReleaseNotes.ts index 29df61b..258b556 100644 --- a/src/ReleaseNotes.ts +++ b/src/ReleaseNotes.ts @@ -36,7 +36,7 @@ export class ReleaseNotes extends Modal { ? Object.keys(RELEASE_NOTES) .filter((key) => key > prevRelease) .map((key: string) => `# ${key}\n${RELEASE_NOTES[key]}`) - .slice(0, 10) + .slice(0, 6) .join("\n\n") : FIRST_RUN; await MarkdownRenderer.renderMarkdown( diff --git a/src/SuggestorInfo.ts b/src/SuggestorInfo.ts index 685ebbf..da4f8f7 100644 --- a/src/SuggestorInfo.ts +++ b/src/SuggestorInfo.ts @@ -539,13 +539,19 @@ export const FRONTMATTER_KEYS_INFO: SuggestorInfo[] = [ { field: "font", code: null, - desc: "This key applies to Markdown Embeds. You can control the appearance of the embedded markdown file on a file by file bases by adding the this front matter keys to your markdown document. Valid values are: Virgil|Cascadia|font_file_name.extension", + desc: "This key applies to Markdown Embeds. You can control the appearance of the embedded markdown file on a file by file bases by adding the this frontmatter key to your markdown document. Valid values are: Virgil|Cascadia|font_file_name.extension", after: ": Virgil", }, { field: "font-color", code: null, - desc: "This key applies to Markdown Embeds. You can control the appearance of the embedded markdown file on a file by file bases by adding the this front matter keys to your markdown document. Valid values are: css-color-name|#HEXcolor|any-other-html-standard-format", + desc: "This key applies to Markdown Embeds. You can control the appearance of the embedded markdown file on a file by file bases by adding the this frontmatter key to your markdown document. Valid values are: css-color-name|#HEXcolor|any-other-html-standard-format", + after: ": SteelBlue", + }, + { + field: "border-color", + code: null, + desc: "This key applies to Markdown Embeds. You can control the appearance of the embedded markdown file on a file by file bases by adding the this frontmatter key to your markdown document. Valid values are: css-color-name|#HEXcolor|any-other-html-standard-format", after: ": SteelBlue", }, { diff --git a/src/constants.ts b/src/constants.ts index f75078f..1f9fd45 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -28,6 +28,7 @@ export const FRONTMATTER_KEY_CUSTOM_LINK_BRACKETS = "excalidraw-link-brackets"; export const FRONTMATTER_KEY_DEFAULT_MODE = "excalidraw-default-mode"; export const FRONTMATTER_KEY_FONT = "excalidraw-font"; export const FRONTMATTER_KEY_FONTCOLOR = "excalidraw-font-color"; +export const FRONTMATTER_KEY_BORDERCOLOR = "excalidraw-border-color"; export const FRONTMATTER_KEY_MD_STYLE = "excalidraw-css"; export const LOCAL_PROTOCOL = "md://"; export const VIEW_TYPE_EXCALIDRAW = "excalidraw"; @@ -197,6 +198,7 @@ COLOR_NAMES.set("white", "#ffffff"); COLOR_NAMES.set("whitesmoke", "#f5f5f5"); COLOR_NAMES.set("yellow", "#ffff00"); COLOR_NAMES.set("yellowgreen", "#9acd32"); +export const DEFAULT_MD_EMBED_CSS = `.excalidraw-md-host{padding:0px 10px}.excalidraw-md-footer{height:5px}foreignObject{background-color:transparent}p{display:block;margin-block-start:1em;margin-block-end:1em;margin-inline-start:0px;margin-inline-end:0px;color:inherit}table,tr,th,td{color:inherit;border:1px solid;border-collapse:collapse;padding:3px}th{font-weight:bold;border-bottom:double;background-color:silver}.copy-code-button{display:none}code[class*=language-],pre[class*=language-]{color:#393a34;font-family:"Consolas","Bitstream Vera Sans Mono","Courier New",Courier,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;font-size:.9em;line-height:1.2em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre>code[class*=language-]{font-size:1em}pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection{background:#C1DEF1}pre[class*=language-]::selection,pre[class*=language-] ::selection,code[class*=language-]::selection,code[class*=language-] ::selection{background:#C1DEF1}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;background-color:#0000001a}:not(pre)>code[class*=language-]{padding:.2em;padding-top:1px;padding-bottom:1px;background:#f8f8f8;border:1px solid #dddddd}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:green;font-style:italic}.token.namespace{opacity:.7}.token.string{color:#a31515}.token.punctuation,.token.operator{color:#393a34}.token.url,.token.symbol,.token.number,.token.boolean,.token.variable,.token.constant,.token.inserted{color:#36acaa}.token.atrule,.token.keyword,.token.attr-value,.language-autohotkey .token.selector,.language-json .token.boolean,.language-json .token.number,code[class*=language-css]{color:#00f}.token.function{color:#393a34}.token.deleted,.language-autohotkey .token.tag{color:#9a050f}.token.selector,.language-autohotkey .token.keyword{color:#00009f}.token.important{color:#e90}.token.important,.token.bold{font-weight:bold}.token.italic{font-style:italic}.token.class-name,.language-json .token.property{color:#2b91af}.token.tag,.token.selector{color:maroon}.token.attr-name,.token.property,.token.regex,.token.entity{color:red}.token.directive.tag .tag{background:#ffff00;color:#393a34}.line-numbers.line-numbers .line-numbers-rows{border-right-color:#a5a5a5}.line-numbers .line-numbers-rows>span:before{color:#2b91af}.line-highlight.line-highlight{background:rgba(193,222,241,.2);background:-webkit-linear-gradient(left,rgba(193,222,241,.2) 70%,rgba(221,222,241,0));background:linear-gradient(to right,rgba(193,222,241,.2) 70%,rgba(221,222,241,0))}blockquote{ font-style:italic;background-color:rgb(46,43,42,0.1);margin:0;margin-left:1em;border-radius:0 4px 4px 0;border:1px solid hsl(0,80%,32%);border-left-width:8px;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;padding:10px 20px;margin-inline-start:30px;margin-inline-end:30px;}`; export const SCRIPTENGINE_ICON = ``; export const DISK_ICON_NAME = "disk"; export const DISK_ICON = ``; diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index 400b86b..98fbe3c 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -239,8 +239,14 @@ export default { MD_DEFAULT_COLOR_NAME: "The default font color to use for embedded markdown files.", MD_DEFAULT_COLOR_DESC: - 'Set this to allowed css color names e.g. "steelblue" (https://www.w3schools.com/colors/colors_names.asp), or a valid hexadecimal color e.g. "#e67700". ' + - 'You can override this setting by adding the following frontmatter-key to the embedded markdown file: "excalidraw-font-color: color_name_or_rgbhex"', + 'Set this to any valid css color name e.g. "steelblue" (color names), or a valid hexadecimal color e.g. "#e67700", ' + + 'or any other valid css color string. You can override this setting by adding the following frontmatter-key to the embedded markdown file: excalidraw-font-color: steelblue', + MD_DEFAULT_BORDER_COLOR_NAME: + "The default border color to use for embedded markdown files.", + MD_DEFAULT_BORDER_COLOR_DESC: + 'Set this to any valid css color name e.g. "steelblue" (color names), or a valid hexadecimal color e.g. "#e67700", ' + + 'or any other valid css color string. You can override this setting by adding the following frontmatter-key to the embedded markdown file: excalidraw-border-color: gray. ' + + "Leave empty if you don't want a border. ", MD_CSS_NAME: "CSS file", MD_CSS_DESC: "The filename of the CSS to apply to markdown embeds. Provide the filename with extension (e.g. 'md-embed.css'). The css file may also be a plain " + diff --git a/src/settings.ts b/src/settings.ts index c86b07a..d29c65b 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -72,6 +72,7 @@ export interface ExcalidrawSettings { mdSVGmaxHeight: number; mdFont: string; mdFontColor: string; + mdBorderColor: string; mdCSS: string; scriptEngineSettings: {}; defaultTrayMode: boolean; @@ -144,6 +145,7 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = { mdSVGmaxHeight: 800, mdFont: "Virgil", mdFontColor: "Black", + mdBorderColor: "Black", mdCSS: "", scriptEngineSettings: {}, defaultTrayMode: false, @@ -734,6 +736,20 @@ export class ExcalidrawSettingTab extends PluginSettingTab { }), ); + new Setting(containerEl) + .setName(t("MD_DEFAULT_BORDER_COLOR_NAME")) + .setDesc(fragWithHTML(t("MD_DEFAULT_BORDER_COLOR_DESC"))) + .addText((text) => + text + .setPlaceholder("CSS Color-name|RGB-HEX") + .setValue(this.plugin.settings.mdBorderColor) + .onChange((value) => { + this.requestReloadDrawings = true; + this.plugin.settings.mdBorderColor = value; + this.applySettingsUpdate(true); + }), + ); + new Setting(containerEl) .setName(t("MD_CSS_NAME")) .setDesc(fragWithHTML(t("MD_CSS_DESC"))) diff --git a/versions.json b/versions.json index 17361de..f389546 100644 --- a/versions.json +++ b/versions.json @@ -1,4 +1,4 @@ { - "1.6.16": "0.12.16", + "1.6.17": "0.12.16", "1.4.2": "0.11.13" }