added sync SVP with Excalidraw file

This commit is contained in:
Zsolt Viczian
2021-04-26 23:02:22 +02:00
parent 25a998fc01
commit d64c00f2dd
5 changed files with 129 additions and 11 deletions

View File

@@ -1,6 +1,8 @@
import {
TextFileView,
WorkspaceLeaf,
normalizePath,
TFile,
} from "obsidian";
import * as React from "react";
import * as ReactDOM from "react-dom";
@@ -19,6 +21,11 @@ import {
} from './constants';
import ExcalidrawPlugin from './main';
export interface ExportSettings {
withBackground: boolean,
withTheme: boolean
}
export default class ExcalidrawView extends TextFileView {
private getScene: any;
private excalidrawRef: React.MutableRefObject<any>;
@@ -35,11 +42,26 @@ export default class ExcalidrawView extends TextFileView {
// get the new file content
getViewData () {
if(this.getScene)
return this.getScene();
if(this.getScene) {
const scene = this.getScene();
if(this.plugin.settings.autoexportSVG) this.saveSVG(scene);
return scene;
}
else return this.data;
}
private async saveSVG(data: string) {
const filepath = this.file.path.substring(0,this.file.path.lastIndexOf('.excalidraw')) + '.svg';
const file = this.app.vault.getAbstractFileByPath(normalizePath(filepath));
const exportSettings: ExportSettings = {
withBackground: this.plugin.settings.exportWithBackground,
withTheme: this.plugin.settings.exportWithTheme
}
const svg = ExcalidrawView.getSVG(data,exportSettings)?.outerHTML;
if(file && file instanceof TFile) await this.app.vault.modify(file,svg);
else await this.app.vault.create(filepath,svg);
}
async onunload() {
if(this.excalidrawRef) await this.save();
}
@@ -172,7 +194,8 @@ export default class ExcalidrawView extends TextFileView {
canvasActions: {
loadScene: false,
saveScene: false,
saveAsScene: false
saveAsScene: false,
export: false
},
},
initialData: initdata,
@@ -191,18 +214,17 @@ export default class ExcalidrawView extends TextFileView {
)
);
});
ReactDOM.render(reactElement,(this as any).contentEl);
ReactDOM.render(reactElement,(this as any).contentEl);
}
public static getSVG(data:string):SVGSVGElement {
public static getSVG(data:string, exportSettings:ExportSettings):SVGSVGElement {
try {
const excalidrawData = JSON.parse(data);
return exportToSvg({
elements: excalidrawData.elements,
appState: {
exportBackground: true,
exportWithDarkMode: excalidrawData.appState?.theme=="light" ? false : true,
exportBackground: exportSettings.withBackground,
exportWithDarkMode: exportSettings.withTheme ? (excalidrawData.appState?.theme=="light" ? false : true) : false,
... excalidrawData.appState,},
exportPadding:10,
metadata: "Generated by Excalidraw-Obsidian plugin",

File diff suppressed because one or more lines are too long

View File

@@ -17,7 +17,7 @@ import {
EXCALIDRAW_FILE_EXTENSION,
CODEBLOCK_EXCALIDRAW,
} from './constants';
import ExcalidrawView from './ExcalidrawView';
import ExcalidrawView, {ExportSettings} from './ExcalidrawView';
import {
ExcalidrawSettings,
DEFAULT_SETTINGS,
@@ -92,7 +92,11 @@ export default class ExcalidrawPlugin extends Plugin {
}
const content = await this.app.vault.read(file);
const svg = ExcalidrawView.getSVG(content);
const exportSettings: ExportSettings = {
withBackground: this.settings.exportWithBackground,
withTheme: this.settings.exportWithTheme
}
const svg = ExcalidrawView.getSVG(content,exportSettings);
if(!svg) {
parseError("Parse error. Not a valid Excalidraw file.");
return;
@@ -138,6 +142,27 @@ export default class ExcalidrawPlugin extends Plugin {
this.createDrawing(this.getNextDefaultFilename());
},
});
//watch filename change to rename .svg
this.app.vault.on('rename',async (file,oldPath) => {
if (!this.settings.keepInSync) return;
const oldSVGpath = oldPath.substring(0,oldPath.lastIndexOf('.excalidraw')) + '.svg';
const svgFile = this.app.vault.getAbstractFileByPath(normalizePath(oldSVGpath));
if(svgFile && svgFile instanceof TFile) {
const newSVGpath = file.path.substring(0,file.path.lastIndexOf('.excalidraw')) + '.svg';
await this.app.vault.rename(svgFile,newSVGpath);
}
});
//watch file delete and delete corresponding .svg
this.app.vault.on('delete',async (file) => {
if (!this.settings.keepInSync) return;
const svgPath = file.path.substring(0,file.path.lastIndexOf('.excalidraw')) + '.svg';
const svgFile = this.app.vault.getAbstractFileByPath(normalizePath(svgPath));
if(svgFile && svgFile instanceof TFile) {
await this.app.vault.delete(svgFile);
}
});
}
public insertCodeblock(data:string) {

View File

@@ -9,6 +9,10 @@ export interface ExcalidrawSettings {
folder: string,
templateFilePath: string,
width: string,
exportWithTheme: boolean,
exportWithBackground: boolean,
autoexportSVG: boolean,
keepInSync: boolean,
library: string,
}
@@ -16,6 +20,10 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
folder: 'Excalidraw',
templateFilePath: 'Excalidraw/Template.excalidraw',
width: '400',
exportWithTheme: true,
exportWithBackground: true,
autoexportSVG: false,
keepInSync: false,
library: `{"type":"excalidrawlib","version":1,"library":[]}`,
}
@@ -67,5 +75,53 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
this.plugin.settings.width = value;
await this.plugin.saveSettings();
}));
this.containerEl.createEl('h1', {text: 'Embedded image settings'});
new Setting(containerEl)
.setName('Export image with background')
.setDesc('If turned of the exported image will be transparent.')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.exportWithBackground)
.onChange(async (value) => {
this.plugin.settings.exportWithBackground = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName('Export image with theme')
.setDesc('Export the image matching the dark/light theme setting used for your drawing in Excalidraw')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.exportWithTheme)
.onChange(async (value) => {
this.plugin.settings.exportWithTheme = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName('Auto export SVG')
.setDesc('Automatically create an SVG export of your drawing matching the title of your .excalidraw file, saved in the same folder. '+
'You can use this file ("my drawing.svg") to embed into documents in a platform independent way. ' +
'The file will get updated every time you edit the excalidraw drawing.')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.autoexportSVG)
.onChange(async (value) => {
this.plugin.settings.autoexportSVG = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName('Keep .svg filename in sync with the .excalidraw filename')
.setDesc('Automaticaly update the .svg filename when .excalidraw file in the same folder is renamed. ' +
'Automatically delete the .svg file when the .excalidraw file in the same folder is deleted. ')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.keepInSync)
.onChange(async (value) => {
this.plugin.settings.keepInSync = value;
await this.plugin.saveSettings();
}));
}
}

View File

@@ -15,4 +15,17 @@
.block-language-excalidraw {
text-align:center;
}
.excalidraw .github-corner {
display: none;
}
@font-face {
font-family: "Virgil";
src: url("https://excalidraw.com/Virgil.woff2");
}
@font-face {
font-family: "Cascadia";
src: url("https://excalidraw.com/Cascadia.woff2");
}