예제 #1
0
파일: TexFormula.cs 프로젝트: Civa/Zenith
        public void Add(TexFormula formula)
        {
            Debug.Assert(formula != null);
            Debug.Assert(formula.RootAtom != null);

            if (formula.RootAtom is RowAtom)
                Add(new RowAtom(formula.RootAtom));
            else
                Add(formula.RootAtom);
        }
예제 #2
0
파일: AccentedAtom.cs 프로젝트: Civa/Zenith
        public AccentedAtom(Atom baseAtom, TexFormula accent)
        {
            var rootSymbol = accent.RootAtom as SymbolAtom;
            if (rootSymbol == null)
                throw new ArgumentException("The formula for the accent is not a single symbol.", "accent");
            this.AccentAtom = (SymbolAtom)rootSymbol;

            if (this.AccentAtom.Type != TexAtomType.Accent)
                throw new ArgumentException("The specified symbol name is not an accent.", "accent");
        }
예제 #3
0
        public void PutDelimiterOver(
            TexDelimiter delimiter,
            TexFormula superscriptFormula,
            TexUnit kernUnit,
            double kern)
        {
            var name = TexFormulaParser.DelimiterNames[(int)delimiter][(int)TexDelimeterType.Over];

            this.Formula.RootAtom = new OverUnderDelimiter(
                this.source,
                this.Formula.RootAtom,
                superscriptFormula?.RootAtom,
                SymbolAtom.GetAtom(name, null),
                kernUnit,
                kern,
                true);
        }
예제 #4
0
파일: Extensions.cs 프로젝트: olesar/Altaxo
        public static byte[] RenderToPng(this TexFormula texForm,
                                         double scale,
                                         double x,
                                         double y,
                                         string systemTextFontName)
        {
            var          trnder = texForm.GetRenderer(TexStyle.Display, scale, systemTextFontName);
            BitmapSource image  = trnder.RenderToBitmap(x, y);

            PngBitmapEncoder encoder = new PngBitmapEncoder();

            encoder.Frames.Add(BitmapFrame.Create(image));

            using (var ms = new MemoryStream())
            {
                encoder.Save(ms);
                return(ms.ToArray());
            }
        }
예제 #5
0
        private TexFormula ReadScript(TexFormula formula, string value, ref int position)
        {
            if (position == value.Length)
            {
                throw new TexParseException("illegal end, missing script!");
            }

            SkipWhiteSpace(value, ref position);
            var ch = value[position];

            if (ch == leftGroupChar)
            {
                return(Parse(ReadGroup(formula, value, ref position, leftGroupChar, rightGroupChar), formula.TextStyle));
            }
            else
            {
                position++;
                return(Parse(ch.ToString(), formula.TextStyle));
            }
        }
예제 #6
0
        /// <remarks>May return <c>null</c>.</remarks>
        private Atom ConvertCharacter(
            TexFormula formula,
            ref int position,
            SourceSpan source,
            ICommandEnvironment environment)
        {
            var character = source[0];

            position++;
            if (IsSymbol(character) && formula.TextStyle != TexUtilities.TextStyleName)
            {
                // Character is symbol.
                var symbolName = symbols.ElementAtOrDefault(character);
                if (string.IsNullOrEmpty(symbolName))
                {
                    if (environment.ProcessUnknownCharacter(formula, character))
                    {
                        return(null);
                    }

                    throw new TexParseException($"Unknown character : '{character}'");
                }

                try
                {
                    return(SymbolAtom.GetAtom(symbolName, source));
                }
                catch (SymbolNotFoundException e)
                {
                    throw new TexParseException("The character '"
                                                + character.ToString()
                                                + "' was mapped to an unknown symbol with the name '"
                                                + (string)symbolName + "'!", e);
                }
            }
            else // Character is alpha-numeric or should be rendered as text.
            {
                return(new CharAtom(source, character, formula.TextStyle));
            }
        }
예제 #7
0
        private static TexFormula ConvertRawText(SourceSpan value, string textStyle)
        {
            var formula = new TexFormula {
                Source = value, TextStyle = textStyle
            };

            var position        = 0;
            var initialPosition = position;

            while (position < value.Length)
            {
                var ch     = value[position];
                var source = value.Segment(position, 1);
                var atom   = IsWhiteSpace(ch)
                    ? (Atom) new SpaceAtom(source)
                    : new CharAtom(source, ch, textStyle);
                position++;
                formula.Add(atom, value.Segment(initialPosition, position - initialPosition));
            }

            return(formula);
        }
예제 #8
0
            public override void Parse(SourceSpan source, XElement element)
            {
                var name = element.AttributeValue("name");
                var args = element.Elements("Argument");

                var argTypes  = GetArgumentTypes(args);
                var argValues = GetArgumentValues(this.TempFormulas, args);

                Debug.Assert(argValues.Length == 1 || argValues.Length == 0);
                TexFormula formula = null;

                if (argValues.Length == 1)
                {
                    var parser = new TexFormulaParser();
                    formula = parser.Parse((string)argValues[0]);
                }
                else
                {
                    formula = new TexFormula();
                }

                this.TempFormulas.Add(name, formula);
            }
            public void Parse(SourceSpan source, XElement element, PredefinedFormulaContext context)
            {
                var name = element.AttributeValue("name");
                var args = element.Elements("Argument");

                var argValues = GetArgumentValues(args, context);

                Debug.Assert(argValues.Length == 1 || argValues.Length == 0);
                TexFormula formula;

                if (argValues.Length == 1)
                {
                    var parser = new TexFormulaParser();
                    formula = parser.Parse((string)argValues[0] !); // Nullable TODO: This might need null checking
                }
                else
                {
                    formula = new TexFormula {
                        Source = source
                    };
                }

                context.AddFormula(name, formula);
            }
예제 #10
0
 public TexFormulaHelper(TexFormula formula)
 {
     this.formulaParser = new TexFormulaParser();
     this.Formula = formula;
 }
예제 #11
0
 public void AddRadical(TexFormula baseFormula, string degreeFormula)
 {
     AddRadical(baseFormula, formulaParser.Parse(degreeFormula));
 }
예제 #12
0
        private TexFormula Parse(
            SourceSpan value,
            ref int position,
            bool allowClosingDelimiter,
            string textStyle,
            ICommandEnvironment environment)
        {
            var formula = new TexFormula {
                Source = value, TextStyle = textStyle
            };
            var closedDelimiter = false;
            var skipWhiteSpace  = ShouldSkipWhiteSpace(textStyle);
            var initialPosition = position;

            while (position < value.Length && !(allowClosingDelimiter && closedDelimiter))
            {
                char ch     = value[position];
                var  source = value.Segment(position, 1);
                if (IsWhiteSpace(ch))
                {
                    if (!skipWhiteSpace)
                    {
                        formula.Add(new SpaceAtom(source), source);
                    }

                    position++;
                }
                else if (ch == escapeChar)
                {
                    ProcessEscapeSequence(
                        formula,
                        value,
                        ref position,
                        allowClosingDelimiter,
                        ref closedDelimiter,
                        environment);
                }
                else if (ch == leftGroupChar)
                {
                    var groupValue     = ReadElement(value, ref position);
                    var parsedGroup    = Parse(groupValue, textStyle, environment.CreateChildEnvironment());
                    var innerGroupAtom = parsedGroup.RootAtom ?? new RowAtom(groupValue);
                    var groupAtom      = new TypedAtom(
                        innerGroupAtom.Source,
                        innerGroupAtom,
                        TexAtomType.Ordinary,
                        TexAtomType.Ordinary);
                    var scriptsAtom = this.AttachScripts(formula, value, ref position, groupAtom, true, environment);
                    formula.Add(scriptsAtom, value.Segment(initialPosition, position - initialPosition));
                }
                else if (ch == rightGroupChar)
                {
                    throw new TexParseException("Found a closing '" + rightGroupChar
                                                + "' without an opening '" + leftGroupChar + "'!");
                }
                else if (ch == superScriptChar || ch == subScriptChar || ch == primeChar)
                {
                    if (position == 0)
                    {
                        throw new TexParseException("Every script needs a base: \""
                                                    + superScriptChar + "\", \"" + subScriptChar + "\" and \""
                                                    + primeChar + "\" can't be the first character!");
                    }
                    else
                    {
                        throw new TexParseException("Double scripts found! Try using more braces.");
                    }
                }
                else
                {
                    var character = ConvertCharacter(formula, ref position, source, environment);
                    if (character != null)
                    {
                        var scriptsAtom = AttachScripts(
                            formula,
                            value,
                            ref position,
                            character,
                            skipWhiteSpace,
                            environment);
                        formula.Add(scriptsAtom, value.Segment(initialPosition, position));
                    }
                }
            }

            return(formula);
        }
예제 #13
0
 public void AddPhantom(TexFormula formula)
 {
     Add(new PhantomAtom(formula == null ? null : formula.RootAtom));
 }
예제 #14
0
 public void AddEmbraced(TexFormula formula, char leftChar, char rightChar)
 {
     AddEmbraced(formula, TexFormulaParser.GetDelimeterMapping(leftChar),
         TexFormulaParser.GetDelimeterMapping(rightChar));
 }
예제 #15
0
        /// <remarks>May return <c>null</c> for commands that produce no atoms.</remarks>
        private Atom ProcessCommand(
            TexFormula formula,
            SourceSpan value,
            ref int position,
            string command,
            bool allowClosingDelimiter,
            ref bool closedDelimiter,
            ICommandEnvironment environment)
        {
            int start = position - command.Length;

            SourceSpan source;

            switch (command)
            {
            case "frac":
            {
                var numeratorFormula = Parse(
                    ReadElement(value, ref position),
                    formula.TextStyle,
                    environment.CreateChildEnvironment());
                var denominatorFormula = Parse(
                    ReadElement(value, ref position),
                    formula.TextStyle,
                    environment.CreateChildEnvironment());
                source = value.Segment(start, position - start);
                return(new FractionAtom(source, numeratorFormula.RootAtom, denominatorFormula.RootAtom, true));
            }

            case "left":
            {
                SkipWhiteSpace(value, ref position);
                if (position == value.Length)
                {
                    throw new TexParseException("`left` command should be passed a delimiter");
                }

                var delimiter = value[position];
                ++position;
                var left = position;

                var internals = ParseUntilDelimiter(value, ref position, formula.TextStyle, environment);

                var opening = GetDelimiterSymbol(
                    GetDelimeterMapping(delimiter),
                    value.Segment(start, left - start));
                if (opening == null)
                {
                    throw new TexParseException($"Cannot find delimiter named {delimiter}");
                }

                var closing = internals.ClosingDelimiter;
                source = value.Segment(start, position - start);
                return(new FencedAtom(source, internals.Body, opening, closing));
            }

            case "overline":
            {
                var overlineFormula = Parse(
                    ReadElement(value, ref position),
                    formula.TextStyle,
                    environment.CreateChildEnvironment());
                source = value.Segment(start, position - start);
                return(new OverlinedAtom(source, overlineFormula.RootAtom));
            }

            case "right":
            {
                if (!allowClosingDelimiter)
                {
                    throw new TexParseException("`right` command is not allowed without `left`");
                }

                SkipWhiteSpace(value, ref position);
                if (position == value.Length)
                {
                    throw new TexParseException("`right` command should be passed a delimiter");
                }

                var delimiter = value[position];
                ++position;

                var closing = GetDelimiterSymbol(
                    GetDelimeterMapping(delimiter),
                    value.Segment(start, position - start));
                if (closing == null)
                {
                    throw new TexParseException($"Cannot find delimiter named {delimiter}");
                }

                closedDelimiter = true;
                return(closing);
            }

            case "sqrt":
            {
                // Command is radical.
                SkipWhiteSpace(value, ref position);

                TexFormula degreeFormula = null;
                if (value.Length > position && value[position] == leftBracketChar)
                {
                    // Degree of radical is specified.
                    degreeFormula = Parse(
                        ReadElementGroup(value, ref position, leftBracketChar, rightBracketChar),
                        formula.TextStyle,
                        environment.CreateChildEnvironment());
                }

                var sqrtFormula = this.Parse(
                    ReadElement(value, ref position),
                    formula.TextStyle,
                    environment.CreateChildEnvironment());

                source = value.Segment(start, position - start);
                return(new Radical(source, sqrtFormula.RootAtom, degreeFormula?.RootAtom));
            }

            case "color":
            {
                var color = ReadColorModelData(value, ref position);

                var bodyValue   = ReadElement(value, ref position);
                var bodyFormula = Parse(bodyValue, formula.TextStyle, environment.CreateChildEnvironment());
                source = value.Segment(start, position - start);

                return(new StyledAtom(source, bodyFormula.RootAtom, null, new SolidColorBrush(color)));
            }

            case "colorbox":
            {
                var color = ReadColorModelData(value, ref position);

                var bodyValue   = ReadElement(value, ref position);
                var bodyFormula = Parse(bodyValue, formula.TextStyle, environment.CreateChildEnvironment());
                source = value.Segment(start, position - start);

                return(new StyledAtom(source, bodyFormula.RootAtom, new SolidColorBrush(color), null));
            }
            }

            if (environment.AvailableCommands.TryGetValue(command, out var parser) ||
                _commandRegistry.TryGetValue(command, out parser))
            {
                var context     = new CommandContext(this, formula, environment, value, start, position);
                var parseResult = parser.ProcessCommand(context);
                if (parseResult.NextPosition < position)
                {
                    throw new TexParseException(
                              $"Incorrect parser behavior for command {command}: NextPosition = {parseResult.NextPosition}, position = {position}. Parser did not made any progress.");
                }

                position = parseResult.NextPosition;
                return(parseResult.Atom);
            }

            throw new TexParseException("Invalid command.");
        }
예제 #16
0
 public void PutOver(TexFormula overFormula, TexUnit overUnit, double overSpace, bool overScriptSize)
 {
     this.Formula.RootAtom = new UnderOverAtom(this.Formula.RootAtom,
                                               overFormula == null ? null : overFormula.RootAtom, overUnit, overSpace, overScriptSize, true);
 }
예제 #17
0
 public void PutUnderAndOver(TexFormula underFormula, TexUnit underUnit, double underSpace, bool underScriptSize,
     TexFormula over, TexUnit overUnit, double overSpace, bool overScriptSize)
 {
     this.Formula.RootAtom = new UnderOverAtom(this.Formula.RootAtom, underFormula == null ?
         null : underFormula.RootAtom, underUnit, underSpace, underScriptSize, over == null ? null : over.RootAtom,
         overUnit, overSpace, overScriptSize);
 }
예제 #18
0
 public void AddPhantom(TexFormula phantom, bool useWidth, bool useHeight, bool useDepth)
 {
     Add(new PhantomAtom(phantom == null ? null : phantom.RootAtom, useWidth, useHeight, useDepth));
 }
예제 #19
0
 public void Add(TexFormula formula)
 {
     this.Formula.Add(formula);
 }
예제 #20
0
 public void AddPhantom(TexFormula formula)
 {
     Add(new PhantomAtom(formula == null ? null : formula.RootAtom));
 }
예제 #21
0
 public void AddOperator(TexFormula operatorFormula, TexFormula lowerLimitFormula, TexFormula upperLimitFormula,
                         bool useVerticalLimits)
 {
     Add(new BigOperatorAtom(operatorFormula == null ? null : operatorFormula.RootAtom,
                             lowerLimitFormula == null ? null : lowerLimitFormula.RootAtom,
                             upperLimitFormula == null ? null : upperLimitFormula.RootAtom, useVerticalLimits));
 }
예제 #22
0
 public void AddOperator(TexFormula operatorFormula, TexFormula lowerLimitFormula, TexFormula upperLimitFormula)
 {
     Add(new BigOperatorAtom(operatorFormula == null ? null : operatorFormula.RootAtom,
                             lowerLimitFormula == null ? null : lowerLimitFormula.RootAtom,
                             upperLimitFormula == null ? null : upperLimitFormula.RootAtom));
 }
예제 #23
0
 public void AddRadical(TexFormula baseFormula, TexFormula degreeFormula)
 {
     Add(new Radical(baseFormula == null ? null : baseFormula.RootAtom,
         degreeFormula == null ? null : degreeFormula.RootAtom));
 }
예제 #24
0
 public void PutUnder(TexFormula underFormula, TexUnit underUnit, double underSpace, bool underScriptSize)
 {
     this.Formula.RootAtom = new UnderOverAtom(this.Formula.RootAtom,
                                               underFormula == null ? null : underFormula.RootAtom, underUnit, underSpace, underScriptSize, false);
 }
예제 #25
0
 public void PutOver(TexFormula overFormula, TexUnit overUnit, double overSpace, bool overScriptSize)
 {
     this.Formula.RootAtom = new UnderOverAtom(this.Formula.RootAtom,
         overFormula == null ? null : overFormula.RootAtom, overUnit, overSpace, overScriptSize, true);
 }
예제 #26
0
 public void AddAccent(TexFormula baseAtom, string accentName)
 {
     Add(new AccentedAtom((baseAtom == null ? null : baseAtom.RootAtom), accentName));
 }
예제 #27
0
 public void AddAccent(TexFormula baseAtom, string accentName)
 {
     Add(new AccentedAtom((baseAtom == null ? null : baseAtom.RootAtom), accentName));
 }
예제 #28
0
 public void AddAccent(TexFormula baseAtom, TexFormula accent)
 {
     Add(new AccentedAtom((baseAtom == null ? null : baseAtom.RootAtom), accent));
 }
예제 #29
0
 public void AddFraction(string numerator, TexFormula denominator, bool drawLine)
 {
     AddFraction(formulaParser.Parse(numerator), denominator, drawLine);
 }
예제 #30
0
 public void AddEmbraced(TexFormula formula, char leftChar, char rightChar)
 {
     AddEmbraced(formula, TexFormulaParser.GetDelimeterMapping(leftChar),
                 TexFormulaParser.GetDelimeterMapping(rightChar));
 }
예제 #31
0
        private Atom AttachScripts(
            TexFormula formula,
            SourceSpan value,
            ref int position,
            Atom atom,
            bool skipWhiteSpace,
            ICommandEnvironment environment)
        {
            if (skipWhiteSpace)
            {
                SkipWhiteSpace(value, ref position);
            }

            var initialPosition = position;

            if (position == value.Length)
            {
                return(atom);
            }

            // Check for prime marks.
            var primesRowAtom = new RowAtom(new SourceSpan(value.Source, position, 0));
            int i             = position;

            while (i < value.Length)
            {
                if (value[i] == primeChar)
                {
                    primesRowAtom = primesRowAtom.Add(SymbolAtom.GetAtom("prime", value.Segment(i, 1)));
                    position++;
                }
                else if (!IsWhiteSpace(value[i]))
                {
                    break;
                }
                i++;
            }

            var primesRowSource = new SourceSpan(
                value.Source,
                primesRowAtom.Source.Start,
                position - primesRowAtom.Source.Start);

            primesRowAtom = primesRowAtom.WithSource(primesRowSource);

            if (primesRowAtom.Elements.Count > 0)
            {
                atom = new ScriptsAtom(primesRowAtom.Source, atom, null, primesRowAtom);
            }

            if (position == value.Length)
            {
                return(atom);
            }

            TexFormula superscriptFormula = null;
            TexFormula subscriptFormula   = null;

            var ch = value[position];

            if (ch == superScriptChar)
            {
                // Attach superscript.
                position++;
                superscriptFormula = ReadScript(formula, value, ref position, environment);

                SkipWhiteSpace(value, ref position);
                if (position < value.Length && value[position] == subScriptChar)
                {
                    // Attach subscript also.
                    position++;
                    subscriptFormula = ReadScript(formula, value, ref position, environment);
                }
            }
            else if (ch == subScriptChar)
            {
                // Add subscript.
                position++;
                subscriptFormula = ReadScript(formula, value, ref position, environment);

                SkipWhiteSpace(value, ref position);
                if (position < value.Length && value[position] == superScriptChar)
                {
                    // Attach superscript also.
                    position++;
                    superscriptFormula = ReadScript(formula, value, ref position, environment);
                }
            }

            if (superscriptFormula == null && subscriptFormula == null)
            {
                return(atom);
            }

            // Check whether to return Big Operator or Scripts.
            var subscriptAtom   = subscriptFormula?.RootAtom;
            var superscriptAtom = superscriptFormula?.RootAtom;

            if (atom.GetRightType() == TexAtomType.BigOperator)
            {
                var source = value.Segment(atom.Source.Start, position - atom.Source.Start);
                if (atom is BigOperatorAtom typedAtom)
                {
                    return(new BigOperatorAtom(
                               source,
                               typedAtom.BaseAtom,
                               subscriptAtom,
                               superscriptAtom,
                               typedAtom.UseVerticalLimits));
                }

                return(new BigOperatorAtom(source, atom, subscriptAtom, superscriptAtom));
            }
            else
            {
                var source = new SourceSpan(value.Source, initialPosition, position - initialPosition);
                return(new ScriptsAtom(source, atom, subscriptAtom, superscriptAtom));
            }
        }
예제 #32
0
 public void AddEmbraced(TexFormula formula, string leftSymbol, string rightSymbol)
 {
     Add(new FencedAtom(formula == null ? null : formula.RootAtom, TexFormulaParser.GetDelimiterSymbol(leftSymbol),
                        TexFormulaParser.GetDelimiterSymbol(rightSymbol)));
 }
예제 #33
0
        private string ReadGroup(TexFormula formula, string value, ref int position, char openChar, char closeChar)
        {
            if (position == value.Length || value[position] != openChar)
                throw new TexParseException("missing '" + openChar + "'!");

            var result = new StringBuilder();
            var group = 0;
            position++;
            while (position < value.Length && !(value[position] == closeChar && group == 0))
            {
                if (value[position] == openChar)
                    group++;
                else if (value[position] == closeChar)
                    group--;
                result.Append(value[position]);
                position++;
            }

            if (position == value.Length)
            {
                // Reached end of formula but group has not been closed.
                throw new TexParseException("Illegal end,  missing '" + closeChar + "'!");
            }

            position++;
            return result.ToString();
        }
예제 #34
0
 public void AddFraction(string numerator, TexFormula denominator, bool drawLine)
 {
     AddFraction(formulaParser.Parse(numerator), denominator, drawLine);
 }
예제 #35
0
 public void AddPhantom(TexFormula phantom, bool useWidth, bool useHeight, bool useDepth)
 {
     Add(new PhantomAtom(phantom == null ? null : phantom.RootAtom, useWidth, useHeight, useDepth));
 }
예제 #36
0
 public void AddFraction(TexFormula numerator, string denominator, bool drawLine)
 {
     AddFraction(numerator, formulaParser.Parse(denominator), drawLine);
 }
예제 #37
0
 public void AddRadical(string baseFormula, TexFormula nthRoot)
 {
     AddRadical(formulaParser.Parse(baseFormula), nthRoot);
 }
예제 #38
0
 public void AddFraction(TexFormula numerator, TexFormula denominator, bool drawLine)
 {
     Add(new FractionAtom(numerator == null ? null : numerator.RootAtom,
                          denominator == null ? null : denominator.RootAtom, drawLine));
 }
예제 #39
0
 public void AddRadical(TexFormula baseFormula)
 {
     AddRadical(baseFormula, (TexFormula)null);
 }
예제 #40
0
 public void AddFraction(TexFormula numerator, TexFormula denominator, bool drawLine,
                         TexAlignment numeratorAlignment, TexAlignment denominatorAlignment)
 {
     Add(new FractionAtom(numerator == null ? null : numerator.RootAtom,
                          denominator == null ? null : denominator.RootAtom, drawLine, numeratorAlignment, denominatorAlignment));
 }
예제 #41
0
 public void PutDelimiterUnder(TexDelimeter delimiter, TexFormula subscriptName, TexUnit kernUnit, double kern)
 {
     var name = TexFormulaParser.DelimiterNames[(int)delimiter][(int)TexDelimeterType.Under];
     this.Formula.RootAtom = new OverUnderDelimiter(this.Formula.RootAtom,
         subscriptName == null ? null : subscriptName.RootAtom, SymbolAtom.GetAtom(name), kernUnit, kern, false);
 }
예제 #42
0
 private TexFormula ReadScript(TexFormula formula, SourceSpan value, ref int position) =>
 Parse(ReadElement(value, ref position), formula.TextStyle);
예제 #43
0
 public void PutUnder(TexFormula underFormula, TexUnit underUnit, double underSpace, bool underScriptSize)
 {
     this.Formula.RootAtom = new UnderOverAtom(this.Formula.RootAtom,
         underFormula == null ? null : underFormula.RootAtom, underUnit, underSpace, underScriptSize, false);
 }
예제 #44
0
        private Atom ProcessCommand(
            TexFormula formula,
            SourceSpan value,
            ref int position,
            string command,
            bool allowClosingDelimiter,
            ref bool closedDelimiter)
        {
            int start = position - command.Length;

            SourceSpan source;

            switch (command)
            {
            case "frac":
            {
                var numeratorFormula   = Parse(ReadElement(value, ref position), formula.TextStyle);
                var denominatorFormula = Parse(ReadElement(value, ref position), formula.TextStyle);
                source = value.Segment(start, position - start);
                return(new FractionAtom(source, numeratorFormula.RootAtom, denominatorFormula.RootAtom, true));
            }

            case "left":
            {
                SkipWhiteSpace(value, ref position);
                if (position == value.Length)
                {
                    throw new TexParseException("`left` command should be passed a delimiter");
                }

                var delimiter = value[position];
                ++position;
                var left = position;

                var internals = ParseUntilDelimiter(value, ref position, formula.TextStyle);

                var opening = GetDelimiterSymbol(
                    GetDelimeterMapping(delimiter),
                    value.Segment(start, left - start));
                if (opening == null)
                {
                    throw new TexParseException($"Cannot find delimiter named {delimiter}");
                }

                var closing = internals.ClosingDelimiter;
                source = value.Segment(start, position - start);
                return(new FencedAtom(source, internals.Body, opening, closing));
            }

            case "overline":
            {
                var overlineFormula = Parse(ReadElement(value, ref position), formula.TextStyle);
                source = value.Segment(start, position - start);
                return(new OverlinedAtom(source, overlineFormula.RootAtom));
            }

            case "right":
            {
                if (!allowClosingDelimiter)
                {
                    throw new TexParseException("`right` command is not allowed without `left`");
                }

                SkipWhiteSpace(value, ref position);
                if (position == value.Length)
                {
                    throw new TexParseException("`right` command should be passed a delimiter");
                }

                var delimiter = value[position];
                ++position;

                var closing = GetDelimiterSymbol(
                    GetDelimeterMapping(delimiter),
                    value.Segment(start, position - start));
                if (closing == null)
                {
                    throw new TexParseException($"Cannot find delimiter named {delimiter}");
                }

                closedDelimiter = true;
                return(closing);
            }

            case "sqrt":
            {
                // Command is radical.
                SkipWhiteSpace(value, ref position);

                TexFormula degreeFormula = null;
                if (value.Length > position && value[position] == leftBracketChar)
                {
                    // Degree of radical is specified.
                    degreeFormula = Parse(
                        ReadElementGroup(value, ref position, leftBracketChar, rightBracketChar),
                        formula.TextStyle);
                }

                var sqrtFormula = Parse(ReadElement(value, ref position), formula.TextStyle);

                source = value.Segment(start, position - start);
                return(new Radical(source, sqrtFormula.RootAtom, degreeFormula?.RootAtom));
            }

            case "underline":
            {
                var underlineFormula = Parse(ReadElement(value, ref position), formula.TextStyle);
                source = value.Segment(start, position - start);
                return(new UnderlinedAtom(source, underlineFormula.RootAtom));
            }

            case "color":
            {
                var colorName = ReadElement(value, ref position);
                if (!predefinedColors.TryGetValue(colorName.ToString(), out var color))
                {
                    throw new TexParseException($"Color {colorName} not found");
                }

                var bodyValue   = ReadElement(value, ref position);
                var bodyFormula = Parse(bodyValue, formula.TextStyle);
                source = value.Segment(start, position - start);
                return(new StyledAtom(source, bodyFormula.RootAtom, null, new SolidColorBrush(color)));
            }

            case "colorbox":
            {
                var colorName       = ReadElement(value, ref position);
                var remainingString = ReadElement(value, ref position);
                var remaining       = Parse(remainingString, formula.TextStyle);
                if (predefinedColors.TryGetValue(colorName.ToString(), out var color))
                {
                    source = value.Segment(start, position - start);
                    return(new StyledAtom(source, remaining.RootAtom, new SolidColorBrush(color), null));
                }

                throw new TexParseException($"Color {colorName} not found");
            }
            }

            throw new TexParseException("Invalid command.");
        }
예제 #45
0
 public void Add(TexFormula formula)
 {
     this.Formula.Add(formula);
 }
예제 #46
0
        public TexFormula(TexFormula formula)
        {
            Debug.Assert(formula != null);

            Add(formula);
        }
예제 #47
0
 public void AddAccent(TexFormula baseAtom, TexFormula accent)
 {
     Add(new AccentedAtom((baseAtom == null ? null : baseAtom.RootAtom), accent));
 }
예제 #48
0
 public void AddFraction(TexFormula numerator, string denominator, bool drawLine)
 {
     AddFraction(numerator, formulaParser.Parse(denominator), drawLine);
 }
예제 #49
0
 public void AddEmbraced(TexFormula formula, string leftSymbol, string rightSymbol)
 {
     Add(new FencedAtom(formula == null ? null : formula.RootAtom, TexFormulaParser.GetDelimiterSymbol(leftSymbol),
         TexFormulaParser.GetDelimiterSymbol(rightSymbol)));
 }
예제 #50
0
파일: TexFormula.cs 프로젝트: Civa/Zenith
        public TexFormula(TexFormula formula)
        {
            Debug.Assert(formula != null);

            Add(formula);
        }
예제 #51
0
 private TexFormula ReadScript(
     TexFormula formula,
     SourceSpan value,
     ref int position,
     ICommandEnvironment environment) =>
 Parse(ReadElement(value, ref position), formula.TextStyle, environment.CreateChildEnvironment());
예제 #52
0
        private Atom ProcessCommand(TexFormula formula, string value, ref int position, string command)
        {
            SkipWhiteSpace(value, ref position);

            switch (command)
            {
                case "frac":
                    // Command is fraction.

                    var numeratorFormula = Parse(ReadGroup(formula, value, ref position, leftGroupChar,
                        rightGroupChar));
                    SkipWhiteSpace(value, ref position);
                    var denominatorFormula = Parse(ReadGroup(formula, value, ref position, leftGroupChar,
                        rightGroupChar));
                    if (numeratorFormula.RootAtom == null || denominatorFormula.RootAtom == null)
                        throw new TexParseException("Both numerator and denominator of a fraction can't be empty!");

                    return new FractionAtom(numeratorFormula.RootAtom, denominatorFormula.RootAtom, true);
                case "sqrt":
                    // Command is radical.

                    SkipWhiteSpace(value, ref position);
                    if (position == value.Length)
                        throw new TexParseException("illegal end!");

                    TexFormula degreeFormula = null;
                    if (value[position] == leftBracketChar)
                    {
                        // Degree of radical- is specified.
                        degreeFormula = Parse(ReadGroup(formula, value, ref position, leftBracketChar,
                            rightBracketChar));
                        SkipWhiteSpace(value, ref position);
                    }

                    return new Radical(Parse(ReadGroup(formula, value, ref position, leftGroupChar, rightGroupChar))
                        .RootAtom, degreeFormula == null ? null : degreeFormula.RootAtom);
            }

            throw new TexParseException("Invalid command.");
        }
예제 #53
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());

                var source      = value.Segment(start, position - start);
                var atom        = styledFormula.RootAtom ?? new NullAtom(source);
                var commandAtom = AttachScripts(formula, value, ref position, atom, true, environment);
                formula.Add(commandAtom, 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 + "'");
            }
        }
예제 #54
0
 public TexExpressionVisitor(System.Linq.Expressions.Expression value, TexFormulaParser tfp )
 {
     _tfp = tfp;
     Formula = new TexFormula();
     Visit(value);
 }
예제 #55
0
        private void ProcessEscapeSequence(TexFormula formula, string value, ref int position)
        {
            var result = new StringBuilder();
            position++;
            while (position < value.Length)
            {
                var ch = value[position];
                var isEnd = position == value.Length - 1;
                if (!char.IsLetter(ch) || isEnd)
                {
                    // Escape sequence has ended.
                    if (isEnd)
                    {
                        result.Append(ch);
                        position++;
                    }
                    break;
                }

                result.Append(ch);
                position++;
            }

            var command = result.ToString();

            SymbolAtom symbolAtom = null;
            TexFormula predefinedFormula = null;

            try
            {
                symbolAtom = SymbolAtom.GetAtom(command);
            }
            catch (SymbolNotFoundException)
            {
            }

            try
            {
                predefinedFormula = GetFormula(command);
            }
            catch (FormulaNotFoundException)
            {
            }

            if (symbolAtom != null)
            {
                // Symbol was found.

                formula.Add(AttachScripts(formula, value, ref position, symbolAtom));
            }
            else if (predefinedFormula != null)
            {
                // Predefined formula was found.

                formula.Add(AttachScripts(formula, value, ref position, predefinedFormula.RootAtom));
            }
            else if (command.Equals("nbsp"))
            {
                // Space was found.

                formula.Add(AttachScripts(formula, value, ref position, new SpaceAtom()));
            }
            else if (textStyles.Contains(command))
            {
                // Text style was found.

                SkipWhiteSpace(value, ref position);
                var styledFormula = Parse(ReadGroup(formula, value, ref position, leftGroupChar, rightGroupChar));
                styledFormula.TextStyle = command;
                formula.Add(AttachScripts(formula, value, ref position, styledFormula.RootAtom));
            }
            else if (commands.Contains(command))
            {
                // Command was found.

                formula.Add(AttachScripts(formula, value, ref position, ProcessCommand(formula, value, ref position,
                    command)));
            }
            else
            {
                // Escape sequence is invalid.
                throw new TexParseException("Unknown symbol or command or predefined TeXFormula: '" + command + "'");
            }
        }
예제 #56
0
 public void AddOperator(TexFormula operatorFormula, TexFormula lowerLimitFormula, TexFormula upperLimitFormula,
     bool useVerticalLimits)
 {
     Add(new BigOperatorAtom(operatorFormula == null ? null : operatorFormula.RootAtom,
         lowerLimitFormula == null ? null : lowerLimitFormula.RootAtom,
         upperLimitFormula == null ? null : upperLimitFormula.RootAtom, useVerticalLimits));
 }
예제 #57
0
 public void AddOperator(TexFormula operatorFormula, TexFormula lowerLimitFormula, TexFormula upperLimitFormula)
 {
     Add(new BigOperatorAtom(operatorFormula == null ? null : operatorFormula.RootAtom,
         lowerLimitFormula == null ? null : lowerLimitFormula.RootAtom,
         upperLimitFormula == null ? null : upperLimitFormula.RootAtom));
 }
예제 #58
0
        private TexFormula ReadScript(TexFormula formula, string value, ref int position)
        {
            if (position == value.Length)
                throw new TexParseException("illegal end, missing script!");

            SkipWhiteSpace(value, ref position);
            var ch = value[position];
            if (ch == leftGroupChar)
            {
                return Parse(ReadGroup(formula, value, ref position, leftGroupChar, rightGroupChar));
            }
            else
            {
                position++;
                return Parse(ch.ToString());
            }
        }
예제 #59
0
 public void AddFraction(TexFormula numerator, TexFormula denominator, bool drawLine)
 {
     Add(new FractionAtom(numerator == null ? null : numerator.RootAtom,
         denominator == null ? null : denominator.RootAtom, drawLine));
 }
예제 #60
0
 public void AddFraction(TexFormula numerator, TexFormula denominator, bool drawLine,
     TexAlignment numeratorAlignment, TexAlignment denominatorAlignment)
 {
     Add(new FractionAtom(numerator == null ? null : numerator.RootAtom,
         denominator == null ? null : denominator.RootAtom, drawLine, numeratorAlignment, denominatorAlignment));
 }