Esempio n. 1
0
        private void ProcessEscapeSequence(TexFormula formula,
                                           SourceSpan value,
                                           ref int position,
                                           bool allowClosingDelimiter,
                                           ref bool closedDelimiter,
                                           ICommandEnvironment environment)
        {
            var initialSrcPosition = position;

            position++;
            var start = position;

            while (position < value.Length)
            {
                var ch    = value[position];
                var isEnd = position == value.Length - 1;
                if (!char.IsLetter(ch) || isEnd)
                {
                    // Escape sequence has ended
                    // Or it's a symbol. Assuming in this case it will only be a single char.
                    if ((isEnd && char.IsLetter(ch)) || position - start == 0)
                    {
                        position++;
                    }
                    break;
                }

                position++;
            }

            var commandSpan   = value.Segment(start, position - start);
            var command       = commandSpan.ToString();
            var formulaSource = new SourceSpan(value.Source, initialSrcPosition, commandSpan.End);

            SymbolAtom symbolAtom = null;

            if (SymbolAtom.TryGetAtom(commandSpan, out symbolAtom))
            {
                // Symbol was found.

                if (symbolAtom.Type == TexAtomType.Accent)
                {
                    var        helper        = new TexFormulaHelper(formula, formulaSource);
                    TexFormula accentFormula = ReadScript(formula, value, ref position, environment);
                    helper.AddAccent(accentFormula, symbolAtom.Name);
                }
                else if (symbolAtom.Type == TexAtomType.BigOperator)
                {
                    var opAtom = new BigOperatorAtom(formulaSource, symbolAtom, null, null);
                    formula.Add(AttachScripts(formula, value, ref position, opAtom, true, environment), formulaSource);
                }
                else
                {
                    formula.Add(
                        AttachScripts(formula, value, ref position, symbolAtom, true, environment), formulaSource);
                }
            }
            else if (predefinedFormulas.TryGetValue(command, out var factory))
            {
                // Predefined formula was found.
                var predefinedFormula = factory(formulaSource);
                var atom = AttachScripts(formula, value, ref position, predefinedFormula.RootAtom, true, environment);
                formula.Add(atom, formulaSource);
            }
            else if (command.Equals("nbsp"))
            {
                // Space was found.
                var atom = AttachScripts(formula, value, ref position, new SpaceAtom(formulaSource), true, environment);
                formula.Add(atom, formulaSource);
            }
            else if (textStyles.Contains(command))
            {
                // Text style was found.
                SkipWhiteSpace(value, ref position);

                var styledFormula = command == TexUtilities.TextStyleName
                    ? ConvertRawText(ReadElement(value, ref position), command)
                    : Parse(ReadElement(value, ref position), command, environment.CreateChildEnvironment());

                if (styledFormula.RootAtom == null)
                {
                    throw new TexParseException("Styled text can't be empty!");
                }

                var atom   = AttachScripts(formula, value, ref position, styledFormula.RootAtom, true, environment);
                var source = new SourceSpan(formulaSource.Source, formulaSource.Start, position);
                formula.Add(atom, source);
            }
            else if (embeddedCommands.Contains(command) ||
                     environment.AvailableCommands.ContainsKey(command) ||
                     _commandRegistry.ContainsKey(command))
            {
                // Command was found.
                var commandAtom = ProcessCommand(
                    formula,
                    value,
                    ref position,
                    command,
                    allowClosingDelimiter,
                    ref closedDelimiter,
                    environment);

                if (commandAtom != null)
                {
                    commandAtom = allowClosingDelimiter
                        ? commandAtom
                        : AttachScripts(
                        formula,
                        value,
                        ref position,
                        commandAtom,
                        true,
                        environment);

                    var source = new SourceSpan(formulaSource.Source, formulaSource.Start, commandAtom.Source.End);
                    formula.Add(commandAtom, source);
                }
            }
            else
            {
                // Escape sequence is invalid.
                throw new TexParseException("Unknown symbol or command or predefined TeXFormula: '" + command + "'");
            }
        }
Esempio n. 2
0
        private Atom AttachScripts(TexFormula formula, string value, ref int position, Atom atom)
        {
            if (position == value.Length)
            {
                return(atom);
            }
            if (value[position] == superScriptChar || value[position] == subScriptChar)
            {
                if (position == value.Length - 1)
                {
                    position++;
                    return(atom);
                }
            }
            else
            {
                return(atom);
            }

            TexFormula superscriptFormula = null;
            TexFormula subscriptFormula   = null;

            //0: Undetermined; 1: Not Yet; 2: Yes, we are; 3: Yes, and make it smaller
            int markAsBig = 0;
            //0: In Beginning;1: We are in _;2: we are in ^
            int lastIsSuper = 0;

            while (position < value.Length)
            {
                var ch = value[position];
                if (ch == superScriptChar || ch == subScriptChar)
                {
                    if (++position < value.Length && (value[position] == ch))
                    {
                        markAsBig = 2;
                        if (++position < value.Length && (value[position] == ch))
                        {
                            markAsBig = 3;
                            position++;
                        }
                    }
                    bool v = ch == superScriptChar;
                    if ((v ? superscriptFormula : subscriptFormula) == null)
                    {
                        lastIsSuper = v ? 2 : 1;
                    }
                    continue;
                }
                else if (ch == rightGroupChar || (value[position - 1] != '^' && value[position - 1] != '_'))
                {
                    break;
                }
                if (lastIsSuper == 2)
                {
                    if (superscriptFormula == null)
                    {
                        superscriptFormula = ReadScript(formula, value, ref position);
                    }
                    else
                    {
                        position--;
                        superscriptFormula.RootAtom = AttachScripts(formula, value, ref position, superscriptFormula.RootAtom);
                    }
                }
                else if (lastIsSuper == 1)
                {
                    if (subscriptFormula == null)
                    {
                        subscriptFormula = ReadScript(formula, value, ref position);
                    }
                    else
                    {
                        position--;
                        subscriptFormula.RootAtom = AttachScripts(formula, value, ref position, subscriptFormula.RootAtom);
                    }
                }
                else
                {
                    break;
                }
            }
            if (superscriptFormula == null && subscriptFormula == null)
            {
                return(atom);
            }

            // Check whether to return Big Operator or Scripts.
            if (atom != null && (atom.GetRightType() == CharType.BigOperator || markAsBig >= 2))
            {
                return(BigOperatorAtom.Get(atom, subscriptFormula == null ? null : subscriptFormula.GetRoot,
                                           superscriptFormula == null ? null : superscriptFormula.GetRoot, markAsBig == 3));
            }
            else
            {
                return(ScriptsAtom.Get(atom, subscriptFormula == null ? null : subscriptFormula.GetRoot,
                                       superscriptFormula == null ? null : superscriptFormula.GetRoot));
            }
        }