完璧:C# BlazorでMarkdownを表示し、コードのハイライトを追加する

完璧:C# BlazorでMarkdownを表示し、コードのハイライトを追加する

自分ではかなり完璧だと思っています。以下にその方法を説明します。

最終更新 2022/02/27 17:46
沙漠尽头的狼
読了目安 4 分
カテゴリ
Blazor
タグ
.NET C# Blazor Markdown

昨日、このライブラリ:C# Blazor で Markdown ファイルを表示するを紹介する記事を投稿しました。Blazor で Markdown コンテンツを表示する方法についての記事で、記事内のコードはハイライトされていませんでした。あれこれ考えた結果、ちゃんとやるべきだと思い、この記事.NET C# Blazor サーバーサイドレンダリング Markdownを百度で見つけました。現在のレンダリング結果は以下の通りです。

ほぼ完璧だと思いますので、以下にその方法を説明します。

一、準備

1.1 Markdown から HTML への変換パッケージ追加:Markdig

Markdig:Markdig は、高速、強力、CommonMark準拠、拡張可能な .NET Markdown プロセッサです。

<PackageReference Include="Markdig" Version="0.27.0" />

1.2 Prism プラグインの導入

このPrismはあのPrismとは異なり、JS プラグインです。Prism は軽量で堅牢かつエレガントなシンタックスハイライトライブラリです。これはDabbletの派生プロジェクトです。

_Layout.cshtmlheadに以下を導入します:

<head>
  ....
  <!-- ブラウザスタイルのリセット -->
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/normalize.css@8.0.1/normalize.css"
  />
  <!-- コードブロックテーマ -->
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/themes/prism-coy.min.css"
  />
  <!-- ツールバープラグイン -->
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/plugins/toolbar/prism-toolbar.min.css"
  />
  <!-- 行番号プラグイン -->
  <link
    rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/plugins/line-numbers/prism-line-numbers.min.css"
  />
  ...
</head>
<body>
  ...
  <!-- prism コア js (コードブロックレンダリング用) -->
  <script src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/prism.min.js"></script>
  <!-- コードブロック行番号表示 -->
  <script src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
  <!-- ツールバー (一部プラグインの前提依存) -->
  <script src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/plugins/toolbar/prism-toolbar.min.js"></script>
  <!-- コードブロックの言語名表示 -->
  <script src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/plugins/show-language/prism-show-language.min.js"></script>
  <!-- コードコピー -->
  <script src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js"></script>
  <!-- CDN から対応言語のシンタックスハイライト js を自動読み込み -->
  <script src="https://cdn.jsdelivr.net/npm/prismjs@1.27.0/plugins/autoloader/prism-autoloader.min.js"></script>
</body>

二、使用

Markdown表示を独立したコンポーネントMarkdownComponent.razorに抽出し、読み込むMarkdownファイルの相対パス、リンクする記事の URL、ソースコードの URL をパラメータとして、他のツールでの再利用を容易にしました。以下のコードスニペットは主にこのファイル内にあります。

コンポーネントパラメータ定義:

@code {
    [Parameter]
    public string LocalPostFilePath { get; set; } = null!;

    [Parameter]
    public string RemotePostUrl { get; set; } = null!;

    [Parameter]
    public string SourceCodeUrl { get; set; } = null!;
}

Markdownコンテンツの読み取り、Markdown形式からhtmlへの変換はOnInitializedAsync()メソッド内で定義します:

protected override async Task OnInitializedAsync()
{
    var markdownData = await File.ReadAllTextAsync(LocalPostFilePath);

    // markdown から html へ変換
    var htmlData = Markdown.ToHtml(markdownData);

    // prism がサポートする言語タグに変換(必須ではない。削除可)
    htmlData = htmlData.Replace("language-golang", "language-go");

    // TODO: https://github.com/mganss/HtmlSanitizer を使用して HTML の XSS をサニタイズ
    if (htmlData.Contains("<script") || htmlData.Contains("<link"))
    {
        _hasXss = true;
    }

    // プレーンテキストからレンダリング可能な HTML 型に変換
    _postHtmlContent = (MarkupString) htmlData;
}

最後のステップとして、コンポーネント完了後にPrismプラグインのメソッドを呼び出す必要があります。これはコードハイライトの鍵となるコードで、OnAfterRenderAsync(bool firstRender)メソッドに記述します:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await _jsRuntime.InvokeVoidAsync("Prism.highlightAll");
}

レンダリングは比較的シンプルです(私たちの使い方に限ります)。以下のコードを参照:

<div class="line-numbers">
  @{ if (_hasXss) { @_postHtmlContent.ToString() } else { @_postHtmlContent } }
</div>

IcoTool.razorでこのコンポーネントを呼び出します:

<MarkdownComponent
  LocalPostFilePath="wwwroot/2022/02/2022-02-22_02.md"
  RemotePostUrl="https://dotnet9.com/2022/02/Perfect-Display-Markdown-in-Csharp-Blazor-and-add-code-highlighting"
  SourceCodeUrl="https://github.com/dotnet9/dotnet9.com/blob/develop/src/Dotnet9.Tools.Web/Pages/Public/ImageTools/IcoTool.razor"
/>

もちろん、コンポーネントのカプセル化は個人のニーズ次第です。大まかな考え方は上記の通りで、詳細なコードは掲載しません。興味があればDotnet9 ツールボックス ソースコードを参照してください。

参考記事:

さらに探索

関連読書

その他の記事
同じカテゴリ / 同じタグ 2024/02/29

Winformでもこんなデータ表示ができる

winform開発の過程で、データ表示機能が必要になることがよくあります。これまではgridcontrolコントロールを使用していましたが、今日は例を通して、winform blazor hybridでant design blazorのtableコンポーネントを使ってデータ表示を行う方法を紹介します。

続きを読む
同じカテゴリ / 同じタグ 2024/02/29

Winformの画面も綺麗にできる?

先日、winformでblazor hybridを使用することを紹介しました。また、blazorのUIを組み合わせることでwinformプログラムのデザインをより美しくできると言いました。今回はwinform blazor hybridで描画する例を挙げて説明します。参考になれば幸いです。

続きを読む