VSCode插件开发之Markdown扩展功能

背景

新的文档采用Git+Markdown实现,本地需要一个好Markdown编辑器,最后选择使用vscode轻量级文本编辑器。

Markdown是一种轻量级的标记语言,虽然优化很多,但有两个明显的缺点:

  1. 图片添加及管理
  2. 表格添加及管理

表格可以采用在线文档替代,再分享或截图添加,图片的管理方式主要是有如下几种:

  1. 图片先上传到图床等cdn服务器,通过生成的网络地址引用
  2. 放置统一的目录,如根目录的img文件夹,再通过相对路径添加
  3. 通过文档名称创建文件夹,把markdown文件和图片资源统一放入

每种方式都各有优缺点,最终考虑到文档的可读性及图片管理,采用了方案2和3的融合方式:

1
2
3
4
5
├── 文档.md
├── img
└── 文档
├── a.png
└── b.png

可以通过vscode的插件Paste Image实现从剪贴板自动复制图片到上述目录,如此插件有两个问题:

  1. 文件目录需要手动创建,不能自动创建
  2. 显示的图片不能修改显示大小,需要手动改为img标签来修改

通过git来管理文档还有比较严重的问题:无法快速的分享文档链接,需要通过web版git获取文档地址

需求及效果

需求如下:

  1. 从剪贴板自动复制图片,同时满足如下要求:
  2. 图片保存到以当前Markdown文件命名的文件里
  3. 通过img标签添加,默认width=500
  4. 获取当前文件的相对路径,并生成gitlab的在线地址

效果如下:

VSCode插件开发流程

参考官方文档:

  1. Your First Extension
  2. Publishing Extensions

阅读上面官方文档,通过代码脚手架,生成Hello World模板工程。

关键点:extension要选择typescript类型,方便复用第三方插件源码。

常用命令:

  1. F5:运行
  2. npm run publish:发布部署

Git Markdown Tools插件开发

vscode的插件开发很简单,如下图所示:

剪贴版复制图片,并设置默认大小

此功能是基于Paste Image插件的源码做的微调,新增img选择,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static renderFilePath(languageId: string, basePath: string, imageFilePath: string): string {
....
let imageSyntaxPrefix = "";
let imageSyntaxSuffix = "";
switch (languageId) {
case "markdown":
imageSyntaxPrefix = `![](`;
imageSyntaxSuffix = `)`;
break;
case "asciidoc":
imageSyntaxPrefix = `image::`;
imageSyntaxSuffix = `[]`;
break;
case "img": // 新增标签类型
imageSyntaxPrefix = `<img src="`;
imageSyntaxSuffix = `" width = "500" />`;
break;
}
....
return result;
}

在右键菜单里添加相应的快捷入口,只需要配置package.json文件即可,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
....
"activationEvents": [
"onCommand:git-markdown-tools.MarkdownImagePastePrimary",
"onCommand:git-markdown-tools.MarkdownImagePasteSubsidiary",
],
"contributes": {
"commands": [
{
"command": "git-markdown-tools.MarkdownImagePastePrimary",
"title": "粘贴图片-Primary",
"category": "58IGit"
},
{
"command": "git-markdown-tools.MarkdownImagePasteSubsidiary",
"title": "粘贴图片-Subsidiary",
"category": "58IGit"
}
],
"menus": {
"editor/context": [ // 编辑器界面
{
"command": "git-markdown-tools.MarkdownImagePastePrimary",
"group": "navigation"
},
{
"command": "git-markdown-tools.MarkdownImagePasteSubsidiary",
"group": "navigation"
}
]
}
}
}

Paste Image插件本身有一个问题:不支持直接复制本地的图片文件。

通过分析Paste Image的源码了解到,剪贴板的操作不是通过javascript实现的,而是通过调用对应平台的脚本实现:

  1. mac:AppleScript脚本
  2. linux:shell脚本

在macOS里,直接复制图片文件到剪贴板时,剪贴板里只有相应的文件路径,没有相应的图片内容,Paste Image的AppleScript脚本不支持这种类型,这个是后续需要修改点。

获取当前Markdown的远程Git地址

这个功能非常简单,主过程是如下:

  1. 先获取当前Markdown文件相对路径
  2. 拼接上相应服务器的地址即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public static copyRemoteUrlToClipboard(){
// get current edit file path
let editor = vscode.window.activeTextEditor;
if(!editor) {
return;
}

let fileUri = editor.document.uri;
if(!fileUri) {
return;
}

// 获取文件的相对路径,相对于项目根目录
let filePath = fileUri.fsPath;
let projectPath = vscode.workspace.rootPath;
let fileRelativePath = filePath.replace(projectPath ?? '', '');

// 通过配置获取远程项目的url地址,git-markdown-tools.romoteurl,'http://igit.58corp.com/wuxian-doc/58app'
let projectRomoteUrlConfig = vscode.workspace.getConfiguration('git-markdown-tools')['romoteurl'];
if (!projectRomoteUrlConfig) {
Logger.showErrorMessage(`The config git-markdown-tools.romoteurl = '${projectRomoteUrlConfig}' is invalid. please check your config.`);
return;
}

let remoteUrl = GitShare.getRemoteUrl(projectRomoteUrlConfig, 'master', fileRelativePath);

vscode.env.openExternal(vscode.Uri.parse(remoteUrl));
}

/**
* 拼接远程url地址
* @param projectRomoteUrl 用户配置,如:http://igit.58corp.com/wuxian-doc/58app
* @param branch master分支,还是当前分支
* @param fileRelativePath 当前文件的相对路径,如:技术文档/请求的Header过大调研.md
*/
private static getRemoteUrl(projectRomoteUrl: string, branch: string, fileRelativePath: string): string{
return `${projectRomoteUrl}/blob/${branch}${fileRelativePath}`;
}

在右键菜单里添加相应的快捷入口,只需要配置package.json文件即可,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
...
"activationEvents": [
"onCommand:git-markdown-tools.CopyRemoteUrlToClipboard"
],
"contributes": {
"commands": [
{
"command": "git-markdown-tools.CopyRemoteUrlToClipboard",
"title": "打开远程Master地址",
"category": "58IGit"
}
],
"menus": {
"editor/title/context": [
{
"command": "git-markdown-tools.CopyRemoteUrlToClipboard",
"group": "navigation"
}
],
"editor/context": [
{
"command": "git-markdown-tools.CopyRemoteUrlToClipboard",
"group": "navigation"
}
]
}
}
}

GitHub开源地址

  1. 源码地址:https://github.com/handsomeliuyang/vscode-git-markdown-tools.git
  2. 插件安装地址:https://marketplace.visualstudio.com/items?itemName=handsomeliuyang.git-markdown-tools&ssr=false#overview

参考

  1. vscode-paste-image
  2. Your First Extension
  3. vscode-gitlens
感谢您的阅读,本文由 刘阳 版权所有。如若转载,请注明出处:刘阳(https://handsomeliuyang.github.io/2020/10/24/%E7%BB%8F%E9%AA%8C%E6%80%BB%E7%BB%93/VSCode%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E4%B9%8BMarkdown%E6%89%A9%E5%B1%95%E5%8A%9F%E8%83%BD/
双开系列:AIDL原理简介及动态扩展实现
hexo本地静态搜索实现