static void InsertAtAtomIndexAndAdvance(this MathList self, int atomIndex, MathAtom 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 Atoms.Placeholder placeholder) { atom.Superscript.Append(placeholder.Superscript); atom.Subscript.Append(placeholder.Subscript); self[atomIndex] = atom; } else { self.Insert(atomIndex, atom); } advance = advanceType switch { MathListSubIndexType.None => advance.Next, _ => advance.LevelUpWithSubIndex(advanceType, MathListIndex.Level0Index(0)), }; }
public static List <MathList> Split(this MathList list, MathAtom splitAtom) { var splitList = new List <MathList>(); var sublist = new MathList(); for (int i = 0; i < list.Count; i++) { var item = list[i]; bool isSplitItem = item == splitAtom; if (!isSplitItem) { sublist.Add(item); } if (isSplitItem || i + 1 == list.Count) { splitList.Add(sublist); sublist = new MathList(); } } return(splitList); }
/// <summary>Inserts <paramref name="atom"/> and modifies <paramref name="index"/> to advance to the next position.</summary> public static void InsertAndAdvance(this MathList self, ref MathListIndex index, MathAtom atom, MathListSubIndexType advanceType) { 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.InsertAtAtomIndexAndAdvance(index.AtomIndex, atom, ref index, advanceType); break; case var _ when index.SubIndex is null: throw new InvalidCodePathException("index.SubIndex is null despite non-None subindex type"); case MathListSubIndexType.BetweenBaseAndScripts: var currentAtom = self.Atoms[index.AtomIndex]; if (currentAtom.Subscript.IsEmpty() && currentAtom.Superscript.IsEmpty()) { throw new SubIndexTypeMismatchException(index); } if (atom.Subscript.IsNonEmpty() || atom.Superscript.IsNonEmpty()) { throw new ArgumentException("Cannot fuse with an atom that already has a subscript or a superscript"); } atom.Subscript.Append(currentAtom.Subscript); atom.Superscript.Append(currentAtom.Superscript); currentAtom.Subscript.Clear(); currentAtom.Superscript.Clear(); var atomIndex = index.AtomIndex; // Prevent further subindexing inside BetweenBaseAndScripts if (advanceType != MathListSubIndexType.None && index.LevelDown() is MathListIndex levelDown) { index = levelDown.Next; } self.InsertAtAtomIndexAndAdvance(atomIndex + 1, atom, ref index, advanceType); break; case MathListSubIndexType.Degree: case MathListSubIndexType.Radicand: if (!(self.Atoms[index.AtomIndex] is Atoms.Radical radical)) { throw new SubIndexTypeMismatchException(typeof(Atoms.Radical), index); } if (index.SubIndexType == MathListSubIndexType.Degree) { radical.Degree.InsertAndAdvance(ref index.SubIndex, atom, advanceType); } else { radical.Radicand.InsertAndAdvance(ref index.SubIndex, atom, advanceType); } break; case MathListSubIndexType.Numerator: case MathListSubIndexType.Denominator: if (!(self.Atoms[index.AtomIndex] is Atoms.Fraction frac)) { throw new SubIndexTypeMismatchException(typeof(Atoms.Fraction), index); } if (index.SubIndexType == MathListSubIndexType.Numerator) { frac.Numerator.InsertAndAdvance(ref index.SubIndex, atom, advanceType); } else { frac.Denominator.InsertAndAdvance(ref index.SubIndex, atom, advanceType); } break; case MathListSubIndexType.Subscript: self.Atoms[index.AtomIndex].Subscript.InsertAndAdvance(ref index.SubIndex, atom, advanceType); break; case MathListSubIndexType.Superscript: self.Atoms[index.AtomIndex].Superscript.InsertAndAdvance(ref index.SubIndex, atom, advanceType); break; case MathListSubIndexType.Inner: if (!(self.Atoms[index.AtomIndex] is Atoms.Inner inner)) { throw new SubIndexTypeMismatchException(typeof(Atoms.Inner), index); } inner.InnerList.InsertAndAdvance(ref index.SubIndex, atom, advanceType); break; default: throw new SubIndexTypeMismatchException(index); } }
static int GetInterElementSpaceArrayIndexForType(MathAtom atomType, bool row) => atomType switch {
public static float Get <TFont, TGlyph>(MathAtom left, MathAtom right, LineStyle style, TFont styleFont, FrontEnd.FontMathTable <TFont, TGlyph> mathTable) where TFont : FrontEnd.IFont <TGlyph> {
internal static void CheckClone(MathAtom original, MathAtom clone) => MathListTest.CheckClone(original, clone);
internal static void CheckClone(MathAtom original, MathAtom clone) { Assert.Equal(original, clone); Assert.NotSame(original, clone); }