首先下载 MathType (http://www.mathtype.cn),国内代理就是著名的思杰马克丁,我用的是 30 天试用版,没有盗版哦,不要抓我。
打开word 新建空白文档 1.doxc,输入著名的求根公式,保存。
然后用 7zip 解压,可以看到 docx 的庐山真面目了。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid wp14"> <w:body> <w:p w14:paraId="2D7B91EE" w14:textId="710BE5AC" w:rsidR="000130C6" w:rsidRDefault="001E73B7"> <w:r w:rsidRPr="001E73B7"> <w:rPr> <w:position w:val="-24"/> </w:rPr> <w:object w:dxaOrig="1400" w:dyaOrig="700" w14:anchorId="6D6BD9DF"> <v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype> <v:shape id="_x0000_i1027" type="#_x0000_t75" style="width:69.85pt;height:34.95pt" o:ole=""> <v:imagedata r:id="rId4" o:title=""/> </v:shape> <o:OLEObject Type="Embed" ProgID="Equation.DSMT4" ShapeID="_x0000_i1027" DrawAspect="Content" ObjectID="_1611409414" r:id="rId5"/> </w:object> </w:r> <w:r> <w:t xml:space="preserve"> </w:t> </w:r> <w:bookmarkStart w:id="0" w:name="_GoBack"/> <w:bookmarkEnd w:id="0"/> </w:p> <w:sectPr w:rsidR="000130C6"> <w:pgSz w:w="11906" w:h="16838"/> <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/> <w:cols w:space="425"/> <w:docGrid w:type="lines" w:linePitch="312"/> </w:sectPr> </w:body> </w:document>
可以看到 word/media/image1.wmf 就是我们输入的公式的图片。
另外一个 oleObject1.bin 就是我们要解析的公式对象,可以看到公式是以一个 OLE 对象嵌入文档中的,除此之外常规的 apache POI,python-docx,OpenXMLSDK 都能解析。
关于 mathtype 的数据结构,网上公开的不多,目前可以参考的只有:
http://rtf2latex2e.sourceforge.net/MTEF3.html
官方曾经公开过 MTEF v4、v5 的数据结构,好在 web.archive.org 组织备份了网页,我们得以一览。
Part 1. How MTEF is Stored in Files and Objects
Window MetaFile (WMF) 前文提到,docx文件解压后可以看到 wmf 文件,这个是微软御用的格式,实际上就是一张图片,可以用绘图板打开。 wmf 是一种公开的格式,如下是一份详尽的规范(https://www.loc.gov/preservation/digital/formats/digformatspecs/WindowsMetafileFormat(wmf)Specification.pdf),相信有不少开源的库实现了,例如 libwmf(http://wvware.sourceforge.net/libwmf.html)。
我们用 hexedit 打开 wmf 文件,可以看到,从 0x040D 开始,到 0x0549,就是 MTEF 的数据结构了。
我们从 0x040D 开始看起,第一个字节 0x05 代表这个文件使用的是 MTEF v.5 版本,非常幸运,我们使用的 MathType 6.9b 使用的是 MTEF v.5 版本的格式,当然,后面的 DSMT6 显示软件的版本是 6 系的,已公开的是 MTEF v.5 DSMT4 后续的数据结构可能会有少量调整。
https://docs.wiris.com/en/mathtype/mathtype_desktop/mathtype-sdk/mtef5
文章转发来源:https://shuker.io/mathtype-hack/