网易首页 > 网易号 > 正文 申请入驻

教你实现Vscode的Markdown预览

0
分享至

vscode 的 markdown 预览是我们整天都在用的功能,有没有想过它是怎么实现的。或许有一天你会接到个定制 markdown 预览的需求,应该怎么做呢?

vscode 的 markdown 预览是我们整天都在用的功能,有没有想过它是怎么实现的。或许有一天你会接到个定制 markdown 预览的需求,应该怎么做呢?

有什么思路么?思考五秒钟。

5

4

3

2

1

其实整体思路比较简单,就是创建一个 webview panel,设置内容为 markdown 生成的 html,之后在 markdown 更新的时候同步修改 webview 的 html 就可以了。

思路分析

通过 vscode.window.createWebviewPanel 创建一个 webview,指定在侧边打开,之后通过该 panel 对象的 webview.html 属性来设置 html。

html 是通过编辑器的 markdown 内容生成的, 编辑器内容通过 editor.document.getText() 拿到,然后调用第三方的 markdown 转 html 的库来生成。

这样就完成了 markdown 的预览。

预览之后需要更新,监听 vscode.workspace.onDidSaveTextDocument 和 vscode.workspace.onDidChangeTextDocument 的事件,在文档更新和保存的时候,拿到编辑器的内容,重新生成 html,然后设置到 webview。

webviewPanel 支持 webview.postMessage(message); 的方式传递消息,支持 updateHTML 等一系列 command,可以通过传递消息来触发。

但是怎么知道哪个文档更新哪个 webview 呢?

可以维护一个 map,在创建 webviewPanel 的时候记录到 map 中,key 为文件路径,这样更新的时候就能查找到对应的 webview 进行更新。

这样,就完成了 markdown 内容的更新。

其实整体思路还是比较简单的,下面我们来写下代码:

代码实现

我们看下 vscode-markdown-preview-enhanced 的插件的代码,这也是一个预览 markdown 的插件,代码还算简洁,可以用来学习。

(以下代码是简化后的代码)

首先,插件要指定触发的条件,也就是在 package.json 里面指定 activationEvents:

"activationEvents": [ "onLanguage:markdown", "onCommand:markdown-preview-enhanced.openPreviewToTheSide" ],

这里一个是编辑 markdown 内容的时候激活,一个是执行 command 的时候激活。

具体激活的逻辑在 active 方法里:

export function activate(context: vscode.ExtensionContext) { const contentProvider = new MarkdownPreviewEnhancedView(context); context.subscriptions.push( vscode.commands.registerCommand( "markdown-preview-enhanced.openPreviewToTheSide", openPreviewToTheSide, ), ); function openPreviewToTheSide(uri?: vscode.Uri) { let resource = uri; if (!(resource instanceof vscode.Uri)) { if (vscode.window.activeTextEditor) { resource = vscode.window.activeTextEditor.document.uri; } } contentProvider.initPreview(resource, vscode.window.activeTextEditor, { viewColumn: vscode.ViewColumn.Two, preserveFocus: true, }); } }

我们注册了那个 command,执行 command 会拿到当前 editor 的 url,然后进行 markdown 的 preview。

preview 的所有逻辑都集中定义在了 MarkdownPreviewEnhancedView 的实例对象中,在 command 触发时执行 initPreivew。

public async initPreview( sourceUri: vscode.Uri, editor: vscode.TextEditor, viewOptions: { viewColumn: vscode.ViewColumn; preserveFocus?: boolean }, ) { // 创建 webview let previewPanel: vscode.WebviewPanel = vscode.window.createWebviewPanel( "markdown-preview-enhanced", `Preview ${path.basename(sourceUri.fsPath)}`, viewOptions ); // 监听 webview 的消息 previewPanel.webview.onDidReceiveMessage((message) => {}); // 记录 webview 到 map 中 this.previewMaps[sourceUri.fsPath] = previewPanel; // 拿到编辑器的文本,生成 html const text = editor.document.getText(); engine .generateHTMLTemplateForPreview({inputString: text}) .then((html) => { // 设置 html 到 previewPanel previewPanel.webview.html = html; }); }

在 initWebivew 里面创建 webviewPanel,同时把 webviewPanel 保存到 map 中,key 为文档的文件路径。拿到编辑器文本来生成 html,设置到 webview.html,这样就完成了 markdown 的预览。

这条路径走通之后,我们就实现了 markdown 的预览。

但是只预览一次不行,更新文档之后需要自动更新,我们继续在 active 方法里添加事件监听:

context.subscriptions.push( vscode.workspace.onDidSaveTextDocument((document) => { if (isMarkdownFile(document)) { contentProvider.updateMarkdown(document.uri, true); } }), ); context.subscriptions.push( vscode.workspace.onDidChangeTextDocument((event) => { if (isMarkdownFile(event.document)) { contentProvider.update(event.document.uri); } }), );

监听文本修改和保存的时候,调用 update 方法来更新。

public updateMarkdown(sourceUri: Uri) { // 从 map 中根据文件路径取出对应的 webviewPanel const previewPanel = this.previewMaps[sourceUri.fsPath]; // 生成最新的 html 传递给 webview const text = document.getText(); engine .parseMD(text) .then(({ markdown, html }) => { previewPanel.webview.postMessage({ command: "updateHTML", html }); } }

这里是通过 webview.postMessage 给 html 内容传递 updateHTML 的 command 消息,触发 html 内容的更新。

这样,我们就实现了 markdown 的同步刷新。

总结

vscode 里面 markdown 的预览是一个常用但实现起来并不难的功能,我们看了下 vscode-markdown-preview-enhanced 插件的源码,理清了整体的流程:

  1. 1. 通过 vscode.window.createWebviewPanel 创建 webviewPanel 来显示 html
  2. 2. html 通过 editor.document.getText() 拿到文本内容之后通过第三方包生成,设置到 webviewPanel
  3. 3. 监听 workspace.onDidSaveTextDocument 和 workspace.onDidChangeTextDocument,来拿到最新内容,之后生成 html 通过 webview.postMessage 传递 udpateHTML 的消息来更新到 webview。
  4. 4. 要注意的是,需要记录一个 map 来保存 uri.fsPath 和 webviewPanel 的对应关系,实现文本内容改变更新对应的 webview

markdown 的预览是一个常见但是并不难的需求,也比较适合入门 vscode 插件的开发,希望这篇文章能够帮大家理清思路。

原文来自:https://mp.weixin.qq.com/s/hLqx5RXxCHNfRE9ahvBsxg
本文地址:https://www.linuxprobe.com/vscode-markdown.html编辑:姜 一 一,审核员:逄增宝
Linux命令大全:https://www.linuxcool.com/

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
霍尼普维拉,今日起访华

霍尼普维拉,今日起访华

政知新媒体
2026-07-10 15:54:33
上午被免职,下午被带走,登24年春晚却忽然消失的黄宏如今咋样

上午被免职,下午被带走,登24年春晚却忽然消失的黄宏如今咋样

一盅情怀
2026-06-29 15:10:26
松岛辉空夺冠才2天,张本兄妹新动态曝光,让全日本球迷彻底心寒

松岛辉空夺冠才2天,张本兄妹新动态曝光,让全日本球迷彻底心寒

仙味少女心
2026-07-10 02:47:29
“戏混子”没走,比资本家丑孩子更可怕的是“星二代”开始世袭了

“戏混子”没走,比资本家丑孩子更可怕的是“星二代”开始世袭了

流史岁月
2026-01-26 10:58:30
肾养好人不老!常吃补肾三宝,一周吃两次,腰腿有劲,走路都带风

肾养好人不老!常吃补肾三宝,一周吃两次,腰腿有劲,走路都带风

江江食研社
2026-06-22 09:31:40
原来她是陈冲母亲,出身上海书香门第,是复旦大学教授,才貌双全

原来她是陈冲母亲,出身上海书香门第,是复旦大学教授,才貌双全

白面书誏
2026-07-09 14:27:55
“他说要跟我重组家庭,双向奔赴!”女子失声痛哭,44万现金追回中被抛撒了一路

“他说要跟我重组家庭,双向奔赴!”女子失声痛哭,44万现金追回中被抛撒了一路

环球网资讯
2026-07-10 16:27:21
青岛市纪委监委通报:吕杰被查

青岛市纪委监委通报:吕杰被查

齐鲁壹点
2026-07-09 15:21:14
法网恢恢疏而不漏!释永信案终于判了,这5位女明星也出了口恶气

法网恢恢疏而不漏!释永信案终于判了,这5位女明星也出了口恶气

林轻吟
2026-06-02 07:49:30
白眼狼的下场!印尼没想到,新政下令首个走的是中企,普拉很后悔

白眼狼的下场!印尼没想到,新政下令首个走的是中企,普拉很后悔

掉了颗大白兔糖
2026-07-10 01:16:09
台风“巴威”最新路径公布!上海局部有大到暴雨!

台风“巴威”最新路径公布!上海局部有大到暴雨!

上海徐汇
2026-07-10 07:56:03
1990年母亲和哥哥赶集,算命先生对母亲说:你将来要享这孩子的福

1990年母亲和哥哥赶集,算命先生对母亲说:你将来要享这孩子的福

农村情感故事
2025-03-26 17:48:10
桑切斯踩12厘米鞋跟,陪贝索斯参加夏令营,亿万富翁的胸肌引热议

桑切斯踩12厘米鞋跟,陪贝索斯参加夏令营,亿万富翁的胸肌引热议

译言
2026-07-09 11:38:36
体制内的最大疲惫:明知没意义,还要认真演

体制内的最大疲惫:明知没意义,还要认真演

职场资深秘书
2026-06-27 16:43:45
不顾公平保送梅西?针对“阿根廷VS埃及”比赛中两大争议判罚,国际足联首席裁判官发声

不顾公平保送梅西?针对“阿根廷VS埃及”比赛中两大争议判罚,国际足联首席裁判官发声

极目新闻
2026-07-09 18:59:11
太残暴了!西部战区公布191远火空爆打击S-400雷达靶标画面,旁边还放了一些活羊

太残暴了!西部战区公布191远火空爆打击S-400雷达靶标画面,旁边还放了一些活羊

爱迷彩的老虎
2026-07-08 23:34:56
岳云鹏豪掷千万给5个姐买房,唯独不帮亲弟,根本原因藏不住了

岳云鹏豪掷千万给5个姐买房,唯独不帮亲弟,根本原因藏不住了

古事寻踪记
2026-07-09 16:39:01
我晒的腊肉被公公全送人,第二年我不买肉,腊月公公催:没眼力见

我晒的腊肉被公公全送人,第二年我不买肉,腊月公公催:没眼力见

晓艾故事汇
2026-07-10 08:38:29
家里藏有这4款“老酒”要留意!每瓶售价不低于茅台,别喝也别卖

家里藏有这4款“老酒”要留意!每瓶售价不低于茅台,别喝也别卖

涛哥美食汇
2026-07-10 08:45:51
网传包头一检察官出狱后自杀,曾被当庭举报索贿30万引爆舆论

网传包头一检察官出狱后自杀,曾被当庭举报索贿30万引爆舆论

追月数星
2026-07-10 16:38:50
2026-07-10 17:36:49
孙有匪 incentive-icons
孙有匪
科技
1595文章数 2008关注度
往期回顾 全部

科技要闻

中国开启可回收火箭时代

头条要闻

特朗普:"伊朗要杀我"的情报来自以色列 我算有点走运

头条要闻

特朗普:"伊朗要杀我"的情报来自以色列 我算有点走运

体育要闻

法国VS摩洛哥:谁才是臭外地的?

娱乐要闻

韩国顶流李钟硕与IU官宣分手!

财经要闻

长征十号乙首飞告捷 海上网系回收成功

汽车要闻

长续航智美纯电轿跑 奇瑞风云A9开启预售11.59万起

态度原创

教育
时尚
艺术
房产
本地

教育要闻

父亲半路开香槟:女儿力争清北、华五备选、C9保底,录取结果来了

汇聚资本力量,共话时尚未来——2026中国时尚产业盛典投资峰会明日启幕

艺术要闻

刚在纳斯达克融了265亿美元,SK海力士上海总部长这样!

房产要闻

海口,终于要发力卖地了!

本地新闻

重庆人有自己的避暑桃花源 | 夏天就去「酉」风的地方!

无障碍浏览 进入关怀版