Solo Markdown 渲染

本贴最后更新于 1748 天前,其中的信息可能已经斗转星移

本文是《Solo 从设计到实现》的一个章节,该系列文章将介绍 Solo 这款 Java 博客系统是如何从无到有的,希望大家能通过它对 Solo 从设计到实现有个直观地了解、能为想参与贡献的人介绍清楚项目,也希望能为给重复发明重新定义博客系统的人做个参考 ❤️

Markdown 渲染指的是将 Markdown 文本转换成 HTML 的过程。

引擎选择

Solo 默认是通过 flexmark-java 进行 Markdown 渲染的。如果启用了独立进程 Lute HTTP 则优先使用 Lute HTTP 引擎渲染。建议使用 Lute 引擎,因为 Lute 是针对中文语境优化的 Markdown 引擎。

if (LUTE_AVAILABLE) {
    try {
        html = toHtmlByLute(markdownText);
    } catch (final Exception e) {
        LOGGER.log(Level.WARN, "Failed to use Lute [" + LUTE_ENGINE_URL + "] for markdown [md=" + StringUtils.substring(markdownText, 0, 256) + "]: " + e.getMessage());
    }
}

if (StringUtils.isBlank(html)) {
    html = toHtmlByFlexmark(markdownText);
}

关于 Lute 引擎更多的细节请看 https://hacpai.com/article/1567047822949。

超时控制

Solo 的 Markdown 渲染是在一个新建线程中完成的,获取处理结果带超时控制(默认 10s)。这样做是为了防止一些无法预期的问题,比如引擎缺陷或是文本怪异导致渲染太耗时,从而耗尽服务线程。

站外链接处理

Markdown 渲染后得到的 HTML 还会通过 jsoup 解析一次,将其中的 a 标签获取出来,如果发现是站外链接,就将其 target 设置为 _blank,点击时以新页签方式打开。

final Document doc = Jsoup.parse(html);
doc.select("a").forEach(a -> {
    final String src = a.attr("href");
    if (!StringUtils.startsWithIgnoreCase(src, Latkes.getServePath())) {
        a.attr("target", "_blank");
    }
});

结果缓存

每次 Markdown 渲染后的最终 HTML 都会放入缓存,下次进行渲染时先从缓存中获取。缓存键是将原 Markdown 文本进行 MD5 哈希得到的,虽然存在一定碰撞的可能,但是目前的结果来看,这个可能性是非常低的。

  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1434 引用 • 10054 回帖 • 490 关注
  • 设计
    114 引用 • 797 回帖 • 1 关注
  • 文档
    56 引用 • 1289 回帖 • 2 关注
1 操作
88250 在 2020-02-08 21:12:06 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • lai-bluejay

    原来影响内容展示,我放新的页面了,抱歉。
    在这儿:https://www.jithub.cn/articles/2019/04/18/1555582980606.html
    但实际单独移出来,还是能显示部份元素的:https://www.jithub.cn/fileserver/test2.html

    1 回复
  • 其他回帖
  • 88250

    等有机会我会写个 Markdown 引擎,还有前端编辑器也想单独提出来开源。减少依赖,同时也可以丰富 B3log 开源项目,让更多的人参与进来完善。

    1 回复
  • zouxiaochaun

    页面中不支持 mermaid 吗?下面这个流程图在页面中显示的是文字,编辑的时候预览是正产的

    graph LR 提交任务-->coreFull{核心线程池是否已满} coreFull--是-->queueFull{队列是否已满} coreFull--否-->创建线程执行给定任务 queueFull--是-->notCore[创建非核心线程执行给定任务] queueFull--否-->将任务存储到队列 notCore--失败-->执行拒绝策略

    test

    1 回复
  • 看了下,两个页面的代码不一样。
    无法显示的 HTML 中 I 为大写,可以部分显示中的是小写,JavaScript 是区分大小写的。

      for (var i = -3; i <= 3; i = i + 0.001) {
        lineData.push({
          x: I,
          y: i >= 0
        });
        lineData_deriv.push({
          x: I,
          y: 0
        });
      }
    
  • 查看全部回帖