码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 基于.NetCore开发博客项目 StarBlog - (19) Markdown渲染方案探索


    前言#

    笔者认为,一个博客网站,最核心的是阅读体验。

    在开发StarBlog的过程中,最耗时的恰恰也是文章的展示部分功能。

    最开始还没研究出来如何很好的使用后端渲染,所以只能先用Editor.md组件做前端渲染,过渡一下。前端渲染我是不满意的,因为性能较差,页面加载出来还会闪一下,有割裂感,影响体验。

    现在我已经做出了比较完善的后端渲染方案,前端渲染就可以直接退休了。本文介绍StarBlog博客开发过程中的各种Markdown渲染方案(主要是介绍后端渲染)。

    两种方案#

    前端渲染#

    使用 Editor.md 组件进行渲染,效果差强人意,主要是看中了其可以生成 ToC(文章目录) 的功能,但生成的 ToC 效果也比较差,后面是我fork了一份源码进行魔改才好一点。

    魔改过程在这篇文章:魔改editormd组件,优化ToC渲染效果

    优化 ToC 的这个功能我给官方提了PR,但没有响应,看了一下GitHub里有几十个PR,上次提交也是快4年前的事了,看来这个项目真的凉了……

    除了这个 editor.md ,还有其他几个前端的方案:

    • Marked
    • Showdown
    • markdown-it

    看起来都不错,有没有 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();
    
    foreach (var heading in document.Descendants()) {
      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样式

    地址: https://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 and colorblind 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内味了,但还没代码高亮

    image

    代码高亮#

    目前使用 highlight.js 包,官网: https://www.npmjs.com/package/highlight.js

    有很多其他的工具,不展开了,用这个足够了~

    下载#

    要在网页上直接用没办法通过安装NPM包的方式,只能通过网址下载: https://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="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/default.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js">script>
    <script>hljs.highlightAll();script>
    

    效果#

    有了代码高亮,一下就不一样了

    image

    还有很多其他主题,styles 目录下很多,引入css的时候自行选择即可

    我来换个深色的主题看看

    image

    系列文章#

    • 基于.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 - https://www.cnblogs.com/makalochen/p/14464519.html#5117019
  • 相关阅读:
    角点检测与SIFT
    asp.net core在其他程序集获取HttpContext
    IO流-数据流
    二、sql手工注入
    十大排序算法(C++)
    Jmeter v5.6.x 使用说明书(简要版)
    基于taro搭建小程序多项目框架
    SPOJ - COT Count on a tree(树上主席树 求树中路径第 k 小权值 + 倍增 LCA)
    Docker将镜像文件发布到私服库
    沐神深度学习报错 can only concatenate str (not “int“) to str
  • 原文地址:https://www.cnblogs.com/deali/p/16834452.html
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号