ホームページ >開発ツール >VSCode >vscode でのマークダウン プレビューの実装原理を深く理解する

vscode でのマークダウン プレビューの実装原理を深く理解する

青灯夜游
青灯夜游転載
2021-09-01 18:13:173054ブラウズ

vscode でのマークダウン プレビューの実装原理を深く理解する

vscode のマークダウン プレビューは、私たちが一日中使用する機能ですが、それがどのように実装されているか考えたことはありますか?おそらくいつか、カスタマイズされたマークダウン プレビューのリクエストを受け取ることになるでしょう。 [推奨学習: "vscode チュートリアル "]

実際、全体的なアイデアは比較的単純です。Web ビュー パネルを作成し、コンテンツをマークダウンによって生成された HTML に設定し、その後、マークダウンが更新されるときに同時に Web ビューを変更します。html で実行します。

アイデア分析

vscode.window.createWebviewPanel を通じて Web ビューを作成し、横に開くように指定して、パネル オブジェクトの webview.html 属性を通じて HTML を設定します。

html は、エディターのマークダウン コンテンツを通じて生成されます。エディターのコンテンツは editor.document.getText() を通じて取得され、サードパーティのマークダウンから HTML への変換ライブラリが呼び出されて生成されます。

これでマークダウンのプレビューが完了しました。

プレビューを更新する必要がある場合は、vscode.workspace.onDidSaveTextDocument および vscode.workspace.onDidChangeTextDocument のイベントをリッスンします。ドキュメントが更新されて保存されたら、エディターのコンテンツを取得し、HTML を再生成します。そしてそれをWebViewに設定します。

WebviewPanel は、メッセージを渡すために webview.postMessage(message); をサポートし、メッセージを渡すことによってトリガーできる updateHTML などの一連のコマンドをサポートします。

しかし、どのドキュメントがどの Web ビューを更新するかをどうやって知るのでしょうか?

webviewPanel の作成時にマップを維持し、マップに記録できます。更新時に対応する Webview を見つけて更新できるように、キーはファイル パスです。

これでマークダウン内容の更新が完了します。

実際、全体的なアイデアは比較的単純です。コードを書き留めてみましょう。

コードの実装

vscode-markdown-preview のコードを見てみましょう-enhanced plug-in. これもマークダウンをプレビューするためのプラグインです. コードは非常にシンプルなので、学習に使用できます。

(次のコードは簡略化されたコードです)

まず、プラグインはトリガー条件を指定する必要があります。つまり、package.json で activityEvents を指定する必要があります:

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

Here is マークダウンコンテンツの編集時にアクティブになるものと、コマンドの実行時にアクティブになるものがあります。

特定のアクティブ化ロジックは 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,
    });
  }
}

コマンドを登録しました。コマンドを実行すると、現在のエディターの URL が取得され、マークダウンがプレビューされます。

プレビューのロジックはすべて MarkdownPreviewEnhancedView のインスタンス オブジェクトで一元的に定義されており、コマンドがトリガーされると 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 をマップに保存します。キーはドキュメントのファイル パスです。 HTML を生成するためのエディター テキストを取得し、それを webview.html に設定すると、マークダウン プレビューが完了します。

このパスを通過すると、マークダウンのプレビューが実現します。

しかし、一度プレビューするだけでは十分ではありません。ドキュメントを更新した後、自動的に更新する必要があります。アクティブなメソッドにイベント監視を追加し続けます:

  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 を通じて updateHTML コマンド メッセージを HTML コンテンツに渡し、HTML コンテンツの更新をトリガーします。

このようにして、マークダウンの同期更新を実現します。

概要

vscode のマークダウンのプレビューは一般的に使用されていますが、実装は難しくありません。vscode-markdown-preview-enhanced プラグインのソース コードを調べて明確にしました。全体的なプロセス:

  • vscode.window.createWebviewPanel を介して webviewPanel を作成し、html
  • html を表示します。 editor.document.getText() を介してテキスト コンテンツを取得した後、それを生成します。サードパーティのパッケージを取得し、それを webviewPanel に設定します
  • workspace.onDidSaveTextDocument と workspace.onDidChangeTextDocument をリッスンして最新のコンテンツを取得し、HTML を生成し、webview.postMessage を通じて udpateHTML メッセージを渡すことによって Webview に更新します。
  • テキストの内容が変更され、対応する webview が更新されるように、uri.fsPath と webviewPanel の間の対応する関係を保存するにはマップを記録する必要があることに注意してください。マークダウンのプレビューは一般的ですが、難しい要件ではなく、エントリーレベルの vscode プラグイン開発に適しています。この記事があなたのアイデアを明確にするのに役立つことを願っています。
プログラミング関連の知識について詳しくは、

プログラミング入門

をご覧ください。 !

以上がvscode でのマークダウン プレビューの実装原理を深く理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。