4

私はいくつかの Word 文書を持っており、それぞれに数百ページの科学データが含まれています。

  • 化学式 (すべて適切な下付き文字と上付き文字を含む H2SO4)
  • 科学数値 (上付き文字を使用してフォーマットされた指数)
  • 数学の方程式がたくさん。Word の数式エディターを使用して記述されています。

問題は、このデータを Word 形式で保存するのは効率的ではないということです。したがって、このすべての情報をデータベース (MySQL) に保存したいと考えています。これらのフォーマットを LaTex に変換したいと考えています。

VBAを使用して、すべての下付き文字と上付き文字と方程式を反復処理する方法はありますか?

数式を繰り返し処理するのはどうでしょうか?

4

4 に答える 4

10

マイケルの答えに対するあなたのコメントに基づいて

いいえ!下付きのコンテンツを _{ subscriptcontent } に置き換え、同様に上付きのコンテンツを ^{ superscriptcontent } に置き換えたいだけです。それはTexに相当します。ここで、すべてをテキスト ファイルにコピーします。これにより、書式設定は削除されますが、これらの文字は残ります。問題が解決しました。しかし、そのためには、ドキュメントの下付きオブジェクトと上付きオブジェクトにアクセスする必要があります

Sub sampler()
    Selection.HomeKey wdStory
    With Selection.find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Font.Superscript = True
        .Replacement.Text = "^^{^&}"
        .Execute Replace:=wdReplaceAll
        .Font.Subscript = True
        .Replacement.Text = "_{^&}"
        .Execute Replace:=wdReplaceAll
    End With
End Sub

編集

OMathsまたは にも変換したい場合はTeX / LaTeX、次のようにします。

  • Omath を反復する > それぞれを MathML に変換する > [MathML をディスクに保存する] + [OMath の代わりに MathML ファイルの参照を説明するマークアップをドキュメントに入れる] > Word ファイルをテキストとして変換する
  • MathParserのようなコンバーターを用意して、MathML ファイルを LateX に変換します
  • テキスト ファイルを解析する > それに応じて LaTeX コードを検索して置換します。

まったく別のアイデアについては、David Carlisle のブログにアクセスしてください。興味があるかもしれません。

アップデート

The module

Option Explicit

'This module requires the following references:
'Microsoft Scripting Runtime
'MicroSoft XML, v6.0

Private fso As New Scripting.FileSystemObject
Private omml2mml$, mml2Tex$

Public Function ProcessFile(fpath$) As Boolean
    'convPath set to my system at (may vary on your system):
    omml2mml = "c:\program files\microsoft office\office14\omml2mml.xsl"
    'download: http://prdownloads.sourceforge.net/xsltml/xsltml_2.0.zip
    'unzip at «c:\xsltml_2.0»
    mml2Tex = "c:\xsltml_2.0\mmltex.xsl"

    Documents.Open fpath

    'Superscript + Subscript
    Selection.HomeKey wdStory
    With Selection.find
        .ClearFormatting
        .Replacement.ClearFormatting

        'to make sure no paragraph should contain any emphasis
        .Text = "^p"
        .Replacement.Text = "^&"
        .Replacement.Font.Italic = False
        .Replacement.Font.Bold = False
        .Replacement.Font.Superscript = False
        .Replacement.Font.Subscript = False
        .Replacement.Font.SmallCaps = False
        .Execute Replace:=wdReplaceAll


        .Font.Italic = True
        .Replacement.Text = "\textit{^&}"
        .Execute Replace:=wdReplaceAll

        .Font.Bold = True
        .Replacement.Text = "\textbf{^&}"
        .Execute Replace:=wdReplaceAll

        .Font.SmallCaps = True
        .Replacement.Text = "\textsc{^&}"
        .Execute Replace:=wdReplaceAll


        .Font.Superscript = True
        .Replacement.Text = "^^{^&}"
        .Execute Replace:=wdReplaceAll


        .Font.Subscript = True
        .Replacement.Text = "_{^&}"
        .Execute Replace:=wdReplaceAll
    End With

    Dim dict As New Scripting.Dictionary
    Dim om As OMath, t, counter&, key$
    key = Replace(LCase(Dir(fpath)), " ", "_omath_")
    counter = 0

    For Each om In ActiveDocument.OMaths
        DoEvents
        counter = counter + 1
        Dim tKey$, texCode$
        tKey = "<" & key & "_" & counter & ">"
        t = om.Range.WordOpenXML

        texCode = TransformString(TransformString(CStr(t), omml2mml), mml2Tex)
        om.Range.Select
        Selection.Delete
        Selection.Text = tKey

        dict.Add tKey, texCode

    Next om

    Dim latexDoc$, oPath$
    latexDoc = "\documentclass[10pt]{article}" & vbCrLf & _
                "\usepackage[utf8]{inputenc} % set input encoding" & vbCrLf & _
                "\usepackage{amsmath,amssymb}" & vbCrLf & _
                "\begin{document}" & vbCrLf & _
                "###" & vbCrLf & _
                "\end{document}"

    oPath = StrReverse(Mid(StrReverse(fpath), InStr(StrReverse(fpath), "."))) & "tex"
    'ActiveDocument.SaveAs FileName:=oPath, FileFormat:=wdFormatText, Encoding:=1200
    'ActiveDocument.SaveAs FileName:=oPath, FileFormat:=wdFormatText, Encoding:=65001
    ActiveDocument.Close

    Dim c$, i
    c = fso.OpenTextFile(oPath).ReadAll()

    counter = 0

    For Each i In dict
        counter = counter + 1
        Dim findText$, replaceWith$
        findText = CStr(i)
        replaceWith = dict.item(i)
        c = Replace(c, findText, replaceWith, 1, 1, vbTextCompare)
    Next i

    latexDoc = Replace(latexDoc, "###", c)

    Dim ost As TextStream
    Set ost = fso.CreateTextFile(oPath)
    ost.Write latexDoc

    ProcessFile = True


End Function

Private Function CreateDOM()
    Dim dom As New DOMDocument60
    With dom
        .async = False
        .validateOnParse = False
        .resolveExternals = False
    End With
    Set CreateDOM = dom
End Function

Private Function TransformString(xmlString$, xslPath$) As String
    Dim xml, xsl, out
    Set xml = CreateDOM
    xml.LoadXML xmlString
    Set xsl = CreateDOM
    xsl.Load xslPath
    out = xml.transformNode(xsl)
    TransformString = out
End Function

The calling(from immediate window):

?ProcessFile("c:\test.doc")

結果は のように作成さtest.texc:\ます。


モジュールはいくつかの場所を修正する必要があるかもしれません。もしそうなら、私に知らせてください。

于 2012-07-26T05:49:28.033 に答える
2

Word の Document オブジェクトには、文書内のすべての oMath オブジェクトを表す oMaths コレクションがあります。oMath オブジェクトには、oMath オブジェクト内の関数のコレクションを返す Functions メソッドが含まれています。したがって、方程式はそれほど大きな問題ではないはずです。

ただし、下付き文字と上付き文字だけでなく、これらの下付き文字と上付き文字を含む方程式全体が必要になると思います。開始点と終了点を定義する必要があるため、これはより困難になる可能性があります。.Find メソッドを使用して下付き文字を検索し、その前の最初のスペース文字とその後の最初のスペース文字の間のすべてを選択する場合、それは機能する可能性がありますが、数式にスペースが含まれていない場合に限ります。

于 2012-07-19T18:21:23.583 に答える
1

この VBA サブスクリプトは、ドキュメント内のすべてのテキスト文字を調べて、LaTeX 表記を挿入するときに上付き文字と下付き文字を削除する必要があります。

Public Sub LatexConversion()

Dim myRange As Word.Range, myChr
For Each myRange In ActiveDocument.StoryRanges
  Do
    For Each myChr In myRange.Characters

        If myChr.Font.Superscript = True Then
            myChr.Font.Superscript = False
            myChr.InsertBefore "^"
        End If

        If myChr.Font.Subscript = True Then
            myChr.Font.Subscript = False
            myChr.InsertBefore "_"
        End If

    Next
    Set myRange = myRange.NextStoryRange
  Loop Until myRange Is Nothing
Next
End Sub

Word の組み込みの数式エディターまたはビルディング ブロック (Word 2010/2007) を使用して作成された数式がコンテンツ コントロール内に存在する場合、上記の方法は機能しません。これらの方程式は、上記を実行する前に、個別の VBA 変換コードまたはテキストのみの方程式への手動変換が必要です。

于 2012-07-25T17:19:07.770 に答える
1

Open XML SDK を使用した LaTex への OpenMath (OMath) の C# 実装。ここから MMLTEX XSL ファイルをダウンロードしますhttp://sourceforge.net/projects/xsltml/

    public void OMathTolaTeX()
    {
        string OMath = "";
        string MathML = "";
        string LaTex = "";
        XslCompiledTransform xslTransform = new XslCompiledTransform();
        // The MML2OMML.xsl file is located under 
        // %ProgramFiles%\Microsoft Office\Office12\
        // Copy to Local folder
        xslTransform.Load(@"D:\OMML2MML.XSL");
        using (WordprocessingDocument wordDoc =
                  WordprocessingDocument.Open("test.docx", true))
        {
            OpenXmlElement doc = wordDoc.MainDocumentPart.Document.Body;

            foreach (var par in doc.Descendants<Paragraph>())
            {
               var math in par.Descendants<DocumentFormat.OpenXml.Math.Paragraph>().FirstOrDefault();
               File.WriteAllText("D:\\openmath.xml", math.OuterXml);
               OMath = math.OuterXml;

           }
        }
        //Load OMath string into stream
        using (XmlReader reader = XmlReader.Create(new StringReader(OMath)))
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlWriterSettings settings = xslTransform.OutputSettings.Clone();

                // Configure xml writer to omit xml declaration.
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                settings.OmitXmlDeclaration = true;

                XmlWriter xw = XmlWriter.Create(ms, settings);

                // Transform our MathML to OfficeMathML
                xslTransform.Transform(reader, xw);
                ms.Seek(0, SeekOrigin.Begin);

                StreamReader sr = new StreamReader(ms, Encoding.UTF8);

                MathML= sr.ReadToEnd();

                Console.Out.WriteLine(MathML);
                File.WriteAllText("d:\\MATHML.xml", MathML);
                // Create a OfficeMath instance from the
                // OfficeMathML xml.
                sr.Close();
                reader.Close();
                ms.Close();

                // Add the OfficeMath instance to our 
                // word template.

            }
        }
        var xmlResolver = new XmlUrlResolver();
        xslTransform = new XslCompiledTransform();
        XsltSettings xsltt = new XsltSettings(true, true);
        // The mmtex.xsl file is to convert to Tex 
        xslTransform.Load("mmltex.xsl", xsltt, xmlResolver);

        using (XmlReader reader = XmlReader.Create(new StringReader(MathML)))
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlWriterSettings settings = xslTransform.OutputSettings.Clone();

                // Configure xml writer to omit xml declaration.
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                settings.OmitXmlDeclaration = true;

                XmlWriter xw = XmlWriter.Create(ms, settings);

                // Transform our MathML to OfficeMathML
                xslTransform.Transform(reader, xw);
                ms.Seek(0, SeekOrigin.Begin);

                StreamReader sr = new StreamReader(ms, Encoding.UTF8);

                LaTex = sr.ReadToEnd();
                sr.Close();
                reader.Close();
                ms.Close();
                Console.Out.WriteLine(LaTex);
                File.WriteAllText("d:\\Latex.txt", LaTex);
                // Create a OfficeMath instance from the
                // OfficeMathML xml.


                // Add the OfficeMath instance to our 
                // word template.

            }
        }
    }

これが C# 開発者に役立つことを願っています。

于 2014-01-05T14:41:12.990 に答える