Web上で適切にレンダリングするには、MS-WORD2003以下のMathType方程式をMathMLに変換する必要があります。MathTypeの組み込み関数「PublishtoMathPage」は非常にうまく機能しますが、方程式の変換プロセスをC#アプリケーションに統合したいと思います。MathPageエクスポートインターフェイスがMathTypeSDKによって提供されているAPI参照が見つからなかったため、個々の方程式の変換を自分で行う方法を見つける必要があります。
現在の手順は、MS-WORD2003以下のドキュメントをOpenXML形式(docx)に変換することです。docx変換後、MathType埋め込みoleオブジェクトのバイナリ文字列がdocxであるopenxmlに保存されていることがわかります。次のステップは、埋め込みオブジェクトのバイナリ文字列からMTEFデータをデコードすることです。そこで、MathType MTEFヘッダーの公式ドキュメントを参照して、MTEFを抽出しようとしました。
MathTypeによって作成された埋め込みオブジェクトを表すbase64バイナリ文字列は、 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メンバーは、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
MTEFデータを解析するために使用しようとした方法に何か問題がありますか?