公式格式简述
-
Latex
一种排版系统和标记语言,通常用于科学、技术、工程和数学(STEM)领域的文档,如学术论文、报告、书籍等。
在学术界和专业领域中得到广泛应用。
示例:
\sqrt[y]{x}
渲染为 <math xmlns="http://www.w3.org/1998/Math/MathML"> x y \sqrt[y]{x} </math>yx -
MML (MathML)
全称为 Mathematical Markup Language(数学标记语言),一种用于在计算机中描述数学公式和数学内容的标记语言,它使用 XML 格式来在计算机系统中表示数学公式。
示例:
xml<math xmlns="http://www.w3.org/1998/Math/MathML"> <mroot> <mi>x</mi> <mi>y</mi> </mroot> </math>
-
OMML
Office Math Markup Language(OMML)是由微软开发的一种标记语言,用于在Microsoft Office文档中表示和排版数学公式和数学内容。OMML 是一种基于XML的标记语言,旨在帮助用户在Microsoft Word、Microsoft PowerPoint 和 Microsoft Excel等Office应用程序中创建和编辑复杂的数学表达式。
OMML 用于 Office Word 中渲染,这里不放示例了。
总结一下这个三种公式格式:
- Latex 在大型论文领域应用的最广泛,所以它对各种奇形怪状的化学/物理公式支持的都较好;
- MML 主要是为了在网页上渲染数学公式;
- OMML 主要是为了在 Office 中渲染数学公式。
成熟的教育产品是如何使用公式的?
MML/OMML 都是侧重于 数学公式,而 Latex 对于理科公式都能良好的表达。
但 MML 便于网页渲染,Latex 则无法直接在网页上渲染。
目前的在线题库/教育资源等网站,一般都采用同时保存 MML/ Latex 公式,便于不同场景的使用。
学科网开放平台推题返回试题信息示例:
我们可以看到,仍在标签中保留了 latex 源码,主要可能用于后台试题编辑。
xml
<math latex="$xOy$">
<mrow><mi>x</mi><mi>O</mi><mi>y</mi></mrow>
</math>
<span style="font-family: 宋体;">中,已知圆</span>
<math latex="$C:5{{x}^{2}}+5{{y}^{2}}+10y-4=0$">
<mrow>
<mi>C</mi><mo>:</mo><mn>5</mn><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mn>5</mn><msup><mi>y</mi><mn>2</mn></msup><mo>+</mo><mn>10</mn><mi>y</mi><mo>−</mo><mn>4</mn><mo>=</mo><mn>0</mn>
</mrow>
</math>
学科网页面渲染,采用 将公式转为 SVG 的方式渲染
21世纪教育网暂无开放平台,页面渲染则采用将 MML 公式转为 PNG 的方式来渲染
公式格式转换
在线题库的题量需求很大,达到百万级也只是毛毛雨。
试题大部分都来源于批量导入,而不是教研老师一道题一道题在页面上编辑。
使用到最多的就是 Word 导入,而上面我们讲过,Word 中公式的格式为 OMML 格式,所以此时就涉及到 OMML --> Latex / MML 格式的转换。
公式之间的相互转换,不是一件简单的事。因为他们各自都有自己的标准。
有一件尴尬的事,目前并没有很好的直接转换 OMML 为 Latex 的方法,所以公式转换的路径一般为 OMML --> MML --> Latex。
比较幸运的,Office 中携带了一些映射文件,我们可以借助映射文件,比较方便的实现上述的路径。
使用方法具体如下:
-
将映射文件放入项目中
-
构建转换方法
java//设置xls依赖文件的路径 public static URIResolver r = (href, base) -> { InputStream inputStream = FormulaConvertUtil.class.getResourceAsStream("/formula/xsl/" + href); return new StreamSource(inputStream); }; /** * <p>Description: office mathml转为mml </p> * * @param xml * @return */ public static String convertOMMLToMML(String xml) { String result = xslConvert(xml, "/formula/xsl/omml2mml.xsl", null); return result; } /** * mathml to latex * * @param mml mathml 公式源码 * @return java.lang.String */ public static String convertMMLToLatex(String mml) { String latex = xslConvert(mml, "/formula/xsl/mmltex.xsl", r); //latex = latex.replaceAll("△"," \\\\triangle "); return latex; } /** * xsl Convert * * @param formula 公式 * @param uriResolver 转换器 * @return java.lang.String * @author YangXinFu */ public static String xslConvert(String formula, String xslPath, URIResolver uriResolver) { TransformerFactory tFac = TransformerFactory.newInstance(); if (uriResolver != null) tFac.setURIResolver(uriResolver); // InputStream inputStream = FormulaConvertUtil.class.getResourceAsStream("/formula/xsl/mmltex.xsl"); InputStream inputStream = FormulaConvertUtil.class.getResourceAsStream(xslPath); StreamSource xslSource = new StreamSource(inputStream); StringWriter writer = new StringWriter(); try { Transformer t = tFac.newTransformer(xslSource); Source source = new StreamSource(new StringReader(formula)); Result result = new StreamResult(writer); t.transform(source, result); } catch (TransformerException e) { log.warn("公式转换失败。",e); return ""; } return writer.getBuffer().toString(); }
到这里基本可以使用了,但还需要注意转换并不是 100% 映射,不常用的符号有可能失败。
Latex转图
在 Java 中 Latex 公式转图片,一般使用 jlatexmath 。
但是在 Maven 仓库中 1.0.8 版本,不支持 \ce
命令,使用时需要注意。
\ce
命令被包含在 Latex 的 Mhchem 扩展中,所以需要额外功能支持。例如:\ce{SO4^2- + Ba^2+ -> BaSO4 v}
应渲染为 :
但,其实早在 2018 年,已经有人提过 issue:
对于 mhchem 的支持,已经被合并到 github.com/opencollab/... 实验分支上,并未推送正式版 jar 包到 Maven Resp 中。
所以想要使用该特性,我们只需要将 experimental 分支代码拉到本地,进行简单的修改,打包推送到自己的 Maven 私服中便可使用。
在此分支中,包含一些 GWT 的代码
GWT 是 Google Web Toolkit 的缩写,它是一个用于构建富客户端 Web 应用程序的开源开发工具集。GWT 最初由 Google 开发并发布,旨在帮助开发人员使用 Java 编程语言来构建现代的、高性能的、交互式的 Web 应用程序。
开发人员可以使用熟悉的 Java 编程语言来构建客户端代码,然后使用 GWT 编译器将 Java 代码转换为高效的 JavaScript 代码。
但是,对在服务转换的情况,基本没什么用。我们只需要"酌情"把 GWT 相关的代码,全部干掉就行了。
打完包,使用方法如下:
java
// 这里需要初始化一个 Provider。
static {
FactoryProvider.setInstance(new FactoryProviderDesktop());
}
public static Image latexToImg(String latex, Float size) {
int style = TeXConstants.STYLE_DISPLAY; // 样式 符号以最大的尺寸呈现
float fontSize = Objects.isNull(size) ? 16 : size ; // 生成公式图片的字体大小
// 字体颜色,黑色
ColorD fg = new ColorD(Color.BLACK);
TeXFormula.setDPITarget(72);
return (BufferedImage) TeXFormula.createBufferedImage(latex, style, fontSize * 3, fg, null);
}
另外,还有 Aspose.TeX 工具可以转图,但是暂不支持中文,即公式中包含中文时,会乱码。
小结
在线题库项目中,公式可存储为 Latex/MML 两种格式,MML 进一步可转为 SVG/PNG 等格式在线渲染,Latex 格式可用于在线编辑。
MML目前没有友好的可视化编辑器,而 Latex 公式有 LatexLive 等很优秀的可视化编辑器。
另外,公式转换想一劳永逸是不可能的事,因为总会有一些奇奇怪怪的符号没发转换,这时只能手动的进行符号对应。
举个例子:
Latex 中有长等号
$\xlongequal[b]{a}$
表现为 <math xmlns="http://www.w3.org/1998/Math/MathML"> = b a \xlongequal[b]{a} </math>a b但是 OMML 并没有对应的符号可以表示,只能通过其他形式处理。