Beispiel #1
0
 public IMathAtom Visit(LargeOperator target, bool finalize)
 => new LargeOperator(target, finalize);
Beispiel #2
0
        public static string MathListToString(IMathList mathList)
        {
            var builder          = new StringBuilder();
            var currentFontStyle = FontStyle.Default;

            foreach (var atom in mathList)
            {
                if (currentFontStyle != atom.FontStyle)
                {
                    if (currentFontStyle != FontStyle.Default)
                    {
                        // close the previous font style
                        builder.Append("}");
                    }
                    if (atom.FontStyle != FontStyle.Default)
                    {
                        // open a new font style
                        var fontStyleName = atom.FontStyle.FontName();
                        builder.Append(@"\" + fontStyleName + "{");
                    }
                }
                currentFontStyle = atom.FontStyle;
                switch (atom.AtomType)
                {
                case MathAtomType.Fraction: {
                    IFraction fraction    = (IFraction)atom;
                    var       numerator   = MathListToString(fraction.Numerator);
                    var       denominator = MathListToString(fraction.Denominator);
                    if (fraction.HasRule)
                    {
                        builder.Append(@"\frac{" + numerator + "}{" + denominator + "}");
                    }
                    else
                    {
                        string command = null;
                        if (fraction.LeftDelimiter == null && fraction.RightDelimiter == null)
                        {
                            command = "atop";
                        }
                        else if (fraction.LeftDelimiter == "(" && fraction.RightDelimiter == ")")
                        {
                            command = "choose";
                        }
                        else if (fraction.LeftDelimiter == "{" && fraction.RightDelimiter == "}")
                        {
                            command = "brace";
                        }
                        else if (fraction.LeftDelimiter == "[" && fraction.RightDelimiter == "]")
                        {
                            command = "brack";
                        }
                        else
                        {
                            command = $"atopwithdelims{fraction.LeftDelimiter}{fraction.RightDelimiter}";
                        }
                        builder.Append("{" + numerator + @" \" + command + " " + denominator + "}");
                    }
                }
                break;

                case MathAtomType.Radical: {
                    builder.Append(@"\sqrt");
                    var radical = (IRadical)atom;
                    if (radical.Degree != null)
                    {
                        builder.Append($"[{MathListToString(radical.Degree)}]");
                    }
                    builder.Append("{" + MathListToString(radical.Radicand) + "}");
                    break;
                }

                case MathAtomType.Inner: {
                    var inner = (IMathInner)atom;
                    if (inner.LeftBoundary == null && inner.RightBoundary == null)
                    {
                        builder.Append("{" + MathListToString(inner.InnerList) + "}");
                    }
                    else
                    {
                        if (inner.LeftBoundary == null)
                        {
                            builder.Append(@"\left. ");
                        }
                        else
                        {
                            builder.Append(@"\left" + DelimiterToString(inner.LeftBoundary) + " ");
                        }
                        builder.Append(MathListToString(inner.InnerList));
                        if (inner.RightBoundary == null)
                        {
                            builder.Append(@"\right. ");
                        }
                        else
                        {
                            builder.Append(@"\right" + DelimiterToString(inner.RightBoundary) + " ");
                        }
                    }
                    break;
                }

                case MathAtomType.Table: {
                    var table = (IMathTable)atom;
                    if (table.Environment != null)
                    {
                        builder.Append(@"\begin{" + table.Environment + "}");
                    }
                    for (int i = 0; i < table.NRows; i++)
                    {
                        var row = table.Cells[i];
                        for (int j = 0; j < row.Count; j++)
                        {
                            var cell = row[j];
                            if (table.Environment == "matrix")
                            {
                                if (cell.Count >= 1 && cell[0].AtomType == MathAtomType.Style)
                                {
                                    // remove the first atom.
                                    var atoms = cell.Atoms.GetRange(1, cell.Count - 1);
                                    cell = MathLists.WithAtoms(atoms.ToArray());
                                }
                            }
                            if (table.Environment == "eqalign" || table.Environment == "aligned" || table.Environment == "split")
                            {
                                if (j == 1 && cell.Count >= 1 && cell[0].AtomType == MathAtomType.Ordinary && string.IsNullOrEmpty(cell[0].Nucleus))
                                {
                                    // empty nucleus added for spacing. Remove it.
                                    var atoms = cell.Atoms.GetRange(1, cell.Count - 1);
                                    cell = MathLists.WithAtoms(atoms.ToArray());
                                }
                            }
                            builder.Append(MathListToString(cell));
                            if (j < row.Count - 1)
                            {
                                builder.Append("&");
                            }
                        }
                        if (i < table.NRows - 1)
                        {
                            builder.Append(@"\\ ");
                        }
                    }
                    if (table.Environment != null)
                    {
                        builder.Append(@"\end{" + table.Environment + "}");
                    }
                    break;
                }

                case MathAtomType.Overline: {
                    var over = (IOverline)atom;
                    builder.Append(@"\overline{" + MathListToString(over.InnerList) + "}");
                    break;
                }

                case MathAtomType.Underline: {
                    var under = (IUnderline)atom;
                    builder.Append(@"\underline{" + MathListToString(under.InnerList) + "}");
                    break;
                }

                case MathAtomType.Accent: {
                    var accent = (IAccent)atom;
                    var list   = accent.InnerList;
                    accent.InnerList = null; //for lookup
                    builder.Append(@"\" + MathAtoms.Commands[(MathAtom)atom] + "{" + MathListToString(list) + "}");
                    break;
                }

                case MathAtomType.LargeOperator: {
                    var           op               = (LargeOperator)atom;
                    var           command          = MathAtoms.LatexSymbolNameForAtom(op);
                    LargeOperator originalOperator = (LargeOperator)MathAtoms.ForLatexSymbolName(command);
                    builder.Append($@"\{command} ");
                    if (originalOperator.Limits != op.Limits)
                    {
                        switch (op.Limits)
                        {
                        case true:
                            builder.Append(@"\limits ");
                            break;

                        case false:
                            if (!op.NoLimits)
                            {
                                builder.Append(@"\nolimits ");
                            }
                            break;

                        case null:
                            break;
                        }
                    }
                    break;
                }

                case MathAtomType.Space: {
                    var space    = (ISpace)atom;
                    var intSpace = (int)space.Length;
                    if (SpaceToCommands.ContainsKey(intSpace) && intSpace == space.Length)
                    {
                        var command = SpaceToCommands[intSpace];
                        builder.Append(@"\" + command + " ");
                    }
                    else
                    {
                        if (space.IsMu)
                        {
                            builder.Append(@"\mkern" + space.Length.ToString("0.0") + "mu");
                        }
                        else
                        {
                            builder.Append(@"\kern" + space.Length.ToString("0.0") + "pt");
                        }
                    }
                    break;
                }

                case MathAtomType.Style: {
                    var style   = (IStyle)atom;
                    var command = StyleToCommands[style.LineStyle];
                    builder.Append(@"\" + command + " ");
                    break;
                }

                case MathAtomType.Color: {
                    var color = (IColor)atom;
                    builder.Append($@"\color{{{color.ColorString}}}{{{MathListToString(color.InnerList)}}}");
                    break;
                }

                case MathAtomType.Group:
                    builder.AppendInBraces(MathListToString(((Group)atom).InnerList), NullHandling.EmptyContent);
                    break;

                case MathAtomType.Prime:
                    builder.Append('\'', ((Prime)atom).Length);
                    break;

                default: {
                    var aNucleus = atom.Nucleus;
                    if (String.IsNullOrEmpty(aNucleus))
                    {
                        builder.Append(@"{}");
                    }
                    else if (aNucleus == "\u2236")
                    {
                        builder.Append(":");
                    }
                    else if (aNucleus == "\u2212")
                    {
                        builder.Append("-");
                    }
                    else
                    {
                        var command = MathAtoms.LatexSymbolNameForAtom((MathAtom)atom);
                        if (command == null)
                        {
                            if (atom is Extension.I_ExtensionAtom ext)
                            {
                                builder.Append(Extension._MathListDestructor.MathAtomToString(ext));
                            }
                            else
                            {
                                builder.Append(aNucleus);
                            }
                        }
                        else
                        {
                            builder.Append(@"\" + command + " ");
                        }
                    }
                    break;
                }
                }
                if (atom.Superscript != null)
                {
                    var scriptString = MathListToString(atom.Superscript);
                    builder.Append(scriptString.Length == 1 ? $"^{scriptString}" : $"^{{{scriptString}}}");
                }
                if (atom.Subscript != null)
                {
                    var scriptString = MathListToString(atom.Subscript);
                    builder.Append(scriptString.Length == 1 ? $"_{scriptString}" : $"_{{{scriptString}}}");
                }
            }
            if (currentFontStyle != FontStyle.Default)
            {
                builder.Append("}");
            }
            return(builder.ToString());
        }