Android完美支持MathML显示公式方程
历经3个开发阶段《Android实现方程编辑器》、《Android完美解决LaTeX中文显示问题》、《Android判断LaTeX是否为空方程》后,『神马笔记』的方程编辑器现已经完美支持LaTeX,接下来尝试支持MathML。
一、目标
『神马笔记』支持MathML显示公式方程。
二、设计思路
在MathML之前,『神马笔记』已经完美支持LaTeX。
最快速实现支持MathML的方式是将MathML转化为LaTeX语言。
这样一来,后续的解析渲染就可以复用LaTeX的实现,不需要再次开发。
三、实现过程
1. 实现方案
方案 | 描述 | 参考资料 |
---|---|---|
JMathTeX | The library uses the typesetting algorithms of the well-known TeX and LaTeX systems and therefore displays formulas in a very professional looking way. Formulas are Java-objects that can be built from scratch (by combining smaller formulas in several ways) and from LaTeX strings. There is also limited support for MathML. | http://jmathtex.sourceforge.net/ |
MathParser | MathParser is a freeware tool that converts MathML into LaTeX. It processes pure MathML code as well as HTML with embedded MathML. It also offers a special built-in parser for Mathcad HTML/MathML files. You do not have to retype all equations for publishing anymore. | http://www.tilman.de/programme/mathparser/index_en.html |
fMath | FMATH is a FREE solution to display mathematics on web pages, desktop app or mobile devices using MathML, LaTeX or OMML (Microsoft Word) standards. | http://www.fmath.info/ |
XSLT MathML Library | The XSLT MathML Library, xsltml, provides the XSLT developer with a set of XSLT templates for MathML 2.0 to LaTeX translation. These are implemented purely in XSLT, that is they do not use any extensions. | http://xsltml.sourceforge.net/ |
2. 参考文章
文章 | 地址 |
---|---|
数学公式:使用xsltml将MathML转LaTex | https://www.jianshu.com/p/b4caef5bf1ab |
java使用XSL+XML生成HTML文件 | http://www.blogjava.net/yangxiang/archive/2009/08/11/290688.html |
3. 测试结果
方案 | 结果 |
---|---|
JMathTeX | 根据JMathTeX介绍,对MathML提供了有限支持。 后来的项目转换过程中JMathTeX->JLaTeXMath->jlatexmath-android, 似乎移除了对MathML的支持。 |
后续有待查证。 | |
MathParser | 采用替换的方式进行转换。 |
未达到预期效果,放弃之。 | |
fMath | 使用JDOM2解析XML并进行转换,部分公式效果未达到预期,但可用。 |
备选方案。 | |
XSLT MathML Library | 使用XSL方式转换,部分公式无法显示,但似乎优于fMath。 |
推荐方案。 |
4. 检测MathML
因为LaTeX和MathML使用同一个编辑框。因此需要自动检查用户输入的语言。
通过检索math>
和<math
两个关键字区分LaTeX和MathML。
public static final boolean isMathML(String text) {
if (TextUtils.isEmpty(text)) {
return false;
}
{
int pos = text.lastIndexOf("math>");
if (pos >= 0) {
return true;
}
}
{
int pos = text.indexOf("<math");
if (pos >= 0) {
return true;
}
}
return false;
}
四、遗留问题
附录中的公式来自于文章《Android完美解决LaTeX中文显示问题》,通过工具将LaTeX转换为MathML。
发现LaTeX能显示为多行的公式,使用MathML只显示一行。
未来有待查找问题根源。
五、Next
『神马笔记』的方程编辑器开发至此,已经实现了以下功能。
- 支持LaTeX和MathML
- 支持无效方程判断
- 支持空方程判定
- 支持LaTeX快捷输入栏
可能是Android平台最强大的方程编辑器了。
接下来将把方程编辑器整合到『神马笔记』中,以实现在笔记中插入方程。
六、Finally
~第一是早早归来~怕红萼无人为主~
七、Appendix
1.
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mi>C</mi>
<msub>
<mi>O</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mo>+</mo>
<msub>
<mi>H</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mi>O</mi>
<mrow class="MJX-TeXAtom-REL">
<munderover>
<mrow class="MJX-TeXAtom-OP MJX-fixedlimits">
<mspace width="0pt" />
<mo stretchy="false">⟶<!-- ⟶ --></mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mrow class="MJX-TeXAtom-ORD">
<mo>叶</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>绿</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>素</mo>
</mrow>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mrow class="MJX-TeXAtom-ORD">
<mo>日</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>光</mo>
</mrow>
</mrow>
</munderover>
</mrow>
</math>
2.
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mrow class="MJX-TeXAtom-ORD">
<mo>用</mo>
</mrow>
<mi mathvariant="normal">P</mi>
<mi mathvariant="normal">t</mi>
<mrow class="MJX-TeXAtom-ORD">
<mo>电</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>极</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>电</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>解</mo>
</mrow>
<mi mathvariant="normal">C</mi>
<mi mathvariant="normal">u</mi>
<mi mathvariant="normal">S</mi>
<msub>
<mi mathvariant="normal">O</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>4</mn>
</mrow>
</msub>
<mrow class="MJX-TeXAtom-ORD">
<mo>溶</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>液</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>,</mo>
</mrow>
<mspace linebreak="newline" />
<mrow class="MJX-TeXAtom-ORD">
<mo>发</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>生</mo>
</mrow>
<mn>2</mn>
<mi mathvariant="normal">C</mi>
<mi mathvariant="normal">u</mi>
<mi mathvariant="normal">S</mi>
<msub>
<mi mathvariant="normal">O</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>4</mn>
</mrow>
</msub>
<mo>+</mo>
<mn>2</mn>
<msub>
<mi mathvariant="normal">H</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mi mathvariant="normal">O</mi>
<mover>
<mrow class="MJX-TeXAtom-OP">
<mstyle scriptlevel="1">
<mtable rowspacing="0.1em" columnspacing="0em" displaystyle="false">
<mtr>
<mtd>
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
</mtd>
</mtr>
</mtable>
</mstyle>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mrow class="MJX-TeXAtom-ORD">
<mo>电</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>解</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mphantom>
<mrow class="MJX-TeXAtom-ORD">
<mo>电</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>解</mo>
</mrow>
</mphantom>
</mrow>
</mrow>
</mover>
<mo>⁡<!-- --></mo>
<mn>2</mn>
<mi mathvariant="normal">C</mi>
<mi mathvariant="normal">u</mi>
<mo>+</mo>
<msub>
<mi mathvariant="normal">O</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mo stretchy="false">↑<!-- ↑ --></mo>
<mo>+</mo>
<mn>2</mn>
<msub>
<mi mathvariant="normal">H</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mi mathvariant="normal">S</mi>
<msub>
<mi mathvariant="normal">O</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>4</mn>
</mrow>
</msub>
<mrow class="MJX-TeXAtom-ORD">
<mo>,</mo>
</mrow>
<mspace linebreak="newline" />
<mrow class="MJX-TeXAtom-ORD">
<mo>只</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>在</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>阳</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>极</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>产</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>生</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>气</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>体</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>,</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>由</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>阴</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>阳</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>两</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>极</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>产</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>生</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>相</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>同</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>体</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>积</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>的</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>气</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>体</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>,</mo>
</mrow>
<mspace linebreak="newline" />
<mrow class="MJX-TeXAtom-ORD">
<mo>还</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>发</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>生</mo>
</mrow>
<mn>2</mn>
<msub>
<mi mathvariant="normal">H</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msub>
<mi mathvariant="normal">O</mi>
<mover>
<mrow class="MJX-TeXAtom-OP">
<mstyle scriptlevel="1">
<mtable rowspacing="0.1em" columnspacing="0em" displaystyle="false">
<mtr>
<mtd>
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
<mspace width="negativethinmathspace" />
<mo>=</mo>
</mtd>
</mtr>
</mtable>
</mstyle>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mrow class="MJX-TeXAtom-ORD">
<mo>电</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>解</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mphantom>
<mrow class="MJX-TeXAtom-ORD">
<mo>电</mo>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>解</mo>
</mrow>
</mphantom>
</mrow>
</mrow>
</mover>
<mo>⁡<!-- --></mo>
<mn>2</mn>
<msub