public SymbolAtom(SymbolAtom symbolAtom, TexAtomType type) : base() { if (!validSymbolTypes[(int)type]) throw new ArgumentException("The specified type is not a valid symbol type.", "type"); this.Type = type; this.Name = symbolAtom.Name; this.IsDelimeter = symbolAtom.IsDelimeter; }
public void PutDelimiterUnder(TexDelimiter delimiter) { var name = TexFormulaParser.DelimiterNames[(int)delimiter][(int)TexDelimeterType.Under]; this.Formula.RootAtom = new OverUnderDelimiter( this.source, this.Formula.RootAtom, null, SymbolAtom.GetAtom(name, null), TexUnit.Ex, 0.0, false); }
public void PutDelimiterUnder(TexDelimiter delimiter, TexFormula subscriptName, TexUnit kernUnit, double kern) { var name = TexFormulaParser.DelimiterNames[(int)delimiter][(int)TexDelimeterType.Under]; this.Formula.RootAtom = new OverUnderDelimiter( this._source, this.Formula.RootAtom, subscriptName?.RootAtom, SymbolAtom.GetAtom(name, null), kernUnit, kern, false); }
public OverUnderDelimiter( Atom baseAtom, Atom script, SymbolAtom symbol, TexUnit kernUnit, double kern, bool over) { this.BaseAtom = baseAtom; this.Script = script; this.Symbol = symbol; this.Kern = new SpaceAtom(kernUnit, 0, kern, 0); this.Over = over; }
internal static SymbolAtom GetDelimiterSymbol(string name, SourceSpan source) { if (name == null) { return(null); } var result = SymbolAtom.GetAtom(name, source); if (!result.IsDelimeter) { return(null); } return(result); }
public OverUnderDelimiter( SourceSpan?source, Atom?baseAtom, Atom?script, SymbolAtom symbol, TexUnit kernUnit, double kern, bool over) : base(source) { this.BaseAtom = baseAtom; this.Script = script; this.Symbol = symbol; this.Kern = new SpaceAtom(null, kernUnit, 0, kern, 0); this.Over = over; }
/// <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)); } }
public void PutDelimiterOver(TexDelimeter delimiter, TexFormula superscriptFormula, TexUnit kernUnit, double kern) { var name = TexFormulaParser.DelimiterNames[(int)delimiter][(int)TexDelimeterType.Over]; this.Formula.RootAtom = new OverUnderDelimiter(this.Formula.RootAtom, superscriptFormula == null ? null : superscriptFormula.RootAtom, SymbolAtom.GetAtom(name), kernUnit, kern, true); }
public void AddSymbol(string name, TexAtomType type) { Add(new SymbolAtom(SymbolAtom.GetAtom(name), type)); }
public void AddSymbol(string name) { Add(SymbolAtom.GetAtom(name)); }
private Atom AttachScripts(TexFormula formula, string value, ref int position, Atom atom, bool skipWhiteSpace = true) { if (skipWhiteSpace) { SkipWhiteSpace(value, ref position); } if (position == value.Length) { return(atom); } // Check for prime marks. var primesRowAtom = new RowAtom(); int i = position; while (i < value.Length) { if (value[i] == primeChar) { primesRowAtom.Add(SymbolAtom.GetAtom("prime")); position++; } else if (!IsWhiteSpace(value[i])) { break; } i++; } if (primesRowAtom.Elements.Count > 0) { atom = new ScriptsAtom(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); SkipWhiteSpace(value, ref position); if (position < value.Length && value[position] == subScriptChar) { // Attach subscript also. position++; subscriptFormula = ReadScript(formula, value, ref position); } } else if (ch == subScriptChar) { // Add subscript. position++; subscriptFormula = ReadScript(formula, value, ref position); SkipWhiteSpace(value, ref position); if (position < value.Length && value[position] == superScriptChar) { // Attach superscript also. position++; superscriptFormula = ReadScript(formula, value, ref position); } } 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) { if (atom is BigOperatorAtom) { var typedAtom = (BigOperatorAtom)atom; return(new BigOperatorAtom(typedAtom.BaseAtom, subscriptAtom, superscriptAtom, typedAtom.UseVerticalLimits)); } return(new BigOperatorAtom(atom, subscriptAtom, superscriptAtom)); } else { return(new ScriptsAtom(atom, subscriptAtom, superscriptAtom)); } }
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 // Or it's a symbol. Assuming in this case it will only be a single char. if (isEnd || result.Length == 0) { 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. if (symbolAtom.Type == TexAtomType.Accent) { TexFormulaHelper helper = new TexFormulaHelper(formula); TexFormula accentFormula = ReadScript(formula, value, ref position); helper.AddAccent(accentFormula, symbolAtom.Name); } else { 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 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 DelimiterInfo(Atom body, SymbolAtom closingDelimiter) { Body = body; ClosingDelimiter = closingDelimiter; }
public void AddSymbol(string name, TexAtomType type) { this.Add(new SymbolAtom(null, SymbolAtom.GetAtom(name, null), type)); }
private void ProcessEscapeSequence( TexFormula formula, SourceSpan value, ref int position, bool allowClosingDelimiter, ref bool closedDelimiter) { 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); helper.AddAccent(accentFormula, symbolAtom.Name); } else if (symbolAtom.Type == TexAtomType.BigOperator) { var opAtom = new BigOperatorAtom(formulaSource, symbolAtom, null, null); formula.Add(this.AttachScripts(formula, value, ref position, opAtom), formulaSource); } else { formula.Add(this.AttachScripts(formula, value, ref position, symbolAtom), formulaSource); } } else if (predefinedFormulas.TryGetValue(command, out var factory)) { // Predefined formula was found. var predefinedFormula = factory(formulaSource); var atom = this.AttachScripts(formula, value, ref position, predefinedFormula.RootAtom); formula.Add(atom, formulaSource); } else if (command.Equals("nbsp")) { // Space was found. var atom = this.AttachScripts(formula, value, ref position, new SpaceAtom(formulaSource)); formula.Add(atom, formulaSource); } else if (textStyles.Contains(command)) { // Text style was found. this.SkipWhiteSpace(value, ref position); var styledFormula = Parse(ReadGroup(formula, value, ref position, leftGroupChar, rightGroupChar), command); if (styledFormula.RootAtom == null) { throw new TexParseException("Styled text can't be empty!"); } var atom = this.AttachScripts(formula, value, ref position, styledFormula.RootAtom); var source = new SourceSpan(formulaSource.Source, formulaSource.Start, position); formula.Add(atom, source); } else if (commands.Contains(command)) { // Command was found. var commandAtom = this.ProcessCommand( formula, value, ref position, command, allowClosingDelimiter, ref closedDelimiter); commandAtom = allowClosingDelimiter ? commandAtom : AttachScripts( formula, value, ref position, commandAtom); var source = new SourceSpan(formulaSource.Source, formulaSource.Start, commandAtom.Source.End); formula.Add(commandAtom, source); } else { // this.AttachScripts(formula, value, ref position, ); position = initialSrcPosition; var fallbackSpan = new SourceSpan(value.Source, start, commandSpan.End); var escapeAtom = this.AttachScripts( formula, value, ref position, new CharAtom(new SourceSpan(value.Source, position, 1), '\\'), true); // this.ConvertCharacter(formula, ref position, new SourceSpan(value.Source,position,1)); var scriptsAtom = this.AttachScripts( formula, value, ref position, this.ConvertCharacter(formula, ref position, fallbackSpan), true); // formula.Add(scriptsAtom, formulaSource ); // Escape sequence is invalid. //throw new TexParseException("Unknown symbol or command or predefined TeXFormula: '" + command + "'"); } }
public FencedAtom(Atom baseAtom, SymbolAtom leftDelimeter, SymbolAtom rightDelimeter) { this.BaseAtom = baseAtom ?? new RowAtom(); this.LeftDelimeter = leftDelimeter; this.RightDelimeter = rightDelimeter; }
public static bool TryGetAtom(string name, out SymbolAtom atom) { return(symbols.TryGetValue(name, out atom)); }
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 static IList <string> GetAllSymbols() { return(SymbolAtom.GetAllSymbols()); }
private void ProcessEscapeSequence( TexFormula formula, string value, ref int position, bool allowClosingDelimiter, ref bool closedDelimiter) { 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 // Or it's a symbol. Assuming in this case it will only be a single char. if ((isEnd && char.IsLetter(ch)) || result.Length == 0) { result.Append(ch); position++; } break; } result.Append(ch); position++; } var command = result.ToString(); SymbolAtom symbolAtom = null; TexFormula predefinedFormula = null; if (SymbolAtom.TryGetAtom(command, out symbolAtom)) { // Symbol was found. if (symbolAtom.Type == TexAtomType.Accent) { TexFormulaHelper helper = new TexFormulaHelper(formula); TexFormula accentFormula = ReadScript(formula, value, ref position); helper.AddAccent(accentFormula, symbolAtom.Name); } else if (symbolAtom.Type == TexAtomType.BigOperator) { var opAtom = new BigOperatorAtom(symbolAtom, null, null); formula.Add(AttachScripts(formula, value, ref position, opAtom)); } else { formula.Add(AttachScripts(formula, value, ref position, symbolAtom)); } } else if (predefinedFormulas.TryGetValue(command, out predefinedFormula)) { // 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), command); if (styledFormula.RootAtom == null) { throw new TexParseException("Styled text can't be empty!"); } formula.Add(AttachScripts(formula, value, ref position, styledFormula.RootAtom)); } else if (commands.Contains(command)) { // Command was found. var commandAtom = ProcessCommand( formula, value, ref position, command, allowClosingDelimiter, ref closedDelimiter); commandAtom = allowClosingDelimiter ? commandAtom : AttachScripts( formula, value, ref position, commandAtom); formula.Add(commandAtom); } else { // Escape sequence is invalid. throw new TexParseException("Unknown symbol or command or predefined TeXFormula: '" + command + "'"); } }