Esempio n. 1
0
        public static MathList MathListForCharacters(string chars)
        {
            var r = new MathList();

            foreach (char c in chars)
            {
                r.Add(ForCharacter(c));
            }
            return(r);
        }
Esempio n. 2
0
        public static MathList WithAtoms(List <IMathAtom> atoms)
        {
            var r = new MathList();

            foreach (var atom in atoms)
            {
                r.Add(atom);
            }
            return(r);
        }
Esempio n. 3
0
 internal MathList StopCommand(string command, MathList list, char stopChar)
 {
     if (command == "right")
     {
         if (_currentInnerAtom == null)
         {
             SetError("Missing \\left");
             return(null);
         }
         _currentInnerAtom.RightBoundary = _BoundaryAtomForDelimiterType("right");
         if (_currentInnerAtom.RightBoundary == null)
         {
             return(null);
         }
         return(list);
     }
     if (fractionCommands.ContainsKey(command))
     {
         bool rule       = (command == "over");
         var  fraction   = new Fraction(rule);
         var  delimiters = fractionCommands[command];
         if (delimiters != null)
         {
             fraction.LeftDelimiter  = delimiters.Value.First;
             fraction.RightDelimiter = delimiters.Value.Second;
         }
         fraction.Numerator   = list;
         fraction.Denominator = BuildInternal(false, stopChar);
         if (_error != null)
         {
             return(null);
         }
         return(MathLists.WithAtoms(fraction));
     }
     else if (command == "\\" || command == "cr")
     {
         if (_currentEnvironment == null)
         {
             var table = BuildTable(null, list, true, stopChar);
             if (table == null)
             {
                 return(null);
             }
             return(MathLists.WithAtoms(table));
         }
         else
         {
             // stop the current list and increment the row count
             _currentEnvironment.NRows++;
             return(list);
         }
     }
     else if (command == "end")
     {
         if (_currentEnvironment == null)
         {
             SetError(@"Missing \begin");
             return(null);
         }
         var env = ReadEnvironment();
         if (env == null)
         {
             return(null);
         }
         if (env != _currentEnvironment.Name)
         {
             SetError($"Begin environment name {_currentEnvironment.Name} does not match end environment name {env}");
             return(null);
         }
         _currentEnvironment.Ended = true;
         return(list);
     }
     return(null);
 }
Esempio n. 4
0
        internal IMathList BuildInternal(bool oneCharOnly, char stopChar)
        {
            if (oneCharOnly && stopChar > 0)
            {
                throw new InvalidOperationException("Cannot set both oneCharOnly and stopChar");
            }
            var       r        = new MathList();
            IMathAtom prevAtom = null;

            while (HasCharacters)
            {
                if (_error != null)
                {
                    return(null);
                }
                IMathAtom atom;
                var       ch = GetNextCharacter();
                if (oneCharOnly)
                {
                    if (ch == '^' || ch == '}' || ch == '_' || ch == '&')
                    {
                        // this is not the character we are looking for. They are for the caller to look at.
                        UnlookCharacter();
                        return(r);
                    }
                }
                if (stopChar > 0 && ch == stopChar)
                {
                    return(r);
                }
                switch (ch)
                {
                case '^':
                    if (prevAtom == null || prevAtom.Superscript != null || !prevAtom.ScriptsAllowed)
                    {
                        prevAtom = MathAtoms.Create(MathAtomType.Ordinary, string.Empty);
                        r.Add(prevAtom);
                    }
                    // this is a superscript for the previous atom.
                    // note, if the next char is StopChar, it will be consumed and doesn't count as stop.
                    prevAtom.Superscript = this.BuildInternal(true);
                    continue;

                case '_':
                    if (prevAtom == null || prevAtom.Subscript != null || !prevAtom.ScriptsAllowed)
                    {
                        prevAtom = MathAtoms.Create(MathAtomType.Ordinary, string.Empty);
                        r.Add(prevAtom);
                    }
                    // this is a subscript for the previous atom.
                    // note, if the next char is StopChar, it will be consumed and doesn't count as stop.
                    prevAtom.Subscript = this.BuildInternal(true);
                    continue;

                case '{':
                    IMathList sublist;
                    if (_currentEnvironment != null && _currentEnvironment.Name == null)
                    {
                        // \\ or \cr which do not have a corrosponding \end
                        var oldEnv = _currentEnvironment;
                        _currentEnvironment = null;
                        sublist             = BuildInternal(false, '}');
                        _currentEnvironment = oldEnv;
                    }
                    else
                    {
                        sublist = BuildInternal(false, '}');
                    }
                    if (sublist == null)
                    {
                        return(null);
                    }
                    prevAtom = sublist.Atoms.LastOrDefault();
                    if (oneCharOnly)
                    {
                        r.Append(sublist);
                        return(r);
                    }
#warning TODO Example
                    //https://phabricator.wikimedia.org/T99369
                    //https://phab.wmfusercontent.org/file/data/xsimlcnvo42siudvwuzk/PHID-FILE-bdcqexocj5b57tj2oezn/math_rendering.png
                    //dt, \text{d}t, \partial t, \nabla\psi \\ \underline\overline{dy/dx, \text{d}y/\text{d}x, \frac{dy}{dx}, \frac{\text{d}y}{\text{d}x}, \frac{\partial^2}{\partial x_1\partial x_2}y} \\ \prime,
                    atom = new Group {
                        InnerList = sublist
                    };
                    break;

                case '}':
                    if (oneCharOnly || stopChar != 0)
                    {
                        throw new InvalidCodePathException("This should have been handled before.");
                    }
                    SetError("Missing opening brace");
                    return(null);

                case '\\':
                    var command = ReadCommand();
                    var done    = StopCommand(command, r, stopChar);
                    if (done != null)
                    {
                        return(done);
                    }
                    if (_error != null)
                    {
                        return(null);
                    }
                    if (ApplyModifier(command, prevAtom))
                    {
                        continue;
                    }
                    var fontStyleQ = MathAtoms.FontStyle(command);
                    if (fontStyleQ.HasValue)
                    {
                        var fontStyle        = fontStyleQ.Value;
                        var oldSpacesAllowed = _textMode;
                        var oldFontStyle     = _currentFontStyle;
                        _textMode         = (command == "text");
                        _currentFontStyle = fontStyle;
                        var childList = BuildInternal(true);
                        if (childList == null)
                        {
                            return(null);
                        }
                        _currentFontStyle = oldFontStyle;
                        _textMode         = oldSpacesAllowed;
                        prevAtom          = childList.Atoms.LastOrDefault();
                        r.Append(childList);
                        if (oneCharOnly)
                        {
                            return(r);
                        }
                        continue;
                    }
                    atom = AtomForCommand(command, stopChar);
                    if (atom == null)
                    {
                        SetError(_error ?? "Internal error");
                        return(null);
                    }
                    break;

                case '&': { // column separation in tables
                    if (_currentEnvironment != null)
                    {
                        return(r);
                    }
                    var table = BuildTable(null, r, false, stopChar);
                    if (table == null)
                    {
                        return(null);
                    }
                    return(MathLists.WithAtoms(table));
                }

                case '\'': // this case is NOT in iosMath
                    int i = 1;
                    while (ExpectCharacter('\''))
                    {
                        i++;
                    }
                    atom = new Prime(i);
                    break;

                default:
                    if (_textMode && ch == ' ')
                    {
                        atom = MathAtoms.ForLatexSymbolName(" ");
                    }
                    else
                    {
                        atom = MathAtoms.ForCharacter(ch);
                        if (atom == null)
                        {
                            // not a recognized character
                            continue;
                        }
                    }
                    break;
                }
                if (atom == null)
                {
                    throw new InvalidCodePathException("Atom shouldn't be null");
                }
                atom.FontStyle = _currentFontStyle;
                r.Add(atom);
                prevAtom = atom;
                if (oneCharOnly)
                {
                    return(r); // we consumed our character.
                }
            }
            if (stopChar > 0)
            {
                if (stopChar == '}')
                {
                    SetError("Missing closing brace");
                }
                else
                {
                    // we never found our stop character.
                    SetError("Expected character not found: " + stopChar.ToString());
                }
            }
            return(r);
        }