This commit is contained in:
Zsolt Viczian
2022-02-19 18:16:00 +01:00
parent bc71bde9b7
commit e98b1755ee
15 changed files with 436 additions and 24 deletions

View File

@@ -195,6 +195,12 @@ export interface ExcalidrawAutomate {
selectElementsInView(elements: ExcalidrawElement[]): void; //sets selection in view
generateElementId(): string; //returns an 8 character long random id
cloneElement(element: ExcalidrawElement): ExcalidrawElement; //Returns a clone of the element with a new id
moveViewElementToZIndex(elementId:number, newZIndex:number): void; //Moves the element to a specific position in the z-index
hexStringToRgb(color: string):number[];
rgbToHexString(color: number[]):string;
hslToRgb(color: number[]):number[];
rgbToHsl(color:number[]):number[];
colorNameToHex(color:string):string;
}
```

View File

@@ -1,7 +1,7 @@
{
"id": "obsidian-excalidraw-plugin",
"name": "Excalidraw",
"version": "1.6.12",
"version": "1.6.13",
"minAppVersion": "0.12.16",
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
"author": "Zsolt Viczian",

View File

@@ -1,6 +1,6 @@
{
"name": "obsidian-excalidraw-plugin",
"version": "1.6.9",
"version": "1.6.13",
"description": "This is an Obsidian.md plugin that lets you view and edit Excalidraw drawings",
"main": "main.js",
"scripts": {
@@ -17,7 +17,9 @@
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "^5.0.0",
"roughjs": "^4.5.2"
"roughjs": "^4.5.2",
"lz-string": "^1.4.4",
"@types/lz-string": "^1.3.34"
},
"devDependencies": {
"@babel/core": "^7.16.12",

View File

@@ -15,6 +15,7 @@ import {
VIEW_TYPE_EXCALIDRAW,
MAX_IMAGE_SIZE,
PLUGIN_ID,
COLOR_NAMES,
} from "./constants";
import {
//debug,
@@ -36,7 +37,6 @@ import {
getMaximumGroups,
intersectElementWithLine,
} from "@zsviczian/excalidraw";
import { stringify } from "querystring";
declare type ConnectionPoint = "top" | "bottom" | "left" | "right" | null;
const GAP = 4;
@@ -234,6 +234,11 @@ export interface ExcalidrawAutomate {
generateElementId(): string; //returns an 8 character long random id
cloneElement(element: ExcalidrawElement): ExcalidrawElement; //Returns a clone of the element with a new id
moveViewElementToZIndex(elementId:number, newZIndex:number): void; //Moves the element to a specific position in the z-index
hexStringToRgb(color: string):number[];
rgbToHexString(color: number[]):string;
hslToRgb(color: number[]):number[];
rgbToHsl(color:number[]):number[];
colorNameToHex(color:string):string;
}
declare let window: any;
@@ -1348,6 +1353,108 @@ export async function initExcalidrawAutomate(
elements: elements,
commitToHistory: true,
});
},
hexStringToRgb(color: string):number[] {
const res = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
return [parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16)];
},
rgbToHexString(color: number[]):string {
const colorInt =
((Math.round(color[0]) & 0xff) << 16) +
((Math.round(color[1]) & 0xff) << 8) +
(Math.round(color[2]) & 0xff);
const colorStr = colorInt.toString(16).toLowerCase();
return "#"+"000000".substring(colorStr.length) + colorStr;
},
hslToRgb(color: number[]):number[] {
const h = color[0] / 360;
const s = color[1] / 100;
const l = color[2] / 100;
let t2;
let t3;
let val;
if (s === 0) {
val = l * 255;
return [val, val, val];
}
if (l < 0.5) {
t2 = l * (1 + s);
} else {
t2 = l + s - l * s;
}
const t1 = 2 * l - t2;
const rgb = [0, 0, 0];
for (let i = 0; i < 3; i++) {
t3 = h + (1 / 3) * -(i - 1);
if (t3 < 0) {
t3++;
}
if (t3 > 1) {
t3--;
}
if (6 * t3 < 1) {
val = t1 + (t2 - t1) * 6 * t3;
} else if (2 * t3 < 1) {
val = t2;
} else if (3 * t3 < 2) {
val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
} else {
val = t1;
}
rgb[i] = val * 255;
}
return rgb;
},
rgbToHsl(color:number[]):number[] {
const r = color[0] / 255;
const g = color[1] / 255;
const b = color[2] / 255;
const min = Math.min(r, g, b);
const max = Math.max(r, g, b);
const delta = max - min;
let h;
let s;
if (max === min) {
h = 0;
} else if (r === max) {
h = (g - b) / delta;
} else if (g === max) {
h = 2 + (b - r) / delta;
} else if (b === max) {
h = 4 + (r - g) / delta;
}
h = Math.min(h * 60, 360);
if (h < 0) {
h += 360;
}
const l = (min + max) / 2;
if (max === min) {
s = 0;
} else if (l <= 0.5) {
s = delta / (max + min);
} else {
s = delta / (2 - max - min);
}
return [h, s * 100, l * 100];
},
colorNameToHex(color:string):string {
if (COLOR_NAMES.has(color.toLowerCase().trim())) {
return COLOR_NAMES.get(color.toLowerCase().trim());
}
return color.trim();
}
};
await initFonts();

View File

@@ -20,6 +20,8 @@ import ExcalidrawPlugin from "./main";
import { JSON_parse } from "./constants";
import { TextMode } from "./ExcalidrawView";
import {
compress,
decompress,
getAttachmentsFolderAndFilePath,
//getBakPath,
getBinaryFileFromDataURL,
@@ -86,8 +88,31 @@ export const REG_LINKINDEX_HYPERLINK = /^\w+:\/\//;
//added \n at and of DRAWING_REG: https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/357
const DRAWING_REG = /\n# Drawing\n[^`]*(```json\n)([\s\S]*?)```\n/gm; //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/182
const DRAWING_REG_FALLBACK = /\n# Drawing\n(```json\n)?(.*)(```)?(%%)?/gm;
const DRAWING_COMPRESSED_REG = /\n# Drawing\n[^`]*(```compressed\-json\n)([\s\S]*?)```\n/gm; //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/182
const DRAWING_COMPRESSED_REG_FALLBACK = /\n# Drawing\n(```compressed\-json\n)?(.*)(```)?(%%)?/gm;
export function getJSON(data: string): { scene: string; pos: number } {
let res = data.matchAll(DRAWING_REG);
let res;
if(data.match(/```compressed\-json\n/gm)) {
res = data.matchAll(DRAWING_COMPRESSED_REG);
//In case the user adds a text element with the contents "# Drawing\n"
let parts;
parts = res.next();
if (parts.done) {
//did not find a match
res = data.matchAll(DRAWING_COMPRESSED_REG_FALLBACK);
parts = res.next();
}
if (parts.value && parts.value.length > 1) {
const result = decompress(parts.value[2]);
return {
scene: result.substring(0, result.lastIndexOf("}") + 1),
pos: parts.value.index,
}; //this is a workaround in case sync merges two files together and one version is still an old version without the ```codeblock
}
return { scene: data, pos: parts.value ? parts.value.index : 0 };
}
res = data.matchAll(DRAWING_REG);
//In case the user adds a text element with the contents "# Drawing\n"
let parts;
@@ -107,8 +132,10 @@ export function getJSON(data: string): { scene: string; pos: number } {
return { scene: data, pos: parts.value ? parts.value.index : 0 };
}
export function getMarkdownDrawingSection(jsonString: string) {
return `%%\n# Drawing\n\x60\x60\x60json\n${jsonString}\n\x60\x60\x60\n%%`;
export function getMarkdownDrawingSection(jsonString: string, compressed: boolean) {
return compressed
? `%%\n# Drawing\n\x60\x60\x60compressed-json\n${compress(jsonString)}\n\x60\x60\x60\n%%`
: `%%\n# Drawing\n\x60\x60\x60json\n${jsonString}\n\x60\x60\x60\n%%`;
}
/**
@@ -372,12 +399,14 @@ export class ExcalidrawData {
if (!file) {
return false;
}
this.loaded = false;
this.compatibilityMode = true;
this.file = file;
this.textElements = new Map<
string,
{ raw: string; parsed: string; wrapAt: number }
>();
this.elementLinks = new Map<string, string>();
this.setShowLinkBrackets();
this.setLinkPrefix();
this.setUrlPrefix();
@@ -394,6 +423,7 @@ export class ExcalidrawData {
this.findNewTextElementsInScene();
this.findNewElementLinksInScene();
await this.setTextMode(TextMode.raw, true); //legacy files are always displayed in raw mode.
this.loaded = true;
return true;
}
@@ -762,6 +792,7 @@ export class ExcalidrawData {
* Generate markdown file representation of excalidraw drawing
* @returns markdown string
*/
disableCompression: boolean = false;
generateMD(): string {
let outString = "# Text Elements\n";
for (const key of this.textElements.keys()) {
@@ -789,7 +820,10 @@ export class ExcalidrawData {
outString += this.equations.size > 0 || this.files.size > 0 ? "\n" : "";
const sceneJSONstring = JSON.stringify(this.scene, null, "\t");
return outString + getMarkdownDrawingSection(sceneJSONstring);
return outString + getMarkdownDrawingSection(
sceneJSONstring,
this.disableCompression ? false: this.plugin.settings.compress
);
}
/**

View File

@@ -6,6 +6,7 @@ import {
WorkspaceItem,
Notice,
Menu,
MarkdownView,
} from "obsidian";
import * as React from "react";
import * as ReactDOM from "react-dom";
@@ -258,7 +259,7 @@ export default class ExcalidrawView extends TextFileView {
//- by monkeypatches on detach(next)
//This semaphore helps avoid collision of saves
private preventSave:boolean = false; //this.saving is taken by Obsidian. When I set this, nothing got saved at all.
async save(preventReload: boolean = true) {
async save(preventReload: boolean = true, forcesave: boolean = false) {
if(this.preventSave) {
return;
}
@@ -278,7 +279,7 @@ export default class ExcalidrawView extends TextFileView {
}
this.preventReload = preventReload;
const allowSave = (this.dirty !== null && this.dirty) || this.autosaving; //dirty == false when view.file == null;
const allowSave = (this.dirty !== null && this.dirty) || this.autosaving || forcesave; //dirty == false when view.file == null;
this.dirty = null;
const scene = this.getScene();
@@ -365,8 +366,12 @@ export default class ExcalidrawView extends TextFileView {
header = header.replace(REG_IMG, "$1");
}
//end of remove
return header + this.excalidrawData.generateMD();
if(!this.excalidrawData.disableCompression) {
this.excalidrawData.disableCompression = this.isEditedAsMarkdownInOtherView();
}
const reuslt = header + this.excalidrawData.generateMD();
this.excalidrawData.disableCompression = false;
return reuslt;
}
if (this.compatibilityMode) {
return JSON.stringify(scene, null, "\t");
@@ -610,7 +615,7 @@ export default class ExcalidrawView extends TextFileView {
});
this.diskIcon = this.addAction(DISK_ICON_NAME, t("FORCE_SAVE"), async () => {
await this.save(false);
await this.save(false, true);
this.plugin.triggerEmbedUpdates();
this.loadSceneFiles();
});
@@ -659,6 +664,7 @@ export default class ExcalidrawView extends TextFileView {
);
}
this.setupAutosaveTimer();
this.contentEl.addClass("excalidraw-view");
}
public setTheme(theme: string) {
@@ -695,7 +701,9 @@ export default class ExcalidrawView extends TextFileView {
public setupAutosaveTimer() {
const timer = async () => {
if (this.dirty &&
if (
this.isLoaded &&
this.dirty &&
this.dirty == this.file?.path &&
this.plugin.settings.autosave
) {
@@ -747,7 +755,8 @@ export default class ExcalidrawView extends TextFileView {
if (!this.file) {
return;
}
if (file) {
const loadOnModifyTrigger = (file && file === this.file);
if (loadOnModifyTrigger) {
this.data = await this.app.vault.cachedRead(file);
}
if (fullreload) {
@@ -757,7 +766,7 @@ export default class ExcalidrawView extends TextFileView {
}
this.excalidrawData.scene.appState.theme =
this.excalidrawAPI.getAppState().theme;
await this.loadDrawing(false);
await this.loadDrawing(loadOnModifyTrigger);
this.dirty = null;
}
@@ -783,8 +792,6 @@ export default class ExcalidrawView extends TextFileView {
}
data = this.data = data.replaceAll("\r\n", "\n").replaceAll("\r", "\n");
this.app.workspace.onLayoutReady(async () => {
this.dirty = null;
this.diskIcon.querySelector("svg").removeClass("excalidraw-dirty");
this.compatibilityMode = this.file.extension === "excalidraw";
await this.plugin.loadSettings();
if (this.compatibilityMode) {
@@ -794,7 +801,9 @@ export default class ExcalidrawView extends TextFileView {
if (!this.plugin.settings.compatibilityMode) {
new Notice(t("COMPATIBILITY_MODE"), 4000);
}
this.excalidrawData.disableCompression = true;
} else {
this.excalidrawData.disableCompression = false;
const textMode = getTextMode(data);
this.changeTextMode(textMode, false);
try {
@@ -864,6 +873,7 @@ export default class ExcalidrawView extends TextFileView {
}, 500);
}
initialContainerSizeUpdate = false;
/**
*
* @param justloaded - a flag to trigger zoom to fit after the drawing has been loaded
@@ -871,6 +881,9 @@ export default class ExcalidrawView extends TextFileView {
private async loadDrawing(justloaded: boolean) {
const excalidrawData = this.excalidrawData.scene;
this.justLoaded = justloaded;
this.initialContainerSizeUpdate =justloaded;
this.dirty = null;
this.diskIcon.querySelector("svg").removeClass("excalidraw-dirty");
const om = this.excalidrawData.getOpenMode();
this.preventReload = false;
if (this.excalidrawRef) {
@@ -922,6 +935,24 @@ export default class ExcalidrawView extends TextFileView {
});
//files are loaded on excalidrawRef readyPromise
}
const isCompressed = this.data.match(/```compressed\-json\n/gm) !== null;
if(
!this.compatibilityMode &&
(this.plugin.settings.compress !== isCompressed) &&
!this.isEditedAsMarkdownInOtherView()
) {
this.dirty = this.file?.path;
this.diskIcon.querySelector("svg").addClass("excalidraw-dirty");
}
}
isEditedAsMarkdownInOtherView():boolean {
//if the user is editing the same file in markdown mode, do not compress it
const leaves = this.app.workspace.getLeavesOfType("markdown");
return leaves
.filter(leaf => (leaf.view as MarkdownView).file === this.file)
.length > 0;
}
//Compatibility mode with .excalidraw files
@@ -961,6 +992,10 @@ export default class ExcalidrawView extends TextFileView {
.setTitle(t("OPEN_AS_MD"))
.setIcon("document")
.onClick(async () => {
if(this.plugin.settings.compress === true) {
this.excalidrawData.disableCompression = true;
await this.save(true,true);
}
this.setMarkdownView();
});
})
@@ -1814,7 +1849,10 @@ export default class ExcalidrawView extends TextFileView {
st.editingLinearElement === null
) {
const sceneVersion = getSceneVersion(et);
if (sceneVersion !== this.previousSceneVersion) {
if (
sceneVersion > 0 &&
sceneVersion !== this.previousSceneVersion
) {
this.previousSceneVersion = sceneVersion;
this.dirty = this.file?.path;
this.diskIcon.querySelector("svg").addClass("excalidraw-dirty");
@@ -2185,7 +2223,13 @@ export default class ExcalidrawView extends TextFileView {
.filter((el: ExcalidrawElement) =>
el.boundElements?.map((e) => e.type).includes("text"),
);
api.updateContainerSize(containers);
if(containers.length > 0) {
if(this.initialContainerSizeUpdate) { //updateContainerSize will bump scene version which will trigger a false autosave
this.justLoaded = true; //after load, which will lead to a ping-pong between two syncronizing devices
}
api.updateContainerSize(containers);
}
this.initialContainerSizeUpdate = false;
};
if (delay) {
setTimeout(() => update(), 50);

View File

@@ -446,6 +446,36 @@ export const EXCALIDRAW_AUTOMATE_INFO:SuggestorInfo[] = [
desc: "Moves the element to a specific position in the z-index",
after: "",
},
{
field: "hexStringToRgb",
code: "hexStringToRgb(color: string):number[];",
desc: "Converts a HEX color to an RGB number array. #FF0000 to [255,0,0]",
after: "",
},
{
field: "rgbToHexString",
code: "rgbToHexString(color: number[]):string;",
desc: "Converts an RGB number array to a HEX string. [255,0,0] to #FF0000",
after: "",
},
{
field: "hslToRgb",
code: "hslToRgb(color: number[]):number[];",
desc: "Converts an HSL number array to an RGB number array. [0,100,50] to [255,0,0]",
after: "",
},
{
field: "rgbToHsl",
code: "rgbToHsl(color:number[]):number[];",
desc: "Converts an RGB number array to an HSL number array. [255,0,0] to [0,100,50]",
after: "",
},
{
field: "colorNameToHex",
code: "colorNameToHex(color:string):string;",
desc: "Converts a CSS color name to its HEX color equivalent. 'White' to #FFFFFF",
after: "",
},
];
export const EXCALIDRAW_SCRIPTENGINE_INFO:SuggestorInfo[] = [

View File

@@ -21,6 +21,7 @@ import {
import ExcalidrawPlugin from "./main";
import { ExcalidrawElement } from "@zsviczian/excalidraw/types/element/types";
import { ExportSettings } from "./ExcalidrawView";
import { compressToBase64, decompressFromBase64 } from "lz-string";
declare module "obsidian" {
interface Workspace {
@@ -550,6 +551,14 @@ export const getLinkParts = (fname: string): LinkParts => {
};
};
export const compress = (data:string):string => {
return compressToBase64(data).replace(/(.{1024})/g, "$1\n");
};
export const decompress = (data:string):string => {
return decompressFromBase64(data.replaceAll("\n","").replaceAll("\r",""));
};
export const errorlog = (data: {}) => {
console.error({ plugin: "Excalidraw", ...data });
};

View File

@@ -55,6 +55,148 @@ export const TEXT_DISPLAY_RAW_ICON_NAME = "presentation";
export const FULLSCREEN_ICON_NAME = "fullscreen";
export const EXIT_FULLSCREEN_ICON_NAME = "exit-fullscreen";
export const SCRIPTENGINE_ICON_NAME = "ScriptEngine";
export const COLOR_NAMES = new Map<string,string>();
COLOR_NAMES.set("aliceblue","#f0f8ff");
COLOR_NAMES.set("antiquewhite","#faebd7");
COLOR_NAMES.set("aqua","#00ffff");
COLOR_NAMES.set("aquamarine","#7fffd4");
COLOR_NAMES.set("azure","#f0ffff");
COLOR_NAMES.set("beige","#f5f5dc");
COLOR_NAMES.set("bisque","#ffe4c4");
COLOR_NAMES.set("black","#000000");
COLOR_NAMES.set("blanchedalmond","#ffebcd");
COLOR_NAMES.set("blue","#0000ff");
COLOR_NAMES.set("blueviolet","#8a2be2");
COLOR_NAMES.set("brown","#a52a2a");
COLOR_NAMES.set("burlywood","#deb887");
COLOR_NAMES.set("cadetblue","#5f9ea0");
COLOR_NAMES.set("chartreuse","#7fff00");
COLOR_NAMES.set("chocolate","#d2691e");
COLOR_NAMES.set("coral","#ff7f50");
COLOR_NAMES.set("cornflowerblue","#6495ed");
COLOR_NAMES.set("cornsilk","#fff8dc");
COLOR_NAMES.set("crimson","#dc143c");
COLOR_NAMES.set("cyan","#00ffff");
COLOR_NAMES.set("darkblue","#00008b");
COLOR_NAMES.set("darkcyan","#008b8b");
COLOR_NAMES.set("darkgoldenrod","#b8860b");
COLOR_NAMES.set("darkgray","#a9a9a9");
COLOR_NAMES.set("darkgreen","#006400");
COLOR_NAMES.set("darkkhaki","#bdb76b");
COLOR_NAMES.set("darkmagenta","#8b008b");
COLOR_NAMES.set("darkolivegreen","#556b2f");
COLOR_NAMES.set("darkorange","#ff8c00");
COLOR_NAMES.set("darkorchid","#9932cc");
COLOR_NAMES.set("darkred","#8b0000");
COLOR_NAMES.set("darksalmon","#e9967a");
COLOR_NAMES.set("darkseagreen","#8fbc8f");
COLOR_NAMES.set("darkslateblue","#483d8b");
COLOR_NAMES.set("darkslategray","#2f4f4f");
COLOR_NAMES.set("darkturquoise","#00ced1");
COLOR_NAMES.set("darkviolet","#9400d3");
COLOR_NAMES.set("deeppink","#ff1493");
COLOR_NAMES.set("deepskyblue","#00bfff");
COLOR_NAMES.set("dimgray","#696969");
COLOR_NAMES.set("dodgerblue","#1e90ff");
COLOR_NAMES.set("firebrick","#b22222");
COLOR_NAMES.set("floralwhite","#fffaf0");
COLOR_NAMES.set("forestgreen","#228b22");
COLOR_NAMES.set("fuchsia","#ff00ff");
COLOR_NAMES.set("gainsboro","#dcdcdc");
COLOR_NAMES.set("ghostwhite","#f8f8ff");
COLOR_NAMES.set("gold","#ffd700");
COLOR_NAMES.set("goldenrod","#daa520");
COLOR_NAMES.set("gray","#808080");
COLOR_NAMES.set("green","#008000");
COLOR_NAMES.set("greenyellow","#adff2f");
COLOR_NAMES.set("honeydew","#f0fff0");
COLOR_NAMES.set("hotpink","#ff69b4");
COLOR_NAMES.set("indianred","#cd5c5c");
COLOR_NAMES.set("indigo","#4b0082");
COLOR_NAMES.set("ivory","#fffff0");
COLOR_NAMES.set("khaki","#f0e68c");
COLOR_NAMES.set("lavender","#e6e6fa");
COLOR_NAMES.set("lavenderblush","#fff0f5");
COLOR_NAMES.set("lawngreen","#7cfc00");
COLOR_NAMES.set("lemonchiffon","#fffacd");
COLOR_NAMES.set("lightblue","#add8e6");
COLOR_NAMES.set("lightcoral","#f08080");
COLOR_NAMES.set("lightcyan","#e0ffff");
COLOR_NAMES.set("lightgoldenrodyellow","#fafad2");
COLOR_NAMES.set("lightgrey","#d3d3d3");
COLOR_NAMES.set("lightgreen","#90ee90");
COLOR_NAMES.set("lightpink","#ffb6c1");
COLOR_NAMES.set("lightsalmon","#ffa07a");
COLOR_NAMES.set("lightseagreen","#20b2aa");
COLOR_NAMES.set("lightskyblue","#87cefa");
COLOR_NAMES.set("lightslategray","#778899");
COLOR_NAMES.set("lightsteelblue","#b0c4de");
COLOR_NAMES.set("lightyellow","#ffffe0");
COLOR_NAMES.set("lime","#00ff00");
COLOR_NAMES.set("limegreen","#32cd32");
COLOR_NAMES.set("linen","#faf0e6");
COLOR_NAMES.set("magenta","#ff00ff");
COLOR_NAMES.set("maroon","#800000");
COLOR_NAMES.set("mediumaquamarine","#66cdaa");
COLOR_NAMES.set("mediumblue","#0000cd");
COLOR_NAMES.set("mediumorchid","#ba55d3");
COLOR_NAMES.set("mediumpurple","#9370d8");
COLOR_NAMES.set("mediumseagreen","#3cb371");
COLOR_NAMES.set("mediumslateblue","#7b68ee");
COLOR_NAMES.set("mediumspringgreen","#00fa9a");
COLOR_NAMES.set("mediumturquoise","#48d1cc");
COLOR_NAMES.set("mediumvioletred","#c71585");
COLOR_NAMES.set("midnightblue","#191970");
COLOR_NAMES.set("mintcream","#f5fffa");
COLOR_NAMES.set("mistyrose","#ffe4e1");
COLOR_NAMES.set("moccasin","#ffe4b5");
COLOR_NAMES.set("navajowhite","#ffdead");
COLOR_NAMES.set("navy","#000080");
COLOR_NAMES.set("oldlace","#fdf5e6");
COLOR_NAMES.set("olive","#808000");
COLOR_NAMES.set("olivedrab","#6b8e23");
COLOR_NAMES.set("orange","#ffa500");
COLOR_NAMES.set("orangered","#ff4500");
COLOR_NAMES.set("orchid","#da70d6");
COLOR_NAMES.set("palegoldenrod","#eee8aa");
COLOR_NAMES.set("palegreen","#98fb98");
COLOR_NAMES.set("paleturquoise","#afeeee");
COLOR_NAMES.set("palevioletred","#d87093");
COLOR_NAMES.set("papayawhip","#ffefd5");
COLOR_NAMES.set("peachpuff","#ffdab9");
COLOR_NAMES.set("peru","#cd853f");
COLOR_NAMES.set("pink","#ffc0cb");
COLOR_NAMES.set("plum","#dda0dd");
COLOR_NAMES.set("powderblue","#b0e0e6");
COLOR_NAMES.set("purple","#800080");
COLOR_NAMES.set("rebeccapurple","#663399");
COLOR_NAMES.set("red","#ff0000");
COLOR_NAMES.set("rosybrown","#bc8f8f");
COLOR_NAMES.set("royalblue","#4169e1");
COLOR_NAMES.set("saddlebrown","#8b4513");
COLOR_NAMES.set("salmon","#fa8072");
COLOR_NAMES.set("sandybrown","#f4a460");
COLOR_NAMES.set("seagreen","#2e8b57");
COLOR_NAMES.set("seashell","#fff5ee");
COLOR_NAMES.set("sienna","#a0522d");
COLOR_NAMES.set("silver","#c0c0c0");
COLOR_NAMES.set("skyblue","#87ceeb");
COLOR_NAMES.set("slateblue","#6a5acd");
COLOR_NAMES.set("slategray","#708090");
COLOR_NAMES.set("snow","#fffafa");
COLOR_NAMES.set("springgreen","#00ff7f");
COLOR_NAMES.set("steelblue","#4682b4");
COLOR_NAMES.set("tan","#d2b48c");
COLOR_NAMES.set("teal","#008080");
COLOR_NAMES.set("thistle","#d8bfd8");
COLOR_NAMES.set("tomato","#ff6347");
COLOR_NAMES.set("turquoise","#40e0d0");
COLOR_NAMES.set("violet","#ee82ee");
COLOR_NAMES.set("wheat","#f5deb3");
COLOR_NAMES.set("white","#ffffff");
COLOR_NAMES.set("whitesmoke","#f5f5f5");
COLOR_NAMES.set("yellow","#ffff00");
COLOR_NAMES.set("yellowgreen","#9acd32");
export const SCRIPTENGINE_ICON = `<g transform="translate(-8,-8)"><path d="M24.318 37.983c-1.234-1.232-8.433-3.903-7.401-7.387 1.057-3.484 9.893-12.443 13.669-13.517 3.776-1.074 6.142 6.523 9.012 7.073 2.87.55 6.797-1.572 8.207-3.694 1.384-2.148-3.147-7.413.15-9.168 3.298-1.755 16.389-2.646 19.611-1.284 3.247 1.363-1.611 7.335-.151 9.483 1.46 2.148 6.067 3.746 8.836 3.38 2.769-.368 4.154-6.733 7.728-5.633 3.575 1.1 12.36 8.828 13.67 12.233 1.308 3.406-5.186 5.423-5.79 8.2-.58 2.75-.026 6.705 2.265 8.355 2.266 1.65 9.642-1.78 11.404 1.598 1.762 3.38 1.007 15.35-.806 18.651-1.787 3.353-7.753-.367-9.969 1.31-2.215 1.65-3.901 5.92-3.373 8.67.504 2.777 7.754 4.48 6.445 7.885C96.49 87.543 87.15 95.454 83.5 96.685c-3.65 1.231-4.96-4.741-7.577-5.16-2.593-.393-6.57.707-8.03 2.75-1.436 2.017 2.668 7.806-.63 9.483-3.323 1.676-15.759 2.226-19.157.655-3.373-1.598.554-7.964-1.108-10.138-1.687-2.174-6.394-3.431-9.012-2.907-2.643.55-3.273 7.282-6.747 6.103-3.499-1.126-12.788-9.535-14.172-13.019-1.36-3.484 5.437-5.108 5.966-7.858.529-2.777-.68-7.073-2.744-8.697-2.064-1.624-7.93 2.41-9.642-1.126-1.737-3.537-2.441-16.765-.654-20.118 1.787-3.3 9.062 1.598 11.429.183 2.366-1.44 2.316-7.282 2.769-8.749m.126-.104c-1.234-1.232-8.433-3.903-7.401-7.387 1.057-3.484 9.893-12.443 13.669-13.517 3.776-1.074 6.142 6.523 9.012 7.073 2.87.55 6.797-1.572 8.207-3.694 1.384-2.148-3.147-7.413.15-9.168 3.298-1.755 16.389-2.646 19.611-1.284 3.247 1.363-1.611 7.335-.151 9.483 1.46 2.148 6.067 3.746 8.836 3.38 2.769-.368 4.154-6.733 7.728-5.633 3.575 1.1 12.36 8.828 13.67 12.233 1.308 3.406-5.186 5.423-5.79 8.2-.58 2.75-.026 6.705 2.265 8.355 2.266 1.65 9.642-1.78 11.404 1.598 1.762 3.38 1.007 15.35-.806 18.651-1.787 3.353-7.753-.367-9.969 1.31-2.215 1.65-3.901 5.92-3.373 8.67.504 2.777 7.754 4.48 6.445 7.885C96.49 87.543 87.15 95.454 83.5 96.685c-3.65 1.231-4.96-4.741-7.577-5.16-2.593-.393-6.57.707-8.03 2.75-1.436 2.017 2.668 7.806-.63 9.483-3.323 1.676-15.759 2.226-19.157.655-3.373-1.598.554-7.964-1.108-10.138-1.687-2.174-6.394-3.431-9.012-2.907-2.643.55-3.273 7.282-6.747 6.103-3.499-1.126-12.788-9.535-14.172-13.019-1.36-3.484 5.437-5.108 5.966-7.858.529-2.777-.68-7.073-2.744-8.697-2.064-1.624-7.93 2.41-9.642-1.126-1.737-3.537-2.441-16.765-.654-20.118 1.787-3.3 9.062 1.598 11.429.183 2.366-1.44 2.316-7.282 2.769-8.749" fill="none" stroke-width="2" stroke-linecap="round" stroke="currentColor"/><path d="M81.235 56.502a23.3 23.3 0 0 1-1.46 8.068 20.785 20.785 0 0 1-1.762 3.72 24.068 24.068 0 0 1-5.337 6.26 22.575 22.575 0 0 1-3.449 2.358 23.726 23.726 0 0 1-7.803 2.803 24.719 24.719 0 0 1-8.333 0 24.102 24.102 0 0 1-4.028-1.074 23.71 23.71 0 0 1-3.776-1.729 23.259 23.259 0 0 1-6.369-5.265 23.775 23.775 0 0 1-2.416-3.353 24.935 24.935 0 0 1-1.762-3.72 23.765 23.765 0 0 1-1.083-3.981 23.454 23.454 0 0 1 0-8.173c.252-1.336.604-2.698 1.083-3.956a24.935 24.935 0 0 1 1.762-3.72 22.587 22.587 0 0 1 2.416-3.378c.881-1.048 1.888-2.017 2.946-2.908a24.38 24.38 0 0 1 3.423-2.357 23.71 23.71 0 0 1 3.776-1.73 21.74 21.74 0 0 1 4.028-1.047 23.437 23.437 0 0 1 8.333 0 24.282 24.282 0 0 1 7.803 2.777 26.198 26.198 0 0 1 3.45 2.357 24.62 24.62 0 0 1 5.336 6.287 20.785 20.785 0 0 1 1.762 3.72 21.32 21.32 0 0 1 1.083 3.955c.251 1.336.302 3.405.377 4.086.05.681.05-.68 0 0" fill="none" stroke-width="4" stroke-linecap="round" stroke="currentColor"/><path d="M69.404 56.633c-6.596-3.3-13.216-6.6-19.51-9.744m19.51 9.744c-6.747-3.379-13.493-6.758-19.51-9.744m0 0v19.489m0-19.49v19.49m0 0c4.355-2.148 8.71-4.322 19.51-9.745m-19.51 9.745c3.978-1.965 7.93-3.956 19.51-9.745m0 0h0m0 0h0" fill="currentColor" stroke-linecap="round" stroke="currentColor" stroke-width="4"/></g>`;
export const DISK_ICON_NAME = "disk";
export const DISK_ICON = `<path fill="none" stroke="currentColor" fill="#fff" d="M0 0h100v100H0z"/><path fill="none" stroke="currentColor" d="M20.832 4.168c21.824.145 43.645.289 74.68.5m-74.68-.5c17.09.113 34.176.227 74.68.5m0 0c.094 27.3.191 54.602.32 91.164m-.32-91.164c.113 32.633.23 65.27.32 91.164m0 0H4.168m91.664 0H4.168m0 0v-75m0 75v-75m0 0L20.832 4.168M4.168 20.832L20.832 4.168M20.832 4.168h58.336m-58.336 0h58.336m0 0v25m0-25v25m0 0H20.832m58.336 0H20.832m0 0v-25m0 25v-25" stroke-width="1.66668" /><path fill="none" stroke="currentColor" d="M29.168 4.168h16.664v16.664H29.168"/><path fill="none" stroke="currentColor" d="M29.168 4.168h16.664m-16.664 0h16.664m0 0v16.664m0-16.664v16.664m0 0H29.168m16.664 0H29.168m0 0V4.168m0 16.664V4.168M12.5 54.168h75m-75 0h75m0 0v41.664m0-41.664v41.664m0 0h-75m75 0h-75m0 0V54.168m0 41.664V54.168M20.832 62.5c20.11-.18 40.219-.36 55.68-.5m-55.68.5c14.656-.133 29.313-.262 55.68-.5M20.832 71.332c13.098-.117 26.2-.234 55.68-.5m-55.68.5l55.68-.5M21.117 79.582c20.645-.184 41.285-.371 55.68-.5m-55.68.5c18.153-.16 36.301-.324 55.68-.5" stroke-width="1.66668"/>`;

View File

@@ -64,7 +64,7 @@ export default {
FILE_DOES_NOT_EXIST:
"File does not exist. Hold down ALT (or ALT+SHIFT) and CLICK link button to create a new file.",
FORCE_SAVE:
"Force-save to update transclusions in adjacent panes.\n(Please note, that autosave is always on)",
"Force-save to update transclusions in adjacent panes.\n(Check autosave settings in plugin settings.)",
RAW: "Change to PREVIEW mode (only effects text-elements with links or transclusions)",
PARSED:
"Change to RAW mode (only effects text-elements with links or transclusions)",
@@ -96,6 +96,16 @@ export default {
"You can access your scripts from Excalidraw via the Obsidian Command Palette. Assign " +
"hotkeys to your favorite scripts just like to any other Obsidian command. " +
"The folder may not be the root folder of your Vault. ",
COMPRESS_NAME: "Compress Excalidraw JSON in Markdown",
COMPRESS_DESC: "By enabling this feature Excalidraw will store the drawing JSON in a Base64 compressed " +
"format using the <a href='https://pieroxy.net/blog/pages/lz-string/index.html'>LZ-String</a> algorithm. " +
"This will reduce the chance of Excalidraw JSON cluttering your search results in Obsidian. " +
"As a side effect, this will also reduce the filesize of Excalidraw drawings. " +
"When you switch an Excalidraw drawing to Markdown view, using the options menu in Excalidraw, the file will " +
"be saved without compression, so that you can read and edit the JSON string. The drawing will be compressed again " +
"once you switch back to Excalidraw view. " +
"The setting only has effect 'point forward', meaning, existing drawings will not be effected by the setting " +
"until you open them and save them. ",
AUTOSAVE_NAME: "Enable Autosave",
AUTOSAVE_DESC:
"Automatically save the active drawing, in case there are changes, every 15, 30 seconds, or 1, 2, 3, 4, or 5 minute. Save normally happens when you close Excalidraw or Obsidian, or move " +

View File

@@ -1539,7 +1539,7 @@ export default class ExcalidrawPlugin extends Plugin {
this.settings.matchTheme && isObsidianThemeDark()
? DARK_BLANK_DRAWING
: BLANK_DRAWING;
return `${FRONTMATTER}\n${getMarkdownDrawingSection(blank)}`;
return `${FRONTMATTER}\n${getMarkdownDrawingSection(blank,this.settings.compress)}`;
}
/**
@@ -1570,7 +1570,7 @@ export default class ExcalidrawPlugin extends Plugin {
}
return (
outString +
getMarkdownDrawingSection(JSON.stringify(JSON_parse(data), null, "\t"))
getMarkdownDrawingSection(JSON.stringify(JSON_parse(data), null, "\t"),this.settings.compress)
);
}

View File

@@ -16,6 +16,7 @@ export interface ExcalidrawSettings {
embedUseExcalidrawFolder: boolean;
templateFilePath: string;
scriptFolderPath: string;
compress: boolean;
autosave: boolean;
autosaveInterval: number;
drawingFilenamePrefix: string;
@@ -79,6 +80,7 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
embedUseExcalidrawFolder: false,
templateFilePath: "Excalidraw/Template.excalidraw",
scriptFolderPath: "Excalidraw/Scripts",
compress: false,
autosave: true,
autosaveInterval: 15000,
drawingFilenamePrefix: "Drawing ",
@@ -261,6 +263,18 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
}),
);
new Setting(containerEl)
.setName(t("COMPRESS_NAME"))
.setDesc(fragWithHTML(t("COMPRESS_DESC")))
.addToggle((toggle) =>
toggle
.setValue(this.plugin.settings.compress)
.onChange(async (value) => {
this.plugin.settings.compress = value;
this.applySettingsUpdate();
}),
);
this.containerEl.createEl("h1", { text: t("FILENAME_HEAD") });
containerEl.createDiv("", (el) => {
el.innerHTML = t("FILENAME_DESC");

View File

@@ -148,4 +148,8 @@ li[data-testid] {
.excalidraw-dirty {
color: red;
}
.workspace-leaf-content .excalidraw-view {
padding: 0px 1px; /*1px so on ipad swipe in from left and right still works*/
}

View File

@@ -1,4 +1,4 @@
{
"1.6.12": "0.12.16",
"1.6.13": "0.12.16",
"1.4.2": "0.11.13"
}

View File

@@ -1748,6 +1748,11 @@
"resolved" "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz"
"version" "0.0.29"
"@types/lz-string@^1.3.34":
"integrity" "sha512-j6G1e8DULJx3ONf6NdR5JiR2ZY3K3PaaqiEuKYkLQO0Czfi1AzrtjfnfCROyWGeDd5IVMKCwsgSmMip9OWijow=="
"resolved" "https://registry.npmjs.org/@types/lz-string/-/lz-string-1.3.34.tgz"
"version" "1.3.34"
"@types/mime@^1":
"integrity" "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
"resolved" "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz"
@@ -5866,6 +5871,11 @@
dependencies:
"yallist" "^4.0.0"
"lz-string@^1.4.4":
"integrity" "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY="
"resolved" "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz"
"version" "1.4.4"
"magic-string@^0.25.0", "magic-string@^0.25.7":
"integrity" "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA=="
"resolved" "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz"