From 63c573a31f2a4c1f3de4b306389c59c19e34cb8b Mon Sep 17 00:00:00 2001
From: Alexander Kachkaev
\@import "your_vega_source.json" {as:"vega"} @@ -71,10 +80,11 @@ For example:* Supported [ditaa](https://github.com/stathissideris/ditaa). - ditaa can convert diagrams drawn using ascii art ('drawings' that contain characters that resemble lines like | / - ), into proper bitmap graphics. (**Java** is required to be installed) + ditaa can convert diagrams drawn using ascii art ('drawings' that contain characters that resemble lines like | / - ), into proper bitmap graphics. (**Java** is required to be installed) - `ditaa` is intergrated with [code chunk](https://shd101wyy.github.io/markdown-preview-enhanced/#/code-chunk), for example: -
+ `ditaa` is intergrated with [code chunk](https://shd101wyy.github.io/markdown-preview-enhanced/#/code-chunk), for example: + +```ditaa {cmd=true args=["-E"]} +--------+ +-------+ +-------+ | | --+ ditaa +--> | | @@ -90,19 +100,16 @@ For example: > shift-enter to run code chunk. > set `{hide=true}` to hide code block. -> set `{run_on_save=true}` to render ditaa when you save the markdown file. +> set `{run_on_save=true}` to render ditaa when you save the markdown file. ![screen shot 2017-07-28 at 8 11 15 am](https://user-images.githubusercontent.com/1908863/28718626-633fa18e-736c-11e7-8a4a-915858dafff6.png) - - ## 0.2.0, 0.2.1 -* Upgraded [mume](https://github.com/shd101wyy/mume) to version `0.1.5`. - * Fixed header id bug [#516](https://github.com/shd101wyy/markdown-preview-enhanced/issues/516). - * Fixed `enableExtendedTableSyntax` bug. - * Fixed `MathJax` init error. - * Fixed plain text code block font size issue. - * Fixed `transformMarkdown` function `Maximum call stack size exceeded` issue [515](https://github.com/shd101wyy/markdown-preview-enhanced/issues/515), [#517](https://github.com/shd101wyy/markdown-preview-enhanced/issues/517). - * Fixed `webview.ts` `clickTagA` action bug [503](https://github.com/shd101wyy/markdown-preview-enhanced/issues/503). - +* Upgraded [mume](https://github.com/shd101wyy/mume) to version `0.1.5`. + * Fixed header id bug [#516](https://github.com/shd101wyy/markdown-preview-enhanced/issues/516). + * Fixed `enableExtendedTableSyntax` bug. + * Fixed `MathJax` init error. + * Fixed plain text code block font size issue. + * Fixed `transformMarkdown` function `Maximum call stack size exceeded` issue [515](https://github.com/shd101wyy/markdown-preview-enhanced/issues/515), [#517](https://github.com/shd101wyy/markdown-preview-enhanced/issues/517). + * Fixed `webview.ts` `clickTagA` action bug [503](https://github.com/shd101wyy/markdown-preview-enhanced/issues/503). diff --git a/docs/welcome.md b/docs/welcome.md index 8246b28..7559ec0 100644 --- a/docs/welcome.md +++ b/docs/welcome.md @@ -7,6 +7,7 @@ @import "https://user-images.githubusercontent.com/1908863/28734960-d71fb3dc-73a8-11e7-8555-847373d1ed0f.gif" {width: 500, style: "position:relative; left: 50%; transform: translateX(-50%);"}
+English 简体中文 @@ -24,4 +25,4 @@
Released under the University of Illinois/NCSA Open Source License
Copyright © 2015-2017 Yiyi Wang - \ No newline at end of file + diff --git a/package.json b/package.json index 1bb7812..17617a6 100644 --- a/package.json +++ b/package.json @@ -398,11 +398,13 @@ } }, "scripts": { - "vscode:prepublish": "tsc -p ./", - "compile": "tsc -watch -p ./", + "lint": "tsc --project . --noEmit && tslint --project . && prettier-check --ignore-path .gitignore \"{.,docs/**,src/**,test/**}/{*.{j,t}s,*.md,ts*.json}\"", + "format": "prettier --write --ignore-path .gitignore \"{.,docs/**,src/**,test/**}/{*.{j,t}s,*.md,ts*.json}\"", + "vscode:prepublish": "npm run compile", + "compile": "tsc -p ./", + "watch": "tsc -watch -p ./", "postinstall": "node ./node_modules/vscode/bin/install", - "test": "node ./node_modules/vscode/bin/test", - "package": "vsce package" + "test": "npm run compile && node ./node_modules/vscode/bin/test" }, "dependencies": { "@shd101wyy/mume": "^0.3.2" @@ -413,6 +415,9 @@ "@types/node": "^9.3.0", "eslint": "^4.15.0", "mocha": "^4.1.0", + "prettier": "^1.11.1", + "prettier-check": "^2.0.0", + "tslint-config-prettier": "^1.10.0", "typescript": "^2.6.2", "vscode": "^1.1.13" } diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..1d5555b --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,4 @@ +module.exports = { + arrowParens: "always", + trailingComma: "all", +}; diff --git a/src/config.ts b/src/config.ts index 3265b90..2fa2852 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,83 +1,96 @@ -import * as vscode from "vscode" -import {MarkdownEngineConfig} from "@shd101wyy/mume" -import { MathRenderingOption } from "../../mume/out/src/markdown-engine-config"; +import { MarkdownEngineConfig } from "@shd101wyy/mume"; +import { MathRenderingOption } from "@shd101wyy/mume/out/src/markdown-engine-config"; +import * as vscode from "vscode"; export class MarkdownPreviewEnhancedConfig implements MarkdownEngineConfig { public static getCurrentConfig() { - return new MarkdownPreviewEnhancedConfig() + return new MarkdownPreviewEnhancedConfig(); } - public readonly usePandocParser: boolean - public readonly breakOnSingleNewLine: boolean - public readonly enableTypographer: boolean - public readonly enableWikiLinkSyntax: boolean - public readonly wikiLinkFileExtension: string - public readonly enableEmojiSyntax: boolean - public readonly enableExtendedTableSyntax: boolean - public readonly enableCriticMarkupSyntax: boolean - public readonly frontMatterRenderingOption:string - public readonly mathRenderingOption: MathRenderingOption - public readonly mathInlineDelimiters: Array- public readonly mathBlockDelimiters: Array - public readonly codeBlockTheme: string - public readonly mermaidTheme: string - public readonly previewTheme: string - public readonly revealjsTheme: string - public readonly protocolsWhiteList: string - public readonly imageFolderPath: string - public readonly imageUploader: string - public readonly printBackground: boolean - public readonly phantomPath: string - public readonly pandocPath: string - public readonly pandocMarkdownFlavor: string - public readonly pandocArguments: string[] - public readonly latexEngine: string - public readonly enableScriptExecution: boolean + public readonly usePandocParser: boolean; + public readonly breakOnSingleNewLine: boolean; + public readonly enableTypographer: boolean; + public readonly enableWikiLinkSyntax: boolean; + public readonly wikiLinkFileExtension: string; + public readonly enableEmojiSyntax: boolean; + public readonly enableExtendedTableSyntax: boolean; + public readonly enableCriticMarkupSyntax: boolean; + public readonly frontMatterRenderingOption: string; + public readonly mathRenderingOption: MathRenderingOption; + public readonly mathInlineDelimiters: string[][]; + public readonly mathBlockDelimiters: string[][]; + public readonly codeBlockTheme: string; + public readonly mermaidTheme: string; + public readonly previewTheme: string; + public readonly revealjsTheme: string; + public readonly protocolsWhiteList: string; + public readonly imageFolderPath: string; + public readonly imageUploader: string; + public readonly printBackground: boolean; + public readonly phantomPath: string; + public readonly pandocPath: string; + public readonly pandocMarkdownFlavor: string; + public readonly pandocArguments: string[]; + public readonly latexEngine: string; + public readonly enableScriptExecution: boolean; // preview config - public readonly scrollSync: boolean - public readonly liveUpdate: boolean + public readonly scrollSync: boolean; + public readonly liveUpdate: boolean; private constructor() { - const config = vscode.workspace.getConfiguration('markdown-preview-enhanced') + const config = vscode.workspace.getConfiguration( + "markdown-preview-enhanced", + ); - this.usePandocParser = config.get ('usePandocParser') - this.breakOnSingleNewLine = config.get ('breakOnSingleNewLine') - this.enableTypographer = config.get ('enableTypographer') - this.enableWikiLinkSyntax = config.get ('enableWikiLinkSyntax') - this.wikiLinkFileExtension = config.get ('wikiLinkFileExtension') - this.enableEmojiSyntax = config.get ('enableEmojiSyntax') - this.enableExtendedTableSyntax = config.get ('enableExtendedTableSyntax') - this.enableCriticMarkupSyntax = config.get ('enableCriticMarkupSyntax') - this.frontMatterRenderingOption = config.get ('frontMatterRenderingOption') - this.mermaidTheme = config.get ('mermaidTheme') - this.mathRenderingOption = config.get ('mathRenderingOption') as MathRenderingOption - this.mathInlineDelimiters = config.get >('mathInlineDelimiters') - this.mathBlockDelimiters = config.get >('mathBlockDelimiters') - this.codeBlockTheme = config.get ('codeBlockTheme') - this.previewTheme = config.get ('previewTheme') - this.revealjsTheme = config.get ('revealjsTheme') - this.protocolsWhiteList = config.get ('protocolsWhiteList') - this.imageFolderPath = config.get ('imageFolderPath') - this.imageUploader = config.get ('imageUploader') - this.printBackground = config.get ('printBackground') - this.phantomPath = config.get ('phantomPath') - this.pandocPath = config.get ('pandocPath') - this.pandocMarkdownFlavor = config.get ('pandocMarkdownFlavor') - this.pandocArguments = config.get ('pandocArguments').split(',').map((x)=> x.trim()) - this.latexEngine = config.get ('latexEngine') - this.enableScriptExecution = config.get ('enableScriptExecution') + this.usePandocParser = config.get ("usePandocParser"); + this.breakOnSingleNewLine = config.get ("breakOnSingleNewLine"); + this.enableTypographer = config.get ("enableTypographer"); + this.enableWikiLinkSyntax = config.get ("enableWikiLinkSyntax"); + this.wikiLinkFileExtension = config.get ("wikiLinkFileExtension"); + this.enableEmojiSyntax = config.get ("enableEmojiSyntax"); + this.enableExtendedTableSyntax = config.get ( + "enableExtendedTableSyntax", + ); + this.enableCriticMarkupSyntax = config.get ( + "enableCriticMarkupSyntax", + ); + this.frontMatterRenderingOption = config.get ( + "frontMatterRenderingOption", + ); + this.mermaidTheme = config.get ("mermaidTheme"); + this.mathRenderingOption = config.get ( + "mathRenderingOption", + ) as MathRenderingOption; + this.mathInlineDelimiters = config.get ("mathInlineDelimiters"); + this.mathBlockDelimiters = config.get ("mathBlockDelimiters"); + this.codeBlockTheme = config.get ("codeBlockTheme"); + this.previewTheme = config.get ("previewTheme"); + this.revealjsTheme = config.get ("revealjsTheme"); + this.protocolsWhiteList = config.get ("protocolsWhiteList"); + this.imageFolderPath = config.get ("imageFolderPath"); + this.imageUploader = config.get ("imageUploader"); + this.printBackground = config.get ("printBackground"); + this.phantomPath = config.get ("phantomPath"); + this.pandocPath = config.get ("pandocPath"); + this.pandocMarkdownFlavor = config.get ("pandocMarkdownFlavor"); + this.pandocArguments = config + .get ("pandocArguments") + .split(",") + .map((x) => x.trim()); + this.latexEngine = config.get ("latexEngine"); + this.enableScriptExecution = config.get ("enableScriptExecution"); - this.scrollSync = config.get ('scrollSync') - this.liveUpdate = config.get ('liveUpdate') + this.scrollSync = config.get ("scrollSync"); + this.liveUpdate = config.get ("liveUpdate"); } public isEqualTo(otherConfig: MarkdownPreviewEnhancedConfig) { - const json1 = JSON.stringify(this) - const json2 = JSON.stringify(otherConfig) - return json1 === json2 + const json1 = JSON.stringify(this); + const json2 = JSON.stringify(otherConfig); + return json1 === json2; - // this is not good because sometimes this[key] is of array type + // this is not good because sometimes this[key] is of array type /* for (let key in this) { if (this.hasOwnProperty(key)) { @@ -89,5 +102,5 @@ export class MarkdownPreviewEnhancedConfig implements MarkdownEngineConfig { */ } - [key: string]: any + [key: string]: any; } diff --git a/src/extension.ts b/src/extension.ts index 32c474f..7ac7b89 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,33 +1,39 @@ // 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 * as path from "path" -import * as fs from "fs" +import * as path from "path"; +import * as vscode from "vscode"; -import {utility} from "@shd101wyy/mume" +import { utility } from "@shd101wyy/mume"; -import {MarkdownPreviewEnhancedView, getPreviewUri, isMarkdownFile, useSinglePreview} from "./preview-content-provider" -import {uploadImageFile, pasteImageFile} from "./image-helper" +import { pasteImageFile, uploadImageFile } from "./image-helper"; +import { + getPreviewUri, + isMarkdownFile, + MarkdownPreviewEnhancedView, + useSinglePreview, +} from "./preview-content-provider"; // this method is called when your extension iopenTextDocuments activated // your extension is activated the very first time the command is executed export function activate(context: vscode.ExtensionContext) { - // assume only one preview supported. - const extensionPath = context.extensionPath - - const contentProvider = new MarkdownPreviewEnhancedView(context) - const contentProviderRegistration = vscode.workspace.registerTextDocumentContentProvider('markdown-preview-enhanced', contentProvider) - - function openPreview(uri?: vscode.Uri) { - let resource = uri - if (!(resource instanceof vscode.Uri)) { - if (vscode.window.activeTextEditor) { - // we are relaxed and don't check for markdown files - resource = vscode.window.activeTextEditor.document.uri - } - } + // assume only one preview supported. + + const contentProvider = new MarkdownPreviewEnhancedView(context); + const contentProviderRegistration = vscode.workspace.registerTextDocumentContentProvider( + "markdown-preview-enhanced", + contentProvider, + ); + + function openPreview(uri?: vscode.Uri) { + let resource = uri; + if (!(resource instanceof vscode.Uri)) { + if (vscode.window.activeTextEditor) { + // we are relaxed and don't check for markdown files + resource = vscode.window.activeTextEditor.document.uri; + } + } - /* + /* if (!(resource instanceof vscode.Uri)) { if (!vscode.window.activeTextEditor) { // this is most likely toggling the preview @@ -38,487 +44,754 @@ export function activate(context: vscode.ExtensionContext) { } */ - - /* + /* if (contentProvider.isPreviewOn(vscode.window.activeTextEditor)) { // return vscode.commands.executeCommand('workbench.action.closeActiveEditor', markdownURI) } else { } */ - const previewUri = getPreviewUri(resource) - return vscode.commands.executeCommand( - 'vscode.previewHtml', - previewUri, - vscode.ViewColumn.Two, - useSinglePreview() ? 'MPE Preview' : `Preview '${path.basename(resource.fsPath)}'`) - .then((success)=> { - // contentProvider.update(previewUri) - // the line above is changed to webviewFinishLoading function. - }, (reason)=> { - vscode.window.showErrorMessage(reason) - }) - } - - function toggleScrollSync() { - const config = vscode.workspace.getConfiguration('markdown-preview-enhanced') - const scrollSync = !config.get ('scrollSync') - config.update('scrollSync', scrollSync, true).then(()=> { - contentProvider.updateConfiguration() - if (scrollSync) { - vscode.window.showInformationMessage('Scroll Sync is enabled') - } else { - vscode.window.showInformationMessage('Scroll Sync is disabled') - } - }) - } - - function toggleLiveUpdate() { - const config = vscode.workspace.getConfiguration('markdown-preview-enhanced') - const liveUpdate = !config.get ('liveUpdate') - config.update('liveUpdate', liveUpdate, true).then(()=> { - contentProvider.updateConfiguration() - if (liveUpdate) { - vscode.window.showInformationMessage('Live Update is enabled') - } else { - vscode.window.showInformationMessage('Live Update is disabled') - } - }) - } - - function toggleBreakOnSingleNewLine() { - const config = vscode.workspace.getConfiguration('markdown-preview-enhanced') - const breakOnSingleNewLine = !config.get ('breakOnSingleNewLine') - config.update('breakOnSingleNewLine', breakOnSingleNewLine, true).then(()=> { - contentProvider.updateConfiguration() - if (breakOnSingleNewLine) { - vscode.window.showInformationMessage('Break On Single New Line is enabled') - } else { - vscode.window.showInformationMessage('Break On Single New Line is disabled') - } - }) - } - - function customizeCSS() { - const globalStyleLessFile = utility.addFileProtocol(path.resolve(utility.extensionConfigDirectoryPath, './style.less')) - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(globalStyleLessFile)) - } - - function openMermaidConfig() { - const mermaidConfigFilePath = utility.addFileProtocol(path.resolve(utility.extensionConfigDirectoryPath, './mermaid_config.js')) - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(mermaidConfigFilePath)) - } - - function openMathJaxConfig() { - const mathjaxConfigFilePath = utility.addFileProtocol(path.resolve(utility.extensionConfigDirectoryPath, './mathjax_config.js')) - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(mathjaxConfigFilePath)) - } - - function openPhantomJSConfig() { - const phantomjsConfigFilePath = utility.addFileProtocol(path.resolve(utility.extensionConfigDirectoryPath, './phantomjs_config.js')) - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(phantomjsConfigFilePath)) - } - - function extendParser() { - const parserConfigPath = utility.addFileProtocol(path.resolve(utility.extensionConfigDirectoryPath, './parser.js')) - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(parserConfigPath)) - } - - function showUploadedImages() { - const imageHistoryFilePath = utility.addFileProtocol(path.resolve(utility.extensionConfigDirectoryPath, './image_history.md')) - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(imageHistoryFilePath)) - } - - function insertNewSlide() { - const editor = vscode.window.activeTextEditor - if (editor && editor.document && editor.edit) { - editor.edit((textEdit)=> { - textEdit.insert(editor.selection.active, '\n') - }) - } - } - - function insertPagebreak() { - const editor = vscode.window.activeTextEditor - if (editor && editor.document && editor.edit) { - editor.edit((textEdit)=> { - textEdit.insert(editor.selection.active, '\n') - }) - } - } - - function createTOC() { - const editor = vscode.window.activeTextEditor - if (editor && editor.document && editor.edit) { - editor.edit((textEdit)=> { - textEdit.insert(editor.selection.active, '\n\n') - }) - } - } - - function insertTable() { - const editor = vscode.window.activeTextEditor - if (editor && editor.document && editor.edit) { - editor.edit((textEdit)=> { - textEdit.insert(editor.selection.active, -`| | | + const previewUri = getPreviewUri(resource); + return vscode.commands + .executeCommand( + "vscode.previewHtml", + previewUri, + vscode.ViewColumn.Two, + useSinglePreview() + ? "MPE Preview" + : `Preview '${path.basename(resource.fsPath)}'`, + ) + .then( + (success) => { + // contentProvider.update(previewUri) + // the line above is changed to webviewFinishLoading function. + }, + (reason) => { + vscode.window.showErrorMessage(reason); + }, + ); + } + + function toggleScrollSync() { + const config = vscode.workspace.getConfiguration( + "markdown-preview-enhanced", + ); + const scrollSync = !config.get ("scrollSync"); + config.update("scrollSync", scrollSync, true).then(() => { + contentProvider.updateConfiguration(); + if (scrollSync) { + vscode.window.showInformationMessage("Scroll Sync is enabled"); + } else { + vscode.window.showInformationMessage("Scroll Sync is disabled"); + } + }); + } + + function toggleLiveUpdate() { + const config = vscode.workspace.getConfiguration( + "markdown-preview-enhanced", + ); + const liveUpdate = !config.get ("liveUpdate"); + config.update("liveUpdate", liveUpdate, true).then(() => { + contentProvider.updateConfiguration(); + if (liveUpdate) { + vscode.window.showInformationMessage("Live Update is enabled"); + } else { + vscode.window.showInformationMessage("Live Update is disabled"); + } + }); + } + + function toggleBreakOnSingleNewLine() { + const config = vscode.workspace.getConfiguration( + "markdown-preview-enhanced", + ); + const breakOnSingleNewLine = !config.get ("breakOnSingleNewLine"); + config + .update("breakOnSingleNewLine", breakOnSingleNewLine, true) + .then(() => { + contentProvider.updateConfiguration(); + if (breakOnSingleNewLine) { + vscode.window.showInformationMessage( + "Break On Single New Line is enabled", + ); + } else { + vscode.window.showInformationMessage( + "Break On Single New Line is disabled", + ); + } + }); + } + + function customizeCSS() { + const globalStyleLessFile = utility.addFileProtocol( + path.resolve(utility.extensionConfigDirectoryPath, "./style.less"), + ); + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse(globalStyleLessFile), + ); + } + + function openMermaidConfig() { + const mermaidConfigFilePath = utility.addFileProtocol( + path.resolve(utility.extensionConfigDirectoryPath, "./mermaid_config.js"), + ); + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse(mermaidConfigFilePath), + ); + } + + function openMathJaxConfig() { + const mathjaxConfigFilePath = utility.addFileProtocol( + path.resolve(utility.extensionConfigDirectoryPath, "./mathjax_config.js"), + ); + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse(mathjaxConfigFilePath), + ); + } + + function openPhantomJSConfig() { + const phantomjsConfigFilePath = utility.addFileProtocol( + path.resolve( + utility.extensionConfigDirectoryPath, + "./phantomjs_config.js", + ), + ); + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse(phantomjsConfigFilePath), + ); + } + + function extendParser() { + const parserConfigPath = utility.addFileProtocol( + path.resolve(utility.extensionConfigDirectoryPath, "./parser.js"), + ); + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse(parserConfigPath), + ); + } + + function showUploadedImages() { + const imageHistoryFilePath = utility.addFileProtocol( + path.resolve(utility.extensionConfigDirectoryPath, "./image_history.md"), + ); + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse(imageHistoryFilePath), + ); + } + + function insertNewSlide() { + const editor = vscode.window.activeTextEditor; + if (editor && editor.document && editor.edit) { + editor.edit((textEdit) => { + textEdit.insert(editor.selection.active, "\n"); + }); + } + } + + function insertPagebreak() { + const editor = vscode.window.activeTextEditor; + if (editor && editor.document && editor.edit) { + editor.edit((textEdit) => { + textEdit.insert(editor.selection.active, "\n"); + }); + } + } + + function createTOC() { + const editor = vscode.window.activeTextEditor; + if (editor && editor.document && editor.edit) { + editor.edit((textEdit) => { + textEdit.insert( + editor.selection.active, + '\n\n', + ); + }); + } + } + + function insertTable() { + const editor = vscode.window.activeTextEditor; + if (editor && editor.document && editor.edit) { + editor.edit((textEdit) => { + textEdit.insert( + editor.selection.active, + `| | | |---|---| | | | -`) - }) - } - } - - function openImageHelper() { - contentProvider.openImageHelper(vscode.window.activeTextEditor.document.uri) - } - - function webviewFinishLoading(uri) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.updateMarkdown(sourceUri) - } - - /** - * Insert imageUrl to markdown file - * @param uri: markdown source uri - * @param imageUrl: url of image to be inserted - */ - function insertImageUrl(uri, imageUrl) { - const sourceUri = vscode.Uri.parse(uri) - - vscode.window.visibleTextEditors - .filter(editor => isMarkdownFile(editor.document) && editor.document.uri.fsPath === sourceUri.fsPath) - .forEach(editor => { - // const line = editor.selection.active.line - editor.edit((textEditorEdit)=> { - textEditorEdit.insert(editor.selection.active, `![enter image description here](${imageUrl})`) - }) - }) - } - - function refreshPreview(uri) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.refreshPreview(sourceUri) - } - - function openInBrowser(uri) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.openInBrowser(sourceUri) - } - - function htmlExport(uri, offline) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.htmlExport(sourceUri, offline) - } - - function chromeExport(uri, type) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.chromeExport(sourceUri, type) - } - - function phantomjsExport(uri, type) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.phantomjsExport(sourceUri, type) - } - - function princeExport(uri) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.princeExport(sourceUri) - } - - function eBookExport(uri, fileType) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.eBookExport(sourceUri, fileType) - } - - function pandocExport(uri) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.pandocExport(sourceUri) - } - - function markdownExport(uri) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.markdownExport(sourceUri) - } - - /* +`, + ); + }); + } + } + + function openImageHelper() { + contentProvider.openImageHelper( + vscode.window.activeTextEditor.document.uri, + ); + } + + function webviewFinishLoading(uri) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.updateMarkdown(sourceUri); + } + + /** + * Insert imageUrl to markdown file + * @param uri: markdown source uri + * @param imageUrl: url of image to be inserted + */ + function insertImageUrl(uri, imageUrl) { + const sourceUri = vscode.Uri.parse(uri); + + vscode.window.visibleTextEditors + .filter( + (editor) => + isMarkdownFile(editor.document) && + editor.document.uri.fsPath === sourceUri.fsPath, + ) + .forEach((editor) => { + // const line = editor.selection.active.line + editor.edit((textEditorEdit) => { + textEditorEdit.insert( + editor.selection.active, + `![enter image description here](${imageUrl})`, + ); + }); + }); + } + + function refreshPreview(uri) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.refreshPreview(sourceUri); + } + + function openInBrowser(uri) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.openInBrowser(sourceUri); + } + + function htmlExport(uri, offline) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.htmlExport(sourceUri, offline); + } + + function chromeExport(uri, type) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.chromeExport(sourceUri, type); + } + + function phantomjsExport(uri, type) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.phantomjsExport(sourceUri, type); + } + + function princeExport(uri) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.princeExport(sourceUri); + } + + function eBookExport(uri, fileType) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.eBookExport(sourceUri, fileType); + } + + function pandocExport(uri) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.pandocExport(sourceUri); + } + + function markdownExport(uri) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.markdownExport(sourceUri); + } + + /* function cacheSVG(uri, code, svg) { const sourceUri = vscode.Uri.parse(uri); contentProvider.cacheSVG(sourceUri, code, svg) } */ - function cacheCodeChunkResult(uri, id, result) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.cacheCodeChunkResult(sourceUri, id, result) - } - - function runCodeChunk(uri, codeChunkId) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.runCodeChunk(sourceUri, codeChunkId) - } - - function runAllCodeChunks(uri) { - const sourceUri = vscode.Uri.parse(uri) - contentProvider.runAllCodeChunks(sourceUri) - } - - function runAllCodeChunksCommand() { - const textEditor = vscode.window.activeTextEditor - if (!textEditor.document) return - if (!isMarkdownFile(textEditor.document)) return - - const previewUri = getPreviewUri(textEditor.document.uri) - if (!previewUri) return - - vscode.commands.executeCommand('_workbench.htmlPreview.postMessage', - previewUri, - { - command: 'runAllCodeChunks' - }) - } - - function runCodeChunkCommand() { - const textEditor = vscode.window.activeTextEditor - if (!textEditor.document) return - if (!isMarkdownFile(textEditor.document)) return - - const previewUri = getPreviewUri(textEditor.document.uri) - if (!previewUri) return - - vscode.commands.executeCommand('_workbench.htmlPreview.postMessage', - previewUri, - { - command: 'runCodeChunk' - }) - } - - function syncPreview() { - const textEditor = vscode.window.activeTextEditor - if (!textEditor.document) return - if (!isMarkdownFile(textEditor.document)) return - - const previewUri = getPreviewUri(textEditor.document.uri) - if (!previewUri) return - - vscode.commands.executeCommand('_workbench.htmlPreview.postMessage', - previewUri, - { - command: 'changeTextEditorSelection', - line: textEditor.selections[0].active.line, - forced: true - }) - } - - function clickTagA(uri, href) { - const sourceUri = vscode.Uri.parse(uri) - href = decodeURIComponent(href) - if (['.pdf', '.xls', '.xlsx', '.doc', '.ppt', '.docx', '.pptx'].indexOf(path.extname(href)) >= 0) { - utility.openFile(href) - } else if (href.match(/^file\:\/\/\//)) { - // openFilePath = href.slice(8) # remove protocal - let openFilePath = utility.addFileProtocol(href.replace(/(\s*)[\#\?](.+)$/, '')) // remove #anchor and ?params... - openFilePath = decodeURI(openFilePath) - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(openFilePath), vscode.ViewColumn.One) - } else { - utility.openFile(href) - } - } - - function clickTaskListCheckbox(uri, dataLine) { - const sourceUri = vscode.Uri.parse(uri) - const visibleTextEditors = vscode.window.visibleTextEditors + function cacheCodeChunkResult(uri, id, result) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.cacheCodeChunkResult(sourceUri, id, result); + } + + function runCodeChunk(uri, codeChunkId) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.runCodeChunk(sourceUri, codeChunkId); + } + + function runAllCodeChunks(uri) { + const sourceUri = vscode.Uri.parse(uri); + contentProvider.runAllCodeChunks(sourceUri); + } + + function runAllCodeChunksCommand() { + const textEditor = vscode.window.activeTextEditor; + if (!textEditor.document) { + return; + } + if (!isMarkdownFile(textEditor.document)) { + return; + } + + const previewUri = getPreviewUri(textEditor.document.uri); + if (!previewUri) { + return; + } + + vscode.commands.executeCommand( + "_workbench.htmlPreview.postMessage", + previewUri, + { + command: "runAllCodeChunks", + }, + ); + } + + function runCodeChunkCommand() { + const textEditor = vscode.window.activeTextEditor; + if (!textEditor.document) { + return; + } + if (!isMarkdownFile(textEditor.document)) { + return; + } + + const previewUri = getPreviewUri(textEditor.document.uri); + if (!previewUri) { + return; + } + + vscode.commands.executeCommand( + "_workbench.htmlPreview.postMessage", + previewUri, + { + command: "runCodeChunk", + }, + ); + } + + function syncPreview() { + const textEditor = vscode.window.activeTextEditor; + if (!textEditor.document) { + return; + } + if (!isMarkdownFile(textEditor.document)) { + return; + } + + const previewUri = getPreviewUri(textEditor.document.uri); + if (!previewUri) { + return; + } + + vscode.commands.executeCommand( + "_workbench.htmlPreview.postMessage", + previewUri, + { + command: "changeTextEditorSelection", + line: textEditor.selections[0].active.line, + forced: true, + }, + ); + } + + function clickTagA(uri, href) { + href = decodeURIComponent(href); + if ( + [".pdf", ".xls", ".xlsx", ".doc", ".ppt", ".docx", ".pptx"].indexOf( + path.extname(href), + ) >= 0 + ) { + utility.openFile(href); + } else if (href.match(/^file\:\/\/\//)) { + // openFilePath = href.slice(8) # remove protocol + let openFilePath = utility.addFileProtocol( + href.replace(/(\s*)[\#\?](.+)$/, ""), + ); // remove #anchor and ?params... + openFilePath = decodeURI(openFilePath); + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse(openFilePath), + vscode.ViewColumn.One, + ); + } else { + utility.openFile(href); + } + } + + function clickTaskListCheckbox(uri, dataLine) { + const sourceUri = vscode.Uri.parse(uri); + const visibleTextEditors = vscode.window.visibleTextEditors; for (let i = 0; i < visibleTextEditors.length; i++) { - const editor = visibleTextEditors[i] + const editor = visibleTextEditors[i]; if (editor.document.uri.fsPath === sourceUri.fsPath) { - dataLine = parseInt(dataLine) - editor.edit((edit)=> { - let line = editor.document.lineAt(dataLine).text - if (line.match(/\[ \]/)) { - line = line.replace('[ ]', '[x]') - } else { - line = line.replace(/\[[xX]\]/, '[ ]') - } - edit.replace(new vscode.Range( - new vscode.Position(dataLine, 0), - new vscode.Position(dataLine, line.length) - ), line) - }) - break - } - } - } - - context.subscriptions.push(vscode.workspace.onDidSaveTextDocument(document => { - if (isMarkdownFile(document)) { - // contentProvider.update(document.uri, true); - contentProvider.updateMarkdown(document.uri, true) - } - })) - - context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(event => { - if (isMarkdownFile(event.document)) { - contentProvider.update(event.document.uri) - } - })) - - context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => { - contentProvider.updateConfiguration() - })) - - context.subscriptions.push(vscode.window.onDidChangeTextEditorSelection(event => { - if (isMarkdownFile(event.textEditor.document)) { - const previewUri = getPreviewUri(event.textEditor.document.uri) - vscode.commands.executeCommand('_workbench.htmlPreview.postMessage', - previewUri, - { - command: 'changeTextEditorSelection', - line: event.selections[0].active.line - }) + dataLine = parseInt(dataLine, 10); + editor.edit((edit) => { + let line = editor.document.lineAt(dataLine).text; + if (line.match(/\[ \]/)) { + line = line.replace("[ ]", "[x]"); + } else { + line = line.replace(/\[[xX]\]/, "[ ]"); + } + edit.replace( + new vscode.Range( + new vscode.Position(dataLine, 0), + new vscode.Position(dataLine, line.length), + ), + line, + ); + }); + break; } - })) - - /** - * Open preview automatically if the `automaticallyShowPreviewOfMarkdownBeingEdited` is on. - * @param textEditor - */ - context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor((textEditor)=> { - if (textEditor && textEditor.document && textEditor.document.uri) { - // console.log('onDidChangeActiveTextEditor', textEditor.document.uri) - if (isMarkdownFile(textEditor.document)) { - const sourceUri = textEditor.document.uri - /** - * Is using single preview and the preview is on. - * When we switched text editor, update preview to that text editor. - */ - if (useSinglePreview() && contentProvider.isPreviewOn(sourceUri)) { - contentProvider.initMarkdownEngine(sourceUri) - contentProvider.updateMarkdown(sourceUri) - } - } - } else { - // console.log('onDidChangeActiveTextEditor', ' preview', textEditor) - } - })) + } + } + + context.subscriptions.push( + vscode.workspace.onDidSaveTextDocument((document) => { + if (isMarkdownFile(document)) { + // contentProvider.update(document.uri, true); + contentProvider.updateMarkdown(document.uri, true); + } + }), + ); - context.subscriptions.push(vscode.workspace.onDidCloseTextDocument(textDocument=> { - // console.log('onDidCloseTextDocument', textDocument.uri) - if (textDocument && textDocument.uri.scheme === 'markdown-preview-enhanced') { - contentProvider.destroyEngine(textDocument.uri) - } - })) + context.subscriptions.push( + vscode.workspace.onDidChangeTextDocument((event) => { + if (isMarkdownFile(event.document)) { + contentProvider.update(event.document.uri); + } + }), + ); + + context.subscriptions.push( + vscode.workspace.onDidChangeConfiguration(() => { + contentProvider.updateConfiguration(); + }), + ); + + context.subscriptions.push( + vscode.window.onDidChangeTextEditorSelection((event) => { + if (isMarkdownFile(event.textEditor.document)) { + const previewUri = getPreviewUri(event.textEditor.document.uri); + vscode.commands.executeCommand( + "_workbench.htmlPreview.postMessage", + previewUri, + { + command: "changeTextEditorSelection", + line: event.selections[0].active.line, + }, + ); + } + }), + ); + + /** + * Open preview automatically if the `automaticallyShowPreviewOfMarkdownBeingEdited` is on. + * @param textEditor + */ + context.subscriptions.push( + vscode.window.onDidChangeActiveTextEditor((textEditor) => { + if (textEditor && textEditor.document && textEditor.document.uri) { + // console.log('onDidChangeActiveTextEditor', textEditor.document.uri) + if (isMarkdownFile(textEditor.document)) { + const sourceUri = textEditor.document.uri; + /** + * Is using single preview and the preview is on. + * When we switched text editor, update preview to that text editor. + */ + if (useSinglePreview() && contentProvider.isPreviewOn(sourceUri)) { + contentProvider.initMarkdownEngine(sourceUri); + contentProvider.updateMarkdown(sourceUri); + } + } + } else { + // console.log('onDidChangeActiveTextEditor', ' preview', textEditor) + } + }), + ); + + context.subscriptions.push( + vscode.workspace.onDidCloseTextDocument((textDocument) => { + // console.log('onDidCloseTextDocument', textDocument.uri) + if ( + textDocument && + textDocument.uri.scheme === "markdown-preview-enhanced" + ) { + contentProvider.destroyEngine(textDocument.uri); + } + }), + ); - /* + /* context.subscriptions.push(vscode.workspace.onDidOpenTextDocument((textDocument)=> { // console.log('onDidOpenTextDocument', textDocument.uri) })) */ - - /* + /* context.subscriptions.push(vscode.window.onDidChangeVisibleTextEditors(textEditors=> { // console.log('onDidChangeonDidChangeVisibleTextEditors ', textEditors) })) */ - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.openPreview', openPreview)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.toggleScrollSync', toggleScrollSync)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.toggleLiveUpdate', toggleLiveUpdate)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.toggleBreakOnSingleNewLine', toggleBreakOnSingleNewLine)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.openImageHelper', openImageHelper)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.runAllCodeChunks', runAllCodeChunksCommand)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.runCodeChunk', runCodeChunkCommand)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.syncPreview', syncPreview)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.customizeCss', customizeCSS)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.openMermaidConfig', openMermaidConfig)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.openMathJaxConfig', openMathJaxConfig)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.openPhantomJSConfig', openPhantomJSConfig)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.extendParser', extendParser)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.showUploadedImages', showUploadedImages)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.insertNewSlide', insertNewSlide)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.insertTable', insertTable)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.insertPagebreak', insertPagebreak)) - - context.subscriptions.push(vscode.commands.registerCommand('markdown-preview-enhanced.createTOC', createTOC)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.revealLine', revealLine)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.insertImageUrl', insertImageUrl)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.pasteImageFile', pasteImageFile)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.uploadImageFile', uploadImageFile)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.refreshPreview', refreshPreview)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.openInBrowser', openInBrowser)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.htmlExport', htmlExport)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.chromeExport', chromeExport)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.phantomjsExport', phantomjsExport)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.princeExport', princeExport)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.eBookExport', eBookExport)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.pandocExport', pandocExport)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.markdownExport', markdownExport)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.webviewFinishLoading', webviewFinishLoading)) + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.openPreview", + openPreview, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.toggleScrollSync", + toggleScrollSync, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.toggleLiveUpdate", + toggleLiveUpdate, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.toggleBreakOnSingleNewLine", + toggleBreakOnSingleNewLine, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.openImageHelper", + openImageHelper, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.runAllCodeChunks", + runAllCodeChunksCommand, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.runCodeChunk", + runCodeChunkCommand, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.syncPreview", + syncPreview, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.customizeCss", + customizeCSS, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.openMermaidConfig", + openMermaidConfig, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.openMathJaxConfig", + openMathJaxConfig, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.openPhantomJSConfig", + openPhantomJSConfig, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.extendParser", + extendParser, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.showUploadedImages", + showUploadedImages, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.insertNewSlide", + insertNewSlide, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.insertTable", + insertTable, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.insertPagebreak", + insertPagebreak, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "markdown-preview-enhanced.createTOC", + createTOC, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.revealLine", revealLine), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.insertImageUrl", insertImageUrl), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.pasteImageFile", pasteImageFile), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.uploadImageFile", uploadImageFile), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.refreshPreview", refreshPreview), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.openInBrowser", openInBrowser), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.htmlExport", htmlExport), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.chromeExport", chromeExport), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.phantomjsExport", phantomjsExport), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.princeExport", princeExport), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.eBookExport", eBookExport), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.pandocExport", pandocExport), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.markdownExport", markdownExport), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "_mume.webviewFinishLoading", + webviewFinishLoading, + ), + ); // context.subscriptions.push(vscode.commands.registerCommand('_mume.cacheSVG', cacheSVG)) - context.subscriptions.push(vscode.commands.registerCommand('_mume.cacheCodeChunkResult', cacheCodeChunkResult)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.runCodeChunk', runCodeChunk)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.runAllCodeChunks', runAllCodeChunks)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.clickTagA', clickTagA)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.clickTaskListCheckbox', clickTaskListCheckbox)) - - context.subscriptions.push(vscode.commands.registerCommand('_mume.showUploadedImageHistory', showUploadedImages)) - - context.subscriptions.push(contentProviderRegistration) + context.subscriptions.push( + vscode.commands.registerCommand( + "_mume.cacheCodeChunkResult", + cacheCodeChunkResult, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.runCodeChunk", runCodeChunk), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.runAllCodeChunks", runAllCodeChunks), + ); + + context.subscriptions.push( + vscode.commands.registerCommand("_mume.clickTagA", clickTagA), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "_mume.clickTaskListCheckbox", + clickTaskListCheckbox, + ), + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "_mume.showUploadedImageHistory", + showUploadedImages, + ), + ); + + context.subscriptions.push(contentProviderRegistration); } - function revealLine(uri, line) { - const sourceUri = vscode.Uri.parse(uri) - - vscode.window.visibleTextEditors - .filter(editor => isMarkdownFile(editor.document) && editor.document.uri.fsPath === sourceUri.fsPath) - .forEach(editor => { - const sourceLine = Math.min(Math.floor(line), editor.document.lineCount - 1) - const fraction = line - sourceLine - const text = editor.document.lineAt(sourceLine).text - const start = Math.floor(fraction * text.length) - editor.revealRange( - new vscode.Range(sourceLine, start, sourceLine + 1, 0), - vscode.TextEditorRevealType.InCenter) - }) + const sourceUri = vscode.Uri.parse(uri); + + vscode.window.visibleTextEditors + .filter( + (editor) => + isMarkdownFile(editor.document) && + editor.document.uri.fsPath === sourceUri.fsPath, + ) + .forEach((editor) => { + const sourceLine = Math.min( + Math.floor(line), + editor.document.lineCount - 1, + ); + const fraction = line - sourceLine; + const text = editor.document.lineAt(sourceLine).text; + const start = Math.floor(fraction * text.length); + editor.revealRange( + new vscode.Range(sourceLine, start, sourceLine + 1, 0), + vscode.TextEditorRevealType.InCenter, + ); + }); } // this method is called when your extension is deactivated export function deactivate() { + // } diff --git a/src/image-helper.ts b/src/image-helper.ts index cdbcb0c..9fdcda9 100644 --- a/src/image-helper.ts +++ b/src/image-helper.ts @@ -1,147 +1,220 @@ -import * as vscode from "vscode" -import * as path from "path" -import * as fs from "fs" -import {utility} from "@shd101wyy/mume" +import { utility } from "@shd101wyy/mume"; +import * as fs from "fs"; +import * as path from "path"; +import * as vscode from "vscode"; -import {isMarkdownFile} from "./preview-content-provider" +import { isMarkdownFile } from "./preview-content-provider"; /** * Copy ans paste image at imageFilePath to config.imageForlderPath. * Then insert markdown image url to markdown file. - * @param uri - * @param imageFilePath + * @param uri + * @param imageFilePath */ export function pasteImageFile(sourceUri: any, imageFilePath: string) { - if (typeof (sourceUri) === 'string') { - sourceUri = vscode.Uri.parse(sourceUri) + if (typeof sourceUri === "string") { + sourceUri = vscode.Uri.parse(sourceUri); } - const imageFolderPath = vscode.workspace.getConfiguration('markdown-preview-enhanced').get < string > ('imageFolderPath') - let imageFileName = path.basename(imageFilePath) - const projectDirectoryPath = vscode.workspace.rootPath - let assetDirectoryPath, description - if (imageFolderPath[0] === '/') { - assetDirectoryPath = path.resolve(projectDirectoryPath, '.' + imageFolderPath) + const imageFolderPath = vscode.workspace + .getConfiguration("markdown-preview-enhanced") + .get ("imageFolderPath"); + let imageFileName = path.basename(imageFilePath); + const projectDirectoryPath = vscode.workspace.rootPath; + let assetDirectoryPath; + let description; + if (imageFolderPath[0] === "/") { + assetDirectoryPath = path.resolve( + projectDirectoryPath, + "." + imageFolderPath, + ); } else { - assetDirectoryPath = path.resolve(path.dirname(sourceUri.fsPath), imageFolderPath) + assetDirectoryPath = path.resolve( + path.dirname(sourceUri.fsPath), + imageFolderPath, + ); } - const destPath = path.resolve(assetDirectoryPath, path.basename(imageFilePath)) + const destPath = path.resolve( + assetDirectoryPath, + path.basename(imageFilePath), + ); vscode.window.visibleTextEditors - .filter(editor => isMarkdownFile(editor.document) && editor.document.uri.fsPath === sourceUri.fsPath) - .forEach(editor => { - + .filter( + (editor) => + isMarkdownFile(editor.document) && + editor.document.uri.fsPath === sourceUri.fsPath, + ) + .forEach((editor) => { fs.mkdir(assetDirectoryPath, (error) => { fs.stat(destPath, (err, stat) => { - if (err == null) { // file existed - const lastDotOffset = imageFileName.lastIndexOf('.') - const uid = '_' + Math.random().toString(36).substr(2, 9) + if (err == null) { + // file existed + const lastDotOffset = imageFileName.lastIndexOf("."); + const uid = + "_" + + Math.random() + .toString(36) + .substr(2, 9); if (lastDotOffset > 0) { - description = imageFileName.slice(0, lastDotOffset) - imageFileName = imageFileName.slice(0, lastDotOffset) + uid + imageFileName.slice(lastDotOffset, imageFileName.length) + description = imageFileName.slice(0, lastDotOffset); + imageFileName = + imageFileName.slice(0, lastDotOffset) + + uid + + imageFileName.slice(lastDotOffset, imageFileName.length); } else { - description = imageFileName - imageFileName = imageFileName + uid + description = imageFileName; + imageFileName = imageFileName + uid; } - fs.createReadStream(imageFilePath).pipe(fs.createWriteStream(path.resolve(assetDirectoryPath, imageFileName))) - } else if (err.code === 'ENOENT') { // file doesn't exist - fs.createReadStream(imageFilePath).pipe(fs.createWriteStream(destPath)) - - if (imageFileName.lastIndexOf('.')) - description = imageFileName.slice(0, imageFileName.lastIndexOf('.')) - else - description = imageFileName + fs + .createReadStream(imageFilePath) + .pipe( + fs.createWriteStream( + path.resolve(assetDirectoryPath, imageFileName), + ), + ); + } else if (err.code === "ENOENT") { + // file doesn't exist + fs + .createReadStream(imageFilePath) + .pipe(fs.createWriteStream(destPath)); + + if (imageFileName.lastIndexOf(".")) { + description = imageFileName.slice( + 0, + imageFileName.lastIndexOf("."), + ); + } else { + description = imageFileName; + } } else { - return vscode.window.showErrorMessage(err.toString()) + return vscode.window.showErrorMessage(err.toString()); } - vscode.window.showInformationMessage(`Image ${imageFileName} has been copied to folder ${assetDirectoryPath}`) + vscode.window.showInformationMessage( + `Image ${imageFileName} has been copied to folder ${assetDirectoryPath}`, + ); - let url = `${imageFolderPath}/${imageFileName}` - if (url.indexOf(' ') >= 0) - url = url.replace(/ /g, '%20') + let url = `${imageFolderPath}/${imageFileName}`; + if (url.indexOf(" ") >= 0) { + url = url.replace(/ /g, "%20"); + } editor.edit((textEditorEdit) => { - textEditorEdit.insert(editor.selection.active, `![${description}](${url})`) - }) - }) - }) - }) + textEditorEdit.insert( + editor.selection.active, + `![${description}](${url})`, + ); + }); + }); + }); + }); } -function replaceHint(editor:vscode.TextEditor, line:number, hint:string, withStr:string):boolean { - let textLine = editor.document.lineAt(line) +function replaceHint( + editor: vscode.TextEditor, + line: number, + hint: string, + withStr: string, +): boolean { + const textLine = editor.document.lineAt(line); if (textLine.text.indexOf(hint) >= 0) { - editor.edit((textEdit)=> { - textEdit.replace(new vscode.Range( - new vscode.Position(line, 0), - new vscode.Position(line, textLine.text.length) - ) , textLine.text.replace(hint, withStr)) - }) - return true + editor.edit((textEdit) => { + textEdit.replace( + new vscode.Range( + new vscode.Position(line, 0), + new vscode.Position(line, textLine.text.length), + ), + textLine.text.replace(hint, withStr), + ); + }); + return true; } - return false + return false; } -function setUploadedImageURL(imageFileName:string, url:string, editor:vscode.TextEditor, hint:string, curPos:vscode.Position) { - let description - if (imageFileName.lastIndexOf('.')) - description = imageFileName.slice(0, imageFileName.lastIndexOf('.')) - else - description = imageFileName +function setUploadedImageURL( + imageFileName: string, + url: string, + editor: vscode.TextEditor, + hint: string, + curPos: vscode.Position, +) { + let description; + if (imageFileName.lastIndexOf(".")) { + description = imageFileName.slice(0, imageFileName.lastIndexOf(".")); + } else { + description = imageFileName; + } - const withStr = `![${description}](${url})` + const withStr = `![${description}](${url})`; if (!replaceHint(editor, curPos.line, hint, withStr)) { - let i = curPos.line - 20 + let i = curPos.line - 20; while (i <= curPos.line + 20) { - if (replaceHint(editor, i, hint, withStr)) - break - i++ + if (replaceHint(editor, i, hint, withStr)) { + break; + } + i++; } } } /** * Upload image at imageFilePath to config.imageUploader. - * Then insert markdown image url to markdown file. - * @param uri - * @param imageFilePath + * Then insert markdown image url to markdown file. + * @param uri + * @param imageFilePath */ -export function uploadImageFile(sourceUri: any, imageFilePath: string, imageUploader:string) { +export function uploadImageFile( + sourceUri: any, + imageFilePath: string, + imageUploader: string, +) { // console.log('uploadImageFile', sourceUri, imageFilePath, imageUploader) - if (typeof (sourceUri) === 'string') { - sourceUri = vscode.Uri.parse(sourceUri) - } - const imageFileName = path.basename(imageFilePath) + if (typeof sourceUri === "string") { + sourceUri = vscode.Uri.parse(sourceUri); + } + const imageFileName = path.basename(imageFilePath); vscode.window.visibleTextEditors - .filter(editor => isMarkdownFile(editor.document) && editor.document.uri.fsPath === sourceUri.fsPath) - .forEach(editor => { - const uid = Math.random().toString(36).substr(2, 9) - const hint = `![Uploading ${imageFileName}… (${uid})]()` - const curPos = editor.selection.active - - editor.edit((textEditorEdit)=> { - textEditorEdit.insert(curPos, hint) - }) - - const config = vscode.workspace.getConfiguration('markdown-preview-enhanced') - const AccessKey = config.get ('AccessKey') || '' - const SecretKey = config.get ('SecretKey') || '' - const Bucket = config.get ('Bucket') || '' - const Domain = config.get ('Domain') || '' - - utility.uploadImage(imageFilePath, {method:imageUploader, qiniu: {AccessKey, SecretKey, Bucket, Domain}}) - .then((url)=> { - setUploadedImageURL(imageFileName, url, editor, hint, curPos) - }) - .catch((err)=> { - vscode.window.showErrorMessage(err) - }) - }) + .filter( + (editor) => + isMarkdownFile(editor.document) && + editor.document.uri.fsPath === sourceUri.fsPath, + ) + .forEach((editor) => { + const uid = Math.random() + .toString(36) + .substr(2, 9); + const hint = `![Uploading ${imageFileName}… (${uid})]()`; + const curPos = editor.selection.active; + + editor.edit((textEditorEdit) => { + textEditorEdit.insert(curPos, hint); + }); + + const config = vscode.workspace.getConfiguration( + "markdown-preview-enhanced", + ); + const AccessKey = config.get ("AccessKey") || ""; + const SecretKey = config.get ("SecretKey") || ""; + const Bucket = config.get ("Bucket") || ""; + const Domain = config.get ("Domain") || ""; + + utility + .uploadImage(imageFilePath, { + method: imageUploader, + qiniu: { AccessKey, SecretKey, Bucket, Domain }, + }) + .then((url) => { + setUploadedImageURL(imageFileName, url, editor, hint, curPos); + }) + .catch((err) => { + vscode.window.showErrorMessage(err); + }); + }); } - diff --git a/src/preview-content-provider.ts b/src/preview-content-provider.ts index f74c2b5..297666b 100644 --- a/src/preview-content-provider.ts +++ b/src/preview-content-provider.ts @@ -1,407 +1,483 @@ -import * as vscode from 'vscode' -import * as path from 'path' -import {Uri, CancellationToken, Event, ProviderResult, TextEditor} from 'vscode' +import * as path from "path"; +import * as vscode from "vscode"; +import { Event, TextEditor, Uri } from "vscode"; -import * as mume from "@shd101wyy/mume" -import {MarkdownEngine} from "@shd101wyy/mume" +import * as mume from "@shd101wyy/mume"; +import { MarkdownEngine } from "@shd101wyy/mume"; -import {MarkdownPreviewEnhancedConfig} from "./config" +import { MarkdownPreviewEnhancedConfig } from "./config"; -let singlePreviewSouceUri:Uri = null +let singlePreviewSouceUri: Uri = null; // http://www.typescriptlang.org/play/ // https://github.com/Microsoft/vscode/blob/master/extensions/markdown/media/main.js // https://github.com/Microsoft/vscode/tree/master/extensions/markdown/src // https://github.com/tomoki1207/gfm-preview/blob/master/src/gfmProvider.ts // https://github.com/cbreeden/vscode-markdownit -export class MarkdownPreviewEnhancedView implements vscode.TextDocumentContentProvider { - private _onDidChange = new vscode.EventEmitter () - private _waiting:boolean = false +export class MarkdownPreviewEnhancedView + implements vscode.TextDocumentContentProvider { + private privateOnDidChange = new vscode.EventEmitter (); + private waiting: boolean = false; /** * The key is markdown file fsPath * value is MarkdownEngine */ - private engineMaps:{[key:string]: MarkdownEngine} = {} + private engineMaps: { [key: string]: MarkdownEngine } = {}; /** * The key is markdown file fsPath * value is JSAndCssFiles */ - private jsAndCssFilesMaps: {[key:string]: string[]} = {} + private jsAndCssFilesMaps: { [key: string]: string[] } = {}; - - private config:MarkdownPreviewEnhancedConfig + private config: MarkdownPreviewEnhancedConfig; public constructor(private context: vscode.ExtensionContext) { - this.config = MarkdownPreviewEnhancedConfig.getCurrentConfig() - - mume.init() // init markdown-preview-enhanced - .then(()=> { - mume.onDidChangeConfigFile(this.refreshAllPreviews.bind(this)) - MarkdownEngine.onModifySource(this.modifySource.bind(this)) - - const extensionVersion = require(path.resolve(this.context.extensionPath, './package.json'))['version'] - if (extensionVersion !== mume.configs.config['vscode_mpe_version']) { - mume.utility.updateExtensionConfig({'vscode_mpe_version': extensionVersion}) - // openWelcomePage() // <== disable welcome page - } - }) + this.config = MarkdownPreviewEnhancedConfig.getCurrentConfig(); + + mume + .init() // init markdown-preview-enhanced + .then(() => { + mume.onDidChangeConfigFile(this.refreshAllPreviews.bind(this)); + MarkdownEngine.onModifySource(this.modifySource.bind(this)); + + const extensionVersion = require(path.resolve( + this.context.extensionPath, + "./package.json", + ))["version"]; + if (extensionVersion !== mume.configs.config["vscode_mpe_version"]) { + mume.utility.updateExtensionConfig({ + vscode_mpe_version: extensionVersion, + }); + // openWelcomePage() // <== disable welcome page + } + }); } private refreshAllPreviews() { // reset configs - for (let key in this.engineMaps) { - this.engineMaps[key].resetConfig() + for (const key in this.engineMaps) { + if (this.engineMaps.hasOwnProperty(key)) { + this.engineMaps[key].resetConfig(); + } } // refresh iframes - vscode.workspace.textDocuments.forEach(document => { - if (document.uri.scheme === 'markdown-preview-enhanced') { - this._onDidChange.fire(document.uri) + vscode.workspace.textDocuments.forEach((document) => { + if (document.uri.scheme === "markdown-preview-enhanced") { + this.privateOnDidChange.fire(document.uri); } - }) + }); } /** * modify markdown source, append `result` after corresponding code chunk. - * @param codeChunkData - * @param result - * @param filePath + * @param codeChunkData + * @param result + * @param filePath */ - private async modifySource(codeChunkData:mume.CodeChunkData, result:string, filePath:string):Promise { - function insertResult(i:number, editor:TextEditor) { - const lineCount = editor.document.lineCount - let start = 0 + private async modifySource( + codeChunkData: mume.CodeChunkData, + result: string, + filePath: string, + ): Promise { + function insertResult(i: number, editor: TextEditor) { + const lineCount = editor.document.lineCount; + let start = 0; // find for (let j = i + 1; j < i + 6 && j < lineCount; j++) { - if (editor.document.lineAt(j).text.startsWith('')) { - start = j - break + if ( + editor.document + .lineAt(j) + .text.startsWith("") + ) { + start = j; + break; } } - if (start) { // found - // TODO: modify exited output - let end = start + 1 + if (start) { + // found + // TODO: modify exited output + let end = start + 1; while (end < lineCount) { - if (editor.document.lineAt(end).text.startsWith('')){ - break + if ( + editor.document + .lineAt(end) + .text.startsWith("") + ) { + break; } - end += 1 + end += 1; } // if output not changed, then no need to modify editor buffer - let r = "" - for (let i = start+2; i < end-1; i++) { - r += editor.document.lineAt(i).text+'\n' + let r = ""; + for (let i2 = start + 2; i2 < end - 1; i2++) { + r += editor.document.lineAt(i2).text + "\n"; } - if (r === result+'\n') return "" // no need to modify output - - editor.edit((edit)=> { - edit.replace(new vscode.Range( - new vscode.Position(start + 2, 0), - new vscode.Position(end-1, 0) - ), result+'\n') - }) - return "" + if (r === result + "\n") { + return ""; + } // no need to modify output + + editor.edit((edit) => { + edit.replace( + new vscode.Range( + new vscode.Position(start + 2, 0), + new vscode.Position(end - 1, 0), + ), + result + "\n", + ); + }); + return ""; } else { - editor.edit((edit)=> { - edit.insert(new vscode.Position(i+1, 0), `\n\n\n${result}\n\n\n`) - }) - return "" + editor.edit((edit) => { + edit.insert( + new vscode.Position(i + 1, 0), + `\n\n\n${result}\n\n\n`, + ); + }); + return ""; } } - const visibleTextEditors = vscode.window.visibleTextEditors + const visibleTextEditors = vscode.window.visibleTextEditors; for (let i = 0; i < visibleTextEditors.length; i++) { - const editor = visibleTextEditors[i] + const editor = visibleTextEditors[i]; if (editor.document.uri.fsPath === filePath) { - let codeChunkOffset = 0, - targetCodeChunkOffset = codeChunkData.normalizedInfo.attributes['code_chunk_offset'] + let codeChunkOffset = 0; + const targetCodeChunkOffset = + codeChunkData.normalizedInfo.attributes["code_chunk_offset"]; - const lineCount = editor.document.lineCount - for (let i = 0; i < lineCount; i++) { - const line = editor.document.lineAt(i) + const lineCount = editor.document.lineCount; + for (let i2 = 0; i2 < lineCount; i2++) { + const line = editor.document.lineAt(i2); if (line.text.match(/^```(.+)\"?cmd\"?\s*[:=]/)) { if (codeChunkOffset === targetCodeChunkOffset) { - i = i + 1 - while (i < lineCount) { - if (editor.document.lineAt(i).text.match(/^\`\`\`\s*/)) { - break + i2 = i2 + 1; + while (i2 < lineCount) { + if (editor.document.lineAt(i2).text.match(/^\`\`\`\s*/)) { + break; } - i += 1 + i2 += 1; } - return insertResult(i, editor) + return insertResult(i2, editor); } else { - codeChunkOffset++ + codeChunkOffset++; } } else if (line.text.match(/\@import\s+(.+)\"?cmd\"?\s*[:=]/)) { if (codeChunkOffset === targetCodeChunkOffset) { // console.log('find code chunk' ) - return insertResult(i, editor) + return insertResult(i2, editor); } else { - codeChunkOffset++ + codeChunkOffset++; } } } - break + break; } } - return "" + return ""; } /** * return markdown engine of sourceUri - * @param sourceUri + * @param sourceUri */ - public getEngine(sourceUri:Uri):MarkdownEngine { - return this.engineMaps[sourceUri.fsPath] + public getEngine(sourceUri: Uri): MarkdownEngine { + return this.engineMaps[sourceUri.fsPath]; } /** * check if the markdown preview is on for the textEditor - * @param textEditor + * @param textEditor */ - public isPreviewOn(sourceUri:Uri) { + public isPreviewOn(sourceUri: Uri) { if (useSinglePreview()) { - return Object.keys(this.engineMaps).length >= 1 + return Object.keys(this.engineMaps).length >= 1; } - return this.getEngine(sourceUri) + return this.getEngine(sourceUri); } /** * remove engine from this.engineMaps - * @param previewUri + * @param previewUri */ public destroyEngine(previewUri: Uri) { - delete(previewUri['markdown_source']) + delete previewUri["markdown_source"]; if (useSinglePreview()) { - return this.engineMaps = {} + return (this.engineMaps = {}); } - const sourceUri = vscode.Uri.parse(previewUri.query) - const engine = this.getEngine(sourceUri) + const sourceUri = vscode.Uri.parse(previewUri.query); + const engine = this.getEngine(sourceUri); if (engine) { // console.log('engine destroyed') - this.engineMaps[sourceUri.fsPath] = null // destroy engine + this.engineMaps[sourceUri.fsPath] = null; // destroy engine } - } + } /** * Initialize MarkdownEngine for this markdown file */ - public initMarkdownEngine(sourceUri: Uri):MarkdownEngine { - let engine = this.getEngine(sourceUri) + public initMarkdownEngine(sourceUri: Uri): MarkdownEngine { + let engine = this.getEngine(sourceUri); if (!engine) { - engine = new MarkdownEngine( - { - filePath: sourceUri.fsPath, - projectDirectoryPath: vscode.workspace.rootPath, - config: this.config - }) - this.engineMaps[sourceUri.fsPath] = engine - this.jsAndCssFilesMaps[sourceUri.fsPath] = [] + engine = new MarkdownEngine({ + filePath: sourceUri.fsPath, + projectDirectoryPath: vscode.workspace.rootPath, + config: this.config, + }); + this.engineMaps[sourceUri.fsPath] = engine; + this.jsAndCssFilesMaps[sourceUri.fsPath] = []; } - return engine + return engine; } - public provideTextDocumentContent(previewUri: Uri) - : Thenable { + public provideTextDocumentContent(previewUri: Uri): Thenable { // console.log(sourceUri, uri, vscode.workspace.rootPath) - let sourceUri:Uri + let sourceUri: Uri; if (useSinglePreview()) { - sourceUri = singlePreviewSouceUri + sourceUri = singlePreviewSouceUri; } else { - sourceUri = vscode.Uri.parse(previewUri.query) + sourceUri = vscode.Uri.parse(previewUri.query); } // console.log('open preview for source: ' + sourceUri.toString()) - let initialLine: number | undefined = undefined; - const editor = vscode.window.activeTextEditor; - if (editor && editor.document.uri.fsPath === sourceUri.fsPath) { - initialLine = editor.selection.active.line; - } + let initialLine: number | undefined; + const editor = vscode.window.activeTextEditor; + if (editor && editor.document.uri.fsPath === sourceUri.fsPath) { + initialLine = editor.selection.active.line; + } - return vscode.workspace.openTextDocument(sourceUri).then(document => { - const text = document.getText() - let engine = this.getEngine(sourceUri) + return vscode.workspace.openTextDocument(sourceUri).then((document) => { + const text = document.getText(); + let engine = this.getEngine(sourceUri); if (!engine) { - engine = this.initMarkdownEngine(sourceUri) + engine = this.initMarkdownEngine(sourceUri); } return engine.generateHTMLTemplateForPreview({ - inputString: text, + inputString: text, config: { previewUri: encodeURIComponent(previewUri.toString()), sourceUri: encodeURIComponent(sourceUri.toString()), - initialLine: initialLine, - vscode: true + initialLine, + vscode: true, }, // webviewScript: path.resolve(this.context.extensionPath, './out/src/webview.js') // use default webview.ts in mume - }) - }) + }); + }); } - public updateMarkdown(sourceUri:Uri, triggeredBySave?:boolean) { - const engine = this.getEngine(sourceUri) - if (!engine) return + public updateMarkdown(sourceUri: Uri, triggeredBySave?: boolean) { + const engine = this.getEngine(sourceUri); + if (!engine) { + return; + } - // presentation mode + // presentation mode if (engine.isPreviewInPresentationMode) { - return this._onDidChange.fire(getPreviewUri(sourceUri)) + return this.privateOnDidChange.fire(getPreviewUri(sourceUri)); } - // not presentation mode - vscode.workspace.openTextDocument(sourceUri).then(document => { - const text = document.getText() + // not presentation mode + vscode.workspace.openTextDocument(sourceUri).then((document) => { + const text = document.getText(); vscode.commands.executeCommand( - '_workbench.htmlPreview.postMessage', + "_workbench.htmlPreview.postMessage", getPreviewUri(sourceUri), { - command: 'startParsingMarkdown', + command: "startParsingMarkdown", + }, + ); + + engine + .parseMD(text, { + isForPreview: true, + useRelativeFilePath: false, + hideFrontMatter: false, + triggeredBySave, }) - - engine.parseMD(text, {isForPreview: true, useRelativeFilePath: false, hideFrontMatter: false, triggeredBySave}) - .then(({markdown, html, tocHTML, JSAndCssFiles, yamlConfig})=> { - // check JSAndCssFiles - if (JSON.stringify(JSAndCssFiles) !== JSON.stringify(this.jsAndCssFilesMaps[sourceUri.fsPath]) || yamlConfig['isPresentationMode'] ) { - this.jsAndCssFilesMaps[sourceUri.fsPath] = JSAndCssFiles - // restart iframe - this._onDidChange.fire(getPreviewUri(sourceUri)) - } else { - vscode.commands.executeCommand( - '_workbench.htmlPreview.postMessage', - getPreviewUri(sourceUri), - { - command: 'updateHTML', - html: html, - tocHTML: tocHTML, - totalLineCount: document.lineCount, - sourceUri: encodeURIComponent(sourceUri.toString()), - id: yamlConfig.id || '', - class: yamlConfig.class || '' - }) - } - }) - }) + .then(({ markdown, html, tocHTML, JSAndCssFiles, yamlConfig }) => { + // check JSAndCssFiles + if ( + JSON.stringify(JSAndCssFiles) !== + JSON.stringify(this.jsAndCssFilesMaps[sourceUri.fsPath]) || + yamlConfig["isPresentationMode"] + ) { + this.jsAndCssFilesMaps[sourceUri.fsPath] = JSAndCssFiles; + // restart iframe + this.privateOnDidChange.fire(getPreviewUri(sourceUri)); + } else { + vscode.commands.executeCommand( + "_workbench.htmlPreview.postMessage", + getPreviewUri(sourceUri), + { + command: "updateHTML", + html, + tocHTML, + totalLineCount: document.lineCount, + sourceUri: encodeURIComponent(sourceUri.toString()), + id: yamlConfig.id || "", + class: yamlConfig.class || "", + }, + ); + } + }); + }); } public refreshPreview(sourceUri: Uri) { - const engine = this.getEngine(sourceUri) + const engine = this.getEngine(sourceUri); if (engine) { - engine.clearCaches() - // restart iframe - this._onDidChange.fire(getPreviewUri(sourceUri)) + engine.clearCaches(); + // restart iframe + this.privateOnDidChange.fire(getPreviewUri(sourceUri)); } } public openInBrowser(sourceUri: Uri) { - const engine = this.getEngine(sourceUri) + const engine = this.getEngine(sourceUri); if (engine) { - engine.openInBrowser({}) - .catch((error)=> { - vscode.window.showErrorMessage(error) - }) + engine.openInBrowser({}).catch((error) => { + vscode.window.showErrorMessage(error); + }); } } - public htmlExport(sourceUri: Uri, offline:boolean) { - const engine = this.getEngine(sourceUri) + public htmlExport(sourceUri: Uri, offline: boolean) { + const engine = this.getEngine(sourceUri); if (engine) { - engine.htmlExport({offline}) - .then((dest)=> { - vscode.window.showInformationMessage(`File ${path.basename(dest)} was created at path: ${dest}`) - }) - .catch((error)=> { - vscode.window.showErrorMessage(error) - }) + engine + .htmlExport({ offline }) + .then((dest) => { + vscode.window.showInformationMessage( + `File ${path.basename(dest)} was created at path: ${dest}`, + ); + }) + .catch((error) => { + vscode.window.showErrorMessage(error); + }); } } public chromeExport(sourceUri: Uri, type: string) { - const engine = this.getEngine(sourceUri) + const engine = this.getEngine(sourceUri); if (engine) { - engine.chromeExport({fileType: type, openFileAfterGeneration: true}) - .then((dest)=> { - vscode.window.showInformationMessage(`File ${path.basename(dest)} was created at path: ${dest}`) - }) - .catch((error)=> { - vscode.window.showErrorMessage(error) - }) - } + engine + .chromeExport({ fileType: type, openFileAfterGeneration: true }) + .then((dest) => { + vscode.window.showInformationMessage( + `File ${path.basename(dest)} was created at path: ${dest}`, + ); + }) + .catch((error) => { + vscode.window.showErrorMessage(error); + }); + } } public phantomjsExport(sourceUri: Uri, type: string) { - const engine = this.getEngine(sourceUri) + const engine = this.getEngine(sourceUri); if (engine) { - engine.phantomjsExport({fileType: type, openFileAfterGeneration: true}) - .then((dest)=> { - if (dest.endsWith('?print-pdf')) // presentation pdf - vscode.window.showInformationMessage(`Please copy and open the link: { ${dest.replace(/\_/g, '\\_')} } in Chrome then Print as Pdf.`) - else - vscode.window.showInformationMessage(`File ${path.basename(dest)} was created at path: ${dest}`) - }) - .catch((error)=> { - vscode.window.showErrorMessage(error) - }) - } + engine + .phantomjsExport({ fileType: type, openFileAfterGeneration: true }) + .then((dest) => { + if (dest.endsWith("?print-pdf")) { + // presentation pdf + vscode.window.showInformationMessage( + `Please copy and open the link: { ${dest.replace( + /\_/g, + "\\_", + )} } in Chrome then Print as Pdf.`, + ); + } else { + vscode.window.showInformationMessage( + `File ${path.basename(dest)} was created at path: ${dest}`, + ); + } + }) + .catch((error) => { + vscode.window.showErrorMessage(error); + }); + } } public princeExport(sourceUri: Uri) { - const engine = this.getEngine(sourceUri) + const engine = this.getEngine(sourceUri); if (engine) { - engine.princeExport({openFileAfterGeneration: true}) - .then((dest)=> { - if (dest.endsWith('?print-pdf')) // presentation pdf - vscode.window.showInformationMessage(`Please copy and open the link: { ${dest.replace(/\_/g, '\\_')} } in Chrome then Print as Pdf.`) - else - vscode.window.showInformationMessage(`File ${path.basename(dest)} was created at path: ${dest}`) - }) - .catch((error)=> { - vscode.window.showErrorMessage(error) - }) + engine + .princeExport({ openFileAfterGeneration: true }) + .then((dest) => { + if (dest.endsWith("?print-pdf")) { + // presentation pdf + vscode.window.showInformationMessage( + `Please copy and open the link: { ${dest.replace( + /\_/g, + "\\_", + )} } in Chrome then Print as Pdf.`, + ); + } else { + vscode.window.showInformationMessage( + `File ${path.basename(dest)} was created at path: ${dest}`, + ); + } + }) + .catch((error) => { + vscode.window.showErrorMessage(error); + }); } } - public eBookExport(sourceUri: Uri, fileType:string) { - const engine = this.getEngine(sourceUri) + public eBookExport(sourceUri: Uri, fileType: string) { + const engine = this.getEngine(sourceUri); if (engine) { - engine.eBookExport({fileType, runAllCodeChunks:false}) - .then((dest)=> { - vscode.window.showInformationMessage(`eBook ${path.basename(dest)} was created as path: ${dest}`) - }) - .catch((error)=> { - vscode.window.showErrorMessage(error) - }) + engine + .eBookExport({ fileType, runAllCodeChunks: false }) + .then((dest) => { + vscode.window.showInformationMessage( + `eBook ${path.basename(dest)} was created as path: ${dest}`, + ); + }) + .catch((error) => { + vscode.window.showErrorMessage(error); + }); } } public pandocExport(sourceUri) { - const engine = this.getEngine(sourceUri) + const engine = this.getEngine(sourceUri); if (engine) { - engine.pandocExport({openFileAfterGeneration: true}) - .then((dest)=> { - vscode.window.showInformationMessage(`Document ${path.basename(dest)} was created as path: ${dest}`) - }) - .catch((error)=> { - vscode.window.showErrorMessage(error) - }) + engine + .pandocExport({ openFileAfterGeneration: true }) + .then((dest) => { + vscode.window.showInformationMessage( + `Document ${path.basename(dest)} was created as path: ${dest}`, + ); + }) + .catch((error) => { + vscode.window.showErrorMessage(error); + }); } } public markdownExport(sourceUri) { - const engine = this.getEngine(sourceUri) + const engine = this.getEngine(sourceUri); if (engine) { - engine.markdownExport({}) - .then((dest)=> { - vscode.window.showInformationMessage(`Document ${path.basename(dest)} was created as path: ${dest}`) - }) - .catch((error)=> { - vscode.window.showErrorMessage(error) - }) + engine + .markdownExport({}) + .then((dest) => { + vscode.window.showInformationMessage( + `Document ${path.basename(dest)} was created as path: ${dest}`, + ); + }) + .catch((error) => { + vscode.window.showErrorMessage(error); + }); } } @@ -414,129 +490,136 @@ export class MarkdownPreviewEnhancedView implements vscode.TextDocumentContentPr } */ - public cacheCodeChunkResult(sourceUri: Uri, id:string, result:string) { - const engine = this.getEngine(sourceUri) + public cacheCodeChunkResult(sourceUri: Uri, id: string, result: string) { + const engine = this.getEngine(sourceUri); if (engine) { - engine.cacheCodeChunkResult(id, result) + engine.cacheCodeChunkResult(id, result); } } public runCodeChunk(sourceUri: Uri, codeChunkId: string) { - const engine = this.getEngine(sourceUri) + const engine = this.getEngine(sourceUri); if (engine) { - engine.runCodeChunk(codeChunkId) - .then(()=> { - this.updateMarkdown(sourceUri) - }) + engine.runCodeChunk(codeChunkId).then(() => { + this.updateMarkdown(sourceUri); + }); } } public runAllCodeChunks(sourceUri) { - const engine = this.getEngine(sourceUri) + const engine = this.getEngine(sourceUri); if (engine) { - engine.runAllCodeChunks() - .then(()=> { - this.updateMarkdown(sourceUri) - }) + engine.runAllCodeChunks().then(() => { + this.updateMarkdown(sourceUri); + }); } } get onDidChange(): Event { - return this._onDidChange.event + return this.privateOnDidChange.event; } public update(sourceUri: Uri) { - if (!this.config.liveUpdate) return - + if (!this.config.liveUpdate) { + return; + } + // console.log('update') - if (!this._waiting) { - this._waiting = true; - setTimeout(() => { - this._waiting = false; - // this._onDidChange.fire(uri); - this.updateMarkdown(sourceUri) - }, 300) - } + if (!this.waiting) { + this.waiting = true; + setTimeout(() => { + this.waiting = false; + // this._onDidChange.fire(uri); + this.updateMarkdown(sourceUri); + }, 300); + } } public updateConfiguration() { - const newConfig = MarkdownPreviewEnhancedConfig.getCurrentConfig() + const newConfig = MarkdownPreviewEnhancedConfig.getCurrentConfig(); if (!this.config.isEqualTo(newConfig)) { - this.config = newConfig + this.config = newConfig; - for (let fsPath in this.engineMaps) { - const engine = this.engineMaps[fsPath] - engine.updateConfiguration(newConfig) + for (const fsPath in this.engineMaps) { + if (this.engineMaps.hasOwnProperty(fsPath)) { + const engine = this.engineMaps[fsPath]; + engine.updateConfiguration(newConfig); + } } // update all generated md documents - vscode.workspace.textDocuments.forEach(document => { - if (document.uri.scheme === 'markdown-preview-enhanced') { - // this.update(document.uri); - this._onDidChange.fire(document.uri) - } - }) + vscode.workspace.textDocuments.forEach((document) => { + if (document.uri.scheme === "markdown-preview-enhanced") { + // this.update(document.uri); + this.privateOnDidChange.fire(document.uri); + } + }); } } - public openImageHelper(sourceUri:Uri) { - if (sourceUri.scheme === 'markdown-preview-enhanced') { - return vscode.window.showWarningMessage('Please focus a markdown file.') + public openImageHelper(sourceUri: Uri) { + if (sourceUri.scheme === "markdown-preview-enhanced") { + return vscode.window.showWarningMessage("Please focus a markdown file."); } else if (!this.isPreviewOn(sourceUri)) { - return vscode.window.showWarningMessage('Please open preview first.') + return vscode.window.showWarningMessage("Please open preview first."); } else { vscode.commands.executeCommand( - '_workbench.htmlPreview.postMessage', + "_workbench.htmlPreview.postMessage", getPreviewUri(sourceUri), { - command: 'openImageHelper' - }) + command: "openImageHelper", + }, + ); } } - } /** * check whehter to use only one preview or not */ export function useSinglePreview() { - const config = vscode.workspace.getConfiguration('markdown-preview-enhanced') - return config.get ('singlePreview') + const config = vscode.workspace.getConfiguration("markdown-preview-enhanced"); + return config.get ("singlePreview"); } - export function getPreviewUri(uri: vscode.Uri) { - if (uri.scheme === 'markdown-preview-enhanced') { - return uri - } - - - let previewUri:Uri + if (uri.scheme === "markdown-preview-enhanced") { + return uri; + } + + let previewUri: Uri; if (useSinglePreview()) { previewUri = uri.with({ - scheme: 'markdown-preview-enhanced', - path: 'single-preview.rendered', - }) - singlePreviewSouceUri = uri + scheme: "markdown-preview-enhanced", + path: "single-preview.rendered", + }); + singlePreviewSouceUri = uri; } else { previewUri = uri.with({ - scheme: 'markdown-preview-enhanced', - path: uri.path + '.rendered', - query: uri.toString() - }) + scheme: "markdown-preview-enhanced", + path: uri.path + ".rendered", + query: uri.toString(), + }); } - return previewUri + return previewUri; } export function isMarkdownFile(document: vscode.TextDocument) { - return document.languageId === 'markdown' - && document.uri.scheme !== 'markdown-preview-enhanced' // prevent processing of own documents + return ( + document.languageId === "markdown" && + document.uri.scheme !== "markdown-preview-enhanced" + ); // prevent processing of own documents } export function openWelcomePage() { - const welcomeFilePath = mume.utility.addFileProtocol(path.resolve(__dirname, '../../docs/welcome.md')).replace(/\\/g, '/') - const uri = vscode.Uri.parse(welcomeFilePath) - vscode.commands.executeCommand('vscode.open', uri).then(()=> { - vscode.commands.executeCommand('markdown-preview-enhanced.openPreview', uri) - }) -} \ No newline at end of file + const welcomeFilePath = mume.utility + .addFileProtocol(path.resolve(__dirname, "../../docs/welcome.md")) + .replace(/\\/g, "/"); + const uri = vscode.Uri.parse(welcomeFilePath); + vscode.commands.executeCommand("vscode.open", uri).then(() => { + vscode.commands.executeCommand( + "markdown-preview-enhanced.openPreview", + uri, + ); + }); +} diff --git a/test/extension.test.js b/test/extension.test.js index c3c1517..566df0d 100644 --- a/test/extension.test.js +++ b/test/extension.test.js @@ -6,19 +6,18 @@ // // The module 'assert' provides assertion methods from node -var assert = require('assert'); +var assert = require("assert"); // You can import and use all API from the 'vscode' module // as well as import your extension to test it -var vscode = require('vscode'); -var myExtension = require('../extension'); +var vscode = require("vscode"); +var myExtension = require("../extension"); // Defines a Mocha test suite to group tests of similar kind together suite("Extension Tests", function() { - - // Defines a Mocha unit test - test("Something 1", function() { - assert.equal(-1, [1, 2, 3].indexOf(5)); - assert.equal(-1, [1, 2, 3].indexOf(0)); - }); -}); \ No newline at end of file + // Defines a Mocha unit test + test("Something 1", function() { + assert.equal(-1, [1, 2, 3].indexOf(5)); + assert.equal(-1, [1, 2, 3].indexOf(0)); + }); +}); diff --git a/test/index.js b/test/index.js index 5604517..28215d1 100644 --- a/test/index.js +++ b/test/index.js @@ -10,13 +10,13 @@ // to report the results back to the caller. When the tests are finished, return // a possible error to the callback or null if none. -var testRunner = require('vscode/lib/testrunner'); +var testRunner = require("vscode/lib/testrunner"); // You can directly control Mocha options by uncommenting the following lines // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info testRunner.configure({ - ui: 'tdd', // the TDD UI is being used in extension.test.js (suite, test, etc.) - useColors: true // colored output from test results + ui: "tdd", // the TDD UI is being used in extension.test.js (suite, test, etc.) + useColors: true, // colored output from test results }); -module.exports = testRunner; \ No newline at end of file +module.exports = testRunner; diff --git a/tsconfig.json b/tsconfig.json index cd676d7..413e3a3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,13 @@ { - "compilerOptions": { - "module": "commonjs", - "target": "es6", - "outDir": "out", - "lib": [ - "es6", - "dom" - ], - "sourceMap": true, - "rootDir": "." - }, - "include": [ - "src/**/*" - ], - "exclude": [ - "node_modules", - ".vscode-test", - "dependencies" - ] -} \ No newline at end of file + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noUnusedLocals": true, + "sourceMap": true, + "outDir": "out", + "lib": ["es6", "dom"], + "rootDir": "." + }, + "include": ["src/**/*", "test/**/*"], + "exclude": ["node_modules"] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..e8fc9a1 --- /dev/null +++ b/tslint.json @@ -0,0 +1,12 @@ +{ + "defaultSeverity": "error", + "extends": ["tslint:recommended", "tslint-config-prettier"], + "rules": { + "interface-name": [true, "never-prefix"], + "member-ordering": false, // TODO: enable and sort MarkdownPreviewEnhancedView + "no-string-literal": false, + "object-literal-sort-keys": false, + "prefer-for-of": false, + "no-eval": false + } +} diff --git a/vsc-extension-quickstart.md b/vsc-extension-quickstart.md index 21fc8da..6331d2b 100644 --- a/vsc-extension-quickstart.md +++ b/vsc-extension-quickstart.md @@ -1,33 +1,38 @@ # Welcome to your first VS Code Extension ## What's in the folder + * This folder contains all of the files necessary for your extension * `package.json` - this is the manifest file in which you declare your extension and command. -The sample plugin registers a command and defines its title and command name. With this information -VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. + The sample plugin registers a command and defines its title and command name. With this information + VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. * `extension.js` - this is the main file where you will provide the implementation of your command. -The file exports one function, `activate`, which is called the very first time your extension is -activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. -We pass the function containing the implementation of the command as the second parameter to -`registerCommand`. + The file exports one function, `activate`, which is called the very first time your extension is + activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. + We pass the function containing the implementation of the command as the second parameter to + `registerCommand`. ## Get up and running straight away + * press `F5` to open a new window with your extension loaded * run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World` * set breakpoints in your code inside extension.ts to debug your extension * find output from your extension in the debug console ## Make changes + * you can relaunch the extension from the debug toolbar after changing code in `extension.js` * you can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes ## Explore the API + * you can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts` ## Run tests + * open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Launch Tests` * press `F5` to run the tests in a new window with your extension loaded * see the output of the test result in the debug console * make changes to `test/extension.test.js` or create new test files inside the `test` folder - * by convention, the test runner will only consider files matching the name pattern `**.test.js` - * you can create folders inside the `test` folder to structure your tests any way you want \ No newline at end of file + * by convention, the test runner will only consider files matching the name pattern `**.test.js` + * you can create folders inside the `test` folder to structure your tests any way you want