目錄
思路分析
程式碼實作
總結
首頁 開發工具 VSCode 深入了解vscode中markdown預覽的實作原理

深入了解vscode中markdown預覽的實作原理

Sep 01, 2021 pm 06:13 PM
vscode

深入了解vscode中markdown預覽的實作原理

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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1663
14
CakePHP 教程
1419
52
Laravel 教程
1313
25
PHP教程
1263
29
C# 教程
1236
24
vscode需要什麼電腦配置 vscode需要什麼電腦配置 Apr 15, 2025 pm 09:48 PM

VS Code 系統要求:操作系統:Windows 10 及以上、macOS 10.12 及以上、Linux 發行版處理器:最低 1.6 GHz,推薦 2.0 GHz 及以上內存:最低 512 MB,推薦 4 GB 及以上存儲空間:最低 250 MB,推薦 1 GB 及以上其他要求:穩定網絡連接,Xorg/Wayland(Linux)

vscode怎麼定義頭文件 vscode怎麼定義頭文件 Apr 15, 2025 pm 09:09 PM

如何使用 Visual Studio Code 定義頭文件?創建頭文件並使用 .h 或 .hpp 後綴命名在頭文件中聲明符號(例如類、函數、變量)使用 #include 指令在源文件中包含頭文件編譯程序,頭文件將被包含並使聲明的符號可用

vscode終端使用教程 vscode終端使用教程 Apr 15, 2025 pm 10:09 PM

vscode 內置終端是一個開發工具,允許在編輯器內運行命令和腳本,以簡化開發流程。如何使用 vscode 終端:通過快捷鍵 (Ctrl/Cmd ) 打開終端。輸入命令或運行腳本。使用熱鍵 (如 Ctrl L 清除終端)。更改工作目錄 (如 cd 命令)。高級功能包括調試模式、代碼片段自動補全和交互式命令歷史。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

vscode終端常用命令 vscode終端常用命令 Apr 15, 2025 pm 10:06 PM

VS Code 終端常用命令包括:清除終端屏幕(clear)列出當前目錄文件(ls)更改當前工作目錄(cd)打印當前工作目錄路徑(pwd)創建新目錄(mkdir)刪除空目錄(rmdir)創建新文件(touch)刪除文件或目錄(rm)複製文件或目錄(cp)移動或重命名文件或目錄(mv)顯示文件內容(cat)查看文件內容並滾動(less)查看文件內容只能向下滾動(more)顯示文件前幾行(head)

vscode中文註釋變成問號怎麼解決 vscode中文註釋變成問號怎麼解決 Apr 15, 2025 pm 11:36 PM

解決 Visual Studio Code 中中文註釋變為問號的方法:檢查文件編碼,確保為“UTF-8 without BOM”。更改字體為支持中文字符的字體,如“宋體”或“微軟雅黑”。重新安裝字體。啟用 Unicode 支持。升級 VSCode,重啟計算機,重新創建源文件。

vscode上一步下一步快捷鍵 vscode上一步下一步快捷鍵 Apr 15, 2025 pm 10:51 PM

VS Code 一步/下一步快捷鍵的使用方法:一步(向後):Windows/Linux:Ctrl ←;macOS:Cmd ←下一步(向前):Windows/Linux:Ctrl →;macOS:Cmd →

vscode終端命令不能用 vscode終端命令不能用 Apr 15, 2025 pm 10:03 PM

VS Code 終端命令無法使用的原因及解決辦法:未安裝必要的工具(Windows:WSL;macOS:Xcode 命令行工具)路徑配置錯誤(添加可執行文件到 PATH 環境變量中)權限問題(以管理員身份運行 VS Code)防火牆或代理限制(檢查設置,解除限制)終端設置不正確(啟用使用外部終端)VS Code 安裝損壞(重新安裝或更新)終端配置不兼容(嘗試不同的終端類型或命令)特定環境變量缺失(設置必要的環境變量)

See all articles