前端完美展现数学公式探讨

背景

最近接手学校的一个高数教学组习题库的项目,经过与团队和老师多次探讨后,总结出几个项目实现上的几个难点,如下:

  • 大量习题的如何存储最佳?
  • 数学公式如何完美处理?
  • 移动端如何与PC端完美接洽?
  • ……

缘由

撇开存储方式的问题,本文主要讨论前端完美展现数学公式的方案。

因为做的是大学数学习题库,各种极限、积分,微分等符号数不胜数,因此数学公式的合理且完美展现成了非常重要的讨论点。

合理是指不要给出题者(即高数组老师)造成太大的负担,因为习题量非常之大,如果处理起来非常麻烦,在项目后期的使用中将会变得无比的痛苦。

完美的含义即首先需要把数学完整的展现出来,其次最好能简易的控制样式,这样能使习题页面显得美观一点。毕竟题目本身难度就不小,还给个黑白、乱码、错位满天飞的页面谁都不会喜欢的。

探讨

好了,到这里我来简述一下我们的思考历程以及最后的选择

1. 图片显示

最开始团队成员提出的方案是静态图片,即把所有公式用MathType输出后再处理成图片,然后通过文件存储方式把所有的题目存储在服务器。 这种图片方案有一定的缺点:

  • 网站公式比较多,服务器需要维护大量公式图片;
  • 图片体积一般都比较大,会影响网页加载效率,占用较多的带宽,移动端也会影响程序性能;
  • 公式不能重用,如果公式发生变化,需要重新编辑图片;
  • 图片放大后会变得比较模糊;
  • ……

再者,又有人提出:将题目整个做成一张图片,即“一题一图”。此方案虽然能一定程度上减少图片数量,然而图片的大小控制问题又来了,Web显示不错的,可是到了移动端,屏幕小图片大,需要放大才能看清,势必体验非常之差。到这时,基本已经需要否定静态图片这一方案了,因为图片处理起来并不那么简单,而且样式可控性并不高。

最后,如果真的想使用图片方式的话,还有一种方法就是动态生成图片。首先需要将数学公式转换为表示公式的TeX语言,用程序将TeX语言生成与公式对应的图片,这种方法解决了直接使用静态图片不能重用的问题,但是这种方法比较复杂,需要后台代码来实现,也可以使用网上开放的API,如Google Charts,如果使用SVG格式图片,公式在放大后也不会影响清晰度。但是考虑到开放的API的不稳定因素,我们并未选择使用此方案。

2. MathML(数学标记语言)

数学置标语言,是一种基于XML的标准,用来在互联网上书写数学符号和公式的置标语言。它是由万维网联盟的数学工作组提出的。

MathML是受XML的启发在万维网联盟数学工作组的具体组织下产生的,作为XML定义的一种应用,它用标记的形式来表示数学表达式。用MathML形式 来描述数学表达式,不仅可以明确地表达数学内容,而且可以在Web的其它应用程序中实现再利用和转换。MathML 标记的递归性和树状结构使得它在计算机程序的实现上更方便、简单。MathML 使用文本的形式来描述数学表达式的树形结构,克服了传统的Web中使用图片表达数学公式的缺点。

以下为二次函数求根公式的MathML代码demo

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" 
    "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">
    <math xmlns="http://www.w3.org/1998/Math/MathML">
            <mi>x</mi>
            <mo>=</mo>
            <mfrac>
                    <mrow>
                            <mrow>
                                    <mo>-</mo>
                                    <mi>b</mi>
                            </mrow>
                            <mo>±</mo>
                            <msqrt>
                                    <msup>
                                            <mi>b</mi>
                                            <mn>2</mn>
                                    </msup>
                                    <mo>-</mo>
                                    <mrow>
                                            <mn>4</mn>
                                            <mo>⁢</mo>
                                            <mi>a</mi>
                                            <mo>⁢</mo>
                                            <mi>c</mi>
                                    </mrow>
                            </msqrt>
                    </mrow>
                    <mrow>
                            <mn>2</mn>
                            <mo>⁢</mo>
                            <mi>a</mi>
                    </mrow>
            </mfrac>
    </math>

可以看出,代码复杂度很高,一个简单的公式需要极多的冗余标记表达。

由于数学符号和公式的结构复杂且符号与符号之间存在多种逻辑关系,MathML的格式十分繁琐。因此,大多数人都不会去手写MathML,而是利用其它的工具来编写,其中包括Tex到MathML的转换器。在现在几个主要的网页浏览器中,最新版的Mozilla、Mozilla Firefox和Netscape Navigator都已经对MathML提供直接的支持,但Chrome却又停止支持,原因是Google出于安全性的考虑,但是Chrome和其它一些不支持MathML的浏览器,仍可以通过适当的HTML+CSS代码将MathML显示出来。微软的IE在安装了MathPlayer插件后也可以识别MathML。此外,MathML还得到了一些办公软件的支持,如openoffice .org和Microsoft Office。

总的来说,使用MathML语言基本可以达到我们的要求,且在移动端也有相应解决的方案,然而顾及老师对于MathML不熟悉,需要使用转化器来实现,我们还是在思索着更好的方案。

3. MathJax渲染

不断探索中,最终我们找到了一款基于Ajax技术JS数学渲染引擎–MathJax

MathJax是一款运行在浏览器中的开源的数学符号渲染引擎,使用MathJax可以方便的在浏览器中显示数学公式,不需要使用图片。目前,MathJax可以解析Latex、MathML和ASCIIMathML的标记语言。 MathJax项目于2009年开始,发起人有American Mathematical Society, Design Science等,还有众多的支持者,个人感觉MathJax会成为今后数学符号渲染引擎中的主流,也许现在已经是了。

可以说,对于大部分的数学公式,目前MathJax的功能和显示效果已经完全可以媲美于LaTex,而HTML/CSS对位置和格式的控制能力要比LaTex更强大。经过我们的多次测试,MathJax的兼容性还是非常棒的,这基本已经贴近我们心中所想了。

对于此项目来说,数学习题可以用LaTex语言来书写,这对于老师来说是极大的福音,因为Tex语言他们再熟悉不过了。反过来对于我们来说也是极大的福音,在MathJax将Tex语言渲染后,我们可以随心所欲的控制其样式,这样我们就可以将习题界面展现的更加优雅,更加美观。

到此我们基本已经决定使用MathJax来展现我们的数学公式,然而在使用下来发现以下几个客观不足性:

  • 直接使用MathJax官方提供的CND共开库,国内访问速度并不是很理想,有时会出现 Math Processing Error 的错误。解决方案是将其JS渲染库clone到自己服务器,这种错误可以得到保障,我已经clone了一份最新版到GitHubGit@OSC上并且去掉了一些不相关的文件,保留了JS核心库、测试文档与docs,大家有需要可以拿去。
  • MathJax官方文档很详细但是不提供中文版,需要大家英语水平不错才行。由于MathJax真心不错,我可能会考虑发起翻译计划,将其最新的开发文档翻译成中文,便于国人的使用。

结束

好啦,到这里,我们决定了使用的数学公式展现方案-MathJax,数学的公式展现方案探讨基本结束。如果有其他方案,我会继续补上。

我在博客中也添加了一个数学公式Demo页面,有兴趣可以看看.

如果有翻译计划,我会找一些队友一起,如果你有兴趣,欢迎联系我。

My Blog Sites:

Aurthur's Blog:http://blog.gitos.cn or http://myblog.gitos.cn

My Resume:

Reusme team:http://resume.gitos.cn

My other Sites:

BQ team:http://bqteam.com

IT News:http://tools.bqteam.com/itnews

Contact Me:

Email:aurthurxlc@gmail.com

Skype:xlclinkong@hotmail.com

Table of Contents