Ejemplo n.º 1
0
 public void SetMathList(IMathList mathList)
 {
     _mathList = mathList;
     Latex     = MathListBuilder.MathListToString(mathList);
     InvalidateIntrinsicContentSize();
     SetNeedsLayout();
 }
Ejemplo n.º 2
0
 static void InsertAtAtomIndexAndAdvance(this IMathList self, int atomIndex, IMathAtom atom, ref MathListIndex advance, MathListSubIndexType advanceType)
 {
     if (atomIndex < 0 || atomIndex > self.Count)
     {
         throw new IndexOutOfRangeException($"Index {atomIndex} is out of bounds for list of size {self.Atoms.Count}");
     }
     // Test for placeholder to the right of index, e.g. \sqrt{‸■} -> \sqrt{2‸}
     if (atomIndex < self.Count && self[atomIndex] is MathAtom placeholder &&
         placeholder?.AtomType is Enumerations.MathAtomType.Placeholder)
     {
         if (placeholder.Superscript is IMathList super)
         {
             if (atom.Superscript != null)
             {
                 super.Append(atom.Superscript);
             }
             atom.Superscript = super;
         }
         if (placeholder.Subscript is IMathList sub)
         {
             if (atom.Subscript != null)
             {
                 sub.Append(atom.Subscript);
             }
             atom.Subscript = sub;
         }
         self[atomIndex] = atom;
     }
Ejemplo n.º 3
0
        public void TestRadical()
        {
            string input = @"\sqrt[3]2";
            var    list  = MathLists.FromString(input);

            Assert.Single(list);
            var radical = list[0] as Radical;

            CheckAtomTypeAndNucleus(radical, MathAtomType.Radical, "");

            IMathList subList = radical.Radicand;

            Assert.Single(subList);

            var atom = subList[0];

            CheckAtomTypeAndNucleus(atom, MathAtomType.Number, "2");

            var degree = radical.Degree;

            Assert.Single(degree);
            CheckAtomTypeAndNucleus(degree[0], MathAtomType.Number, "3");

            var latex = MathListBuilder.MathListToString(list);

            Assert.Equal(@"\sqrt[3]{2}", latex);
        }
Ejemplo n.º 4
0
        public MathList(IMathList cloneMe, bool finalize) : this()
        {
            if (!finalize)
            {
                foreach (var atom in cloneMe.Atoms)
                {
                    var cloneAtom = AtomCloner.Clone(atom, finalize);
                    Add(cloneAtom);
                }
            }
            else
            {
                IMathAtom prevNode = null;
                foreach (var atom in cloneMe.Atoms)
                {
                    var newNode = AtomCloner.Clone(atom, finalize);
                    if (atom.IndexRange == Range.Zero)
                    {
                        int prevIndex = prevNode is null ? 0 : prevNode.IndexRange.Location + prevNode.IndexRange.Length;
                        newNode.IndexRange = new Range(prevIndex, 1);
                    }
                    switch (newNode.AtomType)
                    {
                    case MathAtomType.BinaryOperator:
                        switch (prevNode?.AtomType)
                        {
                        case null:
                        case MathAtomType.BinaryOperator:
                        case MathAtomType.Relation:
                        case MathAtomType.Open:
                        case MathAtomType.Punctuation:
                        case MathAtomType.LargeOperator:
                            newNode.AtomType = MathAtomType.UnaryOperator;
                            break;
                        }
                        break;

                    case MathAtomType.Relation:
                    case MathAtomType.Punctuation:
                    case MathAtomType.Close:
                        if (prevNode != null && prevNode.AtomType == MathAtomType.BinaryOperator)
                        {
                            prevNode.AtomType = MathAtomType.UnaryOperator;
                        }
                        break;

                    case MathAtomType.Number:
                        if (prevNode != null && prevNode.AtomType == MathAtomType.Number && prevNode.Subscript == null && prevNode.Superscript == null)
                        {
                            prevNode.Fuse(newNode);
                            continue; // do not add the new node; we fused it instead.
                        }
                        break;
                    }
                    Add(newNode);
                    prevNode = newNode;
                }
            }
        }
Ejemplo n.º 5
0
 /// <summary>Deep copy</summary>
 public static IMathList Clone(IMathList target, bool finalize)
 {
     if (target == null)
     {
         return(null);
     }
     return(new MathList((MathList)target, finalize));
 }
Ejemplo n.º 6
0
        public static IFraction Fraction(IMathList numerator, IMathList denominator)
        {
            var fraction = new Fraction {
                Numerator   = numerator,
                Denominator = denominator
            };

            return(fraction);
        }
Ejemplo n.º 7
0
        internal IMathAtom BuildTable(string environment, IMathList firstList, bool isRow, char stopChar)
        {
            var oldEnv = _currentEnvironment;

            _currentEnvironment = new TableEnvironmentProperties(environment);
            int currentRow    = 0;
            int currentColumn = 0;
            var rows          = new List <List <IMathList> > {
                new List <IMathList>()
            };

            if (firstList != null)
            {
                rows[currentRow].Add(firstList);
                if (isRow)
                {
                    _currentEnvironment.NRows++;
                    currentRow++;
                    rows.Add(new List <IMathList>());
                }
                else
                {
                    currentColumn++;
                }
            }
            while (HasCharacters && !(_currentEnvironment.Ended))
            {
                var list = BuildInternal(false, stopChar);
                if (list == null)
                {
                    return(null);
                }
                rows[currentRow].Add(list);
                currentColumn++;
                if (_currentEnvironment.NRows > currentRow)
                {
                    currentRow = _currentEnvironment.NRows;
                    rows.Add(new List <IMathList>());
                    currentColumn = 0;
                }
            }
            if (_currentEnvironment.Name != null && !_currentEnvironment.Ended)
            {
                SetError(@"Missing \end");
                return(null);
            }
            var tableResult = MathAtoms.Table(_currentEnvironment.Name, rows);

            if (tableResult.Error is string error)
            {
                SetError(error);
                return(null);
            }
            _currentEnvironment = oldEnv;
            return(tableResult.Value);
        }
Ejemplo n.º 8
0
        /// <summary>Safe to call with a null list. Types cannot be null however.</summary>
        private void CheckAtomTypes(IMathList list, params MathAtomType[] types)
        {
            int atomCount = (list == null) ? 0 : list.Atoms.Count;

            Assert.Equal(types.Count(), atomCount);
            for (int i = 0; i < atomCount; i++)
            {
                var atom = list[i];
                Assert.NotNull(atom);
                Assert.Equal(atom.AtomType, types[i]);
            }
        }
Ejemplo n.º 9
0
 ///<summary>Iteratively expands all groups in the list.</summary>
 private void ExpandGroups(IMathList list)
 {
     for (int i = 0; i < list.Count; i++)
     {
         if (list[i].AtomType == MathAtomType.Group)
         {
             var group = (Group)list[i];
             for (int j = group.InnerList.Count - 1; j >= 0; j--)
             {
                 list.Insert(i + 1, group.InnerList[j]);
             }
             list.RemoveAt(i);
         }
     }
 }
Ejemplo n.º 10
0
        public static void CheckListContents(IMathList list)
        {
            Assert.Equal(10, list.Atoms.Count);
            var atom0 = list.Atoms[0];

            Assert.Equal(MathAtomType.UnaryOperator, atom0.AtomType);
            Assert.Equal("\u2212", atom0.Nucleus);
            Assert.Equal(new Range(0, 1), atom0.IndexRange);
            var atom1 = list.Atoms[1];

            Assert.Equal(MathAtomType.Number, atom1.AtomType);
            Assert.Equal("52", atom1.Nucleus);
            Assert.Equal(new Range(1, 2), atom1.IndexRange);
            var atom2 = list.Atoms[2];

            Assert.Equal(MathAtomType.Variable, atom2.AtomType);
            Assert.Equal("x", atom2.Nucleus);
            Assert.Equal(new Range(3, 1), atom2.IndexRange);
            var superScript = atom2.Superscript;

            Assert.Equal(3, superScript.Atoms.Count);

            var super0 = superScript.Atoms[0];

            Assert.Equal(MathAtomType.Number, super0.AtomType);
            Assert.Equal("13", super0.Nucleus);
            Assert.Equal(new Range(0, 2), super0.IndexRange);
            var super1 = superScript.Atoms[1];

            Assert.Equal(MathAtomType.BinaryOperator, super1.AtomType);
            Assert.Equal("+", super1.Nucleus);
            Assert.Equal(new Range(2, 1), super1.IndexRange);
            var super2 = superScript.Atoms[2];

            Assert.Equal(MathAtomType.Variable, super2.AtomType);
            Assert.Equal("y", super2.Nucleus);
            Assert.Equal(new Range(3, 1), super2.IndexRange);
        }
Ejemplo n.º 11
0
        public static IMathAtom AtomAt(this IMathList self, MathListIndex index)
        {
            if (index is null || index.AtomIndex >= self.Atoms.Count)
            {
                return(null);
            }
            var atom = self.Atoms[index.AtomIndex];

            switch (index.SubIndexType)
            {
            case MathListSubIndexType.None:
            case MathListSubIndexType.Nucleus:
                return(atom);

            case MathListSubIndexType.Subscript:
                return(atom.Subscript.AtomAt(index.SubIndex));

            case MathListSubIndexType.Superscript:
                return(atom.Superscript.AtomAt(index.SubIndex));

            case MathListSubIndexType.Radicand:
            case MathListSubIndexType.Degree:
                if (atom is Radical radical && radical.AtomType == Enumerations.MathAtomType.Radical)
                {
                    if (index.SubIndexType == MathListSubIndexType.Degree)
                    {
                        return(radical.Degree.AtomAt(index.SubIndex));
                    }
                    else
                    {
                        return(radical.Radicand.AtomAt(index.SubIndex));
                    }
                }
                else
                {
                    return(null);
                }
 public static MathListDisplay<TFont, TGlyph> CreateLine<TFont, TGlyph>(this TypesettingContext<TFont, TGlyph> context, IMathList list, TFont font, LineStyle style)
   where TFont: MathFont<TGlyph> {
   return Typesetter<TFont, TGlyph>.CreateLine(list, font, context, style);
   }
Ejemplo n.º 13
0
 public Underline(Underline cloneMe, bool finalize) : base(cloneMe, finalize)
 {
     this.InnerList = AtomCloner.Clone(cloneMe.InnerList, finalize);
 }
Ejemplo n.º 14
0
        public static void RemoveAtoms(this IMathList self, MathListRange?nullableRange)
        {
            if (!nullableRange.HasValue)
            {
                return;
            }
            var range = nullableRange.GetValueOrDefault();
            var start = range.Start;

            switch (start.SubIndexType)
            {
            case MathListSubIndexType.None:
                self.RemoveAtoms(new Range(start.AtomIndex, range.Length));
                break;

            case MathListSubIndexType.Nucleus:
                throw new NotSupportedException("Nuclear fission is not supported");

            case MathListSubIndexType.Radicand:
            case MathListSubIndexType.Degree:
                if (!(self.Atoms[start.AtomIndex] is Radical radical && radical.AtomType == Enumerations.MathAtomType.Radical))
                {
                    throw new SubIndexTypeMismatchException($"No radical found at index {start.AtomIndex}");
                }
                if (start.SubIndexType == MathListSubIndexType.Degree)
                {
                    radical.Degree.RemoveAtoms(range.SubIndexRange);
                }
                else
                {
                    radical.Radicand.RemoveAtoms(range.SubIndexRange);
                }
                break;

            case MathListSubIndexType.Numerator:
            case MathListSubIndexType.Denominator:
                if (!(self.Atoms[start.AtomIndex] is Fraction frac && frac.AtomType == Enumerations.MathAtomType.Fraction))
                {
                    throw new SubIndexTypeMismatchException($"No fraction found at index {start.AtomIndex}");
                }
                if (start.SubIndexType == MathListSubIndexType.Numerator)
                {
                    frac.Numerator.RemoveAtoms(range.SubIndexRange);
                }
                else
                {
                    frac.Denominator.RemoveAtoms(range.SubIndexRange);
                }
                break;

            case MathListSubIndexType.Subscript:
                var current = self.Atoms[start.AtomIndex];
                if (current.Subscript == null)
                {
                    throw new SubIndexTypeMismatchException($"No subscript for atom at index {start.AtomIndex}");
                }
                current.Subscript.RemoveAtoms(range.SubIndexRange);
                break;

            case MathListSubIndexType.Superscript:
                current = self.Atoms[start.AtomIndex];
                if (current.Superscript == null)
                {
                    throw new SubIndexTypeMismatchException($"No superscript for atom at index {start.AtomIndex}");
                }
                current.Superscript.RemoveAtoms(range.SubIndexRange);
                break;
            }
        }
Ejemplo n.º 15
0
 internal static void CheckClone(IMathList original, IMathList clone)
 {
     Assert.Equal(original, clone);
     Assert.False(ReferenceEquals(original, clone));
 }
Ejemplo n.º 16
0
 public Accent(Accent cloneMe, bool finalize) : base(cloneMe, finalize)
 {
     InnerList = AtomCloner.Clone(cloneMe.InnerList, finalize);
 }
Ejemplo n.º 17
0
 public MathSource(IMathList mathList)
 {
     LaTeX        = MathListBuilder.MathListToString(mathList);
     MathList     = mathList;
     ErrorMessage = null;
 }
Ejemplo n.º 18
0
        public static void Insert(this IMathList self, MathListIndex index, IMathAtom atom)
        {
            index = index ?? MathListIndex.Level0Index(0);
            if (index.AtomIndex > self.Atoms.Count)
            {
                throw new IndexOutOfRangeException($"Index {index.AtomIndex} is out of bounds for list of size {self.Atoms.Count}");
            }
            switch (index.SubIndexType)
            {
            case MathListSubIndexType.None:
                self.Insert(index.AtomIndex, atom);
                break;

            case MathListSubIndexType.Nucleus:
                var currentAtom = self.Atoms[index.AtomIndex];
                if (currentAtom.Subscript == null && currentAtom.Superscript == null)
                {
                    throw new SubIndexTypeMismatchException("Nuclear fusion is not supported if there are neither subscripts nor superscripts in the current atom.");
                }
                if (atom.Subscript != null || atom.Superscript != null)
                {
                    throw new ArgumentException("Cannot fuse with an atom that already has a subscript or a superscript");
                }
                atom.Subscript          = currentAtom.Subscript;
                atom.Superscript        = currentAtom.Superscript;
                currentAtom.Subscript   = null;
                currentAtom.Superscript = null;
                self.Insert(index.AtomIndex + index.SubIndex?.AtomIndex ?? 0, atom);
                break;

            case MathListSubIndexType.Degree:
            case MathListSubIndexType.Radicand:
                if (!(self.Atoms[index.AtomIndex] is Radical radical && radical.AtomType == Enumerations.MathAtomType.Radical))
                {
                    throw new SubIndexTypeMismatchException($"No radical found at index {index.AtomIndex}");
                }
                if (index.SubIndexType == MathListSubIndexType.Degree)
                {
                    radical.Degree.Insert(index.SubIndex, atom);
                }
                else
                {
                    radical.Radicand.Insert(index.SubIndex, atom);
                }
                break;

            case MathListSubIndexType.Numerator:
            case MathListSubIndexType.Denominator:
                if (!(self.Atoms[index.AtomIndex] is Fraction frac && frac.AtomType == Enumerations.MathAtomType.Fraction))
                {
                    throw new SubIndexTypeMismatchException($"No fraction found at index {index.AtomIndex}");
                }
                if (index.SubIndexType == MathListSubIndexType.Numerator)
                {
                    frac.Numerator.Insert(index.SubIndex, atom);
                }
                else
                {
                    frac.Denominator.Insert(index.SubIndex, atom);
                }
                break;

            case MathListSubIndexType.Subscript:
                var current = self.Atoms[index.AtomIndex];
                if (current.Subscript == null)
                {
                    throw new SubIndexTypeMismatchException($"No subscript for atom at index {index.AtomIndex}");
                }
                current.Subscript.Insert(index.SubIndex, atom);
                break;

            case MathListSubIndexType.Superscript:
                current = self.Atoms[index.AtomIndex];
                if (current.Superscript == null)
                {
                    throw new SubIndexTypeMismatchException($"No superscript for atom at index {index.AtomIndex}");
                }
                current.Superscript.Insert(index.SubIndex, atom);
                break;
            }
        }
Ejemplo n.º 19
0
        public static void RemoveAt(this IMathList self, MathListIndex index)
        {
            index = index ?? MathListIndex.Level0Index(0);
            if (index.AtomIndex > self.Atoms.Count)
            {
                throw new IndexOutOfRangeException($"Index {index.AtomIndex} is out of bounds for list of size {self.Atoms.Count}");
            }
            switch (index.SubIndexType)
            {
            case MathListSubIndexType.None:
                self.RemoveAt(index.AtomIndex);
                break;

            case MathListSubIndexType.Nucleus:
                var currentAtom = self.Atoms[index.AtomIndex];
                if (currentAtom.Subscript == null && currentAtom.Superscript == null)
                {
                    throw new SubIndexTypeMismatchException("Nuclear fission is not supported if there are no subscripts or superscripts.");
                }
                if (index.AtomIndex > 0)
                {
                    var previous = self.Atoms[index.AtomIndex - 1];
                    if (previous.Subscript != null && previous.Superscript != null)
                    {
                        previous.Superscript = currentAtom.Superscript;
                        previous.Subscript   = currentAtom.Subscript;
                        self.RemoveAt(index.AtomIndex);
                        break;
                    }
                }
                // no previous atom or the previous atom sucks (has sub/super scripts)
                currentAtom.Nucleus = "";
                break;

            case MathListSubIndexType.Radicand:
            case MathListSubIndexType.Degree:
                if (!(self.Atoms[index.AtomIndex] is Radical radical && radical.AtomType == Enumerations.MathAtomType.Radical))
                {
                    throw new SubIndexTypeMismatchException($"No radical found at index {index.AtomIndex}");
                }
                if (index.SubIndexType == MathListSubIndexType.Degree)
                {
                    radical.Degree.RemoveAt(index.SubIndex);
                }
                else
                {
                    radical.Radicand.RemoveAt(index.SubIndex);
                }
                break;

            case MathListSubIndexType.Numerator:
            case MathListSubIndexType.Denominator:
                if (!(self.Atoms[index.AtomIndex] is Fraction frac && frac.AtomType == Enumerations.MathAtomType.Fraction))
                {
                    throw new SubIndexTypeMismatchException($"No fraction found at index {index.AtomIndex}");
                }
                if (index.SubIndexType == MathListSubIndexType.Numerator)
                {
                    frac.Numerator.RemoveAt(index.SubIndex);
                }
                else
                {
                    frac.Denominator.RemoveAt(index.SubIndex);
                }
                break;

            case MathListSubIndexType.Subscript:
                var current = self.Atoms[index.AtomIndex];
                if (current.Subscript == null)
                {
                    throw new SubIndexTypeMismatchException($"No subscript for atom at index {index.AtomIndex}");
                }
                current.Subscript.RemoveAt(index.SubIndex);
                break;

            case MathListSubIndexType.Superscript:
                current = self.Atoms[index.AtomIndex];
                if (current.Superscript == null)
                {
                    throw new SubIndexTypeMismatchException($"No superscript for atom at index {index.AtomIndex}");
                }
                current.Superscript.RemoveAt(index.SubIndex);
                break;
            }
        }
Ejemplo n.º 20
0
 public Group(Group cloneMe, bool finalize) : base(cloneMe, finalize)
 {
     InnerList = AtomCloner.Clone(cloneMe.InnerList, finalize);
 }
Ejemplo n.º 21
0
 public Radical(Radical cloneMe, bool finalize) : base(cloneMe, finalize)
 {
     Radicand = AtomCloner.Clone(cloneMe.Radicand, finalize);
     Degree   = AtomCloner.Clone(cloneMe.Degree, finalize);
 }
Ejemplo n.º 22
0
 internal static void CheckClone(IMathList original, IMathList clone)
 => MathListTest.CheckClone(original, clone);
Ejemplo n.º 23
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: {
                    var 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);
                    var 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.Subscript != null)
                {
                    var scriptString = MathListToString(atom.Subscript);
                    builder.Append(scriptString.Length == 1 ? $"_{scriptString}" : $"_{{{scriptString}}}");
                }

                if (atom.Superscript != null)
                {
                    var scriptString = MathListToString(atom.Superscript);
                    builder.Append(scriptString.Length == 1 ? $"^{scriptString}" : $"^{{{scriptString}}}");
                }
            }
            if (currentFontStyle != FontStyle.Default)
            {
                builder.Append("}");
            }
            return(builder.ToString());
        }
Ejemplo n.º 24
0
        /*public RaiseBox(RaiseBox cloneMe, bool finalize) : base(cloneMe, finalize) =>
         * InnerList = cloneMe.InnerList;*/

        protected override void CopyPropertiesFrom(RaiseBox oldAtom)
        {
            InnerList = oldAtom.InnerList;
            Raise     = oldAtom.Raise;
        }