wordpress插入公式-使用mathjax及注意事项

背景与前言

在显示公式时,我选择了通过JavaScript在前端渲染公式,这样有以下的优势:

  1. 显示清晰,不会因为网页的放大或缩小或web端不同设备的差异带来模糊感。
  2. 避免了复杂的图片管理。
  3. 公式的可复用性高,自己可以将相关公式代码取出,阅读者也易于复用。

通过网上阅读教程[1]等,我选择了mathjax作为渲染的方式。

如何引入mathjax

引入mathjax可以参考[1]中的步骤,在wordpress的主题相关文件header.php中添加对应的代码,有必要的话可以采用wordpress的子主题以增强可维护性。
特别是,我启用了单$的公式定界符,具体配置过程,此处先略去,之后待维护。

实际使用中遇到的问题和处理手段

问题及处理手段

这是这篇记录的关键部分,因为在公式编辑中尝尝出现无法渲染的情况,所以需要在此记录需要注意的事项,以便以后查阅,减少翻看他人博文重复收集资料带来的繁琐流程。
在目前编辑的公式中,发现有四类情况会导致公式渲染失败。通过分析发现,这是markdown的渲染先于mathjax的渲染,会将公式中的一些字符先被markdown渲染而导致mathjax渲染时缺少要素,导致渲染失败。以下mathjax会渲染失败的四种情况:

  • 下标标记_
  • 换行标记\\
  • 大括号{}
  • 小于号 <

所以这四类情况需要加转义符号\进行转义,转义后变成如下情况,其中换行标记需要加两个转义符:

  • 下标标记\_
  • 换行标记\\\\
  • 大括号\{\}
  • 小于号&lt;

出于简单考虑,我使用了word-mathtype输入公式-剪切复制选项设置为应用于网页的公式-转换为TEX-全部替换以上四种关键词,来实现网页上显示的效果。

虽然这样的可替换性较差,但只是为了在此处可以显示,并且可以让其他人看到,我采用了如上的方式渲染公式。

并且可以修改markdown的渲染方法,取消_斜体渲染,但是我没有尝试这个路线。

此外,还有一类特殊情况,就是mathtype转换的独立公式定界符,这类情况不会直接导致渲染公式内部的改变,但是可能导致公式渲染失效,没有被mathjax识别。
在mathtype转换为的独立公式定界符是\[\],需要替换为\\[\\],否则会被识别成中括号。某种程度这也是一种渲染失败,可能在早期使用mathjax的过程中,我都手动换成了$$定界符,导致对这个问题不敏感,直到撰写过程中,调试VBA脚本才意识到这个问题。

效果展示

  1. 下标标记的替换前后:
    转换前:
    $ g = \sum\limits_{i = 1}^n {{ci}{1{{E_i}}}} $,
    可见i}{1部分被转换成了斜体,即_被markdown首先渲染成了下标标记,从而导致公式渲染的失败。
    转换后:

$$ g = \sum\limits_{i = 1}^n {{c_i}{1_{{E_i}}}}$$

  1. 换行标记的替换前后
    转换前:$(\begin{array}{l}f\left( x \right) = 1\g\left( x \right) = 2\end{array})$
    可以发现\\被解释成了一个转义\和一个标记\,留给mathjax的只有一个\了。
    转换后:

$$
\begin{array}{l}f\left( x \right) = 1\\g\left( x \right) = 2\end{array}
$$

  1. 大括号的替换前后
    转换前:$(f\left( x \right) = \left{ {\sin x} \right.)$
    可见left{之间的\消失了,导致渲染失败。左右{}同理。
    转换后:

$$
f\left( x \right) = \left\{ {\sin x} \right.
$$

  1. 小于号的替换前后
    转换前:<会被当做html的标签,导致整体的渲染失败。因为会影响后续页面,不方便单行展示,故不展示。
    转换后:

$$1 < 2$$

  1. 独立公式定界符的替换前后
    转换前:[\sin x=x],很显然\[\]没有被当作公式的定界符,需要额外加一个反斜杠,变成\\[\\]
    转换后:

\[\sin x=x\]

  1. 其它情况的自行修正处理
    由于mathtypo的TEX转换而引入的小括号或中括号,可以在渲染结束后自行检查并视美观程度删除。

批量替换以上符号

可以采用在Word中使用VBA脚本一次性替换掉以上的特殊符号,在Word中点击altF8,即可唤出VBA控制台,自行添加并运行,VBA代码如下:


Sub EscapeSpecialCharacters()
    Dim rng As Range
    Set rng = ActiveDocument.Content

    With rng.Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Forward = True
        .Wrap = wdFindContinue
        .MatchWildcards = False

        ' 替换下标标记 _ 为 \_
        .Text = "_"
        .Replacement.Text = "\_"
        .Execute Replace:=wdReplaceAll

        ' 替换换行标记 \ 为 \\\\(两个反斜杠)
        .Text = "\\"
        .Replacement.Text = "\\\\"
        .Execute Replace:=wdReplaceAll

        ' 替换定界标记 \[ 为 \\[
        .Text = "\["
        .Replacement.Text = "\\["
        .Execute Replace:=wdReplaceAll

        ' 替换下标标记 \] 为 \_
        .Text = "\]"
        .Replacement.Text = "\\]"
        .Execute Replace:=wdReplaceAll

        ' 替换大括号 { 为 \{
        .Text = "\{"
        .Replacement.Text = "\\{"
        .Execute Replace:=wdReplaceAll

        ' 替换大括号 } 为 \}
        .Text = "\}"
        .Replacement.Text = "\\}"
        .Execute Replace:=wdReplaceAll

        ' 替换小于号 <&lt;
        .Text = "<"
        .Replacement.Text = "&lt;"
        .Execute Replace:=wdReplaceAll
    End With

    MsgBox "替换完成!", vbInformation
End Sub

请注意:如果复制这个VBA脚本,请留意替换小于号部分。不要用代码块的copy按钮功能,请直接复制文本,否则还会出现&lt;的诸多问题。这里仅仅是调整了一些转义符,使得人眼直观可以看到最直接的代码逻辑,copy按钮拷贝出来会是转义了的字符。

[1] 使用 MathJax 在 WordPress 中显示数学公式,nex3z's blog

发表评论