TimothyQiu's Blog

keep it simple stupid

更新了博客的数学公式支持

分类:技术,闲扯

这个 Typecho 博客搭成以来,就一直在用从这里下载到的 Markdown 插件,是对 PHP Markdown 的封装。

当年还不存在 XX-flavored Markdown 的概念,有些洁癖的我觉得坚持原生 Markdown 是最佳的选择,不够用时直接 HTML 来凑就好了。然而原生 Markdown 是没有数学公式支持的,如果用 $\TeX$ 语法,很难躲避代码被转义的命运。

单占一行的公式还可以手动用 HTML 块元素标签包裹,这样原生 Markdown 就不会对里面的内容转义了。但是行内的公式则不行,原生 Markdown 里没有任何办法禁止某些东西的转义(除了代码块,但是会把内容包裹在 <code> 里)。

所以最后我的选择是,把 $\TeX$ 代码作为代码块渲染以防止 Markdown 转义;然后强制让 MathJax 翻译 <code> 标签中的代码,显示公式。

这样做牺牲了「显示公式代码本身」的可能,不过够用了。

要解决的问题

时间一晃到了八年后的现在,翻翻以前的文章,参考链接里一个个都是 http,非常直观地给人一种「时代变了」的感觉。

如今 XX-flavored Markdown 已深入人心,在 Markdown 中插入数学公式似乎也形成了一些广为认可的写法。

是时候改一改这八年前的解决方案了。

被懒偷了去

首先想到的是 Typecho 早已原生支持 Markdown 文档,不需要再用插件实现了。要不先切换过去再搞?

然而,Typecho 原生的 Markdown 支持我非常不满意。因为它不允许内嵌任意 HTML,需要用 !!! 裹起来才行。放弃放弃。

于是看了看 PHP Markdown。虽然有 PHP Markdown Extra,但也已经是很多年前的东西,不再更新,更没有更新数学公式的可能。

所幸后来搜到了一个 PHP Markdown Extra with support for jsMath 仓库,非常开心,赶紧拿来替换了原先插件中得到 markdown.php。大体上是不错的,然而它有个 bug:行内的 \(C_{ij} = \vec{u}_{rowi} \vec{v}_{colj}\) 还是被转义了,里面的一对下划线依旧被转成了 <em>,代码被破坏,导致公式转换失败。

解决方法

这样折腾了一圈以后非常绝望,甚至还想过换个静态网站生成器把博客重新搞一下的想法。

不过想想这个工程量,不禁还是摇摇头。既然是 bug,要不然我们来 Debug 一下?

不过那代码看着看着,忽然感觉 PHP Markdown 的代码也没有想象的那么复杂。于是干脆换回官方的 PHP Markdown Extra,在那上面依葫芦画瓢改了一通,很快搞定了 $$$ 的功能。

基本上就是模仿 Markdown 中代码块的语法。

行内 $\vec{a}$ 这么写。

$$
\begin{aligned}
S &= 成块的这么写 \\
  &= 就可以了
\end{aligned}
$$

具体补丁见这个 Gist,基于 PHP Markdown Extra 1.2.8。

下载到两者后,使用 patch markdown.php math.patch 就可以打上补丁使用了。

补丁后的版本中有个 MARKDOWN_MATH_CLASS 常量,非空时会为数学公式代码所在的 <span> 或者 <div> 加上对应的 class。这样就可以在 JS 脚本中找到具有这些 class 的节点,用 MathJax / KaTeX 做精准打击,不用怕正文中的普通单词因为夹在 $ 中间而被误认为是公式了。

以上。

这篇文章没有标签

已有 2 条评论 »

  1. 感谢写的这篇文章,受教了,帮助很大

  2. Martin Martin

    今日为了解决MarkdownExtra修改公式的问题,找到了您的博客。但无奈根据您的指导,仍然没有出现想要的效果,反而出现了错误提醒。不知是何原因。

添加新评论 »