搜尋
首頁開發工具VSCode深入了解vscode中markdown預覽的實作原理

深入了解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刪除
Visual Studio的目的:代碼編輯,調試等等Visual Studio的目的:代碼編輯,調試等等Apr 29, 2025 am 12:48 AM

VisualStudio是一款多功能的集成開發環境,支持多種編程語言和完整的開發流程。 1)代碼編輯:提供智能代碼補全和重構。 2)調試:內置強大調試工具,支持斷點和變量監視。 3)版本控制:集成Git和TFVC,方便團隊協作。 4)測試:支持多種測試類型,確保代碼質量。 5)部署:提供多種部署選項,支持從本地到雲端的部署需求。

Visual Studio vs.vs代碼:代碼編輯器的比較Visual Studio vs.vs代碼:代碼編輯器的比較Apr 28, 2025 am 12:15 AM

VisualStudio適合大型項目開發,VSCode則適用於輕量級和高度可定制的環境。 1.VisualStudio提供強大的智能感知和調試功能,適合大型項目和企業級開發。 2.VSCode通過擴展系統提供靈活性和自定義能力,適用於多種編程語言和跨平台開發。

Visual Studio的定價:了解訂閱模型Visual Studio的定價:了解訂閱模型Apr 27, 2025 am 12:15 AM

VisualStudio訂閱提供多種級別,適合不同開發者需求。 1.基礎版免費,適用於個人和小型團隊。 2.高級版如Professional和Enterprise,提供高級工具和團隊協作功能,適合企業用戶。

Visual Studio與代碼:性能和資源使用情況Visual Studio與代碼:性能和資源使用情況Apr 26, 2025 am 12:18 AM

VisualStudio和VSCode在性能和資源使用上的區別主要體現在:1.啟動速度:VSCode更快;2.內存佔用:VSCode更低;3.CPU使用率:VisualStudio在編譯和調試時更高。選擇時需根據項目需求和開發環境決定。

Visual Studio:C#,C等的IDEVisual Studio:C#,C等的IDEApr 25, 2025 am 12:10 AM

VisualStudio(VS)是微軟開發的一款功能強大的集成開發環境(IDE),支持多種編程語言,如C#、C 、Python等。 1)它提供了豐富的功能集,包括代碼編輯、調試、版本控制和測試。 2)VS通過強大的編輯器和調試器處理代碼,並使用Roslyn和Clang/MSVC編譯器平台支持高級代碼分析和重構。 3)基本用法如創建C#控制台應用程序,高級用法如實現多態性。 4)常見錯誤可通過設置斷點、查看輸出窗口和使用即時窗口調試。 5)性能優化建議包括使用異步編程、代碼重構和性能分析。

Visual Studio:代碼編譯,測試和部署Visual Studio:代碼編譯,測試和部署Apr 24, 2025 am 12:05 AM

在VisualStudio中,代碼編譯、測試和部署的步驟如下:1.編譯:使用VisualStudio的編譯器選項將源代碼轉化為可執行文件,支持多種語言如C#、C 和Python。 2.測試:利用內置的MSTest和NUnit等框架進行單元測試,提高代碼質量和可靠性。 3.部署:通過Web部署、Azure部署等方式,將應用程序從開發環境轉移到生產環境,確保安全性和性能。

Visual Studio:綜合開發環境簡介(IDE)Visual Studio:綜合開發環境簡介(IDE)Apr 23, 2025 am 12:02 AM

VisualStudioismicrosoft'sflagshipide,支持multipleProgrammingLanguagesandEnhancingCodingQodings.1)ItoffersFeaterSfeaturesLikeInkIntellisensensensensensensensensensensensensensensensensenseforcodePrediction,Multi-TabbedInterfaceForProproject Managements,andToolsfordEbugging,andToolsfordEbugging,Repactioning,andVersionControl.2

Visual Studio:探索免費和付費產品Visual Studio:探索免費和付費產品Apr 22, 2025 am 12:09 AM

VisualStudio的免費版和付費版的主要區別在於功能的豐富程度和支持的服務。免費版(Community)適用於個人開發者和小型團隊,提供基本開發工具;付費版(Professional和Enterprise)則提供高級功能,如高級調試和團隊協作工具,適合大型項目和企業級開發。

See all articles

熱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

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

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具