场景描述
我们公司有需要 将 md 渲染 呈现到网页上的需求,内部使用了 editor.md来完成该功能。
但在使用的过程中 碰到了如下问题
- 部分特定的 latex 公式解析不正确
如下 latex部分
$$
NV_{n} = NV_{0} \times P_{0} \times P_{1} \times P_{2} \times \dots \times P_{n}
$$
这种情况下 editor.md 的解析会直接报错,原因是在 之前调用 marked()
进行 markdown 解析的时候, 将 _
转义成了<em>
2. 不同方式初始化 editor.md 会导致不同的 latex 渲染效果
//方式一
editormd.markdownToHTML("test-editormd-view", {
//markdown : markdown ,//+ "\r\n" + $("#append-test").text(),
//htmlDecode : true, // 开启 HTML 标签解析,为了安全性,默认不开启
//toc : false,
//tocm : true, // Using [TOCM]
tocContainer : "#custom-toc-container", // 自定义 ToC 容器层
//gfm : false,
//tocDropdown : true,
// markdownSourceCode : true, // 是否保留 Markdown 源码,即是否删除保存源码的 Textarea 标签
emoji : true,
taskList : true,
tex : true, // 默认不解析
flowChart : true, // 默认不解析
sequenceDiagram : true, // 默认不解析
});
//方式二
editormd("test-editormd-view2", {
htmlDecode : "style,script,iframe", // you can filter tags decode
readOnly : true,
styleActiveLine : false, // disable active line
tex : true, // 默认不解析
path : '../lib/',
});
造成此原因的情况是 源代码中这两种方式会调用不同的 katex 处理细节
editormd.$katex.render(tex.text(), tex[0]); // 1503 当你使用editormd的时候被调用
katex.render(tex.html().replace(/</g, "<").replace(/>/g, ">"), tex[0]); //4018 当你使用editormd.markdownToHTML的时候被调用
解决过程
-
针对情况二
- 我们尝试了 将两端的代码统一为
tex.text()
调用
- 我们尝试了 将两端的代码统一为
-
针对情况一
- 我们首先 将有问题的 latex 公式复制至最新的 katex 在线解析器中,用于排除 katex 类库无法解析的问题。
- 公式在 katex 中可以被解析,故尝试升级 katex 版本号,升至最新再次预览。
- 依然不行,在调用 katex 渲染处打断点 (editormd.js#4017),输出日志得到 如下
<p> <span class="editormd-tex"> NV<em>{n} = NV</em>{0} \times P<em>{0} \times P</em>{1} \times P<em>{2} \times \dots \times P</em>{n} </span> </p>
- 阅读源代码发现 解析的 tex 是由上游的 marked 解析得到的,再次断点,得到如下日志
<p> <span class="editormd-tex"> NV<em>{n} = NV</em>{0} \times P<em>{0} \times P</em>{1} \times P<em>{2} \times \dots \times P</em>{n} </span> </p>
- 发现从源头就出现了错误的解析,查看 marked 版本号,发现是 0.3.x ,故尝试升级 marked
- marked 升级到最新后,发现 如下问题
- api 不兼容,最新的 marked 与 老版本 marked 存在大量 api 兼容性问题
- 尝试新建工程,只用 marked 解析,验证是否 可以得到正确的 解析结果
- 验证过程中,关于 _ 的验证得到了预期的结果,但形如
ABC**How To Use:**The Demo
这样的文本 出现了不一致的解析
- 验证过程中,关于 _ 的验证得到了预期的结果,但形如
- marked 升级无法解决该问题,转变方向
解决方案
- 不使用$$进行行内公式渲染,使用 latex 代码块进行公式的书写,
- 优点:简单,无需改动代码
- 缺点: 复杂公式无法内嵌在行内。影响排版
- 基于 marked 二次开发 markdown 编辑器,并结合社区 marked-katex 来完成公式的渲染(我们选择的方案)
- 优点:方便升级,可以基于 marked 提供的扩展接口进行升级
- 缺点:需要理解 marked 相关 api。