Android完美支持MathML显示公式方程

本文介绍了在Android应用"神马笔记"中实现MathML显示公式方程的目标、设计思路和过程。通过将MathML转换为LaTeX,利用已有的LaTeX解析渲染功能,实现了对MathML的支持。然而,目前存在MathML显示多行公式的问题,开发者计划进一步完善并整合到笔记功能中。
摘要由CSDN通过智能技术生成

历经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

神马笔记』的方程编辑器开发至此,已经实现了以下功能。

  1. 支持LaTeX和MathML
  2. 支持无效方程判断
  3. 支持空方程判定
  4. 支持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">&#x27F6;<!-- ⟶ --></mo>
      </mrow>
      <mrow class="MJX-TeXAtom-ORD">
        <mrow class="MJX-TeXAtom-ORD">
          <mo>&#x53F6;</mo>
        </mrow>
        <mrow class="MJX-TeXAtom-ORD">
          <mo>&#x7EFF;</mo>
        </mrow>
        <mrow class="MJX-TeXAtom-ORD">
          <mo>&#x7D20;</mo>
        </mrow>
      </mrow>
      <mrow class="MJX-TeXAtom-ORD">
        <mrow class="MJX-TeXAtom-ORD">
          <mo>&#x65E5;</mo>
        </mrow>
        <mrow class="MJX-TeXAtom-ORD">
          <mo>&#x5149;</mo>
        </mrow>
      </mrow>
    </munderover>
  </mrow>
</math>

2.

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x7528;</mo>
  </mrow>
  <mi mathvariant="normal">P</mi>
  <mi mathvariant="normal">t</mi>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x7535;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x6781;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x7535;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x89E3;</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>&#x6EB6;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x6DB2;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#xFF0C;</mo>
  </mrow>
  <mspace linebreak="newline" />
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x53D1;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x751F;</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>&#x7535;</mo>
      </mrow>
      <mrow class="MJX-TeXAtom-ORD">
        <mo>&#x89E3;</mo>
      </mrow>
      <mrow class="MJX-TeXAtom-ORD">
        <mphantom>
          <mrow class="MJX-TeXAtom-ORD">
            <mo>&#x7535;</mo>
          </mrow>
          <mrow class="MJX-TeXAtom-ORD">
            <mo>&#x89E3;</mo>
          </mrow>
        </mphantom>
      </mrow>
    </mrow>
  </mover>
  <mo>&#x2061;<!-- ⁡ --></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">&#x2191;<!-- ↑ --></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>&#xFF0C;</mo>
  </mrow>
  <mspace linebreak="newline" />
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x53EA;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x5728;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x9633;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x6781;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x4EA7;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x751F;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x6C14;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x4F53;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#xFF0C;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x7531;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x9634;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x9633;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x4E24;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x6781;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x4EA7;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x751F;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x76F8;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x540C;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x4F53;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x79EF;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x7684;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x6C14;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x4F53;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#xFF0C;</mo>
  </mrow>
  <mspace linebreak="newline" />
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x8FD8;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x53D1;</mo>
  </mrow>
  <mrow class="MJX-TeXAtom-ORD">
    <mo>&#x751F;</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>&#x7535;</mo>
      </mrow>
      <mrow class="MJX-TeXAtom-ORD">
        <mo>&#x89E3;</mo>
      </mrow>
      <mrow class="MJX-TeXAtom-ORD">
        <mphantom>
          <mrow class="MJX-TeXAtom-ORD">
            <mo>&#x7535;</mo>
          </mrow>
          <mrow class="MJX-TeXAtom-ORD">
            <mo>&#x89E3;</mo>
          </mrow>
        </mphantom>
      </mrow>
    </mrow>
  </mover>
  <mo>&#x2061;<!-- ⁡ --></mo>
  <mn>2</mn>
  <msub
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值