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); }
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"); }
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); }
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()); } }
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)); } }
/// <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)); } }
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); }
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); }
public TexFormulaHelper(TexFormula formula) { this.formulaParser = new TexFormulaParser(); this.Formula = formula; }
public void AddRadical(TexFormula baseFormula, string degreeFormula) { AddRadical(baseFormula, formulaParser.Parse(degreeFormula)); }
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); }
public void AddPhantom(TexFormula formula) { Add(new PhantomAtom(formula == null ? null : formula.RootAtom)); }
public void AddEmbraced(TexFormula formula, char leftChar, char rightChar) { AddEmbraced(formula, TexFormulaParser.GetDelimeterMapping(leftChar), TexFormulaParser.GetDelimeterMapping(rightChar)); }
/// <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."); }
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); }
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); }
public void AddPhantom(TexFormula phantom, bool useWidth, bool useHeight, bool useDepth) { Add(new PhantomAtom(phantom == null ? null : phantom.RootAtom, useWidth, useHeight, useDepth)); }
public void Add(TexFormula formula) { this.Formula.Add(formula); }
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)); }
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)); }
public void AddRadical(TexFormula baseFormula, TexFormula degreeFormula) { Add(new Radical(baseFormula == null ? null : baseFormula.RootAtom, degreeFormula == null ? null : degreeFormula.RootAtom)); }
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); }
public void AddAccent(TexFormula baseAtom, string accentName) { Add(new AccentedAtom((baseAtom == null ? null : baseAtom.RootAtom), accentName)); }
public void AddAccent(TexFormula baseAtom, TexFormula accent) { Add(new AccentedAtom((baseAtom == null ? null : baseAtom.RootAtom), accent)); }
public void AddFraction(string numerator, TexFormula denominator, bool drawLine) { AddFraction(formulaParser.Parse(numerator), denominator, drawLine); }
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)); } }
public void AddEmbraced(TexFormula formula, string leftSymbol, string rightSymbol) { Add(new FencedAtom(formula == null ? null : formula.RootAtom, TexFormulaParser.GetDelimiterSymbol(leftSymbol), TexFormulaParser.GetDelimiterSymbol(rightSymbol))); }
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(); }
public void AddFraction(TexFormula numerator, string denominator, bool drawLine) { AddFraction(numerator, formulaParser.Parse(denominator), drawLine); }
public void AddRadical(string baseFormula, TexFormula nthRoot) { AddRadical(formulaParser.Parse(baseFormula), nthRoot); }
public void AddFraction(TexFormula numerator, TexFormula denominator, bool drawLine) { Add(new FractionAtom(numerator == null ? null : numerator.RootAtom, denominator == null ? null : denominator.RootAtom, drawLine)); }
public void AddRadical(TexFormula baseFormula) { AddRadical(baseFormula, (TexFormula)null); }
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)); }
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); }
private TexFormula ReadScript(TexFormula formula, SourceSpan value, ref int position) => Parse(ReadElement(value, ref position), formula.TextStyle);
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."); }
public TexFormula(TexFormula formula) { Debug.Assert(formula != null); Add(formula); }
private TexFormula ReadScript( TexFormula formula, SourceSpan value, ref int position, ICommandEnvironment environment) => Parse(ReadElement(value, ref position), formula.TextStyle, environment.CreateChildEnvironment());
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."); }
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 + "'"); } }
public TexExpressionVisitor(System.Linq.Expressions.Expression value, TexFormulaParser tfp ) { _tfp = tfp; Formula = new TexFormula(); Visit(value); }
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 + "'"); } }
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()); } }