mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
Compare commits
1 Commits
1.7.26
...
event---ct
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75b9083ec8 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -15,5 +15,4 @@ data.json
|
||||
lib
|
||||
|
||||
#VSCode
|
||||
.vscode
|
||||
yarn.lock
|
||||
.vscode
|
||||
@@ -17,10 +17,7 @@ Please upgrade to Obsidian v0.12.19 or higher to get the latest release.
|
||||
|[](https://youtu.be/eKFmrSQhFA4)|[](https://youtu.be/qbPIAZguJeo)|[](https://youtu.be/2Y8OhkGiTHg)|
|
||||
|[](https://youtu.be/2v9TZmQNO8c)|[](https://youtu.be/xHPGWR3m0c8)|[](https://youtu.be/gMIKXyhS-dM)|
|
||||
|[](https://youtu.be/Etskjw7a5zo)|[](https://youtu.be/4N6efq1DtH0)|[](https://youtu.be/U2LkBRBk4LY)|
|
||||
| [](https://youtu.be/qiKuqMcNWgU)|[](https://youtu.be/yZQoJg2RCKI)|[](https://youtu.be/6PLGHBH9VZ4) |
|
||||
|[](https://youtu.be/epYNx2FSf2w) | [](https://youtu.be/Amhlv6r9WvM) | [](https://youtu.be/r9oB1SlK1GU) |
|
||||
|[](https://youtu.be/7gJDwNgQ6NU) | | |
|
||||
|
||||
| [](https://youtu.be/qiKuqMcNWgU)|[](https://youtu.be/yZQoJg2RCKI)| |
|
||||
|
||||
|
||||
# Key features
|
||||
@@ -53,8 +50,8 @@ Please upgrade to Obsidian v0.12.19 or higher to get the latest release.
|
||||
- Insert LaTeX formulas using the Command Palette action "Insert LaTeX formula". You can edit formulas either in Markdown view, or by <kbd>CTRL/CMD + Click</kbd> on the formula.
|
||||
- Drag & Drop support
|
||||
- You can drag files from the Obsidian file explorer and they will become links to those files in Excalidraw.
|
||||
- Dragging image files (PNG, SVG, JPG, ICO, GIF, WEBP, Excalidraw) from Obsidian's file explorer while pressing the <kbd>CTRL</kbd> (<kbd>SHIFT</kbd> on Mac) button will embed the image into your drawing.
|
||||
- If in addition to <kbd>CTRL</kbd> or <kbd>SHIFT</kbd> you also hold down <kbd>ALT<kbd>, the image will be inserted at 100% of its size. ⚠ Note: this is a very niche feature with a very particular behavior that I built primarily for myself (even more so than other features in Excalidraw Obsidian - also built primarily for myself 😉)... This will reset your embedded image to 100% size every time you open the Excalidraw drawing, or in case you have embedded an Excalidraw drawing on your canvas inserted using this function, every time you update the embedded drawing, it will be scaled back to 100% size. This means that even if you resize the image on the drawing, it will reset to 100% the next time you open the file or you modify the original embedded object. This feature is useful when you decompose a drawing into separate Excalidraw files, but when combined onto a single canvas you want the individual pieces to maintain their actual sizes. I use this feature to construct Book-on-a-Page summaries from atomic drawings.
|
||||
- Dragging image files (PNG, SVG, JPG, Excalidraw) from Obsidian's file explorer while pressing the <kbd>CTRL/CMD</kbd> button will embed the image into your drawing.
|
||||
- You can drag and drop images from outside Obsidian onto Excalidraw. These images will be embedded into your drawing and saved to Obsidian.
|
||||
- You can drag and drop text from Markdown views onto Excalidraw.
|
||||
- You can drag and drop web addresses from your browser and they will become links.
|
||||
- Image support
|
||||
|
||||
@@ -362,7 +362,7 @@ export declare class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
* If set, this callback is triggered, when the user hovers a link in the scene.
|
||||
* You can use this callback in case you want to do something additional when the onLinkHover event occurs.
|
||||
* This callback must return a boolean value.
|
||||
* In case you want to prevent the excalidraw onLinkHover action you must return true, it will stop the native excalidraw onLinkHover management flow.
|
||||
* In case you want to prevent the excalidraw onLinkHover action you must return false, it will stop the native excalidraw onLinkHover management flow.
|
||||
*/
|
||||
onLinkHoverHook: (element: NonDeletedExcalidrawElement, linkText: string, view: ExcalidrawView, ea: ExcalidrawAutomate) => boolean;
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "1.7.26",
|
||||
"version": "1.7.22",
|
||||
"minAppVersion": "0.15.6",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsidian-excalidraw-plugin",
|
||||
"version": "1.7.26",
|
||||
"version": "1.7.11",
|
||||
"description": "This is an Obsidian.md plugin that lets you view and edit Excalidraw drawings",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
@@ -18,7 +18,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/lz-string": "^1.3.34",
|
||||
"@zsviczian/excalidraw": "0.13.0-obsidian",
|
||||
"@zsviczian/excalidraw": "0.12.0-obsidian-9",
|
||||
"clsx": "^1.1.1",
|
||||
"lz-string": "^1.4.4",
|
||||
"monkey-around": "^2.3.0",
|
||||
@@ -49,7 +49,7 @@
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"html2canvas": "^1.4.0",
|
||||
"nanoid": "^4.0.0",
|
||||
"obsidian": "^0.16.3",
|
||||
"obsidian": "^0.15.4",
|
||||
"prettier": "^2.5.1",
|
||||
"rollup": "^2.70.1",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,6 @@ import {
|
||||
ExcalidrawBindableElement,
|
||||
FileId,
|
||||
NonDeletedExcalidrawElement,
|
||||
ExcalidrawImageElement,
|
||||
} from "@zsviczian/excalidraw/types/element/types";
|
||||
import { normalizePath, TFile, WorkspaceLeaf } from "obsidian";
|
||||
import ExcalidrawView, { ExportSettings, TextMode } from "./ExcalidrawView";
|
||||
@@ -26,7 +25,6 @@ import {
|
||||
embedFontsInSVG,
|
||||
errorlog,
|
||||
getEmbeddedFilenameParts,
|
||||
getImageSize,
|
||||
getPNG,
|
||||
getSVG,
|
||||
isVersionNewerThanOther,
|
||||
@@ -893,7 +891,6 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
topX: number,
|
||||
topY: number,
|
||||
imageFile: TFile,
|
||||
scale: boolean = true, //true will scale the image to MAX_IMAGE_SIZE, false will insert image at 100% of its size
|
||||
): Promise<string> {
|
||||
const id = nanoid();
|
||||
const loader = new EmbeddedFilesLoader(
|
||||
@@ -910,11 +907,11 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
id: fileId,
|
||||
dataURL: image.dataURL,
|
||||
created: image.created,
|
||||
file: imageFile.path + (scale ? "":"|100%"),
|
||||
file: imageFile.path,
|
||||
hasSVGwithBitmap: image.hasSVGwithBitmap,
|
||||
latex: null,
|
||||
};
|
||||
if (scale && (Math.max(image.size.width, image.size.height) > MAX_IMAGE_SIZE)) {
|
||||
if (Math.max(image.size.width, image.size.height) > MAX_IMAGE_SIZE) {
|
||||
const scale =
|
||||
MAX_IMAGE_SIZE / Math.max(image.size.width, image.size.height);
|
||||
image.size.width = scale * image.size.width;
|
||||
@@ -1217,7 +1214,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
getViewElements(): ExcalidrawElement[] {
|
||||
//@ts-ignore
|
||||
if (!this.targetView || !this.targetView?._loaded) {
|
||||
errorMessage("targetView not set", "getViewElements()");
|
||||
errorMessage("targetView not set", "getViewSelectedElements()");
|
||||
return [];
|
||||
}
|
||||
const current = this.targetView?.excalidrawRef?.current;
|
||||
@@ -1235,7 +1232,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
deleteViewElements(elToDelete: ExcalidrawElement[]): boolean {
|
||||
//@ts-ignore
|
||||
if (!this.targetView || !this.targetView?._loaded) {
|
||||
errorMessage("targetView not set", "deleteViewElements()");
|
||||
errorMessage("targetView not set", "getViewSelectedElements()");
|
||||
return false;
|
||||
}
|
||||
const current = this.targetView?.excalidrawRef?.current;
|
||||
@@ -1283,7 +1280,7 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
getViewFileForImageElement(el: ExcalidrawElement): TFile | null {
|
||||
//@ts-ignore
|
||||
if (!this.targetView || !this.targetView?._loaded) {
|
||||
errorMessage("targetView not set", "getViewFileForImageElement()");
|
||||
errorMessage("targetView not set", "getViewSelectedElements()");
|
||||
return null;
|
||||
}
|
||||
if (!el || el.type !== "image") {
|
||||
@@ -1491,15 +1488,6 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
pointerPosition: { x: number; y: number }; //the pointer position on canvas at the time of drop
|
||||
}) => boolean = null;
|
||||
|
||||
/**
|
||||
* If set, this callback is triggered whenever the active canvas color changes
|
||||
*/
|
||||
onCanvasColorChangeHook: (
|
||||
ea: ExcalidrawAutomate,
|
||||
view: ExcalidrawView, //the excalidraw view
|
||||
color: string,
|
||||
) => void = null;
|
||||
|
||||
/**
|
||||
* utility function to generate EmbeddedFilesLoader object
|
||||
* @param isDark
|
||||
@@ -1690,30 +1678,6 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
return { width: size.w ?? 0, height: size.h ?? 0 };
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the size of the image element at 100% (i.e. the original size)
|
||||
* @param imageElement an image element from the active scene on targetView
|
||||
*/
|
||||
async getOriginalImageSize(imageElement: ExcalidrawImageElement): Promise<{width: number; height: number}> {
|
||||
//@ts-ignore
|
||||
if (!this.targetView || !this.targetView?._loaded) {
|
||||
errorMessage("targetView not set", "getOriginalImageSize()");
|
||||
return null;
|
||||
}
|
||||
if(!imageElement || imageElement.type !== "image") {
|
||||
errorMessage("Please provide a single image element as input", "getOriginalImageSize()");
|
||||
return null;
|
||||
}
|
||||
const ef = this.targetView.excalidrawData.getFile(imageElement.fileId);
|
||||
if(!ef) {
|
||||
errorMessage("Please provide a single image element as input", "getOriginalImageSize()");
|
||||
return null;
|
||||
}
|
||||
const isDark = this.getExcalidrawAPI().getAppState().theme === "dark";
|
||||
const dataURL = ef.getImage(isDark);
|
||||
return await getImageSize(dataURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* verifyMinimumPluginVersion returns true if plugin version is >= than required
|
||||
* recommended use:
|
||||
@@ -1867,10 +1831,6 @@ export class ExcalidrawAutomate implements ExcalidrawAutomateInterface {
|
||||
log("Creates a CM object. Visit https://github.com/lbragile/ColorMaster for documentation.");
|
||||
return;
|
||||
}
|
||||
if(typeof color === "string") {
|
||||
color = this.colorNameToHex(color);
|
||||
}
|
||||
|
||||
return CM(color);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -488,7 +488,7 @@ export class ExcalidrawData {
|
||||
let res = data.matchAll(/\s\^(.{8})[\n]+/g);
|
||||
let parts;
|
||||
while (!(parts = res.next()).done) {
|
||||
let text = data.substring(position, parts.value.index);
|
||||
const text = data.substring(position, parts.value.index);
|
||||
const id: string = parts.value[1];
|
||||
const textEl = this.scene.elements.filter((el: any) => el.id === id)[0];
|
||||
if (textEl) {
|
||||
@@ -502,13 +502,6 @@ export class ExcalidrawData {
|
||||
this.elementLinks.set(id, text);
|
||||
} else {
|
||||
const wrapAt = estimateMaxLineLen(textEl.text, textEl.originalText);
|
||||
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/566
|
||||
const elementLinkRes = text.matchAll(/^%%\*\*\*>>>text element-link:(\[\[[^<*\]]*]])<<<\*\*\*%%/gm);
|
||||
const elementLink = elementLinkRes.next();
|
||||
if(!elementLink.done) {
|
||||
text = text.replace(/^%%\*\*\*>>>text element-link:\[\[[^<*\]]*]]<<<\*\*\*%%/gm,"");
|
||||
textEl.link = elementLink.value[1];
|
||||
}
|
||||
const parseRes = await this.parse(text);
|
||||
this.textElements.set(id, {
|
||||
raw: text,
|
||||
@@ -877,14 +870,8 @@ export class ExcalidrawData {
|
||||
}
|
||||
if (REGEX_LINK.isTransclusion(parts)) {
|
||||
//transclusion //parts.value[1] || parts.value[4]
|
||||
let contents = this
|
||||
.parseCheckbox((await this.getTransclusion(REGEX_LINK.getLink(parts))).contents)
|
||||
.replaceAll(/%%[^%]*%%/gm,""); //remove comments, consequence of https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/566
|
||||
if(this.plugin.settings.removeTransclusionQuoteSigns) {
|
||||
//remove leading > signs from transcluded quotations; the first > sign is not explicitlyl removed becuse
|
||||
//Obsidian app.metadataCache.blockCache returns the block position already discarding the first '> '
|
||||
contents = contents.replaceAll(/\n\s*>\s?/gm,"\n");
|
||||
}
|
||||
const contents = this.parseCheckbox((await this.getTransclusion(REGEX_LINK.getLink(parts)))
|
||||
.contents);
|
||||
outString +=
|
||||
text.substring(position, parts.value.index) +
|
||||
wrapText(
|
||||
@@ -1004,15 +991,7 @@ export class ExcalidrawData {
|
||||
generateMD(deletedElements: ExcalidrawElement[] = []): string {
|
||||
let outString = "# Text Elements\n";
|
||||
for (const key of this.textElements.keys()) {
|
||||
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/566
|
||||
const element = this.scene.elements.filter((el:any)=>el.id===key);
|
||||
let elementString = this.textElements.get(key).raw;
|
||||
if(element && element.length===1 && element[0].link && element[0].rawText === element[0].originalText) {
|
||||
if(element[0].link.match(/^\[\[[^\]]*]]$/g)) { //apply this only to markdown links
|
||||
elementString = `%%***>>>text element-link:${element[0].link}<<<***%%` + elementString;
|
||||
}
|
||||
}
|
||||
outString += `${elementString} ^${key}\n\n`;
|
||||
outString += `${this.textElements.get(key).raw} ^${key}\n\n`;
|
||||
}
|
||||
|
||||
for (const key of this.elementLinks.keys()) {
|
||||
@@ -1030,13 +1009,7 @@ export class ExcalidrawData {
|
||||
}
|
||||
if (this.files.size > 0) {
|
||||
for (const key of this.files.keys()) {
|
||||
const PATHREG = /(^[^#\|]*)/;
|
||||
const ef = this.files.get(key);
|
||||
//https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/829
|
||||
const path = ef.file
|
||||
? ef.linkParts.original.replace(PATHREG,app.metadataCache.fileToLinktext(ef.file,this.file.path))
|
||||
: ef.linkParts.original;
|
||||
outString += `${key}: [[${path}]]\n`;
|
||||
outString += `${key}: [[${this.files.get(key).linkParts.original}]]\n`;
|
||||
}
|
||||
}
|
||||
outString += this.equations.size > 0 || this.files.size > 0 ? "\n" : "";
|
||||
@@ -1087,7 +1060,7 @@ export class ExcalidrawData {
|
||||
});
|
||||
|
||||
//check if there are any images that need to be processed in the new scene
|
||||
if (!scene.files || Object.keys(scene.files).length === 0) {
|
||||
if (!scene.files || scene.files == {}) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1579,15 +1552,15 @@ export const getTransclusion = async (
|
||||
if (!para) {
|
||||
return { contents: linkParts.original.trim(), lineNum: 0 };
|
||||
}
|
||||
if (["blockquote"].includes(para.type)) {
|
||||
if (["blockquote", "listItem"].includes(para.type)) {
|
||||
para = para.children[0];
|
||||
} //blockquotes are special, they have one child, which has the paragraph
|
||||
const startPos = para.position.start.offset;
|
||||
const lineNum = para.position.start.line;
|
||||
const endPos = para.position.end.offset; //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/853
|
||||
//para.children[para.children.length - 1]?.position.start.offset - 1; //!not clear what the side effect of the #853 change is
|
||||
const endPos =
|
||||
para.children[para.children.length - 1]?.position.start.offset - 1; //alternative: filter((c:any)=>c.type=="blockid")[0]
|
||||
return {
|
||||
contents: contents.substring(startPos, endPos).replaceAll(/ \^\S*$|^\^\S*$/gm,"").trim(), //remove the block reference from the end of the line, or from the beginning of a new line
|
||||
contents: contents.substring(startPos, endPos).trim(),
|
||||
lineNum,
|
||||
};
|
||||
}
|
||||
@@ -1638,7 +1611,7 @@ export const getTransclusion = async (
|
||||
return {
|
||||
leadingHashes: "#".repeat(depth) + " ",
|
||||
contents: contents.substring(startPos).trim(),
|
||||
lineNum
|
||||
lineNum
|
||||
};
|
||||
}
|
||||
return { contents: linkParts.original.trim(), lineNum: 0 };
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,6 @@ export const updateEquation = async (
|
||||
created: data.created,
|
||||
size: data.size,
|
||||
hasSVGwithBitmap: false,
|
||||
shouldScale: true,
|
||||
});
|
||||
addFiles(files, view);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ export const REG_LINKINDEX_INVALIDCHARS = /[<>:"\\|?*#]/g;
|
||||
export const REG_BLOCK_REF_CLEAN =
|
||||
/[!"#$%&()*+,.:;<=>?@^`{|}~\/\[\]\\]/g; //https://discord.com/channels/686053708261228577/989603365606531104/1000128926619816048
|
||||
// /\+|\/|~|=|%|\(|\)|{|}|,|&|\.|\$|!|\?|;|\[|]|\^|#|\*|<|>|&|@|\||\\|"|:|\s/g;
|
||||
export const IMAGE_TYPES = ["jpeg", "jpg", "png", "gif", "svg", "webp", "bmp", "ico"];
|
||||
export const IMAGE_TYPES = ["jpeg", "jpg", "png", "gif", "svg"];
|
||||
export const EXPORT_TYPES = ["svg", "dark.svg", "light.svg", "png", "dark.png", "light.png"];
|
||||
export const MAX_IMAGE_SIZE = 500;
|
||||
export const FRONTMATTER_KEY = "excalidraw-plugin";
|
||||
|
||||
@@ -17,23 +17,12 @@ export class InsertImageDialog extends FuzzySuggestModal<TFile> {
|
||||
this.limit = 20;
|
||||
this.setInstructions([
|
||||
{
|
||||
command: t("SELECT_FILE_WITH_OPTION_TO_SCALE"),
|
||||
command: t("SELECT_FILE"),
|
||||
purpose: "",
|
||||
},
|
||||
]);
|
||||
this.setPlaceholder(t("SELECT_DRAWING"));
|
||||
this.emptyStateText = t("NO_MATCH");
|
||||
this.inputEl.onkeyup = (e) => {
|
||||
//@ts-ignore
|
||||
if (e.key === "Enter" && e.altKey && this.chooser.values) {
|
||||
this.onChooseItem(
|
||||
//@ts-ignore
|
||||
this.chooser.values[this.chooser.selectedItem].item,
|
||||
new KeyboardEvent("keypress",{altKey: true})
|
||||
);
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getItems(): TFile[] {
|
||||
@@ -50,13 +39,13 @@ export class InsertImageDialog extends FuzzySuggestModal<TFile> {
|
||||
return item.path;
|
||||
}
|
||||
|
||||
onChooseItem(item: TFile, event: KeyboardEvent): void {
|
||||
onChooseItem(item: TFile): void {
|
||||
const ea = this.plugin.ea;
|
||||
ea.reset();
|
||||
ea.setView(this.view);
|
||||
ea.canvas.theme = this.view.excalidrawAPI.getAppState().theme;
|
||||
(async () => {
|
||||
await ea.addImage(0, 0, item, !event.altKey);
|
||||
await ea.addImage(0, 0, item);
|
||||
ea.addElementsToView(true, false, true);
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -17,60 +17,6 @@ I develop this plugin as a hobby, spending most of my free time doing this. If y
|
||||
|
||||
<div class="ex-coffee-div"><a href="https://ko-fi.com/zsolt"><img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" height=45></a></div>
|
||||
`,
|
||||
"1.7.26":`## Fixed
|
||||
- Transcluded block with a parent bullet does not embed sub-bullet [#853](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/853)
|
||||
- Transcluded text will now exclude ^block-references at end of lines
|
||||
- Phantom duplicates of the drawing appear when "zoom to fit" results in a zoom value below 10% and there are many objects on the canvas [#850](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/850)
|
||||
- CTRL+Wheel will increase/decrease zoom in steps of 5% matching the behavior of the "+" & "-" zoom buttons.
|
||||
- Latest updates from Excalidarw.com
|
||||
- Freedraw flip not scaling correctly [#5752](https://github.com/excalidraw/excalidraw/pull/5752)
|
||||
- Multiple elements resizing regressions [#5586](https://github.com/excalidraw/excalidraw/pull/5586)
|
||||
|
||||
## New - power user features
|
||||
- Force the embedded image to always scale to 100%. Note: this is a very niche feature with a very particular behavior that I built primarily for myself (even more so than other features in Excalidraw Obsidian - also built primarily for myself 😉)... This will reset your embedded image to 100% size every time you open the Excalidraw drawing, or in case you have embedded an Excalidraw drawing on your canvas inserted using this function, every time you update the embedded drawing, it will be scaled back to 100% size. This means that even if you resize the image on the drawing, it will reset to 100% the next time you open the file or you modify the original embedded object. This feature is useful when you decompose a drawing into separate Excalidraw files, but when combined onto a single canvas you want the individual pieces to maintain their actual sizes. I use this feature to construct Book-on-a-Page summaries from atomic drawings.
|
||||
- I added an action to the command palette to temporarily disable/enable Excalidraw autosave. When autosave is disabled, Excalidraw will still save your drawing when changing to another Obsidian window, but it will not save every 10 seconds. On a mobile device (but also on a desktop) this can lead to data loss if you terminate Obsidian abruptly (i.e. swipe the application away, or close Obsidian without first closing the drawing). Use this feature if you find Excalidraw laggy.`,
|
||||
"1.7.25":`## Fixed
|
||||
- Tool buttons did not "stick" the first time you clicked them.
|
||||
- Tray (in tray mode) was higher when the help button was visible. The tray in tablet mode was too large and the help button was missing.
|
||||
- ExcalidrawAutomate ${String.fromCharCode(96)}getCM(color:TInput): ColorMaster;${String.fromCharCode(96)} function will now properly convert valid [css color names](https://www.w3schools.com/colors/colors_names.asp) to ColorMaster objects.
|
||||
- The downloaded script icons in the Excalidraw-Obsidian menu were not always correct
|
||||
- The obsidian mobile navigation bar at the bottom overlapped with Excalidraw
|
||||
|
||||
## New
|
||||
- Created ExcalidrawAutomate hook for styling script when the canvas color changes. See sample [onCanvasColorChangeHook](https://gist.github.com/zsviczian/c7223c5b4af30d5c88a0cae05300305c) implementation following the link.
|
||||
|
||||
<div class="excalidraw-videoWrapper"><div>
|
||||
<iframe src="https://www.youtube.com/embed/LtR04fNTKTM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div></div>
|
||||
|
||||
${String.fromCharCode(96, 96, 96)}typescript
|
||||
/**
|
||||
* If set, this callback is triggered whenever the active canvas color changes
|
||||
*/
|
||||
onCanvasColorChangeHook: (
|
||||
ea: ExcalidrawAutomate,
|
||||
view: ExcalidrawView, //the Excalidraw view
|
||||
color: string,
|
||||
) => void = null;
|
||||
${String.fromCharCode(96, 96, 96)}
|
||||
`,
|
||||
"1.7.24":`
|
||||
# New and improved
|
||||
- **Updated Chinese translation**. Thanks, @tswwe!
|
||||
- **Improved update for TextElement links**: Until now, when you attached a link to a file to a TextElement using the "Create Link" command, this link did not get updated when the file was renamed or moved. Only links created as markdown links in the TextElement text were updated. Now both approaches work. Keep in mind however, that if you have a link in the TextElemenet text, it will override the link attached to the text element using the create link command. [#566](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/566)
|
||||
- **Transclusion filters markdown comments**: Text transclusion in a TextElement using the ${String.fromCharCode(96)}![[file]]${String.fromCharCode(96)} or ${String.fromCharCode(96)}![[file#section]]${String.fromCharCode(96)} format did not filter out markdown comments in the file placed ${String.fromCharCode(96)}%% inside a comment block %%${String.fromCharCode(96)}. Now they do.
|
||||
- **Remove leading '>' from trancluded quotes**: Added a new option in settings under **Links and Transclusion** to remove the leading ${String.fromCharCode(96)}> ${String.fromCharCode(96)} characters from quotes you transclude as a text element in your drawing.
|
||||

|
||||
- **Added support for ${String.fromCharCode(96)}webp${String.fromCharCode(96)}, ${String.fromCharCode(96)}bmp${String.fromCharCode(96)}, and ${String.fromCharCode(96)}ico${String.fromCharCode(96)} images**. This extends the already supported formats (${String.fromCharCode(96)}jpg${String.fromCharCode(96)}, ${String.fromCharCode(96)}gif${String.fromCharCode(96)}, ${String.fromCharCode(96)}png${String.fromCharCode(96)}, ${String.fromCharCode(96)}svg${String.fromCharCode(96)}).
|
||||
- **Added command palette action to reset images to original size**. Select a single image or embedded Excalidraw drawing on your canvas and choose ${String.fromCharCode(96)}Set selected image element size to 100% of original${String.fromCharCode(96)} from the command palette. This function is especially helpful when you combine atomic drawings on a single canvas, keeping each atomic piece in its original excalidraw file (i.e. the way I create [book on a page summaries](https://www.youtube.com/playlist?list=PL6mqgtMZ4NP1-mbCYc3T7mr-unmsIXpEG))
|
||||
- The ${String.fromCharCode(96)}async getOriginalImageSize(imageElement: ExcalidrawImageElement): Promise<{width: number; height: number}>${String.fromCharCode(96)} function is also avaiable via ExcalidrawAutomate. You may use this function to resize images to custom scales (e.g. 50% size, or to fit a certain bounding rectangle).
|
||||
|
||||
# Fixed
|
||||
- **Upgraded perfect freehand package to resolve unwanted dots on end of lines** [#5727](https://github.com/excalidraw/excalidraw/pull/5727)
|
||||
- **Pinch zoom in View mode opens images** resulting in a very annoying behavior [#837](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/837)
|
||||
- **Embedded files** such as transcluded markdown documents and images **did not honor the Obsidian "New Link Format" setting** (shortest path, relative path, absolute path). [#829](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/829)
|
||||
- **Fixed error with dataview queries involving Excalidraw files**: In case you created a task on an Excalidraw canvas (${String.fromCharCode(96)}docA.md${String.fromCharCode(96)}) by typing ${String.fromCharCode(96)}- [ ] Task [[owner]] #tag${String.fromCharCode(96)}, and then you created a Dataview tasklist in another document (${String.fromCharCode(96)}docB.md${String.fromCharCode(96)}) such that the query criteria matched the task in ${String.fromCharCode(96)}docA.md${String.fromCharCode(96)}, then the task from ${String.fromCharCode(96)}docA.md${String.fromCharCode(96)} only appeared as an empty line when viewing ${String.fromCharCode(96)}docB.md${String.fromCharCode(96)}. If you now embedded ${String.fromCharCode(96)}docB.md${String.fromCharCode(96)} into a third markdown document (${String.fromCharCode(96)}docC.md${String.fromCharCode(96)}), then instead of the contents of ${String.fromCharCode(96)}docB.md${String.fromCharCode(96)} Obsidian rendered ${String.fromCharCode(96)}docA.md${String.fromCharCode(96)}. [#835](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/835)
|
||||
`,
|
||||
"1.7.22":`
|
||||
# Fixed
|
||||
- Text size in sticky notes increased when opening the drawing and when editing a sticky note [#824](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/824)
|
||||
|
||||
@@ -52,7 +52,7 @@ export default {
|
||||
INSERT_LINK_TO_ELEMENT_ERROR: "Select a single element in the scene",
|
||||
INSERT_LINK_TO_ELEMENT_READY: "Link is READY and available on the clipboard",
|
||||
INSERT_LINK: "Insert link to file",
|
||||
INSERT_IMAGE: "Insert image or Excalidraw drawing from your vault",
|
||||
INSERT_IMAGE: "Insert image from vault",
|
||||
INSERT_MD: "Insert markdown file from vault",
|
||||
INSERT_LATEX:
|
||||
"Insert LaTeX formula (e.g. \\binom{n}{k} = \\frac{n!}{k!(n-k)!})",
|
||||
@@ -60,9 +60,6 @@ export default {
|
||||
READ_RELEASE_NOTES: "Read latest release notes",
|
||||
TRAY_MODE: "Toggle property-panel tray-mode",
|
||||
SEARCH: "Search for text in drawing",
|
||||
RESET_IMG_TO_100: "Set selected image element size to 100% of original",
|
||||
TEMPORARY_DISABLE_AUTOSAVE: "Disable autosave until next time Obsidian starts (only set this if you know what you are doing)",
|
||||
TEMPORARY_ENABLE_AUTOSAVE: "Enable autosave",
|
||||
|
||||
//ExcalidrawView.ts
|
||||
INSTALL_SCRIPT_BUTTON: "Install or update Excalidraw Scripts",
|
||||
@@ -115,7 +112,7 @@ export default {
|
||||
"Template.md, the setting would be: Excalidraw/Template.md (or just Excalidraw/Template - you may omit the .md file extension). " +
|
||||
"If you are using Excalidraw in compatibility mode, then your template must be a legacy Excalidraw file as well " +
|
||||
"such as Excalidraw/Template.excalidraw.",
|
||||
SCRIPT_FOLDER_NAME: "Excalidraw Automate script folder (CASE SeNSitiVE!)",
|
||||
SCRIPT_FOLDER_NAME: "Excalidraw Automate script folder",
|
||||
SCRIPT_FOLDER_DESC:
|
||||
"The files you place in this folder will be treated as Excalidraw Automate scripts. " +
|
||||
"You can access your scripts from Excalidraw via the Obsidian Command Palette. Assign " +
|
||||
@@ -262,9 +259,6 @@ export default {
|
||||
PAGE_TRANSCLUSION_CHARCOUNT_DESC:
|
||||
"The maximum number of characters to display from the page when transcluding an entire page with the " +
|
||||
"![[markdown page]] format.",
|
||||
QUOTE_TRANSCLUSION_REMOVE_NAME: "Quote translusion: remove leading '> ' from each line",
|
||||
QUOTE_TRANSCLUSION_REMOVE_DESC: "Remove the leading '> ' from each line of the transclusion. This will improve readibility of quotes in text only transclusions<br>" +
|
||||
"<b>Toggle ON:</b> Remove leading '> '<br><b>Toggle OFF:</b> Do not remove leading '> ' (note it will still be removed from the first row due to Obsidian API functionality)",
|
||||
GET_URL_TITLE_NAME: "Use iframely to resolve page title",
|
||||
GET_URL_TITLE_DESC:
|
||||
"Use the <code>http://iframely.server.crestify.com/iframely?url=</code> to get title of page when dropping a link into Excalidraw",
|
||||
@@ -420,10 +414,9 @@ export default {
|
||||
|
||||
//openDrawings.ts
|
||||
SELECT_FILE: "Select a file then press enter.",
|
||||
SELECT_FILE_WITH_OPTION_TO_SCALE: "Select a file then press ENTER, or ALT+ENTER to insert at 100% scale.",
|
||||
NO_MATCH: "No file matches your query.",
|
||||
SELECT_FILE_TO_LINK: "Select the file you want to insert the link for.",
|
||||
SELECT_DRAWING: "Select the image or drawing you want to insert",
|
||||
SELECT_DRAWING: "Select the drawing you want to insert",
|
||||
TYPE_FILENAME: "Type name of drawing to select.",
|
||||
SELECT_FILE_OR_TYPE_NEW:
|
||||
"Select existing drawing or type name of a new drawing then press Enter.",
|
||||
|
||||
4423
src/main.ts
4423
src/main.ts
File diff suppressed because it is too large
Load Diff
@@ -287,15 +287,3 @@ export const ICONS = {
|
||||
</svg>
|
||||
),
|
||||
};
|
||||
|
||||
export const stringToSVG = (svg: string) => {
|
||||
svg = svg
|
||||
.replace(/stroke\s*=\s*['"][^"']*['"]/g,"")
|
||||
.replace(/width\s*=\s*['"][^"']*['"]/g,"")
|
||||
.replace(/height\s*=\s*['"][^"']*['"]/g,"")
|
||||
.replace("<svg ",`<svg style="stroke:var(--icon-fill-color);color:var(--icon-fill-color);fill:var(--icon-fill-color)" `)
|
||||
|
||||
return (
|
||||
<div dangerouslySetInnerHTML={{__html: svg}}></div>
|
||||
)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,6 @@ import {
|
||||
getEmbedFilename,
|
||||
} from "./utils/FileUtils";
|
||||
import {
|
||||
fragWithHTML,
|
||||
setLeftHandedMode,
|
||||
} from "./utils/Utils";
|
||||
|
||||
@@ -59,7 +58,6 @@ export interface ExcalidrawSettings {
|
||||
forceWrap: boolean;
|
||||
pageTransclusionCharLimit: number;
|
||||
wordWrappingDefault: number;
|
||||
removeTransclusionQuoteSigns: boolean;
|
||||
iframelyAllowed: boolean;
|
||||
pngExportScale: number;
|
||||
exportWithTheme: boolean;
|
||||
@@ -151,7 +149,6 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
|
||||
forceWrap: false,
|
||||
pageTransclusionCharLimit: 200,
|
||||
wordWrappingDefault: 0,
|
||||
removeTransclusionQuoteSigns: true,
|
||||
iframelyAllowed: true,
|
||||
pngExportScale: 1,
|
||||
exportWithTheme: true,
|
||||
@@ -199,6 +196,9 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
|
||||
mathjaxSourceURL: "https://cdn.jsdelivr.net/npm/mathjax@3.2.1/es5/tex-svg.js"
|
||||
};
|
||||
|
||||
const fragWithHTML = (html: string) =>
|
||||
createFragment((frag) => (frag.createDiv().innerHTML = html));
|
||||
|
||||
export class ExcalidrawSettingTab extends PluginSettingTab {
|
||||
plugin: ExcalidrawPlugin;
|
||||
private requestEmbedUpdate: boolean = false;
|
||||
@@ -809,19 +809,6 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
|
||||
}),
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("QUOTE_TRANSCLUSION_REMOVE_NAME"))
|
||||
.setDesc(fragWithHTML(t("QUOTE_TRANSCLUSION_REMOVE_DESC")))
|
||||
.addToggle(toggle =>
|
||||
toggle
|
||||
.setValue(this.plugin.settings.removeTransclusionQuoteSigns)
|
||||
.onChange(value => {
|
||||
this.plugin.settings.removeTransclusionQuoteSigns = value;
|
||||
this.requestEmbedUpdate = true;
|
||||
this.applySettingsUpdate(true);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("GET_URL_TITLE_NAME"))
|
||||
.setDesc(fragWithHTML(t("GET_URL_TITLE_DESC")))
|
||||
|
||||
3
src/types.d.ts
vendored
3
src/types.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { ExcalidrawBindableElement, ExcalidrawElement, ExcalidrawImageElement, FileId, FillStyle, NonDeletedExcalidrawElement, StrokeSharpness, StrokeStyle } from "@zsviczian/excalidraw/types/element/types";
|
||||
import { ExcalidrawBindableElement, ExcalidrawElement, FileId, FillStyle, NonDeletedExcalidrawElement, StrokeSharpness, StrokeStyle } from "@zsviczian/excalidraw/types/element/types";
|
||||
import { Point } from "@zsviczian/excalidraw/types/types";
|
||||
import { TFile, WorkspaceLeaf } from "obsidian";
|
||||
import { EmbeddedFilesLoader } from "./EmbeddedFileLoader";
|
||||
@@ -223,7 +223,6 @@ export interface ExcalidrawAutomateInterface {
|
||||
//verifyMinimumPluginVersion returns true if plugin version is >= than required
|
||||
//recommended use:
|
||||
//if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.5.20")) {new Notice("message");return;}
|
||||
getOriginalImageSize(imageElement: ExcalidrawImageElement): Promise<{width: number; height: number}>;
|
||||
verifyMinimumPluginVersion(requiredVersion: string): boolean;
|
||||
isExcalidrawView(view: any): boolean;
|
||||
selectElementsInView(elements: ExcalidrawElement[]): void; //sets selection in view
|
||||
|
||||
1315
src/utils/Utils.ts
1315
src/utils/Utils.ts
File diff suppressed because it is too large
Load Diff
@@ -223,8 +223,4 @@ textarea.excalidraw-wysiwyg {
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.is-tablet .excalidraw button {
|
||||
padding: initial;
|
||||
}
|
||||
26
yarn.lock
26
yarn.lock
@@ -2216,10 +2216,10 @@
|
||||
dependencies:
|
||||
"@zerollup/ts-helpers" "^1.7.18"
|
||||
|
||||
"@zsviczian/excalidraw@0.13.0-obsidian":
|
||||
"integrity" "sha512-c4SnBEGKtenLB/1gSjXe3BVA+yZfo8b1p2E7sVcaPG8MTz6cpQsCB2+cv7Zta5ihIxuGfK3ZSepVhMbN7RFY2w=="
|
||||
"resolved" "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.13.0-obsidian.tgz"
|
||||
"version" "0.13.0-obsidian"
|
||||
"@zsviczian/excalidraw@0.12.0-obsidian-9":
|
||||
"integrity" "sha512-mJ1MB0eKgHjtXPxSCCQkn/z/hdg3pI9vQQuwyCqNs5hjspuLJ+DdGkhaHvX+HrDuFdwPl/s+vfPC/tjTj6tmbA=="
|
||||
"resolved" "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.12.0-obsidian-9.tgz"
|
||||
"version" "0.12.0-obsidian-9"
|
||||
|
||||
"abab@^2.0.3", "abab@^2.0.5":
|
||||
"integrity" "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q=="
|
||||
@@ -6206,10 +6206,10 @@
|
||||
dependencies:
|
||||
"minimist" "^1.2.5"
|
||||
|
||||
"moment@2.29.4":
|
||||
"integrity" "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||
"resolved" "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz"
|
||||
"version" "2.29.4"
|
||||
"moment@2.29.3":
|
||||
"integrity" "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw=="
|
||||
"resolved" "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz"
|
||||
"version" "2.29.3"
|
||||
|
||||
"monkey-around@^2.3.0":
|
||||
"integrity" "sha512-QWcCUWjqE/MCk9cXlSKZ1Qc486LD439xw/Ak8Nt6l2PuL9+yrc9TJakt7OHDuOqPRYY4nTWBAEFKn32PE/SfXA=="
|
||||
@@ -6420,13 +6420,13 @@
|
||||
"define-properties" "^1.1.3"
|
||||
"es-abstract" "^1.19.1"
|
||||
|
||||
"obsidian@^0.16.3":
|
||||
"integrity" "sha512-hal9qk1A0GMhHSeLr2/+o3OpLmImiP+Y+sx2ewP13ds76KXsziG96n+IPFT0mSkup1zSwhEu+DeRhmbcyCCXWw=="
|
||||
"resolved" "https://registry.npmjs.org/obsidian/-/obsidian-0.16.3.tgz"
|
||||
"version" "0.16.3"
|
||||
"obsidian@^0.15.4":
|
||||
"integrity" "sha512-FE11CxxpVD6t/DBvjLvlT7q7YYW91ubTqPKIIp286LdnyLipS8Xi3Tif8i8ALPv87Vg9obKM43aWcPsYLxLllQ=="
|
||||
"resolved" "https://registry.npmjs.org/obsidian/-/obsidian-0.15.4.tgz"
|
||||
"version" "0.15.4"
|
||||
dependencies:
|
||||
"@types/codemirror" "0.0.108"
|
||||
"moment" "2.29.4"
|
||||
"moment" "2.29.3"
|
||||
|
||||
"obuf@^1.0.0", "obuf@^1.1.2":
|
||||
"integrity" "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="
|
||||
|
||||
Reference in New Issue
Block a user