diff --git a/.gitignore b/.gitignore
index 5fe00fe..89c2164 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ out
node_modules
.vscode-test/
*.vsix
+.vscode/
\ No newline at end of file
diff --git a/html/mind-map-preview-webview.template.html b/html/mind-map-preview-webview.template.html
new file mode 100644
index 0000000..a091231
--- /dev/null
+++ b/html/mind-map-preview-webview.template.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index c46534c..3366684 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,8 @@
"Other"
],
"activationEvents": [
- "onCommand:mdmmp.showMindMap"
+ "onCommand:mdmmp.showMindMap",
+ "onCommand:mdmmp.exportSvg"
],
"main": "./out/extension.js",
"contributes": {
@@ -39,6 +40,15 @@
"light": "./icon/mind-map-theme-light.svg",
"dark": "./icon/mind-map-theme-dark.svg"
}
+ },
+ {
+ "when": "resourceLangId == markdown",
+ "command": "mdmmp.exportSvg",
+ "title": "Export Mind Map SVG",
+ "icon": {
+ "light": "./icon/mind-map-theme-light.svg",
+ "dark": "./icon/mind-map-theme-dark.svg"
+ }
}
],
"menus": {
@@ -70,6 +80,5 @@
"mocha": "^8.1.3",
"typescript": "^4.0.2",
"vscode-test": "^1.4.0"
- },
- "dependencies": {}
+ }
}
diff --git a/src/extension.ts b/src/extension.ts
index d2fdf8b..08838ed 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -1,18 +1,25 @@
-// The module 'vscode' contains the VS Code extensibility API
-// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
import { MindMapPreview } from "./mindMapPreviewWebview";
-// this method is called when your extension is activated
-// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
+ let mindMapPreview: MindMapPreview;
context.subscriptions.push(
vscode.commands.registerCommand('mdmmp.showMindMap', () => {
- const mindMapPreview = new MindMapPreview(context);
+ if ((mindMapPreview === undefined) || mindMapPreview.isDisposed) {
+ mindMapPreview = new MindMapPreview(context);
+ }
mindMapPreview.updatePreview();
})
);
+ context.subscriptions.push(
+ vscode.commands.registerCommand('mdmmp.exportSvg', () => {
+ if ((mindMapPreview === undefined) || mindMapPreview.isDisposed) {
+ vscode.window.showWarningMessage("Sorry, you need open the preview tab first.");
+ return;
+ }
+ mindMapPreview.exportSvg();
+ })
+ );
}
-// this method is called when your extension is deactivated
export function deactivate() {}
diff --git a/src/mindMapPreviewWebview.ts b/src/mindMapPreviewWebview.ts
index 16123fe..77d50c2 100644
--- a/src/mindMapPreviewWebview.ts
+++ b/src/mindMapPreviewWebview.ts
@@ -1,11 +1,35 @@
import * as vscode from 'vscode';
import * as path from "path";
+import * as fs from "fs";
+import * as utils from "./utils";
class MindMapPreview {
+ context: vscode.ExtensionContext;
view: vscode.WebviewPanel;
editingEditor!: vscode.TextEditor;
+ isDisposed: boolean = false;
+
+ // Configure initialization here.
+ configureWebviewScripts(webviewScripts: string[]) {
+ webviewScripts.push("d3.js");
+ webviewScripts.push("transform.min.js");
+ webviewScripts.push("view.min.js");
+ return webviewScripts;
+ }
+
+ configureDisposables(disposables: vscode.Disposable[]) {
+ disposables.push(vscode.workspace.onDidChangeTextDocument(() => {
+ this.updatePreview();
+ }));
+ disposables.push(this.view.webview.onDidReceiveMessage((message) => {
+ this.onMessageReceived(message);
+ }, null, this.context.subscriptions));
+ return disposables;
+ }
constructor(context: vscode.ExtensionContext) {
+ this.context = context;
+
this.view = vscode.window.createWebviewPanel(
"mindMapPreview",
"Mind Map Preview",
@@ -18,67 +42,80 @@ class MindMapPreview {
}
);
- this.view.webview.html = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `;
-
const editingEditor = vscode.window.activeTextEditor;
- if (editingEditor === undefined) { return; }
+ if (editingEditor === undefined) {
+ vscode.window.showWarningMessage("Sorry, the active text editor is not valid.");
+ return;
+ }
this.editingEditor = editingEditor;
- const editingEvent = vscode.workspace.onDidChangeTextDocument(() => {
- this.updatePreview();
+ this.initialize();
+ this.isDisposed = false;
+ }
+
+ initialize() {
+ this.initializeWebviewHtml();
+ this.registerDisposables();
+ }
+
+ initializeWebviewHtml() {
+ let loadingScriptHtml: string[] = [];
+ this.configureWebviewScripts([]).forEach(path => {
+ loadingScriptHtml.push(``);
});
+ const html: string = fs.readFileSync(path.join(this.getHtmlAssetPath("mind-map-preview-webview.template.html"))).toString("utf-8");
+ this.view.webview.html = html.replace(//g, loadingScriptHtml.join("\r\n"));
+ }
+
+ registerDisposables() {
+ const disposables: vscode.Disposable[] = this.configureDisposables([]);
this.view.onDidDispose(
() => {
- editingEvent.dispose();
+ disposables.forEach(disposable => {
+ disposable.dispose();
+ });
+ this.isDisposed = true;
},
null,
- context.subscriptions
+ this.context.subscriptions
);
}
+ getHtmlAssetPath(filename: string) {
+ return path.join(this.context.extensionPath, 'html', filename);
+ }
+
+ onMessageReceived(message: any) {
+ switch (message.command) {
+ case "saveSvgData": {
+ this.onSvgDataReceived(message.html);
+ break;
+ }
+ }
+ }
+
+ onSvgDataReceived(html: string) {
+ const editor = vscode.window.activeTextEditor;
+ if (editor === undefined) {
+ vscode.window.showWarningMessage("Sorry, the active text editor is not valid.");
+ return;
+ }
+ const fsPath = editor.document.uri.fsPath;
+ const tempFile = path.dirname(fsPath);
+
+ const filename = utils.getFileNameWithoutExtension(path.basename(fsPath));
+ let tempImage = path.resolve(tempFile, filename + '.svg');
+ fs.writeFileSync(tempImage, html);
+ }
+
updatePreview() {
const data = this.editingEditor.document.getText();
- this.view.webview.postMessage(data);
+ this.view.webview.postMessage({ "command": "renderMarkdown", "data": data });
+ }
+
+ exportSvg() {
+ this.view.webview.postMessage({ "command": "saveSvg" });
}
}
diff --git a/src/modules.d.ts b/src/modules.d.ts
deleted file mode 100644
index 316d34b..0000000
--- a/src/modules.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare module 'markmap-lib/dist/transform';
\ No newline at end of file
diff --git a/src/utils.ts b/src/utils.ts
new file mode 100644
index 0000000..38ba811
--- /dev/null
+++ b/src/utils.ts
@@ -0,0 +1,9 @@
+export function getFileNameWithoutExtension(filename: string) {
+ var pattern = /\.[A-Za-z]+$/;
+ let ansMatch = pattern.exec(filename);
+ if (ansMatch !== null) {
+ return (filename.slice(0, ansMatch.index));
+ } else {
+ return filename;
+ }
+}