基於.NetCore開發部落格項目 StarBlog – (19) Markdown渲染方案探索
- 2022 年 10 月 28 日
- 筆記
- .Net / AspNetCore, ASP.NetCore, StarBlog部落格開發筆記
前言
筆者認為,一個部落格網站,最核心的是閱讀體驗。
在開發StarBlog的過程中,最耗時的恰恰也是文章的展示部分功能。
最開始還沒研究出來如何很好的使用後端渲染,所以只能先用Editor.md組件做前端渲染,過渡一下。前端渲染我是不滿意的,因為性能較差,頁面載入出來還會閃一下,有割裂感,影響體驗。
現在我已經做出了比較完善的後端渲染方案,前端渲染就可以直接退休了。本文介紹StarBlog部落格開發過程中的各種Markdown渲染方案(主要是介紹後端渲染)。
兩種方案
前端渲染
使用 Editor.md 組件進行渲染,效果差強人意,主要是看中了其可以生成 ToC(文章目錄) 的功能,但生成的 ToC 效果也比較差,後面是我fork了一份源碼進行魔改才好一點。
魔改過程在這篇文章:魔改editormd組件,優化ToC渲染效果
優化 ToC 的這個功能我給官方提了PR,但沒有響應,看了一下GitHub里有幾十個PR,上次提交也是快4年前的事了,看來這個項目真的涼了……
除了這個 editor.md ,還有其他幾個前端的方案:
看起來都不錯,有沒有 ToC 我沒研究,部落格園上有大佬寫了一篇比較的文章,有興趣的同學可以在參考資料中看看~
後端渲染
目前 C# 可用的 Markdown 庫似乎只有 Markdig ,一開始我還在吐槽文檔缺失導致很難用,甚至一度想自己造輪子重新做一個,不過最近有所改善,在研究了官方新增的幾個文檔之後,我對這個庫的了解又加深了一些,功能確實很多,設計得也不錯,擴展性很好~
所以暫時就用這個啦~
目前我的做法是用 Markdig 將 Markdown 生成 HTML,然後前端展示這個 HTML ,再結合 Bootstrap 或者 github-markdown-css 等樣式庫來美化正文顯示效果,用 highlight.js 之類的JS庫實現程式碼高亮。
至於文章的 ToC ,Markdig 沒有現成的,我自己造輪子實現~
詳見這篇文章:C#實現生成Markdown文檔目錄樹
其實算是一種混合式的方案吧~
接下來介紹的內容圍繞後端渲染展開。
處理 ToC
上一篇文章對於生成目錄樹已經說得比較清楚了,本文不再重複那麼多,只說一下有區別的地方~
先解析Markdown文檔,拿到所有標題節點
var headings = new List<Heading>();
foreach (var heading in document.Descendants<HeadingBlock>()) {
var item = new Heading {Level = heading.Level, Text = heading.Inline?.FirstChild?.ToString()};
headings.Add(item);
}
遍歷進行處理。
原本直接把標題作為錨點的 href
屬性,實際使用的時候是不行的,根據測試,Markdig生成錨點ID的規則如下
中文按照
- section
- section-1
- section-2
- …
section後面的數字是在所有中文標題里出現的順序,不是在全部標題裡面的順序。
英文就替換空格 + 轉小寫 (未考慮其他情況,事實上應該把特殊符號也一併替換掉)
所以處理 href
的時候分兩種情況,用正則表達式 [\u4e00-\u9fbb]
檢測是否包含中文字元。
var chineseTitleCount = 0;
for (var i = 0; i < headings.Count; i++) {
var item = headings[i];
var text = item.Text ?? "";
if (Regex.IsMatch(text, "[\u4e00-\u9fbb]")) {
item.Slug = chineseTitleCount == 0 ? "section" : $"section-{chineseTitleCount}";
chineseTitleCount++;
}
else {
item.Slug = text.Replace(" ", "-").ToLower();
}
// ...
}
搞定
樣式
bootstrap 默認樣式
默認樣式還可以,不過會覺得少了點啥,或許可以研究一下各種在線Markdown編輯器的樣式~
github-markdown-css
顧名思義是GitHub的markdown樣式
地址: //www.npmjs.com/package/github-markdown-css
安裝後有三個文件
- github-markdown.css: (默認) 通過
@media (prefers-color-scheme)
實現自動切換亮色/暗色主題 - github-markdown-light.css: 亮色主題
- github-markdown-dark.css: 暗色主題
官網還有一句話,但我不知道怎麼自己生成,難道要我去github扒css下來?
You may know that now GitHub supports more than 2 themes including
dark_dimmed
,dark_high_contrast
andcolorblind
variants. If you want to try these themes, you can generate them on your own!
安裝
yarn add github-markdown-css
引入
<link rel="stylesheet" href="~/lib/github-markdown-css/github-markdown-light.css">
使用
<div class="markdown-body">
@Html.Raw(Model.ContentHtml)
</div>
效果
確實有GitHub內味了,但還沒程式碼高亮
程式碼高亮
目前使用 highlight.js
包,官網: //www.npmjs.com/package/highlight.js
有很多其他的工具,不展開了,用這個足夠了~
下載
要在網頁上直接用沒辦法通過安裝NPM包的方式,只能通過網址下載: //highlightjs.org/download/
如果不想下載的話可以用CDN,但就只能支援部分語言高亮。
裡面有好多種語言,竟然沒全選按鈕,一個個選太麻煩了,我寫了個全選腳本,複製到瀏覽器控制台執行就能全選,然後下載。
document.querySelectorAll('input').forEach( item => {
if(item.getAttribute('type')==='checkbox') item.checked=true
})
引入
下載後把zip解壓放到 wwwroot/lib
下
<link rel="stylesheet" href="~/lib/highlight/styles/default.min.css">
<script src="~/lib/highlight/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
或者不下載,直接使用 CDN
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
效果
有了程式碼高亮,一下就不一樣了
還有很多其他主題,styles
目錄下很多,引入css的時候自行選擇即可
我來換個深色的主題看看
系列文章
- 基於.NetCore開發部落格項目 StarBlog – (1) 為什麼需要自己寫一個部落格?
- 基於.NetCore開發部落格項目 StarBlog – (2) 環境準備和創建項目
- 基於.NetCore開發部落格項目 StarBlog – (3) 模型設計
- 基於.NetCore開發部落格項目 StarBlog – (4) markdown部落格批量導入
- 基於.NetCore開發部落格項目 StarBlog – (5) 開始搭建Web項目
- 基於.NetCore開發部落格項目 StarBlog – (6) 頁面開發之部落格文章列表
- 基於.NetCore開發部落格項目 StarBlog – (7) 頁面開發之文章詳情頁面
- 基於.NetCore開發部落格項目 StarBlog – (8) 分類層級結構展示
- 基於.NetCore開發部落格項目 StarBlog – (9) 圖片批量導入
- 基於.NetCore開發部落格項目 StarBlog – (10) 圖片瀑布流
- 基於.NetCore開發部落格項目 StarBlog – (11) 實現訪問統計
- 基於.NetCore開發部落格項目 StarBlog – (12) Razor頁面動態編譯
- 基於.NetCore開發部落格項目 StarBlog – (13) 加入友情鏈接功能
- 基於.NetCore開發部落格項目 StarBlog – (14) 實現主題切換功能
- 基於.NetCore開發部落格項目 StarBlog – (15) 生成隨機尺寸圖片
- 基於.NetCore開發部落格項目 StarBlog – (16) 一些新功能 (監控/統計/配置/初始化)
- 基於.NetCore開發部落格項目 StarBlog – (17) 自動下載文章里的外部圖片
- 基於.NetCore開發部落格項目 StarBlog – (18) 實現本地Typora文章打包上傳
- 基於.NetCore開發部落格項目 StarBlog – (19) Markdown渲染方案探索
參考資料
- JavaScript解析和渲染Markdown – //www.cnblogs.com/makalochen/p/14464519.html#5117019