解析来自OLE二进制字符串MathType的MTEF数据(Parse MathType MTEF d

2019-08-17 10:52发布

有必要对MathType的公式转换在2003年MS-WORD或低于成MathML为了很好地呈现在网络上。 在MathType中内置的功能“发布到MathPage”可以做的工作非常漂亮,但我想公式转换过程在我的C#应用​​程序集成。 因为我无法找到该MathPage出口接口由MathType的SDK提供的API参考,我需要想出一个办法自己做独立式转换。

当前过程是到MS-Word 2003或以下的文件转换成打开XML格式(DOCX)。 在DOCX转换后,我可以看到MathType的嵌入OLE对象的二进制字符串保存在打开XML,这是DOCX。 然后,下一个步骤是从嵌入对象二进制串的MTEF数据进行解码,所以我试图通过参照上的MathType MTEF头中的正式文件以提取MTEF。

所述的base64二进制串 ,表示由创建的MathType嵌入对象,从提取的MS-WORD测试DOCX文件 。

中期支出框架头定义:

MTEF数据被保存为对象的本地数据格式。 每当一个等式对象是要被写入到一个OLE“流”中,28-字节的头被写入,随后MTEF数据。 用于该标题的C结构如下:

struct EQNOLEFILEHDR {
    WORD    cbHdr;     // length of header, sizeof(EQNOLEFILEHDR) = 28 bytes
    DWORD   version;   // hiword = 2, loword = 0
    WORD    cf;        // clipboard format ("MathType EF")
    DWORD   cbObject;  // length of MTEF data following this header in bytes
    DWORD   reserved1; // not used
    DWORD   reserved2; // not used
    DWORD   reserved3; // not used
    DWORD   reserved4; // not used
};

在CF成员是Windows API函数的RegisterClipboardFormat(“MathType的EF”)的调用的返回值。

然后我试图将其转换为C#版本:

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct EQNOLEFILEHDR
{
    public UInt16 cbHdr;
    public UInt32 version;
    public UInt16 format;
    public UInt32 size;
    public UInt32 reserved1;
    public UInt32 reserved2;
    public UInt32 reserved3;
    public UInt32 reserved4;
}

与插头结构准备,下面的代码试图填补从嵌入对象二进制串标头结构的信息。

foreach (EmbeddedObjectPart eop in wordDoc.MainDocumentPart.EmbeddedObjectParts)
{
    Stream stream = eop.GetStream();
    byte[] buffer = new byte[int.Parse(stream.Length.ToString())];
    using (BinaryReader reader = new BinaryReader(stream))
    {
        int res = reader.Read(buffer, 0, int.Parse(stream.Length.ToString()));
    }
    GCHandle hdl = GCHandle.Alloc(buffer, GCHandleType.Pinned);
    IntPtr intp = Marshal.AllocHGlobal(buffer.Length);
    Marshal.Copy(buffer, 0, intp, Marshal.SizeOf(typeof(EQNOLEFILEHDR)));
    EQNOLEFILEHDR header = (EQNOLEFILEHDR)Marshal.PtrToStructure(intp, typeof(EQNOLEFILEHDR));
    Marshal.FreeHGlobal(intp);
}

然而,充满在头结构中的数据是不正确的,让我觉得这是不是从DOCX文件中嵌入的对象二进制字符串解析MTEF数据是正确的做法。

我也看了在MathType的SDK下载的样本.NET代码,并找到了IDataObject用来包含MathType的信息和转换程序。 因此,另一种方法是使用BinaryFormatter ,看它是否可以反序列化二进制串到IDataObject的类型的对象中,通过使用码BinaryFormatter.Deserialize(stream) 。 但它也不行,提示异常Binary stream '0' does not contain a valid BinaryHeader

什么错在我试图用解析中期支出框架数据的方法?

Answer 1:

卡塔,你应该已经收到我的电子邮件回复,但对于其他人有兴趣,我们是从我们的SDK修改的样品,我们会很乐意发送给任何人谁需要它。 对于使用它的人,它可能不会太大意义,如果你还没有下载SDK。 请让我知道,如果你想给它一个尝试。

鲍勃·马修斯
设计科学



文章来源: Parse MathType MTEF data from OLE binary string