diff --git a/manifest.json b/manifest.json index 2b9be14..9b15419 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "2.1.3", + "version": "2.1.4", "minAppVersion": "1.1.6", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", diff --git a/src/ExcalidrawView.ts b/src/ExcalidrawView.ts index c7d3598..717de5e 100644 --- a/src/ExcalidrawView.ts +++ b/src/ExcalidrawView.ts @@ -16,6 +16,7 @@ import { //import Excalidraw from "@zsviczian/excalidraw"; import { ExcalidrawElement, + ExcalidrawGenericElement, ExcalidrawImageElement, ExcalidrawTextElement, FileId, @@ -101,6 +102,8 @@ import { isContainer, fragWithHTML, isMaskFile, + shouldEmbedScene, + getContainerElement, } from "./utils/Utils"; import { cleanSectionHeading, getLeaf, getParentOfClass, obsidianPDFQuoteWithRef, openLeaf } from "./utils/ObsidianUtils"; import { splitFolderAndFilename } from "./utils/FileUtils"; @@ -434,6 +437,10 @@ export default class ExcalidrawView extends TextFileView { isMask: isMaskFile(this.plugin, this.file), }; + if(typeof embedScene === "undefined") { + embedScene = shouldEmbedScene(this.plugin, this.file); + } + return await getSVG( { ...scene, @@ -512,6 +519,11 @@ export default class ExcalidrawView extends TextFileView { withTheme: true, isMask: isMaskFile(this.plugin, this.file), }; + + if(typeof embedScene === "undefined") { + embedScene = shouldEmbedScene(this.plugin, this.file); + } + return await getPNG( { ...scene, @@ -778,6 +790,7 @@ export default class ExcalidrawView extends TextFileView { [FRONTMATTER_KEYS["export-dark"].name, this.exportDialog.theme === "dark" ? "true" : "false"], [FRONTMATTER_KEYS["export-transparent"].name, this.exportDialog.transparent ? "true" : "false"], [FRONTMATTER_KEYS["plugin"].name, this.textMode === TextMode.raw ? "raw" : "parsed"], + [FRONTMATTER_KEYS["export-embed-scene"].name, this.exportDialog.embedScene ? "true" : "false"], ] : [ [FRONTMATTER_KEYS["plugin"].name, this.textMode === TextMode.raw ? "raw" : "parsed"] @@ -949,7 +962,7 @@ export default class ExcalidrawView extends TextFileView { let linkText: string = null; if (selectedText?.id || selectedElementWithLink?.id) { - const selectedTextElement = selectedText.id + const selectedTextElement: ExcalidrawTextElement = selectedText.id ? this.excalidrawAPI.getSceneElements().find((el:ExcalidrawElement)=>el.id === selectedText.id) : null; @@ -961,9 +974,20 @@ export default class ExcalidrawView extends TextFileView { const partsArray = REGEX_LINK.getResList(linkText); if (!linkText || partsArray.length === 0) { - linkText = selectedTextElement?.link; + //the container link takes precedence over the text link + if(selectedTextElement?.containerId) { + const container = getContainerElement(selectedTextElement, {elements: this.excalidrawAPI.getSceneElements()}); + if(container) { + linkText = container.link; + } + } + if(!linkText) { + linkText = selectedTextElement?.link; + } } + + if (!linkText) { return; } @@ -3101,7 +3125,7 @@ export default class ExcalidrawView extends TextFileView { if (!(isWinCTRLorMacCMD(e)||isWinMETAorMacCTRL(e))) { return; } - if (!this.plugin.settings.allowCtrlClick && !!isWinMETAorMacCTRL(e)) { + if (!this.plugin.settings.allowCtrlClick && !isWinMETAorMacCTRL(e)) { return; } //added setTimeout when I changed onClick(e: MouseEvent) to onPointerDown() in 1.7.9. diff --git a/src/MarkdownPostProcessor.ts b/src/MarkdownPostProcessor.ts index 7c74da3..c23ac48 100644 --- a/src/MarkdownPostProcessor.ts +++ b/src/MarkdownPostProcessor.ts @@ -592,8 +592,18 @@ const tmpObsidianWYSIWYG = async ( //@ts-ignore const containerEl = ctx.containerEl; + + if(!plugin.settings.renderImageInMarkdownReadingMode && containerEl.parentElement?.parentElement?.hasClass("markdown-reading-view")) { + return; + } + + if(!plugin.settings.renderImageInMarkdownToPDF && containerEl.parentElement?.hasClass("print")) { + return; + } + let internalEmbedDiv: HTMLElement = containerEl; while ( + !internalEmbedDiv.hasClass("print") && !internalEmbedDiv.hasClass("dataview") && !internalEmbedDiv.hasClass("cm-preview-code-block") && !internalEmbedDiv.hasClass("cm-embed-block") && @@ -613,18 +623,23 @@ const tmpObsidianWYSIWYG = async ( return; //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/835 } + const isPrinting = Boolean(internalEmbedDiv.hasClass("print")); + const attr: imgElementAttributes = { fname: ctx.sourcePath, - fheight: getDefaultHeight(plugin), - fwidth: getDefaultWidth(plugin), + fheight: isPrinting ? "100%" : getDefaultHeight(plugin), + fwidth: isPrinting ? "100%" : getDefaultWidth(plugin), style: ["excalidraw-svg"], }; attr.file = file; const markdownEmbed = internalEmbedDiv.hasClass("markdown-embed"); - const markdownReadingView = internalEmbedDiv.hasClass("markdown-reading-view"); + const markdownReadingView = internalEmbedDiv.hasClass("markdown-reading-view") || isPrinting; if (!internalEmbedDiv.hasClass("internal-embed") && (markdownEmbed || markdownReadingView)) { + if(isPrinting) { + internalEmbedDiv = containerEl; + } //We are processing the markdown preview of an actual Excalidraw file //the excalidraw file in markdown preview mode const isFrontmatterDiv = Boolean(el.querySelector(".frontmatter")); diff --git a/src/Scripts.ts b/src/Scripts.ts index 177b63f..046f0b1 100644 --- a/src/Scripts.ts +++ b/src/Scripts.ts @@ -172,6 +172,7 @@ export class ScriptEngine { (async()=>{ const script = await app.vault.read(f); if(script) { + //remove YAML frontmatter if present this.executeScript(view, script, scriptName,f); } })() @@ -212,6 +213,7 @@ export class ScriptEngine { if (!view || !script || !title) { return; } + script = script.replace(/^---.*?---\n/gs, ""); const ea = getEA(view); ea.activeScript = title; diff --git a/src/constants/constants.ts b/src/constants/constants.ts index 228b6f4..5ee2212 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -164,6 +164,7 @@ export const FRONTMATTER_KEYS:{[key:string]: {name: string, type: string, depric "export-svgpadding": {name: "excalidraw-export-svgpadding", type: "number", depricated: true}, "export-padding": {name: "excalidraw-export-padding", type: "number"}, "export-pngscale": {name: "excalidraw-export-pngscale", type: "number"}, + "export-embed-scene": {name: "excalidraw-export-embed-scene", type: "checkbox"}, "link-prefix": {name: "excalidraw-link-prefix", type: "text"}, "url-prefix": {name: "excalidraw-url-prefix", type: "text"}, "link-brackets": {name: "excalidraw-link-brackets", type: "checkbox"}, diff --git a/src/dialogs/ExportDialog.ts b/src/dialogs/ExportDialog.ts index 8db1261..73678ab 100644 --- a/src/dialogs/ExportDialog.ts +++ b/src/dialogs/ExportDialog.ts @@ -5,7 +5,7 @@ import { DEVICE } from "src/constants/constants"; import { ExcalidrawAutomate } from "src/ExcalidrawAutomate"; import ExcalidrawView from "src/ExcalidrawView"; import ExcalidrawPlugin from "src/main"; -import { fragWithHTML, getExportPadding, getExportTheme, getPNGScale, getWithBackground } from "src/utils/Utils"; +import { fragWithHTML, getExportPadding, getExportTheme, getPNGScale, getWithBackground, shouldEmbedScene } from "src/utils/Utils"; export class ExportDialog extends Modal { private ea: ExcalidrawAutomate; @@ -40,7 +40,7 @@ export class ExportDialog extends Modal { this.scale = getPNGScale(this.plugin,this.file) this.theme = getExportTheme(this.plugin, this.file, (this.api).getAppState().theme) this.boundingBox = this.ea.getBoundingBox(this.ea.getViewElements()); - this.embedScene = false; + this.embedScene = shouldEmbedScene(this.plugin, this.file); this.exportSelectedOnly = false; this.saveToVault = true; this.transparent = !getWithBackground(this.plugin, this.file); diff --git a/src/dialogs/Messages.ts b/src/dialogs/Messages.ts index 0129d66..fb1e73e 100644 --- a/src/dialogs/Messages.ts +++ b/src/dialogs/Messages.ts @@ -17,6 +17,24 @@ I develop this plugin as a hobby, spending my free time doing this. If you find
`, +"2.1.4":` +## Fixed +- Fixed the **aspect ratio** of an Excalidraw embedded within another Excalidraw **not updating**. [#1707](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1707) +- Some plugins automatically add document properties to all files in the Vault. Users with this configuration were **unable to run Excalidraw scripts**. Excalidraw now removes document properties from the script before execution. +- The very last markdown edit sometimes **wasn't saved when immediately switching from Markdown to Excalidraw View**. I now force a save before switching views. +- The setting to disable/enable ${String.fromCharCode(96)}CTRL/CMD + CLICK on text with [[links]] or [](links) to open them${String.fromCharCode(96)} works again. [#1704](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1704) +- **Annotation and cropping** of images in Markdown notes now also work **with Markdown links that have encoded characters** e.g.: ${String.fromCharCode(96)}${String.fromCharCode(96)}. +- Solved compatibility issue of **Taskbone OCR on Android**. + +## New +- New settings: + - Under "Appearance and Behavior": Option to **render Excalidraw file as an image in Markdown reading mode**. This setting is disabled by default. [#1706](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1706), [#1705](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1705) + - Under "Embedding Excalidraw ... and Exporting"/"Export Settings": Option to **render Excalidraw file as an image when exporting to PDF** in Markdown mode. This option is disabled by default. When enabled, exporting an Excalidraw drawing in markdown view mode to PDF will render the image on the page. +- **Enhanced annotation and cropping** of images in Markdown documents: + - Newly embedded **links will now follow the style of the original link**. If the original format was a ${String.fromCharCode(96)}${String.fromCharCode(96)}, the annotated file will follow this format. For ${String.fromCharCode(96)}[[wiki links]]${String.fromCharCode(96)}, it will follow that style. Additionally, if an alias was specified like ${String.fromCharCode(96)}[[link|alias]]${String.fromCharCode(96)}, the annotated or cropped image will retain the alias. + - Introduced a new setting under "Saving" titled **"Preserve image size when annotating"**. This setting is disabled by default. When enabled, the embed link replacing the annotated image will maintain the size of the original image. +- Option to **automaticaly embed the scene in exported PNG and SVG image files**. Including the scene will allow users to open the picture on Excalidraw.com or in another Obsidian Vault as an editable Excalidraw file.New setting is under the Export category. The new frontmatter tag is: ${String.fromCharCode(96)}excalidraw-export-embed-scene: true/false${String.fromCharCode(96)}. +`, "2.1.3":` This is a republish of 2.1.2 with a minor change. Sorry about the frequent releases. I will hold back for a few weeks now. `, diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index 670435e..4f0b195 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -139,6 +139,9 @@ export default { ANNOTATE_PREFIX_DESC: "The first part of the filename for new drawings created when annotating an image. " + "If empty the default 'annotated_' will be used.", + ANNOTATE_PRESERVE_SIZE_NAME: "Preserve image size when annotating", + ANNOTATE_PRESERVE_SIZE_DESC: + "When annotating an image in markdown the replacment image link will include the width of the original image.", CROP_FOLDER_NAME: "Crop file folder", CROP_FOLDER_DESC: "Default location for new drawings created when cropping an image. If empty, drawings will be created following the Vault attachments settings.", @@ -285,6 +288,17 @@ FILENAME_HEAD: "Filename", SHOW_PEN_MODE_FREEDRAW_CROSSHAIR_DESC: "Show crosshair in pen mode when using the freedraw tool. Toggle ON: SHOW Toggle OFF: HIDEexcalidraw-export-embed-scene: true/false frontmatter key. " +
+ "The setting only takes effect the next time you (re)open drawings.",
EXPORT_HEAD: "Auto-export Settings",
EXPORT_SYNC_NAME:
"Keep the .SVG and/or .PNG filenames in sync with the drawing file",
@@ -614,7 +632,9 @@ FILENAME_HEAD: "Filename",
"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",
+ "fades out. The text is still there, but the visual clutter is reduced. Note, you can place the %% in the line right above # Text Elements, " +
+ "in this case the entire drawing markdown will fade out including # Text Elements. The side effect is you won't be able to block reference text in other markdown notes, that is after the %% comment section. This is seldom an issue. " +
+ "Should you want to edit the Excalidraw markdown script, simply switch to markdown view mode and temporarily remove the %% comment.",
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 4529b6f..8cc3fc1 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -81,6 +81,7 @@ import {
checkAndCreateFolder,
download,
fileShouldDefaultAsExcalidraw,
+ getAliasWithSize,
getAnnotationFileNameAndFolder,
getCropFileNameAndFolder,
getDrawingFilename,
@@ -101,6 +102,7 @@ import {
getExportTheme,
isCallerFromTemplaterPlugin,
decompress,
+ getImageSize,
} from "./utils/Utils";
import { extractSVGPNGFileName, getActivePDFPageNumberFromPDFView, getAttachmentsFolderAndFilePath, getNewOrAdjacentLeaf, getParentOfClass, isObsidianThemeDark, mergeMarkdownFiles, openLeaf } from "./utils/ObsidianUtils";
import { ExcalidrawElement, ExcalidrawEmbeddableElement, ExcalidrawImageElement, ExcalidrawTextElement, FileId } from "@zsviczian/excalidraw/types/excalidraw/element/types";
@@ -1735,7 +1737,11 @@ export default class ExcalidrawPlugin extends Plugin {
const line = editor.getLine(cursor.line);
const parts = REGEX_LINK.getResList(line);
if(parts.length === 0) return false;
- const imgpath = REGEX_LINK.getLink(parts[0]);
+ let imgpath = REGEX_LINK.getLink(parts[0]);
+ const isWikilink = REGEX_LINK.isWikiLink(parts[0]);
+ let alias = REGEX_LINK.getAliasOrLink(parts[0]);
+ if(alias === imgpath) alias = null;
+ imgpath = decodeURI(imgpath);
const imagePathParts = imgpath.split("#");
const hasRef = imagePathParts.length === 2;
const imageFile = this.app.metadataCache.getFirstLinkpathDest(
@@ -1759,11 +1765,11 @@ export default class ExcalidrawPlugin extends Plugin {
const pdfLink = isFile && ref
? "\n" + getLink(this ,{
embed: false,
- alias: `${imageFile.basename}, ${ref.replace("="," ")}`,
+ alias: alias ?? `${imageFile.basename}, ${ref.replace("="," ")}`,
path:`${imageFile.path}#${ref}`
- })
+ }, isWikilink)
: "";
- editor.setLine(cursor.line,lineparts[0] + getLink(this ,{embed: true, path:link}) + pdfLink + lineparts[1]);
+ editor.setLine(cursor.line,lineparts[0] + getLink(this ,{embed: true, path:link, alias}, isWikilink) + pdfLink + lineparts[1]);
}
carveout(isFile, markdownView.file, imageFile, imagepath, replacer, ref);
}
@@ -1792,8 +1798,11 @@ export default class ExcalidrawPlugin extends Plugin {
new Notice(`Can't load image\n\n${imageURL}`);
return;
}
- ea.getElement(imageID).locked = true;
-
+ const el = ea.getElement(imageID) as Mutable;
+ el.locked = true;
+ const size = this.settings.annotatePreserveSize
+ ? await getImageSize(ea.imagesDict[el.fileId].dataURL)
+ : null;
let fnBase = "";
let imageLink = "";
if(isFile) {
@@ -1841,7 +1850,7 @@ export default class ExcalidrawPlugin extends Plugin {
if(!newFile) return;
const link = this.app.metadataCache.fileToLinktext(newFile,sourceFile.path, true);
- replacer(link, newFile);
+ replacer(link, newFile, size ? `${size.width}` : null);
}
if(isCanvas) {
@@ -1883,7 +1892,11 @@ export default class ExcalidrawPlugin extends Plugin {
const line = editor.getLine(cursor.line);
const parts = REGEX_LINK.getResList(line);
if(parts.length === 0) return false;
- const imgpath = REGEX_LINK.getLink(parts[0]);
+ let imgpath = REGEX_LINK.getLink(parts[0]);
+ const isWikilink = REGEX_LINK.isWikiLink(parts[0]);
+ let alias = REGEX_LINK.getAliasOrLink(parts[0]);
+ if(alias === imgpath) alias = null;
+ imgpath = decodeURI(imgpath);
const imagePathParts = imgpath.split("#");
const hasRef = imagePathParts.length === 2;
const imageFile = this.app.metadataCache.getFirstLinkpathDest(
@@ -1902,16 +1915,19 @@ export default class ExcalidrawPlugin extends Plugin {
if(extension !== "pdf" && !IMAGE_TYPES.contains(extension) && !isExcalidraw) return false;
if(checking) return true;
const ref = imagePathParts[1];
- const replacer = (link:string) => {
+ const replacer = (link:string, _:TFile, size:string) => {
const lineparts = line.split(parts[0].value[0])
const pdfLink = isFile && ref
? "\n" + getLink(this ,{
embed: false,
- alias: `${imageFile.basename}, ${ref.replace("="," ")}`,
+ alias: getAliasWithSize(alias ?? `${imageFile.basename}, ${ref.replace("="," ")}`,size),
path:`${imageFile.path}#${ref}`
- })
+ }, isWikilink)
: "";
- editor.setLine(cursor.line,lineparts[0] + getLink(this ,{embed: true, path:link}) + pdfLink + lineparts[1]);
+ editor.setLine(
+ cursor.line,
+ lineparts[0] + getLink(this ,{embed: true, path:link, alias: getAliasWithSize(alias,size)}, isWikilink) + pdfLink + lineparts[1]
+ );
}
carveout(isFile, markdownView.file, imageFile, imagepath, replacer, ref);
}
@@ -2096,10 +2112,13 @@ export default class ExcalidrawPlugin extends Plugin {
const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView)
if (markdownView && fileIsExcalidraw) {
- const activeLeaf = markdownView.leaf;
- this.excalidrawFileModes[(activeLeaf as any).id || activeFile.path] =
- VIEW_TYPE_EXCALIDRAW;
- this.setExcalidrawView(activeLeaf);
+ (async()=>{
+ await markdownView.save();
+ const activeLeaf = markdownView.leaf;
+ this.excalidrawFileModes[(activeLeaf as any).id || activeFile.path] =
+ VIEW_TYPE_EXCALIDRAW;
+ this.setExcalidrawView(activeLeaf);
+ })()
return;
}
},
@@ -2125,6 +2144,7 @@ export default class ExcalidrawPlugin extends Plugin {
}
(async () => {
+ await activeView.save();
const template = await this.getBlankDrawing();
const target = await this.app.vault.read(activeFile);
const mergedTarget = mergeMarkdownFiles(template, target);
@@ -2252,7 +2272,8 @@ export default class ExcalidrawPlugin extends Plugin {
.setTitle(t("OPEN_AS_EXCALIDRAW"))
.setIcon(ICON_NAME)
.setSection("excalidraw")
- .onClick(() => {
+ .onClick(async () => {
+ await view.save();
//@ts-ignore
this.excalidrawFileModes[leaf.id || file.path] = VIEW_TYPE_EXCALIDRAW;
this.setExcalidrawView(leaf);
@@ -2263,7 +2284,9 @@ export default class ExcalidrawPlugin extends Plugin {
this.registerEvent(
app.workspace.on("file-menu", (menu, file, source, leaf) => {
- if (!leaf || !(leaf.view instanceof MarkdownView)) return;
+ if (!leaf) return;
+ const view = leaf.view;
+ if(!view || !(view instanceof MarkdownView)) return;
if (!(file instanceof TFile)) return;
const cache = this.app.metadataCache.getFileCache(file);
if (!cache?.frontmatter || !cache.frontmatter[FRONTMATTER_KEYS["plugin"].name]) return;
@@ -2273,7 +2296,8 @@ export default class ExcalidrawPlugin extends Plugin {
.setTitle(t("OPEN_AS_EXCALIDRAW"))
.setIcon(ICON_NAME)
.setSection("pane")
- .onClick(() => {
+ .onClick(async () => {
+ await view.save();
//@ts-ignore
this.excalidrawFileModes[leaf.id || file.path] = VIEW_TYPE_EXCALIDRAW;
this.setExcalidrawView(leaf);
diff --git a/src/ocr/Taskbone.ts b/src/ocr/Taskbone.ts
index 896daf7..37df4a8 100644
--- a/src/ocr/Taskbone.ts
+++ b/src/ocr/Taskbone.ts
@@ -114,7 +114,18 @@ export default class Taskbone {
}]
};
- const apiResponse = await requestUrl ({
+ const apiResponse = await fetch(url,{
+ method: "post",
+ //@ts-ignore
+ contentType: "application/json",
+ body: JSON.stringify(input),
+ headers: {
+ "Content-Type": "application/json",
+ authorization: `Bearer ${this.apiKey}`
+ }});
+ const content = await apiResponse?.json();
+
+ /*const apiResponse = await requestUrl ({
url: url,
method: "post",
contentType: "application/json",
@@ -124,7 +135,7 @@ export default class Taskbone {
},
throw: false
});
- const content = apiResponse?.json;
+ const content = apiResponse?.json;*/
if(!content || apiResponse.status !== 200) {
new Notice("Something went wrong while processing your request. Please check developer console for more information");
diff --git a/src/settings.ts b/src/settings.ts
index b04540d..868cf01 100644
--- a/src/settings.ts
+++ b/src/settings.ts
@@ -55,6 +55,7 @@ export interface ExcalidrawSettings {
useExcalidrawExtension: boolean;
cropPrefix: string;
annotatePrefix: string;
+ annotatePreserveSize: boolean;
displaySVGInPreview: boolean; //No longer used since 1.9.13
previewImageType: PreviewImageType; //Introduced with 1.9.13
allowImageCache: boolean;
@@ -71,6 +72,8 @@ export interface ExcalidrawSettings {
defaultMode: string;
defaultPenMode: "never" | "mobile" | "always";
penModeCrosshairVisible: boolean;
+ renderImageInMarkdownReadingMode: boolean,
+ renderImageInMarkdownToPDF: boolean,
allowPinchZoom: boolean;
allowWheelZoom: boolean;
zoomToFitOnOpen: boolean;
@@ -98,6 +101,7 @@ export interface ExcalidrawSettings {
exportWithTheme: boolean;
exportWithBackground: boolean;
exportPaddingSVG: number;
+ exportEmbedScene: boolean;
keepInSync: boolean;
autoexportSVG: boolean;
autoexportPNG: boolean;
@@ -207,6 +211,7 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
useExcalidrawExtension: true,
cropPrefix: CROPPED_PREFIX,
annotatePrefix: ANNOTATED_PREFIX,
+ annotatePreserveSize: false,
displaySVGInPreview: undefined,
previewImageType: undefined,
allowImageCache: true,
@@ -222,7 +227,9 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
matchThemeTrigger: false,
defaultMode: "normal",
defaultPenMode: "never",
- penModeCrosshairVisible: false,
+ penModeCrosshairVisible: true,
+ renderImageInMarkdownReadingMode: false,
+ renderImageInMarkdownToPDF: false,
allowPinchZoom: false,
allowWheelZoom: false,
zoomToFitOnOpen: true,
@@ -250,6 +257,7 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
exportWithTheme: true,
exportWithBackground: true,
exportPaddingSVG: 10, //since 1.6.17, not only SVG but also PNG
+ exportEmbedScene: false,
keepInSync: false,
autoexportSVG: false,
autoexportPNG: false,
@@ -831,6 +839,19 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
this.applySettingsUpdate();
}),
);
+
+ new Setting(detailsEl)
+ .setName(t("ANNOTATE_PRESERVE_SIZE_NAME"))
+ .setDesc(fragWithHTML(t("ANNOTATE_PRESERVE_SIZE_DESC")))
+ .addToggle((toggle) =>
+ toggle
+ .setValue(this.plugin.settings.annotatePreserveSize)
+ .onChange(async (value) => {
+ this.plugin.settings.annotatePreserveSize = value;
+ this.applySettingsUpdate();
+ }),
+ );
+
//------------------------------------------------
// AI Settings
//------------------------------------------------
@@ -947,6 +968,18 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
}),
);
+ new Setting(detailsEl)
+ .setName(t("SHOW_DRAWING_OR_MD_IN_READING_MODE_NAME"))
+ .setDesc(fragWithHTML(t("SHOW_DRAWING_OR_MD_IN_READING_MODE_DESC")))
+ .addToggle((toggle) =>
+ toggle
+ .setValue(this.plugin.settings.renderImageInMarkdownReadingMode)
+ .onChange(async (value) => {
+ this.plugin.settings.renderImageInMarkdownReadingMode = value;
+ this.applySettingsUpdate();
+ }),
+ );
+
new Setting(detailsEl)
.setName(t("LEFTHANDED_MODE_NAME"))
.setDesc(fragWithHTML(t("LEFTHANDED_MODE_DESC")))
@@ -1708,12 +1741,36 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
cls: "excalidraw-setting-h3",
});
addIframe(detailsEl, "wTtaXmRJ7wg",171);
+
+ new Setting(detailsEl)
+ .setName(t("SHOW_DRAWING_OR_MD_IN_EXPORTPDF_NAME"))
+ .setDesc(fragWithHTML(t("SHOW_DRAWING_OR_MD_IN_EXPORTPDF_DESC")))
+ .addToggle((toggle) =>
+ toggle
+ .setValue(this.plugin.settings.renderImageInMarkdownToPDF)
+ .onChange(async (value) => {
+ this.plugin.settings.renderImageInMarkdownToPDF = value;
+ this.applySettingsUpdate();
+ }),
+ );
+
+ new Setting(detailsEl)
+ .setName(t("EXPORT_EMBED_SCENE_NAME"))
+ .setDesc(fragWithHTML(t("EXPORT_EMBED_SCENE_DESC")))
+ .addToggle((toggle) =>
+ toggle
+ .setValue(this.plugin.settings.exportEmbedScene)
+ .onChange(async (value) => {
+ this.plugin.settings.exportEmbedScene = value;
+ this.applySettingsUpdate();
+ }),
+ );
+
detailsEl = exportDetailsEl.createEl("details");
detailsEl.createEl("summary", {
text: t("EMBED_SIZING"),
cls: "excalidraw-setting-h4",
});
-
new Setting(detailsEl)
.setName(t("EMBED_WIDTH_NAME"))
.setDesc(fragWithHTML(t("EMBED_WIDTH_DESC")))
diff --git a/src/utils/FileUtils.ts b/src/utils/FileUtils.ts
index c00e5e0..3702e3a 100644
--- a/src/utils/FileUtils.ts
+++ b/src/utils/FileUtils.ts
@@ -367,13 +367,24 @@ export const getInternalLinkOrFileURLLink = (
*/
export const getLink = (
plugin: ExcalidrawPlugin,
- { embed = true, path, alias }: { embed?: boolean; path: string; alias?: string }
+ { embed = true, path, alias }: { embed?: boolean; path: string; alias?: string },
+ wikilinkOverride?: boolean
):string => {
- return plugin.settings.embedWikiLink
+ const isWikiLink = (typeof wikilinkOverride !== "undefined")
+ ? wikilinkOverride
+ : plugin.settings.embedWikiLink;
+ return isWikiLink
? `${embed ? "!" : ""}[[${path}${alias ? `|${alias}` : ""}]]`
: `${embed ? "!" : ""}[${alias ?? ""}](${encodeURI(path)})`
}
+export const getAliasWithSize = (alias: string, size: string): string => {
+ if(alias && alias !== "") {
+ return `${alias}${size?`|${size}`:""}`;
+ }
+ return size;
+}
+
export const getCropFileNameAndFolder = async (plugin: ExcalidrawPlugin, hostPath: string, baseNewFileName: string):Promise<{folderpath: string, filename: string}> => {
let prefix = plugin.settings.cropPrefix;
if(!prefix || prefix.trim() === "") prefix = CROPPED_PREFIX;
diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts
index 6611183..ded83b7 100644
--- a/src/utils/Utils.ts
+++ b/src/utils/Utils.ts
@@ -4,6 +4,7 @@ import {
request,
requestUrl,
TFile,
+ TFolder,
} from "obsidian";
import { Random } from "roughjs/bin/math";
import { BinaryFileData, DataURL} from "@zsviczian/excalidraw/types/excalidraw/types";
@@ -30,6 +31,8 @@ import { Mutable } from "@zsviczian/excalidraw/types/excalidraw/utility-types";
import { cleanBlockRef, cleanSectionHeading, getFileCSSClasses } from "./ObsidianUtils";
import { updateElementLinksToObsidianLinks } from "src/ExcalidrawAutomate";
import { CropImage } from "./CropImage";
+import { ExcalidrawData } from "src/ExcalidrawData";
+import { ExcalidrawGenericElement } from "lib/svgToExcalidraw/types";
declare const PLUGIN_VERSION:string;
@@ -440,7 +443,15 @@ export const scaleLoadedImage = (
if (!files || !scene) {
return { dirty, scene };
}
- for (const f of files.filter((f:TFile)=>EXCALIDRAW_PLUGIN?.isExcalidrawFile(f))) {
+
+ for (const f of files.filter((f:any)=>{
+ if(!Boolean(EXCALIDRAW_PLUGIN)) return true; //this should never happen
+ const ef = EXCALIDRAW_PLUGIN.filesMaster.get(f.id);
+ if(!ef) return false;
+ const file = EXCALIDRAW_PLUGIN.app.vault.getAbstractFileByPath(ef.path.replace(/#.*$/,"").replace(/\|.*$/,""));
+ if(!file || (file instanceof TFolder)) return false;
+ return EXCALIDRAW_PLUGIN.isExcalidrawFile(file as TFile)
+ })) {
const [w_image, h_image] = [f.size.width, f.size.height];
const imageAspectRatio = f.size.width / f.size.height;
scene.elements
@@ -587,6 +598,22 @@ export const getExportTheme = (
return plugin.settings.exportWithTheme ? theme : "light";
};
+export const shouldEmbedScene = (
+ plugin: ExcalidrawPlugin,
+ file: TFile
+): boolean => {
+ if (file) {
+ const fileCache = plugin.app.metadataCache.getFileCache(file);
+ if (
+ fileCache?.frontmatter &&
+ fileCache.frontmatter[FRONTMATTER_KEYS["export-embed-scene"].name] != null
+ ) {
+ return fileCache.frontmatter[FRONTMATTER_KEYS["export-embed-scene"].name];
+ }
+ }
+ return plugin.settings.exportEmbedScene;
+};
+
export const hasExportBackground = (
plugin: ExcalidrawPlugin,
file: TFile,
@@ -740,13 +767,13 @@ export const getContainerElement = (
element:
| (ExcalidrawElement & { containerId: ExcalidrawElement["id"] | null })
| null,
- scene: ExcalidrawScene,
+ scene: any,
) => {
if (!element) {
return null;
}
if (element.containerId) {
- return scene.elements.filter(el=>el.id === element.containerId)[0] ?? null;
+ return scene.elements.find((el:ExcalidrawElement)=>el.id === element.containerId) ?? null;
}
return null;
};