Perfect: Display Markdown in C#Blazor and add code highlighting

Perfect: Display Markdown in C#Blazor and add code highlighting

I think it should be perfect, so let's talk about how to do it.

最后更新 2/27/2022 5:46 PM
沙漠尽头的狼
预计阅读 4 分钟
分类
Blazor
标签
.NET C# Blazor Markdown

昨天发了一篇介绍这个库:C# Blazor 中显示 Markdown 文件,介绍怎么在 Blazor 中显示 Markdown 内容的文章,文章内的代码是没有高亮的,思来相去,还是要做好,于是百度到这篇文章.NET C# Blazor 服务端渲染 Markdown,现在渲染效果如下:

I think it should be perfect, so let's talk about how to do it.

1. Preparation tools

1.1 Add Markdown to html package: Markdig

Markdig:Markdig 是一个快速、强大、符合CommonMark标准、可扩展的 .NET Markdown 处理器。

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

1.2 Introducing the Prism plug-in

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>

2. Use

我将Markdown展示单独提取成了组件MarkdownComponent.razor,将加载的Markdown文件相对路径、需要链接的文章链接和源码链接做成参数,方便后面其他工具复用,下面的代码片段主要在这个文件内。

Component parameter definition:

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

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

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

Markdown内容读取,Markdown格式转htmlOnInitializedAsync()方法中定义:

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

Rendering is relatively simple (for our use only), see the following code:

<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 工具箱源码

Reference article:

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 11/6/2024

Why is my blog site back in Blazor?

The blog website has gone through hardships in development. It has tried nearly 10 versions such as MVC, Vue, and Go. Now it has returned to Blazor and adopts static SSR. The speed has skyrocketed and it has been successfully launched.

继续阅读
同分类 / 同标签 2/29/2024

Data display can also be done in Winform

In the process of developing winform, data display functions are often needed. I have been using the gridcontrol before. Today, I want to use an example to introduce to you how to use the table component in ant design blazor hybrid to display data.

继续阅读
同分类 / 同标签 2/29/2024

Can Winform's interface become better?

A few days ago, I introduced to you the use of blazor hybrid in winform, and I also said that with blazor's ui, our winform program design can be more beautiful. Next, I want to use an example of drawing in winform blazor hybrid to illustrate it, hoping to be helpful to you.

继续阅读