>개발 도구 >VSCode >vscode의 마크다운 미리보기 구현 원리에 대한 심층적인 이해

vscode의 마크다운 미리보기 구현 원리에 대한 심층적인 이해

青灯夜游
青灯夜游앞으로
2021-09-01 18:13:173106검색

vscode의 마크다운 미리보기 구현 원리에 대한 심층적인 이해

vscode의 마크다운 미리보기는 우리가 하루 종일 사용하는 기능인데 어떻게 구현되는지 궁금하신가요? 언젠가는 맞춤형 마크다운 미리보기 요청을 받게 될 것입니다. 어떻게 해야 할까요? [추천학습: "vscode tutorial"]

사실 전체적인 아이디어는 상대적으로 간단합니다. 웹뷰 패널을 생성하고, 마크다운으로 생성된 html에 콘텐츠를 설정한 후, 웹뷰의 html을 동기적으로 수정하는 것입니다. 마크다운이 업데이트될 때.

아이디어 분석

vscode.window.createWebviewPanel을 통해 웹뷰를 생성하고, 측면에서 열리도록 지정한 후, 패널 객체의 webview.html 속성을 통해 html을 설정합니다.

html은 편집기의 마크다운 콘텐츠를 통해 생성됩니다. 편집기 콘텐츠는 editor.document.getText()를 통해 얻은 다음 이를 생성하기 위해 타사 마크다운-html 변환 라이브러리를 호출합니다.

이걸로 마크다운 미리보기가 완료됩니다.

미리 본 후 업데이트해야 합니다. vscode.workspace.onDidSaveTextDocument 및 vscode.workspace.onDidChangeTextDocument의 이벤트를 듣고 문서가 업데이트되고 저장되면 편집기의 내용을 가져오고 html을 다시 생성한 다음 설정합니다. 웹뷰로 갑니다.

webviewPanel은 메시지 전달을 위해 webview.postMessage(message)를 지원하고, 메시지 전달을 통해 트리거될 수 있는 updateHTML과 같은 일련의 명령을 지원합니다.

하지만 어떤 문서가 어떤 웹뷰를 업데이트하는지 어떻게 알 수 있나요?

webviewPanel 생성 시 지도를 유지하고 지도에 기록할 수 있습니다. 핵심은 파일 경로이므로 업데이트 시 해당 웹뷰를 찾아서 업데이트할 수 있습니다.

이로써 마크다운 콘텐츠 업데이트가 완료되었습니다.

사실 전체적인 아이디어는 비교적 간단합니다. 아래 코드를 작성해 보겠습니다.

코드 구현

vscode-markdown-preview-enhanced 플러그인의 코드를 살펴보겠습니다. 마크다운을 미리보기 위한 코드입니다. 학습에 사용할 수 있습니다.

(다음 코드는 단순화된 코드입니다)

우선 플러그인에서 트리거 조건을 지정해야 합니다. 즉, package.json에 activateEvents를 지정해야 합니다.

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

하나는 마크다운 콘텐츠 편집 시 활성화되고, 다른 하나는 활성화를 위한 명령 시간을 실행하는 것입니다.

특정 활성화 로직은 활성 메서드에 있습니다:

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);
      }
    }),
  );

텍스트 수정을 모니터링하고 저장할 때 업데이트 메서드를 호출하여 업데이트합니다. .

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은 html을 표시하는 webviewPanel을 생성합니다. .onDidSaveTextDocument 및 Workspace.onDidChangeTextDocument를 사용하여 최신 콘텐츠를 가져옵니다. 그런 다음 html을 생성하고 webview.postMessage를 통해 udpateHTML 메시지를 전달하여 webview로 업데이트합니다.
  • uri.fsPath와 webviewPanel 사이의 해당 관계를 저장하려면 지도를 기록해야 텍스트 내용이 해당 웹뷰를 변경하고 업데이트할 수 있다는 점에 유의해야 합니다. Markdown 미리 보기는 일반적이지만 어렵지 않은 요구 사항입니다. 또한 시작하기에 더 적합합니다. vscode 플러그인 개발과 관련하여 이 기사가 귀하의 아이디어를 명확히 하는 데 도움이 되기를 바랍니다.
  • 더 많은 프로그래밍 관련 지식을 보려면
  • 프로그래밍 소개
  • 를 방문하세요! !

위 내용은 vscode의 마크다운 미리보기 구현 원리에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제