コード例 #1
0
        /// <summary>
        /// Searches in a predefined conversion table and returns the converted result or null.
        /// </summary>
        /// <param name="table">The conversion table to search in.</param>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The converted result or null.</returns>
        private static string SearchInTables(IDictionary <string, string> table, LatexExpression expr)
        {
            string constant;

            if (table.TryGetValue(expr.Name, out constant))
            {
                string children = "";
                if (expr.Expressions != null && expr.Options != null && expr.Options.AsExpressions != null)
                {
                    for (int i = 0; i < expr.Options.AsExpressions.Count; i++)
                    {
                        children += expr.Options.AsExpressions[i].Convert();
                    }
                }
                if (expr.Expressions != null)
                {
                    for (int i = 0; i < expr.Expressions.Count; i++)
                    {
                        for (int j = 0; j < expr.Expressions[i].Count; j++)
                        {
                            children += expr.Expressions[i][j].Convert();
                        }
                    }
                }
                return(constant + children);
            }
            return(null);
        }
コード例 #2
0
        public string ConvertToMathMLTree(string latexExpression)
        {
            //string prefixLatex = @"\begin{document}";
            //string postfixLatex = @"\end{document}";
            //string resultLatexExpression = string.Format("{0}{1}{2}", prefixLatex, latexExpression, postfixLatex);
            string resultLatexExpression = latexExpression;
            var    parser = new LatexParser(resultLatexExpression, this);

            try
            {
                LatexExpression root = parser.Root;

                CallEventHandler(AfterDocumentWasParsed);

                String        linkToMMLDDT = "<!DOCTYPE math SYSTEM 'http://www.w3.org/Math/DTD/mathml1/mathml.dtd'>";
                StringBuilder sb           = new StringBuilder(linkToMMLDDT);

                Output = root.Convert();
                return(Output);
            }
            catch (Exception exp)
            {
                return(exp.Message);
            }
        }
コード例 #3
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            if (expr.Expressions == null)
            {
                return("");
            }
            GetParameters();
            var bld = new StringBuilder();

            if (_mathMode)
            {
                bld.Append("<mover accent=\"true\">\n");
                if (!_stretchy)
                {
                    bld.Append(expr.Expressions[0][0].Convert());
                }
                else
                {
                    bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
                }
                bld.Append("<mo stretchy=\"true\">" + _value + "</mo>\n</mover>\n");
            }
            else
            {
                MathConverter.AppendMathProlog(bld, "accent", true, expr.Customization);
                bld.Append("<mrow>");
                bld.Append("<mover accent=\"true\">\n");
                bld.Append(expr.Expressions[0][0].Convert());
                bld.Append("<mo>" + _value + "</mo>\n</mover>\n");
                bld.Append("</mrow>\n");
                MathConverter.AppendMathEpilog(bld);
            }
            return(bld.ToString());
        }
コード例 #4
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            var bld = new StringBuilder("<");
            var tag = _tag;

            if (CommandConverter.MathFunctionsScriptCommandConstants.ContainsKey(expr.Expressions[0][0].Name))
            {
                tag = (_tag == "msup") ? "mover" : "munder";
            }
            bld.Append(tag);
            bld.Append(">\n<mrow>\n");
            var first = expr.Expressions[0][0].Convert();

            if (first != "</mrow>\n</mfenced>\n")
            {
                bld.Append(first);
            }
            bld.Append("</mrow>\n<mrow>\n");
            bld.Append(expr.Expressions[0][1].Convert());
            bld.Append("</mrow>\n</");
            bld.Append(tag);
            bld.Append(">\n");
            if (first != "</mrow>\n</mfenced>\n")
            {
                return(bld.ToString());
            }
            return(first + bld);
        }
コード例 #5
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            var bodyBuilder = new StringBuilder();

            // Convert the {document} block
            LatexExpression documentExpression = expr.FindDocument();

            if (documentExpression != null)
            {
                try
                {
                    bodyBuilder.Append(documentExpression.Convert());
                }
                // ReSharper disable RedundantCatchClause
#pragma warning disable 168
                catch (Exception e)
#pragma warning restore 168
                {
#if DEBUG
                    throw;
#else
                    Log.Error("Failed to convert the document block", e);
#endif
                }
                // ReSharper restore RedundantCatchClause
                // ReSharper restore RedundantCatchClause
            }

            return(bodyBuilder.ToString());
        }
コード例 #6
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     if (expr.Expressions == null) return "";
     var url = expr.Expressions[0][0].Name;
     var text = SequenceConverter.ConvertOutline(expr.Expressions[1], expr.Customization);
     return "<a href=\"" + url + "\">" + text + "</a>";
 }
コード例 #7
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     if (expr.Expressions == null) return "";
     GetParameters();
     var bld = new StringBuilder();
     if (_mathMode)
     {
         bld.Append("<mover accent=\"true\">\n");
         if (!_stretchy)
         {
             bld.Append(expr.Expressions[0][0].Convert());
         }
         else
         {
             bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
         }
         bld.Append("<mo stretchy=\"true\">" + _value + "</mo>\n</mover>\n");
     }
     else
     {
         MathConverter.AppendMathProlog(bld, "accent", true, expr.Customization);
         bld.Append("<mrow>");
         bld.Append("<mover accent=\"true\">\n");
         bld.Append(expr.Expressions[0][0].Convert());
         bld.Append("<mo>" + _value + "</mo>\n</mover>\n");
         bld.Append("</mrow>\n");
         MathConverter.AppendMathEpilog(bld);
     }
     return bld.ToString();
 }
コード例 #8
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     if (expr.Expressions == null) return "";
     var alg = "<code class=\"algorithm\">";
     alg += SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization);
     return alg + "</code>\n";
 }
コード例 #9
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            if (!expr.MathMode)
            {
                var formatDiv = "<span class=\"" + "normalsize" + "\">";
                formatDiv += LatexStringToXmlString(expr.Name);
                return(formatDiv + "</span>");
            }
            if (expr.Name == "InvisibleTimes")
            {
                return("<mo>&#x2062;<!-- &InvisibleTimes; --></mo>\n");
            }
            if (char.IsLetter(expr.Name[0]))
            {
                return("<mi>" + expr.Name + "</mi>\n");
            }
            if (char.IsDigit(expr.Name[0]))
            {
                return("<mn>" + expr.Name + "</mn>\n");
            }
            string str;

            if (MathConstants.TryGetValue(expr.Name, out str))
            {
                return(str);
            }
            return("<mo>" + LatexStringToXmlString(expr.Name.Trim()) + "</mo>\n");
        }
コード例 #10
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     var bld = new StringBuilder("<");
     var tag = _tag;
     bool reverse = false;
     if (CommandConverter.MathFunctionsScriptCommandConstants.ContainsKey(expr.Expressions[0][0].Name))
     {
         tag = (_tag == "msupsub") ? "moverunder" : "munderover";
     }
     else
     {
         tag = "msubsup";
         reverse = _tag != tag;
     }
     bld.Append(tag);
     bld.Append(">\n<mrow>\n");
     var first = expr.Expressions[0][0].Convert();
     if (first != "</mrow>\n</mfenced>\n")
     {
         bld.Append(first);
     }
     bld.Append("</mrow>\n<mrow>\n");
     bld.Append(expr.Expressions[0][reverse? 2 : 1].Convert());
     bld.Append("</mrow>\n<mrow>\n");
     bld.Append(expr.Expressions[0][reverse? 1 : 2].Convert());
     bld.Append("</mrow>\n</");
     bld.Append(tag);
     bld.Append(">\n");
     if (first != "</mrow>\n</mfenced>\n")
     {
         return bld.ToString();
     }
     return first + bld;
 }
コード例 #11
0
        /// <summary>
        /// Parses the document and builds the document object tree.
        /// </summary>
        /// <param name="rdr">The reader to read the document from.</param>
        /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
        /// <returns>The root of the document object tree.</returns>
        public static LatexExpression CreateRoot(TextReader rdr, LatexMathToMathMLConverter customization)
        {
            bool verbatimMode = false;
            int  rootIndex    = 0;
            var  root         = new LatexExpression(null, 0, ref rootIndex, ref verbatimMode,
                                                    ExpressionType.Root, false, customization, null, null, null)
            {
                Expressions = new List <List <LatexExpression> >(1)
            };
            var             children  = new List <LatexExpression>();
            string          beginning = null;
            string          end;
            LatexExpression cmd;

            rootIndex = 0;
            bool mathMode         = false;
            bool whitespaceBefore = false;

            while ((cmd = ReadFromTextReader(root, 0, ref rootIndex, ref verbatimMode,
                                             mathMode, customization, beginning, rdr, out end, ref whitespaceBefore)) != null)
            {
                CheckMathMode(cmd, ref mathMode);
                beginning = end;
                children.Add(cmd);
            }
            root.Expressions.Add(children);
            return(root);
        }
コード例 #12
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
			var bodyBuilder = new StringBuilder();

            // Convert the {document} block
            LatexExpression documentExpression = expr.FindDocument();
            if (documentExpression != null)
            {
                try
                {
                    bodyBuilder.Append(documentExpression.Convert());
                }
                // ReSharper disable RedundantCatchClause
#pragma warning disable 168
                catch (Exception e)
#pragma warning restore 168
                {
#if DEBUG
                    throw;
#else
                Log.Error("Failed to convert the document block", e);
#endif
                }
                // ReSharper restore RedundantCatchClause
                // ReSharper restore RedundantCatchClause
            }

			return bodyBuilder.ToString();
        }
コード例 #13
0
        /// <summary>
        /// Builds the document object tree.
        /// </summary>
        /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
        /// <remarks>The parsing procedure consists of stand-alone passes, so that it resembles a compiler pipeline.</remarks>
        public void Parse(LatexMathToMathMLConverter customization)
        {
            foreach (var rule in PreformatRules)
            {
                _source = _source.Replace(rule[0], rule[1]);
            }
            var        rdr        = new StringReader(_source);
            const byte PASS_COUNT = 14;
            byte       step       = 1;

            // Build the tree
            LogInfo("CreateRoot");
            _root = LatexExpression.CreateRoot(rdr, customization);
            OnProgressEvent(step++, PASS_COUNT);

            //TODO Go through the usage of _customCommands
            // Rebuild tree with custom commands
            _customCommands = new Dictionary <string, LatexExpression>();
            LogInfo("RecursiveParseCustomCommands");

            // Incapsulate fragments between \begin and \end
            LogInfo("IncapsulateCommands");
            IncapsulateCommands(Root.Expressions[0]);
            OnProgressEvent(step++, PASS_COUNT);

            // Post-parse arrays
            LogInfo("PostParseArrays");
            PostParseArrays(Root.Expressions[0], customization);
            OnProgressEvent(step++, PASS_COUNT);

            // Build super- and subscripts
            LogInfo("BuildScripts");
            BuildScripts(Root.Expressions[0], customization);
            OnProgressEvent(step++, PASS_COUNT);

            // Simplify math blocks that begin with baseless scripts
            LogInfo("SimplifyScripts");
            SimplifyBaselessScripts(Root.Expressions[0]);
            OnProgressEvent(step++, PASS_COUNT);

            // Numerate blocks (needed for the next step)
            LogInfo("NumerateBlocks");
            NumerateBlocks(Root.FindDocument().Expressions[0]);
            Root.Customization.Counters.Add("document", 0);
            OnProgressEvent(step++, PASS_COUNT);

            // Simplify math blocks that begin with baseless scripts
            LogInfo("PreProcessLabels");
            PreprocessLabels(Root.FindDocument().Expressions[0]);
            Root.Customization.Counters.Clear();
            OnProgressEvent(step++, PASS_COUNT);

            // Deal with algorithmic blocks
            LogInfo("PreprocessAlgorithms");
            PreprocessAlgorithms(Root.FindDocument().Expressions[0]);
            OnProgressEvent(step++, PASS_COUNT);

            LogInfo("Finished");
        }
コード例 #14
0
 /// <summary>
 /// Recursively incapsulates tree fragments between \begin and \end.
 /// </summary>
 /// <param name="outline">The outline of a LatexExpression instance.</param>
 private static void IncapsulateCommands(List <LatexExpression> outline)
 {
     for (int i = 0; i < outline.Count; i++)
     {
         if (outline[i].ExprType == ExpressionType.Command &&
             outline[i].Name == "begin")
         {
             var cmdValue = outline[i].Expressions[0][0].Name;
             int j;
             for (j = i;
                  outline[j].Name != "end" || outline[j].Expressions == null || outline[j].Expressions[0][0].Name != cmdValue;
                  j++)
             {
             }
             int length     = j - i - 1;
             var subOutline = new LatexExpression[length];
             // Cut the right chunk
             outline.CopyTo(i + 1, subOutline, 0, length);
             outline.RemoveRange(i + 1, length + 1);
             // Update outline[i]
             outline[i].Name     = cmdValue;
             outline[i].ExprType = ExpressionType.Block;
             outline[i].Expressions.RemoveAt(0);
             for (int k = 0; k < outline[i].Expressions.Count; k++)
             {
                 foreach (var expr in outline[i].Expressions[k])
                 {
                     expr.ParentChildNumber--;
                 }
             }
             // Update outline
             for (int k = i + 1; k < outline.Count; k++)
             {
                 outline[k].IndexInParentChild -= length + 1;
             }
             // Update subOutline
             int parentChildNumber = outline[i].Expressions.Count;
             for (int k = 0; k < subOutline.Length; k++)
             {
                 subOutline[k].Parent             = outline[i];
                 subOutline[k].ParentChildNumber  = parentChildNumber;
                 subOutline[k].IndexInParentChild = k;
             }
             // Link subOutline
             outline[i].Expressions.Add(new List <LatexExpression>(subOutline));
             IncapsulateCommands(outline[i].Expressions[parentChildNumber]);
         }
     }
     for (int i = 0; i < outline.Count; i++)
     {
         if (outline[i].Expressions != null)
         {
             foreach (var subTree in outline[i].Expressions)
             {
                 IncapsulateCommands(subTree);
             }
         }
     }
 }
コード例 #15
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     expr.ExprType = ExpressionType.BlockMath;
     expr.Expressions.Add(new List <LatexExpression> {
         new LatexExpression("equation", expr, 1, 0, expr.Customization)
     });
     return(expr.Convert());
 }
コード例 #16
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     var bld = new StringBuilder("<p style=\"text-align:");
     bld.Append(_alignment);
     bld.Append(";\">\n");
     bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
     bld.Append("</p>\n");
     return bld.ToString();
 }
コード例 #17
0
 /// <summary>
 /// Recursively replaces all occurences of src in all subtrees with the specified sequence of expressions.
 /// </summary>
 /// <param name="src">The string to search and replace.</param>
 /// <param name="repl">The replacesment sequence of expressions.</param>
 public void RecursiveReplace(string src, List <LatexExpression> repl)
 {
     if (Expressions != null)
     {
         foreach (var childOutline in Expressions)
         {
             for (int i = 0; i < childOutline.Count; i++)
             {
                 childOutline[i].RecursiveReplace(src, repl);
             }
         }
     }
     if (ExprType == ExpressionType.PlainText)
     {
         int pos = Name.IndexOf(src);
         if (pos > -1)
         {
             if (pos > 0)
             {
                 var  beg          = Name.Substring(0, pos);
                 bool verbatimMode = false;
                 int  index        = IndexInParentChild;
                 Parent.Expressions[ParentChildNumber].Insert(IndexInParentChild,
                                                              new LatexExpression(Parent, ParentChildNumber, ref index,
                                                                                  ref verbatimMode, ExpressionType.PlainText, MathMode,
                                                                                  Customization, beg, null, null));
                 IndexInParentChild++;
             }
             Parent.Expressions[ParentChildNumber].RemoveAt(IndexInParentChild);
             for (int i = IndexInParentChild; i < Parent.Expressions[ParentChildNumber].Count; i++)
             {
                 Parent.Expressions[ParentChildNumber][i].IndexInParentChild = i + repl.Count;
             }
             var localRepl = new LatexExpression[repl.Count];
             repl.CopyTo(localRepl);
             for (int i = 0; i < repl.Count; i++)
             {
                 var expr = localRepl[i];
                 expr.Parent             = Parent;
                 expr.ParentChildNumber  = ParentChildNumber;
                 expr.IndexInParentChild = i + IndexInParentChild;
             }
             Parent.Expressions[ParentChildNumber].InsertRange(IndexInParentChild, localRepl);
             var end = Name.Substring(src.Length);
             if (end != "")
             {
                 bool verbatimMode2 = false;
                 int  index2        = IndexInParentChild + repl.Count;
                 Parent.Expressions[ParentChildNumber].Insert(index2,
                                                              new LatexExpression(Parent, ParentChildNumber, ref index2,
                                                                                  ref verbatimMode2, ExpressionType.PlainText, MathMode,
                                                                                  Customization, end, null, null));
             }
         }
     }
 }
コード例 #18
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            BlockConverter converter;

            if (BlockConverters.TryGetValue(expr.Name, out converter))
            {
                return(converter.Convert(expr));
            }
            return((new UnknownBlockConverter()).Convert(expr));
        }
コード例 #19
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     var bld = new StringBuilder();
     bld.Append("<mfrac>\n<mrow>\n");
     bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
     bld.Append("</mrow>\n<mrow>\n");
     bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[1], expr.Customization));
     bld.Append("</mrow>\n</mfrac>\n");
     return bld.ToString();
 }
コード例 #20
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            if (expr.Expressions == null)
            {
                return("");
            }
            var url = expr.Expressions[0][0].Name;

            return("<a href=\"" + url + "\">" + url + "</a>");
        }
コード例 #21
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            var bld = new StringBuilder("<p style=\"text-align:");

            bld.Append(_alignment);
            bld.Append(";\">\n");
            bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
            bld.Append("</p>\n");
            return(bld.ToString());
        }
コード例 #22
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            var bld = new StringBuilder();

            bld.Append("<mfrac>\n<mrow>\n");
            bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
            bld.Append("</mrow>\n<mrow>\n");
            bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[1], expr.Customization));
            bld.Append("</mrow>\n</mfrac>\n");
            return(bld.ToString());
        }
コード例 #23
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            if (expr.Expressions == null)
            {
                return("");
            }
            var url  = expr.Expressions[0][0].Name;
            var text = SequenceConverter.ConvertOutline(expr.Expressions[1], expr.Customization);

            return("<a href=\"" + url + "\">" + text + "</a>");
        }
コード例 #24
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            if (expr.Expressions == null)
            {
                return("");
            }
            var alg = "<code class=\"algorithm\">";

            alg += SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization);
            return(alg + "</code>\n");
        }
コード例 #25
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            var tag    = (int[])expr.Tag;
            var result = "<br />";

            if (tag != null)
            {
                result += new string(' ', tag[1]);
            }
            return(result);
        }
コード例 #26
0
 /// <summary>
 /// Builds a new LatexExpression instance (front).
 /// </summary>
 /// <param name="parent">The parent of the builded expression.</param>
 /// <param name="parentChildNumber">Index of the parent child outline.</param>
 /// <param name="indexInParentChild">Index in the parent child outline.</param>
 /// <param name="verbatimMode">True if verbatim mode is on; otherwise, false.</param>
 /// <param name="beginning">The beginning string.</param>
 /// <param name="rdr">The reader to read ahead.</param>
 /// <param name="end">The stub of the unparsed part.</param>
 /// <param name="mathMode">The math mode switch.</param>
 /// <param name="whitespaceBefore">Indicates whether there was at least one whitespace char before the returned result.</param>
 /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
 /// <returns></returns>
 private static LatexExpression ReadFromTextReader(LatexExpression parent, int parentChildNumber,
                                                   ref int indexInParentChild, ref bool verbatimMode, bool mathMode, LatexMathToMathMLConverter customization,
                                                   string beginning, TextReader rdr, out string end, ref bool whitespaceBefore)
 {
     if (beginning == null && rdr == null)
     {
         end = null;
         return(null);
     }
     return(ReadFromTextReaderInner(parent, parentChildNumber, ref indexInParentChild, ref verbatimMode,
                                    mathMode, customization, beginning ?? rdr.ReadLine(), rdr, out end, ref whitespaceBefore));
 }
コード例 #27
0
 /// <summary>
 /// Initializes a new instance of the LatexExpression class of type ExpressionType.Block.
 /// </summary>
 /// <param name="name">The name of the block.</param>
 /// <param name="parent">The parent of the builded expression.</param>
 /// <param name="parentChildNumber">Index of the parent child outline.</param>
 /// <param name="indexInParentChild">Index in the parent child outline.</param>
 /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
 public LatexExpression(string name, LatexExpression parent, int parentChildNumber, int indexInParentChild, LatexMathToMathMLConverter customization)
 {
     Name          = name;
     Customization = customization;
     ExprType      = ExpressionType.Block;
     MathMode      = parent.MathMode |
                     parent.ExprType == ExpressionType.BlockMath | parent.ExprType == ExpressionType.InlineMath;
     Parent             = parent;
     ParentChildNumber  = parentChildNumber;
     IndexInParentChild = indexInParentChild;
     Expressions        = new List <List <LatexExpression> > {
         new List <LatexExpression>()
     };
 }
コード例 #28
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     if (expr.Expressions == null) return "";
     if (expr.Parent.ExprType == ExpressionType.Block && expr.Parent.Name.IndexOf("script") > -1)
     {
         return SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization);
     }
     var bld = new StringBuilder();
     string tag;
     tag = expr.Name == "^" ? "sup" : "sub";
     bld.Append("<" + tag + ">\n");
     bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
     bld.Append("</" + tag + ">");
     return bld.ToString();
 }
コード例 #29
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            if (expr.Expressions == null)
            {
                return("");
            }
            var    letter = expr.Expressions[0][0].Name[0];
            string converted;

            if (!ConversionTable.TryGetValue(letter, out converted))
            {
                converted = "" + letter;
            }
            return(converted);
        }
コード例 #30
0
 /// <summary>
 /// Checks for the beginning or the ending of a future block that must be parsed in math mode.
 /// </summary>
 /// <param name="expr">The suspected expression.</param>
 /// <param name="mathMode">The math mode flag.</param>
 private static void CheckMathMode(LatexExpression expr, ref bool mathMode)
 {
     if (!mathMode && expr.ExprType == ExpressionType.Command &&
         expr.Expressions != null && expr.Name == "begin")
     {
         mathMode = BlockConverter.ImpliesMathMode(expr.Expressions[0][0].Name);
     }
     if (mathMode && expr.ExprType == ExpressionType.Command &&
         expr.Expressions != null && expr.Name == "end")
     {
         if (BlockConverter.ImpliesMathMode(expr.Expressions[0][0].Name))
         {
             mathMode = false;
         }
     }
 }
コード例 #31
0
 /// <summary>
 /// Initializes a new instance of the LatexExpression class and copies the specified expression data to it.
 /// </summary>
 /// <param name="expression">The expression to clone.</param>
 public LatexExpression(LatexExpression expression)
 {
     Parent        = expression.Parent;
     Name          = expression.Name;
     ExprType      = expression.ExprType;
     MathMode      = expression.MathMode;
     Customization = expression.Customization;
     if (expression.Options != null)
     {
         Options = new ExpressionOptions();
     }
     if (expression.Expressions != null)
     {
         Expressions = new List <List <LatexExpression> >(expression.Expressions);
     }
 }
コード例 #32
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            CommandConverter converter;

            if (CommandConverters.TryGetValue(expr.GetCommandConverterHashCode(), out converter))
            {
                if (converter.ExpectedBranchesCount > 0 && (expr.Expressions == null || expr.Expressions.Count < converter.ExpectedBranchesCount))
                {
                    throw new FormatException(@"Unexpected format in command \\" + converter.Name);
                    //return "<!-- Unexpected format in command \\" + converter.Name + " -->";
                }
                var result = converter.Convert(expr);
                // Make sure that {} blocks which were attached to the command by mistake will be converted, too.
                // Goddamn ancient Latex
                if (expr.Expressions != null && expr.Expressions.Count > converter.ExpectedBranchesCount)
                {
                    for (int i = converter.ExpectedBranchesCount; i < expr.Expressions.Count; i++)
                    {
                        result += SequenceConverter.ConvertOutline(expr.Expressions[i], expr.Customization);
                    }
                }
                return(result);
            }
            string constant;

            if (CommandConstants.TryGetValue(expr.Name, out constant))
            {
                if (expr.MathMode)
                {
                    return("<mi>" + constant + "</mi>");
                }
                return(constant);
            }
            if ((constant = SearchInTables(MathCommandConstants, expr)) != null)
            {
                return(constant);
            }
            if ((constant = SearchInTables(MathFunctionsCommandConstants, expr)) != null)
            {
                return(constant);
            }
            if ((constant = SearchInTables(MathFunctionsScriptCommandConstants, expr)) != null)
            {
                return(constant);
            }
            return("<!-- \\" + LatexStringToXmlString(expr.Name) + " -->\n");
        }
コード例 #33
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     var bld = new StringBuilder();
     if (expr.Options == null)
     {
         bld.Append("<msqrt>\n<mrow>\n");
         bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
         bld.Append("</mrow>\n</msqrt>\n");
         return bld.ToString();
     }
     bld.Append("<mroot>\n<mrow>\n");
     bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
     bld.Append("</mrow>\n<mrow>\n");
     bld.Append(SequenceConverter.ConvertOutline(expr.Options.AsExpressions, expr.Customization));
     bld.Append("</mrow>\n</mroot>\n");
     return bld.ToString();
 }
コード例 #34
0
        /// <summary>
        /// Performs the conversion procedure (comments the expression).
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            var bld = new StringBuilder();
            int parentChildNumber = expr.Expressions.Count == 1 ? 0 : 1;
            var rows       = expr.Expressions[parentChildNumber];
            var alignments = parentChildNumber > 0 ? expr.Expressions[0][0].Name : "";

            alignments = alignments.Replace("|", "");
            bld.Append("<mtable>\n");
            for (int i = 0; i < rows.Count; i++)
            {
                bld.Append("<mtr>\n");
                for (int j = 0; j < rows[i].Expressions[0].Count; j++)
                {
                    #region Determine the alignment
                    var alignment = "center";
                    if (j < alignments.Length)
                    {
                        switch (alignments[j])
                        {
                        case 'c':
                            alignment = "center";
                            break;

                        case 'l':
                            alignment = "left";
                            break;

                        case 'r':
                            alignment = "right";
                            break;
                        }
                    }
                    #endregion
                    bld.Append("<mtd columnalign=\"");
                    bld.Append(alignment);
                    bld.Append("\">\n<mrow>\n");
                    bld.Append(SequenceConverter.ConvertOutline(rows[i].Expressions[0][j].Expressions[0], expr.Customization));
                    bld.Append("</mrow>\n</mtd>\n");
                }
                bld.Append("</mtr>\n");
            }
            bld.Append("</mtable>\n");
            return(bld.ToString());
        }
コード例 #35
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            var bld = new StringBuilder();

            if (expr.Options == null)
            {
                bld.Append("<msqrt>\n<mrow>\n");
                bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
                bld.Append("</mrow>\n</msqrt>\n");
                return(bld.ToString());
            }
            bld.Append("<mroot>\n<mrow>\n");
            bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
            bld.Append("</mrow>\n<mrow>\n");
            bld.Append(SequenceConverter.ConvertOutline(expr.Options.AsExpressions, expr.Customization));
            bld.Append("</mrow>\n</mroot>\n");
            return(bld.ToString());
        }
コード例 #36
0
        /// <summary>
        /// Find the document block in children (valid only for the root expression).
        /// </summary>
        /// <returns></returns>
        public LatexExpression FindDocument()
        {
            if (ExprType != ExpressionType.Root)
            {
                return(null);
            }
            LatexExpression documentExpression = null;

            foreach (var child in Expressions[0])
            {
                if (child.ExprType == ExpressionType.Block && child.Name == "document")
                {
                    documentExpression = child;
                    break;
                }
            }
            return(documentExpression);
        }
コード例 #37
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            if (expr.Expressions == null)
            {
                return("");
            }
            if (expr.Parent.ExprType == ExpressionType.Block && expr.Parent.Name.IndexOf("script") > -1)
            {
                return(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
            }
            var    bld = new StringBuilder();
            string tag;

            tag = expr.Name == "^" ? "sup" : "sub";
            bld.Append("<" + tag + ">\n");
            bld.Append(SequenceConverter.ConvertOutline(expr.Expressions[0], expr.Customization));
            bld.Append("</" + tag + ">");
            return(bld.ToString());
        }
コード例 #38
0
 /// <summary>
 /// Performs the conversion procedure (comments the expression).
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     var bld = new StringBuilder();
     int parentChildNumber = expr.Expressions.Count == 1 ? 0 : 1;
     var rows = expr.Expressions[parentChildNumber];
     var alignments = parentChildNumber > 0 ? expr.Expressions[0][0].Name : "";
     alignments = alignments.Replace("|", "");
     bld.Append("<mtable>\n");
     for (int i = 0; i < rows.Count; i++)
     {
         bld.Append("<mtr>\n");
         for (int j = 0; j < rows[i].Expressions[0].Count; j++)
         {
             #region Determine the alignment
             var alignment = "center";
             if (j < alignments.Length)
             {
                 switch (alignments[j])
                 {
                     case 'c':
                         alignment = "center";
                         break;
                     case 'l':
                         alignment = "left";
                         break;
                     case 'r':
                         alignment = "right";
                         break;
                 }
             }
             #endregion
             bld.Append("<mtd columnalign=\"");
             bld.Append(alignment);
             bld.Append("\">\n<mrow>\n");
             bld.Append(SequenceConverter.ConvertOutline(rows[i].Expressions[0][j].Expressions[0], expr.Customization));
             bld.Append("</mrow>\n</mtd>\n");
         }
         bld.Append("</mtr>\n");
     }
     bld.Append("</mtable>\n");
     return bld.ToString();
 }
コード例 #39
0
 /// <summary>
 /// Performs the conversion procedure (comments the expression).
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     var bld = new StringBuilder();
     MathConverter.AppendMathProlog(bld, "eqnarray", false, expr.Customization);
     var rows = expr.Expressions[0];
     bld.Append("<mtable>\n");
     for (int i = 0; i < rows.Count; i++)
     {
         bld.Append("<mtr>\n");
         for (int j = 0; j < rows[i].Expressions[0].Count; j++)
         {
             bld.Append("<mtd columnalign=\"left\">\n<mrow>\n");
             bld.Append(SequenceConverter.ConvertOutline(rows[i].Expressions[0][j].Expressions[0], expr.Customization));
             bld.Append("</mrow>\n</mtd>\n");
         }
         bld.Append("</mtr>\n");
     }
     bld.Append("</mtable>\n");
     MathConverter.AppendMathEpilog(bld);
     return bld.ToString();
 }
コード例 #40
0
        /// <summary>
        /// Performs the conversion procedure (comments the expression).
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            var bld = new StringBuilder();

            MathConverter.AppendMathProlog(bld, "eqnarray", false, expr.Customization);
            var rows = expr.Expressions[0];

            bld.Append("<mtable>\n");
            for (int i = 0; i < rows.Count; i++)
            {
                bld.Append("<mtr>\n");
                for (int j = 0; j < rows[i].Expressions[0].Count; j++)
                {
                    bld.Append("<mtd columnalign=\"left\">\n<mrow>\n");
                    bld.Append(SequenceConverter.ConvertOutline(rows[i].Expressions[0][j].Expressions[0], expr.Customization));
                    bld.Append("</mrow>\n</mtd>\n");
                }
                bld.Append("</mtr>\n");
            }
            bld.Append("</mtable>\n");
            MathConverter.AppendMathEpilog(bld);
            return(bld.ToString());
        }
コード例 #41
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     return CommonConvert(expr.Expressions[0],
         LatexStringToXmlString(expr.Expressions[1][0].Name),
         expr.ExprType == ExpressionType.InlineMath, expr.Customization);
 }
コード例 #42
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     expr.ExprType = ExpressionType.BlockMath;
     expr.Expressions.Add(new List<LatexExpression> {new LatexExpression("equation", expr, 1, 0, expr.Customization)});
     return expr.Convert();
 }
コード例 #43
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     BlockConverter converter;
     if (BlockConverters.TryGetValue(expr.Name, out converter))
     {
         return converter.Convert(expr);
     }
     return (new UnknownBlockConverter()).Convert(expr);
 }
コード例 #44
0
 /// <summary>
 /// Builds a new LatexExpression instance (front).
 /// </summary>
 /// <param name="parent">The parent of the builded expression.</param>
 /// <param name="parentChildNumber">Index of the parent child outline.</param>
 /// <param name="indexInParentChild">Index in the parent child outline.</param>
 /// <param name="verbatimMode">True if verbatim mode is on; otherwise, false.</param>
 /// <param name="beginning">The beginning string.</param>
 /// <param name="rdr">The reader to read ahead.</param>
 /// <param name="end">The stub of the unparsed part.</param>
 /// <param name="mathMode">The math mode switch.</param>
 /// <param name="whitespaceBefore">Indicates whether there was at least one whitespace char before the returned result.</param>
 /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
 /// <returns></returns>
 private static LatexExpression ReadFromTextReader(LatexExpression parent, int parentChildNumber, 
     ref int indexInParentChild, ref bool verbatimMode, bool mathMode, LatexMathToMathMLConverter customization,
     string beginning, TextReader rdr, out string end, ref bool whitespaceBefore)
 {
     if (beginning == null && rdr == null)
     {
         end = null;
         return null;
     }
     return ReadFromTextReaderInner(parent, parentChildNumber, ref indexInParentChild, ref verbatimMode,
         mathMode, customization, beginning ?? rdr.ReadLine(), rdr, out end, ref whitespaceBefore);
 }
コード例 #45
0
        /// <summary>
        /// Builds a new LatexExpression instance (main).
        /// </summary>
        /// <param name="parent">The parent of the builded expression.</param>
        /// <param name="parentChildNumber">Index of the parent child outline.</param>
        /// <param name="indexInParentChild">Index in the parent child outline.</param>
        /// <param name="verbatimMode">True if verbatim mode is on; otherwise, false.</param>
        /// <param name="beginning">The beginning string.</param>
        /// <param name="rdr">The reader to read ahead.</param>
        /// <param name="mathMode">The math mode switch.</param>
        /// <param name="end">The stub of the unparsed part.</param>
        /// <param name="whitespaceBefore">Indicates whether there was at least one whitespace char before the returned result.</param>
        /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
        /// <returns>The parsed LatexExpression instance.</returns>
        private static LatexExpression ReadFromTextReaderInner(LatexExpression parent, int parentChildNumber,
            ref int indexInParentChild, ref bool verbatimMode, bool mathMode, LatexMathToMathMLConverter customization,
            string beginning, TextReader rdr, out string end, ref bool whitespaceBefore)
        {
            string name;

            #region Verbatim
            if (verbatimMode)
            {
                name = ReadToVerbatimEnd(beginning, rdr, out end);
                return new LatexExpression(parent, parentChildNumber, ref indexInParentChild,
                    ref verbatimMode, ExpressionType.Verbatim, false, customization, name, null, null);
            }
            #endregion

            bool whitespaceBeforeGuard;
            string str = ReadToNotEmptyString(beginning, rdr, out whitespaceBeforeGuard);
            whitespaceBefore |= whitespaceBeforeGuard;
            if (str == null)
            {
                end = null;
                return null;
            }
            string value;
            switch (str[0])
            {
                case '\\':
                    #region Command
                    string options;
                    string[] values;
                    name = Regex.Match(str.Substring(1), @"^[a-zA-Z]+\*?").Value;
                    if (String.IsNullOrEmpty(name))
                    {
                        name = "" + str[1];
                        options = null;
                        if (name != "[")
                        {
                            values = null;
                            end = str.Substring(2);
                        }
                        else // Math
                        {
                            value = ParseBraces(ref str, rdr, "\\[", "\\]", out whitespaceBefore);
                            end = str;
                            return new LatexExpression(parent, parentChildNumber, ref indexInParentChild,
                                ref verbatimMode, ExpressionType.BlockMath, mathMode, customization,
                                name, null, value);
                        }
                    }
                    else
                    {
                        ParseCommandOptionsAndValues(
                            str.Substring(name.Length + 1), rdr, out end,
                            out options, out values, out whitespaceBefore);
                    }
                    return new LatexExpression(parent, parentChildNumber, ref indexInParentChild, ref verbatimMode,
                        ExpressionType.Command, mathMode, customization, name, options, values);
                    #endregion
                case '$':
                    #region Math
                    ExpressionType type;
                    if (str[1] == '$')
                    {
                        name = "$$";
                        value = ParseBraces(ref str, rdr, "$$", "$$", out whitespaceBefore);
                        type = ExpressionType.BlockMath;
                    }
                    else
                    {
                        name = "$";
                        value = ParseBraces(ref str, rdr, "$", "$", out whitespaceBefore);
                        type = ExpressionType.InlineMath;
                    }
                    end = str;
                    return new LatexExpression(parent, parentChildNumber, ref indexInParentChild,
                        ref verbatimMode, type, false, customization, name, null, value);
                    #endregion
                case '%':
                    #region Comment
                    end = null;
                    return new LatexExpression(parent, parentChildNumber, ref indexInParentChild, ref verbatimMode,
                        ExpressionType.Comment, false, customization, str.Substring(1), null, null);
                    #endregion
                case '{':
                    #region Block
                    value = ParseBraces(ref str, rdr, "{", "}", out whitespaceBefore);
                    end = str;
                    return new LatexExpression(parent, parentChildNumber, ref indexInParentChild,
                        ref verbatimMode, ExpressionType.Block, mathMode, customization, "{}", null, value);
                    #endregion
                case '&':
                    #region Table cell
                    end = str.Substring(1);
                    return new LatexExpression(parent, parentChildNumber, ref indexInParentChild, ref verbatimMode,
                        ExpressionType.PlainText, mathMode, customization, "&", null, null);
                    #endregion
                case '^':
                case '_':
                    #region Block for sub and sup
                    if (mathMode)
                    {
                        name = "" + str[0];
                        str = ReadToNotEmptyString(str.Substring(1), rdr, out whitespaceBefore);
                        switch (str[0])
                        {
                            case '{':
                                value = ParseBraces(ref str, rdr, "{", "}", out whitespaceBefore);
                                end = str;
                                break;
                            case '\\':
                                var cmdName = Regex.Match(str.Substring(1), @"^[a-zA-Z]+\*?").Value;
                                ParseCommandOptionsAndValues(
                                    str.Substring(cmdName.Length + 1), rdr, out end,
                                    out options, out values, out whitespaceBefore);
                                value = "\\" + cmdName + options;
                                if (values != null)
                                {
                                    for (int i = 0; i < values.Length; i++)
                                    {
                                        value += "{" + values[i] + "}";
                                    }
                                }
                                break;
                            default:
                                value = "" + str[0];
                                if (char.IsDigit(str[0]))
                                {
                                    value = Regex.Match(str, @"\d+").Value;
                                }
                                if (char.IsLetter(str[0]))
                                {
                                    value = Regex.Match(str, @"[a-zA-Z]+").Value;
                                }
                                end = str.Substring(value.Length);
                                break;
                        }
                        return new LatexExpression(parent, parentChildNumber, ref indexInParentChild,
                            ref verbatimMode, ExpressionType.Block, true, customization, name, null, value);
                    }
                    goto default;
                    #endregion
                default:
                    #region Plain text block
                    name = "";
                    var stopChars = mathMode ? new[] { '\\', '$', '{', '%', '&', '^', '_' } :
                        new[] { '\\', '$', '{', '%', '&' };
                    int stopPos;
                    while ((stopPos = GetStopPos(str, stopChars)) == -1)
                    {
                        if (rdr != null)
                        {
                            name += str + " ";
                            str = rdr.ReadLine();
                            if (str == null) // End of the document
                            {
                                name = name.Substring(0, name.Length - 1);
                                break;
                            }
                            if (str.Trim() == "")
                            {
                                str = "\\paragraph";
                                stopPos = 0;
                                break;
                            }
                        }
                        else
                        {
                            stopPos = str.Length;
                            break;
                        }
                    }
                    if (str == null) // End of the document?
                    {
                        end = null;
                    }
                    else
                    {
                        name += str.Substring(0, stopPos);
                        if (stopPos < str.Length && (str[stopPos] == '^' || str[stopPos] == '_'))
                        {
                            var match = Regex.Match(name, @"[a-zA-Z]+\s*\Z");
                            var chunk = match.Value;
                            if (chunk.Trim() == "")
                            {
                                match = Regex.Match(name, @"\d+\s*\Z");
                                chunk = match.Value;
                                if (chunk.Trim() == "")
                                {
                                    match = Regex.Match(name, @"\S\s*\Z");
                                    chunk = match.Value.Trim();
                                }
                            }
                            if (name != chunk)
                            {
                                end = name.Substring(match.Index) + str.Substring(stopPos);
                                name = name.Substring(0, match.Index);
                            }
                            else
                            {
                                end = str.Substring(stopPos);
                            }
                        }
                        else
                        {
                            end = str.Substring(stopPos);
                        }
                    }
                    return new LatexExpression(parent, parentChildNumber, ref indexInParentChild, ref verbatimMode,
                        ExpressionType.PlainText, mathMode, customization, (whitespaceBefore? " " : "") + SmartTextTrim(name), null, null);
                    #endregion
            }
        }
コード例 #46
0
 /// <summary>
 /// Searches in a predefined conversion table and returns the converted result or null.
 /// </summary>
 /// <param name="table">The conversion table to search in.</param>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The converted result or null.</returns>
 private static string SearchInTables(IDictionary<string, string> table, LatexExpression expr)
 {
     string constant;
     if (table.TryGetValue(expr.Name, out constant))
     {
         string children = "";
         if (expr.Expressions != null && expr.Options != null && expr.Options.AsExpressions != null)
         {
             for (int i = 0; i < expr.Options.AsExpressions.Count; i++)
             {
                 children += expr.Options.AsExpressions[i].Convert();
             }
         }
         if (expr.Expressions != null)
         {
             for (int i = 0; i < expr.Expressions.Count; i++)
             {
                 for (int j = 0; j < expr.Expressions[i].Count; j++)
                 {
                     children += expr.Expressions[i][j].Convert();
                 }
             }
         }
         return constant + children;
     }
     return null;
 }
コード例 #47
0
 /// <summary>
 /// Checks for the beginning or the ending of a future block that must be parsed in math mode.
 /// </summary>
 /// <param name="expr">The suspected expression.</param>
 /// <param name="mathMode">The math mode flag.</param>
 private static void CheckMathMode(LatexExpression expr, ref bool mathMode)
 {
     if (!mathMode && expr.ExprType == ExpressionType.Command &&
                 expr.Expressions != null && expr.Name == "begin")
     {
         mathMode = BlockConverter.ImpliesMathMode(expr.Expressions[0][0].Name);
     }
     if (mathMode && expr.ExprType == ExpressionType.Command &&
         expr.Expressions != null && expr.Name == "end")
     {
         if (BlockConverter.ImpliesMathMode(expr.Expressions[0][0].Name))
         {
             mathMode = false;
         }
     }
 }
コード例 #48
0
        /// <summary>
        /// Initializes a new instance of the LatexExpression class.
        /// </summary>
        /// <param name="parent">The parent of the builded expression.</param>
        /// <param name="parentChildNumber">Index of the parent child outline.</param>
        /// <param name="indexInParentChild">Index in the parent child outline.</param>
        /// <param name="verbatimMode">True if verbatim mode is on; otherwise, false.</param>
        /// <param name="type">The expression type.</param>
        /// <param name="mathMode">The math mode switch.</param>
        /// <param name="name">The expression name.</param>
        /// <param name="options">The options of the expression.</param>
        /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
        /// <param name="values">The child outlines of the expression.</param>
        private LatexExpression(LatexExpression parent, int parentChildNumber, ref int indexInParentChild,
            ref bool verbatimMode, ExpressionType type, bool mathMode, LatexMathToMathMLConverter customization,
            string name, string options, params string[] values)
        {
            Parent = parent;
            ParentChildNumber = parentChildNumber;
            IndexInParentChild = indexInParentChild++;
            Customization = customization;
            Name = name;
            ExprType = type;
            MathMode = mathMode;
            #region Switch verbatim mode on/off
            if (type == ExpressionType.Verbatim)
            {
                verbatimMode = false;
            }
            if (Expressions != null && Name == "begin" &&
                Expressions[0][0].Name == "verbatim" && Expressions.Count == 1)
            {
                verbatimMode = true;
            }
            #endregion
            ParseOptions(options);
            if (values != null)
            {
                ParseExpressions(values);
            }
            #region If a math block, add the alternative text
            if (type == ExpressionType.InlineMath || type == ExpressionType.BlockMath)
            {
                // ReSharper disable PossibleNullReferenceException
                Expressions.Add(new List<LatexExpression>());
                int index = 0;
                Expressions[1].Add(new LatexExpression(this, 1, ref index, ref verbatimMode,
                    ExpressionType.PlainText, false, Customization, values[0], null, null));
                // ReSharper restore PossibleNullReferenceException
            }
            #endregion
            #region Post-parse plain text if in math mode
            if (ExprType == ExpressionType.PlainText && mathMode && Name.Length > 1 &&
                (Parent.ExprType != ExpressionType.Block || Parent.Name != "PlainText") &&
                (Parent.ExprType != ExpressionType.Command || Parent.Name != "begin" && Parent.Name != "end"))
            {
                ExprType = ExpressionType.Block;
                Name = "PlainText";
                #region Parse
                var list = new List<string>();
                var buf = "" + name[0];
                for (int pos = 1; pos < name.Length; pos++)
                {
                    var chrPre = name[pos - 1];
                    var chr = name[pos];
                    if (char.IsWhiteSpace(chr))
                    {
                        list.Add(buf);
                        buf = "";
                        continue;
                    }
                    if (char.IsDigit(chr))
                    {
                        #region Digit
                        if (char.IsDigit(chrPre))
                        {
                            buf += chr;
                            continue;
                        }
                        if (char.IsLetter(chr) || chr == '(')
                        {
                            list.Add("InvisibleTimes");
                        }
                        list.Add(buf);
                        buf = "" + chr;
                        continue;

                        #endregion
                    }
                    if (char.IsLetter(chr))
                    {
                        #region Letter
                        if (char.IsLetter(chrPre))
                        {
                            buf += chr;
                            continue;
                        }
                        if (char.IsDigit(chr) || chr == '(')
                        {
                            list.Add("InvisibleTimes");
                        }
                        list.Add(buf);
                        buf = "" + chr;
                        continue;

                        #endregion
                    }
                    #region >=, <=
                    if (chr == '=')
                    {
                        if (chrPre == '>' || chrPre == '<')
                        {
                            buf += chr;
                        }
                    }
                    #endregion
                    list.Add(buf);
                    buf = "" + chr;
                }
                list.Add(buf);
                #endregion
                Expressions = new List<List<LatexExpression>>(list.Count) {new List<LatexExpression>()};
                int i;
                for (i = 0; i < list.Count;)
                {
                    if (list[i].Trim() != "")
                    {
                        Expressions[0].Add(new LatexExpression(this, 0, ref i, ref verbatimMode,
                            ExpressionType.PlainText, true, customization, list[i].Trim(), null, null));
                    }
                    else
                    {
                        i++;
                    }
                }
            }
            #endregion
        }
コード例 #49
0
 /// <summary>
 /// Parses the document and builds the document object tree.
 /// </summary>
 /// <param name="rdr">The reader to read the document from.</param>
 /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
 /// <returns>The root of the document object tree.</returns>
 public static LatexExpression CreateRoot(TextReader rdr, LatexMathToMathMLConverter customization)
 {
     bool verbatimMode = false;
     int rootIndex = 0;
     var root = new LatexExpression(null, 0, ref rootIndex, ref verbatimMode,
         ExpressionType.Root, false, customization, null, null, null)
     {
         Expressions = new List<List<LatexExpression>>(1)
     };
     var children = new List<LatexExpression>();
     string beginning = null;
     string end;
     LatexExpression cmd;
     rootIndex = 0;
     bool mathMode = false;
     bool whitespaceBefore = false;
     while ((cmd = ReadFromTextReader(root, 0, ref rootIndex, ref verbatimMode,
         mathMode, customization, beginning, rdr, out end, ref whitespaceBefore)) != null)
     {
         CheckMathMode(cmd, ref mathMode);
         beginning = end;
         children.Add(cmd);
     }
     root.Expressions.Add(children);
     return root;
 }
コード例 #50
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     return "<br /><span class=\"algorithm_token\">end procedure</span>";
 }
コード例 #51
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     if (expr.Expressions == null) return "";
     var url = expr.Expressions[0][0].Name;
     return "<a href=\"" + url + "\">" + url + "</a>";
 }
コード例 #52
0
 /// <summary>
 /// Recursively incapsulates tree fragments between \begin and \end.
 /// </summary>
 /// <param name="outline">The outline of a LatexExpression instance.</param>
 private static void IncapsulateCommands(List<LatexExpression> outline)
 {
     for (int i = 0; i < outline.Count; i++)
     {
         if (outline[i].ExprType == ExpressionType.Command &&
             outline[i].Name == "begin")
         {
             var cmdValue = outline[i].Expressions[0][0].Name;
             int j;
             for (j = i;
                 outline[j].Name != "end" || outline[j].Expressions == null || outline[j].Expressions[0][0].Name != cmdValue;
                 j++) { }
             int length = j - i - 1;
             var subOutline = new LatexExpression[length];
             // Cut the right chunk
             outline.CopyTo(i + 1, subOutline, 0, length);
             outline.RemoveRange(i + 1, length + 1);
             // Update outline[i]
             outline[i].Name = cmdValue;
             outline[i].ExprType = ExpressionType.Block;
             outline[i].Expressions.RemoveAt(0);
             for (int k = 0; k < outline[i].Expressions.Count; k++)
             {
                 foreach (var expr in outline[i].Expressions[k])
                 {
                     expr.ParentChildNumber--;
                 }
             }
             // Update outline
             for (int k = i + 1; k < outline.Count; k++)
             {
                 outline[k].IndexInParentChild -= length + 1;
             }
             // Update subOutline
             int parentChildNumber = outline[i].Expressions.Count;
             for (int k = 0; k < subOutline.Length; k++)
             {
                 subOutline[k].Parent = outline[i];
                 subOutline[k].ParentChildNumber = parentChildNumber;
                 subOutline[k].IndexInParentChild = k;
             }
             // Link subOutline
             outline[i].Expressions.Add(new List<LatexExpression>(subOutline));
             IncapsulateCommands(outline[i].Expressions[parentChildNumber]);
         }
     }
     for (int i = 0; i < outline.Count; i++)
     {
         if (outline[i].Expressions != null)
         {
             foreach (var subTree in outline[i].Expressions)
             {
                 IncapsulateCommands(subTree);
             }
         }
     }
 }
コード例 #53
0
 /// <summary>
 /// Recursively build scripts (for msup, munder, etc.)
 /// </summary>
 /// <param name="list">The outline of a LatexExpression instance.</param>
 /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
 private static void BuildScripts(List<LatexExpression> list, LatexMathToMathMLConverter customization)
 {
     for (int i = 0; i < list.Count; i++)
     {
         if (list[i].Expressions != null)
         {
             foreach (var subTree in list[i].Expressions)
             {
                 BuildScripts(subTree, customization);
             }
         }
         if (list[i].ExprType == ExpressionType.Block &&
             (list[i].Name == "^" || list[i].Name == "_") && i > 0)
         {
             if (list[i - 1].ExprType == ExpressionType.Command && list[i - 1].Name == "limits")
             {
                 list[i - 1].EraseFromParent();
                 i--;
             }
             #region Place the previous expression to the script block
             if (i < list.Count - 1 && list[i + 1].ExprType == ExpressionType.Block &&
                 (list[i + 1].Name == "^" || list[i + 1].Name == "_"))
             {
                 var block = new LatexExpression("script" + list[i].Name + list[i + 1].Name, list[i].Parent,
                     list[i].ParentChildNumber, i - 1, customization);
                 block.MathMode = list[i].MathMode;
                 block.Expressions[0].Add(new LatexExpression(list[i - 1]));
                 block.Expressions[0].Add(new LatexExpression(list[i]));
                 block.Expressions[0].Add(new LatexExpression(list[i + 1]));
                 block.Expressions[0][0].Parent = block;
                 block.Expressions[0][0].ParentChildNumber = 0;
                 block.Expressions[0][0].IndexInParentChild = 0;
                 block.Expressions[0][0].MathMode = block.MathMode;
                 block.Expressions[0][1].Parent = block;
                 block.Expressions[0][1].ParentChildNumber = 0;
                 block.Expressions[0][1].IndexInParentChild = 1;
                 block.Expressions[0][1].MathMode = block.MathMode;
                 block.Expressions[0][2].Parent = block;
                 block.Expressions[0][2].ParentChildNumber = 0;
                 block.Expressions[0][2].IndexInParentChild = 2;
                 block.Expressions[0][2].MathMode = block.MathMode;
                 list[i - 1] = block;
                 list[i].EraseFromParent();
                 list[i].EraseFromParent();
             }
             else
             {
                 var block = new LatexExpression("script" + list[i].Name, list[i].Parent, list[i].ParentChildNumber, i - 1, customization);
                 block.MathMode = list[i].MathMode;
                 block.Expressions[0].Add(new LatexExpression(list[i - 1]));
                 block.Expressions[0].Add(new LatexExpression(list[i]));
                 block.Expressions[0][0].Parent = block;
                 block.Expressions[0][0].ParentChildNumber = 0;
                 block.Expressions[0][0].IndexInParentChild = 0;
                 block.Expressions[0][0].MathMode = block.MathMode;
                 block.Expressions[0][1].Parent = block;
                 block.Expressions[0][1].ParentChildNumber = 0;
                 block.Expressions[0][1].IndexInParentChild = 1;
                 block.Expressions[0][1].MathMode = block.MathMode;
                 list[i - 1] = block;
                 list[i].EraseFromParent();
             }
             i--;
             #endregion
         }
     }
 }
コード例 #54
0
        /// <summary>
        /// Builds the document object tree.
        /// </summary>
        /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
        /// <remarks>The parsing procedure consists of stand-alone passes, so that it resembles a compiler pipeline.</remarks>
        public void Parse(LatexMathToMathMLConverter customization)
        {
            foreach (var rule in PreformatRules)
            {
                _source = _source.Replace(rule[0], rule[1]);
            }
            var rdr = new StringReader(_source);
            const byte PASS_COUNT = 14;
            byte step = 1;

            // Build the tree
            LogInfo("CreateRoot");
            _root = LatexExpression.CreateRoot(rdr, customization);
            OnProgressEvent(step++, PASS_COUNT);

            //TODO Go through the usage of _customCommands
            // Rebuild tree with custom commands
            _customCommands = new Dictionary<string, LatexExpression>();
            LogInfo("RecursiveParseCustomCommands");

            // Incapsulate fragments between \begin and \end
            LogInfo("IncapsulateCommands");
            IncapsulateCommands(Root.Expressions[0]);
            OnProgressEvent(step++, PASS_COUNT);

            // Post-parse arrays
            LogInfo("PostParseArrays");
            PostParseArrays(Root.Expressions[0], customization);
            OnProgressEvent(step++, PASS_COUNT);

            // Build super- and subscripts
            LogInfo("BuildScripts");
            BuildScripts(Root.Expressions[0], customization);
            OnProgressEvent(step++, PASS_COUNT);

            // Simplify math blocks that begin with baseless scripts
            LogInfo("SimplifyScripts");
            SimplifyBaselessScripts(Root.Expressions[0]);
            OnProgressEvent(step++, PASS_COUNT);

            // Numerate blocks (needed for the next step)
            LogInfo("NumerateBlocks");
            NumerateBlocks(Root.FindDocument().Expressions[0]);
            Root.Customization.Counters.Add("document", 0);
            OnProgressEvent(step++, PASS_COUNT);

            // Simplify math blocks that begin with baseless scripts
            LogInfo("PreProcessLabels");
            PreprocessLabels(Root.FindDocument().Expressions[0]);
            Root.Customization.Counters.Clear();
            OnProgressEvent(step++, PASS_COUNT);

            // Deal with algorithmic blocks
            LogInfo("PreprocessAlgorithms");
            PreprocessAlgorithms(Root.FindDocument().Expressions[0]);
            OnProgressEvent(step++, PASS_COUNT);

            LogInfo("Finished");
        }
コード例 #55
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     if (expr.Expressions == null) return "";
     var letter = expr.Expressions[0][0].Name[0];
     string converted;
     if (!ConversionTable.TryGetValue(letter, out converted))
     {
         converted = "" + letter;
     }
     return converted;
 }
コード例 #56
0
 /// <summary>
 /// Recursively replaces all occurences of src in all subtrees with the specified sequence of expressions.
 /// </summary>
 /// <param name="src">The string to search and replace.</param>
 /// <param name="repl">The replacesment sequence of expressions.</param>
 public void RecursiveReplace(string src, List<LatexExpression> repl)
 {
     if (Expressions != null)
     {
         foreach (var childOutline in Expressions)
         {
             for (int i = 0; i < childOutline.Count; i++ )
             {
                 childOutline[i].RecursiveReplace(src, repl);
             }
         }
     }
     if (ExprType == ExpressionType.PlainText)
     {
         int pos = Name.IndexOf(src);
         if (pos > -1)
         {
             if (pos > 0)
             {
                 var beg = Name.Substring(0, pos);
                 bool verbatimMode = false;
                 int index = IndexInParentChild;
                 Parent.Expressions[ParentChildNumber].Insert(IndexInParentChild,
                     new LatexExpression(Parent, ParentChildNumber, ref index,
                         ref verbatimMode, ExpressionType.PlainText, MathMode,
                         Customization, beg, null, null));
                 IndexInParentChild++;
             }
             Parent.Expressions[ParentChildNumber].RemoveAt(IndexInParentChild);
             for (int i = IndexInParentChild; i < Parent.Expressions[ParentChildNumber].Count; i++)
             {
                 Parent.Expressions[ParentChildNumber][i].IndexInParentChild = i + repl.Count;
             }
             var localRepl = new LatexExpression[repl.Count];
             repl.CopyTo(localRepl);
             for (int i = 0; i < repl.Count; i++)
             {
                 var expr = localRepl[i];
                 expr.Parent = Parent;
                 expr.ParentChildNumber = ParentChildNumber;
                 expr.IndexInParentChild = i + IndexInParentChild;
             }
             Parent.Expressions[ParentChildNumber].InsertRange(IndexInParentChild, localRepl);
             var end = Name.Substring(src.Length);
             if (end != "")
             {
                 bool verbatimMode2 = false;
                 int index2 = IndexInParentChild + repl.Count;
                 Parent.Expressions[ParentChildNumber].Insert(index2,
                     new LatexExpression(Parent, ParentChildNumber, ref index2,
                         ref verbatimMode2, ExpressionType.PlainText, MathMode,
                         Customization, end, null, null));
             }
         }
     }
 }
コード例 #57
0
 /// <summary>
 /// Initializes a new instance of the LatexExpression class and copies the specified expression data to it.
 /// </summary>
 /// <param name="expression">The expression to clone.</param>
 public LatexExpression(LatexExpression expression)
 {
     Parent = expression.Parent;
     Name = expression.Name;
     ExprType = expression.ExprType;
     MathMode = expression.MathMode;
     Customization = expression.Customization;
     if (expression.Options != null)
     {
         Options = new ExpressionOptions();
     }
     if (expression.Expressions != null)
     {
         Expressions = new List<List<LatexExpression>>(expression.Expressions);
     }
 }
コード例 #58
0
        /// <summary>
        /// Performs the conversion procedure.
        /// </summary>
        /// <param name="expr">The expression to convert.</param>
        /// <returns>The conversion result.</returns>
        public override string Convert(LatexExpression expr)
        {
            CommandConverter converter;
            if (CommandConverters.TryGetValue(expr.GetCommandConverterHashCode(), out converter))
            {
                if (converter.ExpectedBranchesCount > 0 && (expr.Expressions == null || expr.Expressions.Count < converter.ExpectedBranchesCount))
                {

                    throw new FormatException(@"Unexpected format in command \\" + converter.Name);
                    //return "<!-- Unexpected format in command \\" + converter.Name + " -->";
                }
                var result = converter.Convert(expr);
                // Make sure that {} blocks which were attached to the command by mistake will be converted, too.
                // Goddamn ancient Latex
                if (expr.Expressions != null && expr.Expressions.Count > converter.ExpectedBranchesCount)
                {
                    for (int i = converter.ExpectedBranchesCount; i < expr.Expressions.Count; i++)
                    {
                        result += SequenceConverter.ConvertOutline(expr.Expressions[i], expr.Customization);
                    }
                }
                return result;
            }
            string constant;
            if (CommandConstants.TryGetValue(expr.Name, out constant))
            {
                if (expr.MathMode)
                {
                    return "<mi>" + constant + "</mi>";
                }
                return constant;
            }
            if ((constant = SearchInTables(MathCommandConstants, expr)) != null)
            {
                return constant;
            }
            if ((constant = SearchInTables(MathFunctionsCommandConstants, expr)) != null)
            {
                return constant;
            }
            if ((constant = SearchInTables(MathFunctionsScriptCommandConstants, expr)) != null)
            {
                return constant;
            }
            return "<!-- \\" + LatexStringToXmlString(expr.Name) + " -->\n";
        }
コード例 #59
0
 /// <summary>
 /// Performs the conversion procedure.
 /// </summary>
 /// <param name="expr">The expression to convert.</param>
 /// <returns>The conversion result.</returns>
 public override string Convert(LatexExpression expr)
 {
     return(ConvertOutline(expr.Expressions[0], expr.Customization));
 }
コード例 #60
0
 /// <summary>
 /// Initializes a new instance of the LatexExpression class of type ExpressionType.Block.
 /// </summary>
 /// <param name="name">The name of the block.</param>
 /// <param name="parent">The parent of the builded expression.</param>
 /// <param name="parentChildNumber">Index of the parent child outline.</param>
 /// <param name="indexInParentChild">Index in the parent child outline.</param>
 /// <param name="customization">The LatexMathToMathMLConverter class instance to customize the conversion result.</param>
 public LatexExpression(string name, LatexExpression parent, int parentChildNumber, int indexInParentChild, LatexMathToMathMLConverter customization)
 {
     Name = name;
     Customization = customization;
     ExprType = ExpressionType.Block;
     MathMode = parent.MathMode |
         parent.ExprType == ExpressionType.BlockMath | parent.ExprType == ExpressionType.InlineMath;
     Parent = parent;
     ParentChildNumber = parentChildNumber;
     IndexInParentChild = indexInParentChild;
     Expressions = new List<List<LatexExpression>> {new List<LatexExpression>()};
 }