中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vscode中markdown預覽的實現原理

發布時間:2021-09-01 19:32:33 來源:億速云 閱讀:231 作者:chen 欄目:軟件技術

這篇文章主要講解了“vscode中markdown預覽的實現原理”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“vscode中markdown預覽的實現原理”吧!

思路分析

通過 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

感謝各位的閱讀,以上就是“vscode中markdown預覽的實現原理”的內容了,經過本文的學習后,相信大家對vscode中markdown預覽的實現原理這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

梁河县| 永宁县| 凤凰县| 昌邑市| 万源市| 巴马| 望奎县| 和田市| 涞水县| 南丹县| 米易县| 六安市| 广宗县| 平昌县| 黑龙江省| 怀安县| 玉林市| 大石桥市| 辽宁省| 犍为县| 静乐县| 新干县| 商洛市| 阿拉尔市| 化州市| 陇南市| 上栗县| 宁乡县| 浏阳市| 桃源县| 新蔡县| 贺州市| 旌德县| 舒兰市| 乌拉特中旗| 政和县| 绥化市| 山阴县| 陇川县| 辰溪县| 中阳县|