vscode 的 markdown 预览是我们整天都在用的功能,有没有想过它是怎么实现的。或许有一天你会接到个定制 markdown 预览的需求,应该怎么做呢?【推荐学习:《vscode教程》】
其实整体思路比较简单,就是创建一个 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 插件的源码,理清了整体的流程:
- 通过 vscode.window.createWebviewPanel 创建 webviewPanel 来显示 html
- html 通过 editor.document.getText() 拿到文本内容之后通过第三方包生成,设置到 webviewPanel
- 监听 workspace.onDidSaveTextDocument 和 workspace.onDidChangeTextDocument,来拿到最新内容,之后生成 html 通过 webview.postMessage 传递 udpateHTML 的消息来更新到 webview。
- 要注意的是,需要记录一个 map 来保存 uri.fsPath 和 webviewPanel 的对应关系,实现文本内容改变更新对应的 webview
markdown 的预览是一个常见但是并不难的需求,也比较适合入门 vscode 插件的开发,希望这篇文章能够帮大家理清思路。
更多编程相关知识,请访问:编程入门!!
以上是深入了解vscode中markdown预览的实现原理的详细内容。更多信息请关注PHP中文网其他相关文章!

VisualStudio是一款多功能的集成开发环境,支持多种编程语言和完整的开发流程。1)代码编辑:提供智能代码补全和重构。2)调试:内置强大调试工具,支持断点和变量监视。3)版本控制:集成Git和TFVC,方便团队协作。4)测试:支持多种测试类型,确保代码质量。5)部署:提供多种部署选项,支持从本地到云端的部署需求。

VisualStudio适合大型项目开发,VSCode则适用于轻量级和高度可定制的环境。1.VisualStudio提供强大的智能感知和调试功能,适合大型项目和企业级开发。2.VSCode通过扩展系统提供灵活性和自定义能力,适用于多种编程语言和跨平台开发。

VisualStudio订阅提供多种级别,适合不同开发者需求。1.基础版免费,适用于个人和小型团队。2.高级版如Professional和Enterprise,提供高级工具和团队协作功能,适合企业用户。

VisualStudio和VSCode在性能和资源使用上的区别主要体现在:1.启动速度:VSCode更快;2.内存占用:VSCode更低;3.CPU使用率:VisualStudio在编译和调试时更高。选择时需根据项目需求和开发环境决定。

VisualStudio(VS)是微软开发的一款功能强大的集成开发环境(IDE),支持多种编程语言,如C#、C 、Python等。1)它提供了丰富的功能集,包括代码编辑、调试、版本控制和测试。2)VS通过强大的编辑器和调试器处理代码,并使用Roslyn和Clang/MSVC编译器平台支持高级代码分析和重构。3)基本用法如创建C#控制台应用程序,高级用法如实现多态性。4)常见错误可通过设置断点、查看输出窗口和使用即时窗口调试。5)性能优化建议包括使用异步编程、代码重构和性能分析。

在VisualStudio中,代码编译、测试和部署的步骤如下:1.编译:使用VisualStudio的编译器选项将源代码转化为可执行文件,支持多种语言如C#、C 和Python。2.测试:利用内置的MSTest和NUnit等框架进行单元测试,提高代码质量和可靠性。3.部署:通过Web部署、Azure部署等方式,将应用程序从开发环境转移到生产环境,确保安全性和性能。

VisualStudioisMicrosoft'sflagshipIDE,supportingmultipleprogramminglanguagesandenhancingcodingefficiency.1)ItoffersfeatureslikeIntelliSenseforcodeprediction,multi-tabbedinterfaceforprojectmanagement,andtoolsfordebugging,refactoring,andversioncontrol.2

VisualStudio的免费版和付费版的主要区别在于功能的丰富程度和支持的服务。免费版(Community)适用于个人开发者和小型团队,提供基本开发工具;付费版(Professional和Enterprise)则提供高级功能,如高级调试和团队协作工具,适合大型项目和企业级开发。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

Dreamweaver Mac版
视觉化网页开发工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 Linux新版
SublimeText3 Linux最新版

Atom编辑器mac版下载
最流行的的开源编辑器

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具