diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 0915202..e0607e8 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,5 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the extensions.json format - "recommendations": [ - "dbaeumer.vscode-eslint" - ] -} \ No newline at end of file + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the extensions.json format + "recommendations": ["dbaeumer.vscode-eslint"] +} diff --git a/.vscode/launch.json b/.vscode/launch.json index cd6b87b..f779a35 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,28 +1,30 @@ // A launch configuration that compiles the extension and then opens it inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 { - "version": "0.1.0", - "configurations": [ - { - "name": "Launch Extension", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], - "stopOnEntry": false, - "sourceMaps": true, - "outFiles": [ "${workspaceRoot}/out/src/**/*.js" ], - "preLaunchTask": "npm" - }, - { - "name": "Launch Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], - "stopOnEntry": false, - "sourceMaps": true, - "outFiles": [ "${workspaceRoot}/out/test/**/*.js" ], - "preLaunchTask": "npm" - } - ] + "version": "0.2.0", + "configurations": [ + { + "name": "Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": ["--extensionDevelopmentPath=${workspaceFolder}"], + "outFiles": ["${workspaceFolder}/out/**/*.js"], + "preLaunchTask": "npm: watch" + }, + { + "name": "Extension Tests", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}", + "--extensionTestsPath=${workspaceFolder}/out/test" + ], + "outFiles": ["${workspaceFolder}/out/test/**/*.js"], + "preLaunchTask": "npm: watch" + } + ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index d137133..bc48eac 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,9 @@ // Place your settings in this file to overwrite default and user settings. { - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - } -} \ No newline at end of file + "files.exclude": { + "out": false // set this to true to hide the "out" folder with the compiled JS files + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + } +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 1e37eb7..078ff7e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,30 +1,20 @@ -// Available variables which can be used inside of strings. -// ${workspaceRoot}: the root folder of the team -// ${file}: the current opened file -// ${fileBasename}: the current opened file's basename -// ${fileDirname}: the current opened file's dirname -// ${fileExtname}: the current opened file's extension -// ${cwd}: the current working directory of the spawned process - -// A task runner that calls a custom npm script that compiles the extension. +// See https://go.microsoft.com/fwlink/?LinkId=733558 +// for the documentation about the tasks.json format { - "version": "0.1.0", - - // we want to run npm - "command": "npm", - - // the command is a shell script - "isShellCommand": true, - - // show the output window only if unrecognized errors occur. - "showOutput": "silent", - - // we run the custom script "compile" as defined in package.json - "args": ["run", "compile", "--loglevel", "silent"], - - // The tsc compiler is started in watching mode - "isBackground": true, - - // use the standard tsc in watch mode problem matcher to find compile problems in the output. - "problemMatcher": "$tsc-watch" -} \ No newline at end of file + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "watch", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 4065666..bca9950 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1 @@ -Please go check the [project releases page](https://github.com/shd101wyy/vscode-markdown-preview-enhanced). \ No newline at end of file +Please go check the [project releases page](https://github.com/shd101wyy/vscode-markdown-preview-enhanced). diff --git a/LICENSE.md b/LICENSE.md index 936c0c5..997447e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,5 +1,5 @@ University of Illinois/NCSA -Open Source License +Open Source License ``` Copyright (c) 2017 Yiyi Wang @@ -7,7 +7,7 @@ All rights reserved. Developed by: Yiyi Wang and many other contributors https://github.com/shd101wyy/markdown-preview-enhanced -``` +``` Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index dd2cbba..8f349bc 100644 --- a/README.md +++ b/README.md @@ -14,42 +14,49 @@ vscode
-*Still Beta Version!* +_Still Beta Version!_ ## Supporting this project -Markdown Preview Enhanced is an open source project released under the [University of Illinois/NCSA Open Source License](LICENSE.md). Its ongoing development is made possible thanks to the support by these awesome [backers](https://shd101wyy.github.io/markdown-preview-enhanced/#/backers). You can help make this project better by [supporting us on Patreon](https://www.patreon.com/shd101wyy), [PayPal](https://shd101wyy.github.io/markdown-preview-enhanced/#/paypal), or [微信支付 Wechat Pay](https://shd101wyy.github.io/markdown-preview-enhanced/#/wechat). Thank you! -## Introduction -Markdown Preview Enhanced is an extension that provides you with many useful functionalities such as automatic scroll sync, [math typesetting](https://shd101wyy.github.io/markdown-preview-enhanced/#/math), [mermaid](https://shd101wyy.github.io/markdown-preview-enhanced/#/diagrams?id=mermaid), [PlantUML](https://shd101wyy.github.io/markdown-preview-enhanced/#/diagrams?id=plantuml), [pandoc](https://shd101wyy.github.io/markdown-preview-enhanced/#/pandoc), PDF export, [code chunk](https://shd101wyy.github.io/markdown-preview-enhanced/#/code-chunk), [presentation writer](https://rawgit.com/shd101wyy/markdown-preview-enhanced/master/docs/presentation-intro.html), etc. A lot of its ideas are inspired by [Markdown Preview Plus](https://github.com/atom-community/markdown-preview-plus) and [RStudio Markdown](http://rmarkdown.rstudio.com/). +Markdown Preview Enhanced is an open source project released under the [University of Illinois/NCSA Open Source License](LICENSE.md). Its ongoing development is made possible thanks to the support by these awesome [backers](https://shd101wyy.github.io/markdown-preview-enhanced/#/backers). You can help make this project better by [supporting us on Patreon](https://www.patreon.com/shd101wyy), [PayPal](https://shd101wyy.github.io/markdown-preview-enhanced/#/paypal), or [微信支付 Wechat Pay](https://shd101wyy.github.io/markdown-preview-enhanced/#/wechat). Thank you! + +## Introduction + +Markdown Preview Enhanced is an extension that provides you with many useful functionalities such as automatic scroll sync, [math typesetting](https://shd101wyy.github.io/markdown-preview-enhanced/#/math), [mermaid](https://shd101wyy.github.io/markdown-preview-enhanced/#/diagrams?id=mermaid), [PlantUML](https://shd101wyy.github.io/markdown-preview-enhanced/#/diagrams?id=plantuml), [pandoc](https://shd101wyy.github.io/markdown-preview-enhanced/#/pandoc), PDF export, [code chunk](https://shd101wyy.github.io/markdown-preview-enhanced/#/code-chunk), [presentation writer](https://rawgit.com/shd101wyy/markdown-preview-enhanced/master/docs/presentation-intro.html), etc. A lot of its ideas are inspired by [Markdown Preview Plus](https://github.com/atom-community/markdown-preview-plus) and [RStudio Markdown](http://rmarkdown.rstudio.com/). Feel free to ask questions, post issues, submit pull request, and request new features. For more information about this project and how to use this extension, please check out our documentation ⬇︎ ## Documentation + To check out the documentation, visit -* [English](https://shd101wyy.github.io/markdown-preview-enhanced/#/) -* [简体中文](https://shd101wyy.github.io/markdown-preview-enhanced/#/zh-cn/) -* [正體中文](https://shd101wyy.github.io/markdown-preview-enhanced/#/zh-tw/) + +* [English](https://shd101wyy.github.io/markdown-preview-enhanced/#/) +* [简体中文](https://shd101wyy.github.io/markdown-preview-enhanced/#/zh-cn/) +* [正體中文](https://shd101wyy.github.io/markdown-preview-enhanced/#/zh-tw/) Contact me if you are willing to help translate the documentation :) ## Keybindings -> The cmd key for *Windows* is ctrl. - -| Shortcuts | Functionality | -|---|---| -| cmd-k v | Open preview | -| ctrl-shift-s | Sync preview / Sync source | -| shift-enter | Run Code Chunk | -| ctrl-shift-enter | Run all Code Chunks | -| cmd-= or cmd-shift-= | Preview zoom in | -| cmd-- or cmd-shift-\_ | Preview zoom out | -| cmd-0 | Preview reset zoom | -| esc | Toggle sidebar TOC | + +> The cmd key for _Windows_ is ctrl. + +| Shortcuts | Functionality | +| ------------------------------------------- | -------------------------- | +| cmd-k v | Open preview | +| ctrl-shift-s | Sync preview / Sync source | +| shift-enter | Run Code Chunk | +| ctrl-shift-enter | Run all Code Chunks | +| cmd-= or cmd-shift-= | Preview zoom in | +| cmd-- or cmd-shift-\_ | Preview zoom out | +| cmd-0 | Preview reset zoom | +| esc | Toggle sidebar TOC | ## Changelog -Please check the [Releases](https://github.com/shd101wyy/vscode-markdown-preview-enhanced/releases) page of this project. + +Please check the [Releases](https://github.com/shd101wyy/vscode-markdown-preview-enhanced/releases) page of this project. ## License -[University of Illinois/NCSA Open Source License](LICENSE.md) + +[University of Illinois/NCSA Open Source License](LICENSE.md) diff --git a/docs/newest.md b/docs/newest.md index 14f4214..ecb55a7 100644 --- a/docs/newest.md +++ b/docs/newest.md @@ -1,39 +1,47 @@ ## 0.2.8 -* Upgraded mume to [0.2.2](https://github.com/shd101wyy/mume/blob/master/CHANGELOG.md). -* Removed `ctrl-shift-i` keybord shortcut. -* Added `Open Preview` command to context menu. -## 0.2.7 -* Added `ignoreLink` option to TOC. -* Fixed issue [#585](https://github.com/shd101wyy/markdown-preview-enhanced/issues/585), [#586](https://github.com/shd101wyy/markdown-preview-enhanced/issues/585). +* Upgraded mume to [0.2.2](https://github.com/shd101wyy/mume/blob/master/CHANGELOG.md). +* Removed `ctrl-shift-i` keybord shortcut. +* Added `Open Preview` command to context menu. -## 0.2.6 -* Removed the `Welcome Page`. -* Supported revealjs `fragment` [#559](https://github.com/shd101wyy/markdown-preview-enhanced/issues/559). -* Supported Experimental Puppeteer export (Headless Chrome). +## 0.2.7 -## 0.2.5 -* Fixed revealjs html export style bug. +* Added `ignoreLink` option to TOC. +* Fixed issue [#585](https://github.com/shd101wyy/markdown-preview-enhanced/issues/585), [#586](https://github.com/shd101wyy/markdown-preview-enhanced/issues/585). + +## 0.2.6 + +* Removed the `Welcome Page`. +* Supported revealjs `fragment` [#559](https://github.com/shd101wyy/markdown-preview-enhanced/issues/559). +* Supported Experimental Puppeteer export (Headless Chrome). + +## 0.2.5 + +* Fixed revealjs html export style bug. * Supported configuring attributes for diagram **containers**. -For example: + For example: - ```puml {.center} - // your code here - ``` - will add `class="center"` to the container. -* By default, all exported files will use `github-light.css` style. You can use your preview theme for export by setting `printBackground` to `true` from the extension settings, or add `print_background:true` to front-matter. + ```puml {.center} + // your code here + ``` + will add `class="center"` to the container. + +* By default, all exported files will use `github-light.css` style. You can use your preview theme for export by setting `printBackground` to `true` from the extension settings, or add `print_background:true` to front-matter. ## 0.2.3 & 0.2.4 + * The old feature [WaveDrom diagram](https://shd101wyy.github.io/markdown-preview-enhanced/#/diagrams?id=wavedrom) is now supported again. * The doc of customization css is updated, please [check it here](https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css). * Sidebar TOC is now supported in HTML export, and it is enabled by default. ![screen shot 2017-08-05 at 8 50 16 pm](https://user-images.githubusercontent.com/1908863/28999904-c40b56b6-7a1f-11e7-9a9e-ab2e19a82b41.png) You can configure the sidebar TOC by front-matter. For more information, please check [this doc](https://shd101wyy.github.io/markdown-preview-enhanced/#/html?id=configuration). + * Upgraded [mume](https://github.com/shd101wyy/mume) to version [0.1.7](https://github.com/shd101wyy/mume/blob/master/CHANGELOG.md). -## 0.2.2 -* Deprecated the old way of defining attribtues (still supported but not recommened) [#529](https://github.com/shd101wyy/markdown-preview-enhanced/issues/529). Now attributes should be defined like below in order to be compatible with the pandoc parser: +## 0.2.2 + +* Deprecated the old way of defining attribtues (still supported but not recommened) [#529](https://github.com/shd101wyy/markdown-preview-enhanced/issues/529). Now attributes should be defined like below in order to be compatible with the pandoc parser: {#identifier .class .class key=value key=value} @@ -54,16 +62,17 @@ For example: \@import "test.png" {width=50% height=30%} -* Added a few more preview themes. -* Supported [vega](https://vega.github.io/vega/) and [vega-lite](https://vega.github.io/vega-lite/). [#524](https://github.com/shd101wyy/markdown-preview-enhanced/issues/524). - * Code block with `vega` notation will be rendered by [vega](https://vega.github.io/vega/). - * Code block with `vega-lite` notation will be rendered by [vega-lite](https://vega.github.io/vega-lite/). - * Both `JSON` and `YAML` inputs are supported. +* Added a few more preview themes. +* Supported [vega](https://vega.github.io/vega/) and [vega-lite](https://vega.github.io/vega-lite/). [#524](https://github.com/shd101wyy/markdown-preview-enhanced/issues/524). + + * Code block with `vega` notation will be rendered by [vega](https://vega.github.io/vega/). + * Code block with `vega-lite` notation will be rendered by [vega-lite](https://vega.github.io/vega-lite/). + * Both `JSON` and `YAML` inputs are supported. - ![screen shot 2017-07-28 at 7 59 58 am](https://user-images.githubusercontent.com/1908863/28718265-d023e1c2-736a-11e7-8678-a29704f3a23c.png) + ![screen shot 2017-07-28 at 7 59 58 am](https://user-images.githubusercontent.com/1908863/28718265-d023e1c2-736a-11e7-8678-a29704f3a23c.png) - You can also [@import](https://shd101wyy.github.io/markdown-preview-enhanced/#/file-imports) a `JSON` or `YAML` file as `vega` diagram, for example: + You can also [@import](https://shd101wyy.github.io/markdown-preview-enhanced/#/file-imports) a `JSON` or `YAML` file as `vega` diagram, for example:\@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