Анализ данных MathType MTEF из двоичной строки OLE

Необходимо преобразовать уравнения MathType в MS-WORD 2003 или более ранних версиях в MathML, чтобы они хорошо отображались в Интернете. Встроенная функция MathType "Publish to MathPage" может очень хорошо выполнять эту работу, но я хочу интегрировать процесс преобразования уравнений в свое приложение C#. Поскольку я не смог найти никаких ссылок на API, указывающих на то, что интерфейс экспорта MathPage предоставляется пакетом SDK MathType, мне нужно найти способ самостоятельно преобразовать отдельные уравнения.

Текущая процедура заключается в преобразовании документов MS-WORD 2003 или более ранней версии в формат Open XML (docx). После преобразования docx я вижу, что двоичная строка встроенного ole-объекта MathType сохраняется в открытом xml, который является файлом docx. Затем следующим шагом является декодирование данных MTEF из двоичной строки встроенного объекта, поэтому я попытался извлечь MTEF, обратившись к официальной документации по заголовку MathType MTEF.

двоичная строка base64, представляющая встроенный объект, созданный MathType, извлекается из Тестовый файл MS-WORD в формате DOCX.

Определение заголовка MTEF:

Данные 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 является возвращаемым значением вызова функции RegisterClipboardFormat Windows API ("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);
}

Однако данные, заполненные в структуре заголовка, неверны, что заставляет меня думать, что это неправильный подход к анализу данных MTEF из двоичной строки внедренного объекта в файле DOCX.

Я также просмотрел пример кода .NET в загружаемом SDK MathType и обнаружил, что IDataObject используется для хранения информации MathType и процедур преобразования. Таким образом, другой подход состоит в том, чтобы использовать BinaryFormatter, чтобы увидеть, может ли он десериализовать двоичную строку в объект типа IDataObject, используя код BinaryFormatter.Deserialize(stream). Но это тоже не работает, вызывая исключение Binary stream '0' does not contain a valid BinaryHeader

Что-то не так с методами, которые я пытался использовать для анализа данных MTEF?


person Kata    schedule 10.03.2013    source источник