private Atom Meta(TexFormula formula, string value, ref int position) { var metaRule = formula.AttachedMetaRenderer; if (metaRule == null) { metaRule = formula.AttachedMetaRenderer = ObjPool <TexMetaRenderer> .Get(); } else { metaRule.Reset(); } metaRule.ParseString(ReadInsideBracket(value, ref position)); // because \meta[font=xxx] must done at parsing metaRule.ApplyBeforeParsing(); return(null); }
private TexFormula ReadScript(TexFormula formula, string value, ref int position) { SkipWhiteSpace(value, ref position); if (position == value.Length) { // abort return(Parse(string.Empty)); } var ch = value[position]; if (ch == leftGroupChar) { return(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar))); } else { return(Parse(ReadScriptGroup(value, ref position))); } }
private Atom ProcessCommand(TexFormula formula, string value, ref int position, string command) { SkipWhiteSpace(value, ref position); if (position == value.Length) { return(null); } switch (command) { case "meta": // Command is meta var metaRule = formula.AttachedMetaRenderer; if (metaRule == null) { metaRule = formula.AttachedMetaRenderer = ObjPool <TexMetaRenderer> .Get(); } else { metaRule.Reset(); } string metaPar = null; if (value[position] == leftBracketChar) { metaPar = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); metaRule.ParseString(metaPar); } return(null); case "root": case "sqrt": // Command is radical. TexFormula degreeFormula = null; if (value[position] == leftBracketChar) { degreeFormula = Parse(ReadGroup(value, ref position, leftBracketChar, rightBracketChar)); SkipWhiteSpace(value, ref position); } return(Radical.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, degreeFormula == null ? null : degreeFormula.GetRoot)); case "vmatrix": case "matrix": //Command is Matrix MatrixAtom matrixAtom = MatrixAtom.Get(); List <List <Atom> > childs = matrixAtom.Elements; Atom parsedChild = (Parse(ReadGroup( value, ref position, leftGroupChar, rightGroupChar)).GetRoot); childs.Add(ListPool <Atom> .Get()); if (parsedChild == null) { MatrixAtom.Last(childs).Add(SpaceAtom.Get()); } if (parsedChild is RowAtom) { List <Atom> el = ((RowAtom)parsedChild).Elements; if (command == "matrix") { MatrixAtom.ParseMatrix(el, childs); } else { MatrixAtom.ParseMatrixVertical(el, childs); } el.Clear(); ObjPool <RowAtom> .Release((RowAtom)parsedChild); } else { MatrixAtom.Last(childs).Add(parsedChild); } matrixAtom.Elements = childs; return(matrixAtom); case "math": case "text": var idx = TexUtility.RawRenderFont < 0 ? TEXConfiguration.main.Typeface_Text : -2; var style = TexUtility.RenderFontStyle; if (value[position] == leftBracketChar) { var str = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); if (!int.TryParse(str, out idx)) { idx = TexUtility.RawRenderFont < 0 ? TEXConfiguration.main.Typeface_Text : -2; style = ParseFontStyle(str); } SkipWhiteSpace(value, ref position); } else if (command == "math") { idx = -1; } var oldType = TexUtility.RenderFont; var oldStyle = TexUtility.RenderFontStyle; TexUtility.RenderFont = idx; TexUtility.RenderFontStyle = style; var parsed = Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot; TexUtility.RenderFont = oldType; TexUtility.RenderFontStyle = oldStyle; return(parsed); case "clr": case "mclr": case "color": // Command is color string clr = null; if (value[position] == leftBracketChar) { clr = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } if (position == value.Length) { return(null); } AttrColorAtom endColor; var startColor = AttrColorAtom.Get(clr, command == "color" ? 1 : (command == "clr" ? 0 : 2), out endColor); return(InsertAttribute(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot, startColor, endColor)); case "bg": case "vbg": if (value[position] == leftBracketChar) { clr = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } else { clr = null; } return(AttrBgAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, clr, command == "bg")); case "size": // Command is size string sz = null; if (value[position] == leftBracketChar) { sz = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } if (position == value.Length) { return(null); } return(AttrSizeAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, sz)); case "link": case "ulink": // Command is Link string meta = null; if (value[position] == leftBracketChar) { meta = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } if (position == value.Length) { return(null); } string groupBrack = ReadGroup(value, ref position, leftGroupChar, rightGroupChar); if (meta == null) { meta = groupBrack; } return(AttrLinkAtom.Get(Parse(groupBrack).GetRoot, meta, command == "ulink")); case "under": command = "anot"; break; case "over": command = "bnot"; break; } if (command.Length > 2 && command.Substring(command.Length - 3) == "not") { int NotMode = 0; bool UseMargin = true; string prefix = command.Substring(0, command.Length - 3); if (prefix.Length > 0) { switch (prefix[0]) { case 'n': NotMode = 1; break; case 'h': NotMode = 2; break; case 'd': NotMode = 3; break; case 'u': NotMode = 4; break; case 'o': NotMode = 5; break; case 'v': if (prefix.Length > 1 && prefix[1] == 'n') { NotMode = 7; } else { NotMode = 6; } break; case 'a': NotMode = 4; UseMargin = false; break; case 'b': NotMode = 5; UseMargin = false; break; } } if (position == value.Length) { return(null); } string sz = null; if (value[position] == leftBracketChar) { sz = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } return(NegateAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, NotMode, sz, UseMargin)); } if (command.Length > 2 && command.Substring(command.Length - 3) == "trs") { int PivotMode = 0; string prefix = command.Substring(0, command.Length - 3); if (prefix.Length > 0) { switch (prefix[0]) { case 'm': PivotMode = 1; break; case 'l': PivotMode = 2; break; } } if (position == value.Length) { return(null); } string trs = null; if (value[position] == leftBracketChar) { trs = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); SkipWhiteSpace(value, ref position); } AttrTransformationAtom endTRS; var startTRS = AttrTransformationAtom.Get(trs, PivotMode, out endTRS); return(InsertAttribute(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot, startTRS, endTRS)); } if (command.Length > 3 && command.Substring(command.Length - 4) == "frac") { int FracAlignT = 0, FracAlignB = 0; bool FracAlignN = true; string prefix = command.Substring(0, command.Length - 4); if (prefix.Length > 0) { if (prefix[0] == 'n') { FracAlignN = false; prefix = prefix.Substring(1); } if (prefix.Length == 1) { FracAlignT = fracP(prefix[0]); FracAlignB = FracAlignT; } else if (prefix.Length == 2) { FracAlignT = fracP(prefix[0]); FracAlignB = fracP(prefix[1]); } } if (position == value.Length) { return(null); } Atom numeratorFormula = null, denominatorFormula = null; numeratorFormula = Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot; SkipWhiteSpace(value, ref position); if (position != value.Length) { denominatorFormula = Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)).GetRoot; } return(FractionAtom.Get(numeratorFormula, denominatorFormula, FracAlignN, (TexAlignment)FracAlignT, (TexAlignment)FracAlignB)); } if (command.Length > 3 && command.Substring(command.Length - 4) == "hold") { TexAlignment align = TexAlignment.Center; bool isVertical = false; string prefix = command.Substring(0, command.Length - 3); if (prefix.Length > 0) { switch (prefix[0]) { case 'v': isVertical = true; break; case 'l': align = TexAlignment.Left; break; case 'r': align = TexAlignment.Right; break; case 'b': align = TexAlignment.Bottom; goto case 'v'; case 't': align = TexAlignment.Top; goto case 'v'; } } Vector2 sz = Vector2.zero; if (position < value.Length && value[position] == leftBracketChar) { var frag = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); int idx = frag.IndexOf(','); if (idx >= 0) { var fragL = frag.Substring(0, idx); var fragR = frag.Substring(idx + 1); float.TryParse(fragL, out sz.x); float.TryParse(fragR, out sz.y); } else { if (isVertical) { float.TryParse(frag, out sz.y); } else { float.TryParse(frag, out sz.x); } } SkipWhiteSpace(value, ref position); } if (position < value.Length && value[position] == leftGroupChar) { return(HolderAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .GetRoot, sz.x, sz.y, align)); } else { return(HolderAtom.Get(null, sz.x, sz.y, align)); } } if (command.Length > 4 && command.Substring(command.Length - 5) == "table") { bool vertical = false; int align = 1 + 8 + 64; string prefix = command.Substring(0, command.Length - 5); if (prefix.Length > 0) { if (prefix[0] == 'v') { vertical = true; prefix = prefix.Substring(1); } if (prefix.Length == 1) { var pref = fracP(prefix[0]); align = Math.Max(1, pref * 2) + Math.Max(8, pref * 16) + Math.Max(64, pref * 128); } else if (prefix.Length == 3) { var pref0 = fracP(prefix[0]); var pref1 = fracP(prefix[1]); var pref2 = fracP(prefix[2]); align = Math.Max(1, pref0 * 2) + Math.Max(8, pref1 * 16) + Math.Max(64, pref2 * 128); } } int lineStyleH = 0, lineStyleV = 0; if (value[position] == leftBracketChar) { string lineOpt; int lineP = 0; lineOpt = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); for (int i = 0; i < lineOpt.Length; i++) { if (!int.TryParse(lineOpt[i].ToString(), out lineP)) { continue; } if (i >= 6) { break; } switch (i) { case 0: lineStyleH += lineP >= 2 ? 17 : lineP; break; case 1: lineStyleH += lineP >= 2 ? 10 : (lineP == 1 ? 2 : 0); break; case 2: lineStyleH += lineP >= 1 ? 4 : 0; break; case 3: lineStyleV += lineP >= 2 ? 17 : lineP; break; case 4: lineStyleV += lineP >= 2 ? 10 : (lineP == 1 ? 2 : 0); break; case 5: lineStyleV += lineP >= 1 ? 4 : 0; break; } } SkipWhiteSpace(value, ref position); } else { lineStyleH = 7; lineStyleV = 7; } List <List <Atom> > childs = new List <List <Atom> >(); MatrixAtom matrixAtom = ObjPool <MatrixAtom> .Get(); matrixAtom.horizontalAlign = align; matrixAtom.horizontalLine = lineStyleH; matrixAtom.verticalLine = lineStyleV; Atom parsedChild = (Parse(ReadGroup( value, ref position, leftGroupChar, rightGroupChar)).GetRoot); childs.Add(ListPool <Atom> .Get()); if (parsedChild == null) { MatrixAtom.Last(childs).Add(SpaceAtom.Get()); } if (parsedChild is RowAtom) { List <Atom> el = ((RowAtom)parsedChild).Elements; if (!vertical) { MatrixAtom.ParseMatrix(el, childs); } else { MatrixAtom.ParseMatrixVertical(el, childs); } el.Clear(); ObjPool <RowAtom> .Release((RowAtom)parsedChild); } else { MatrixAtom.Last(childs).Add(parsedChild); } matrixAtom.Elements = childs; return(matrixAtom); } throw new TexParseException("Invalid command."); }
private Atom AttachScripts(TexFormula formula, string value, ref int position, Atom atom) { if (position == value.Length) { return(atom); } if (value[position] == superScriptChar || value[position] == subScriptChar) { if (position == value.Length - 1) { position++; return(atom); } } else { return(atom); } TexFormula superscriptFormula = null; TexFormula subscriptFormula = null; //0: Undetermined; 1: Not Yet; 2: Yes, we are; 3: Yes, and make it smaller int markAsBig = 0; //0: In Beginning;1: We are in _;2: we are in ^ int lastIsSuper = 0; while (position < value.Length) { var ch = value[position]; if (ch == superScriptChar || ch == subScriptChar) { if (++position < value.Length && (value[position] == ch)) { markAsBig = 2; if (++position < value.Length && (value[position] == ch)) { markAsBig = 3; position++; } } bool v = ch == superScriptChar; if ((v ? superscriptFormula : subscriptFormula) == null) { lastIsSuper = v ? 2 : 1; } continue; } else if (ch == rightGroupChar || (value[position - 1] != '^' && value[position - 1] != '_')) { break; } if (lastIsSuper == 2) { if (superscriptFormula == null) { superscriptFormula = ReadScript(formula, value, ref position); } else { position--; superscriptFormula.RootAtom = AttachScripts(formula, value, ref position, superscriptFormula.RootAtom); } } else if (lastIsSuper == 1) { if (subscriptFormula == null) { subscriptFormula = ReadScript(formula, value, ref position); } else { position--; subscriptFormula.RootAtom = AttachScripts(formula, value, ref position, subscriptFormula.RootAtom); } } else { break; } } if (superscriptFormula == null && subscriptFormula == null) { return(atom); } // Check whether to return Big Operator or Scripts. if (atom != null && (atom.RightType == CharType.BigOperator || markAsBig >= 2)) { return(BigOperatorAtom.Get(atom, subscriptFormula == null ? null : subscriptFormula.ExtractRoot(), superscriptFormula == null ? null : superscriptFormula.ExtractRoot(), markAsBig == 3)); } else { return(ScriptsAtom.Get(atom, subscriptFormula == null ? null : subscriptFormula.ExtractRoot(), superscriptFormula == null ? null : superscriptFormula.ExtractRoot())); } }
private Atom ProcessCommand(TexFormula formula, string value, ref int position, string command) { SkipWhiteSpace(value, ref position); if (position == value.Length) { return(null); } switch (command) { case "meta": return(Meta(formula, value, ref position)); case "root": case "sqrt": return(Root(formula, value, ref position)); case "vmatrix": case "matrix": return(Matrix(value, ref position, command == "vmatrix")); case "style": case "math": case "text": var idx = command == "text" ? TEXConfiguration.main.Typeface_Text : (command == "math" ? -1 : -2); var style = ParseStyle(value, ref position); return(ParseFontStyle(value, ref position, idx, style)); case "clr": case "mclr": case "color": return(Color(value, ref position, command == "color" ? 1 : (command == "clr" ? 0 : 2))); case "bg": case "vbg": return(BgColor(value, ref position, command == "bg")); case "size": return(Size(value, ref position)); case "link": case "ulink": return(Link(value, ref position, command == "ulink")); case "trs": case "mtrs": case "ltrs": return(TRS(value, ref position, command == "trs" ? 0 : (command == "mtrs" ? 1 : 2))); case "under": case "over": return(Not(value, ref position, command == "under" ? 4 : 5, false)); case "border": case "vborder": return(Border(value, ref position, command == "border")); } if (NotFamily.Contains(command)) { return(Not(value, ref position, ParseNotMode(command[0], command[1]), true)); } if (FracFamily.Contains(command)) { int FracAlignT = 0, FracAlignB = 0; bool FracAlignN = true; string prefix = command.Substring(0, command.Length - 4); if (prefix.Length > 0) { if (prefix[0] == 'n') { FracAlignN = false; prefix = prefix.Substring(1); } if (prefix.Length == 1) { FracAlignT = fracP(prefix[0]); FracAlignB = FracAlignT; } else if (prefix.Length == 2) { FracAlignT = fracP(prefix[0]); FracAlignB = fracP(prefix[1]); } } return(Frac(value, ref position, FracAlignN, (TexAlignment)FracAlignT, (TexAlignment)FracAlignB)); } if (HoldFamily.Contains(command)) { TexAlignment align = TexAlignment.Center; bool vertical = false; holdP(command.Substring(0, command.Length - 3), ref vertical, ref align); string size = ReadInsideBracket(value, ref position); if (position < value.Length && value[position] == leftGroupChar) { return(HolderAtom.Get(Parse(ReadGroup(value, ref position, leftGroupChar, rightGroupChar)) .ExtractRoot(), size, vertical, align)); } else { return(HolderAtom.Get(null, size, vertical, align)); } } if (TableFamily.Contains(command)) { bool vertical = false; int align = 1 + 8 + 64; string prefix = command.Substring(0, command.Length - 5); if (prefix.Length > 0) { if (prefix[0] == 'v') { vertical = true; prefix = prefix.Substring(1); } if (prefix.Length == 1) { var pref = fracP(prefix[0]); align = Math.Max(1, pref * 2) + Math.Max(8, pref * 16) + Math.Max(64, pref * 128); } else if (prefix.Length == 3) { var pref0 = fracP(prefix[0]); var pref1 = fracP(prefix[1]); var pref2 = fracP(prefix[2]); align = Math.Max(1, pref0 * 2) + Math.Max(8, pref1 * 16) + Math.Max(64, pref2 * 128); } } int lineStyleH = 0, lineStyleV = 0; if (value[position] == leftBracketChar) { string lineOpt; int lineP = 0; lineOpt = ReadGroup(value, ref position, leftBracketChar, rightBracketChar); for (int i = 0; i < lineOpt.Length; i++) { if (!int.TryParse(lineOpt[i].ToString(), out lineP)) { continue; } if (i >= 6) { break; } switch (i) { case 0: lineStyleH += lineP >= 2 ? 17 : lineP; break; case 1: lineStyleH += lineP >= 2 ? 10 : (lineP == 1 ? 2 : 0); break; case 2: lineStyleH += lineP >= 1 ? 4 : 0; break; case 3: lineStyleV += lineP >= 2 ? 17 : lineP; break; case 4: lineStyleV += lineP >= 2 ? 10 : (lineP == 1 ? 2 : 0); break; case 5: lineStyleV += lineP >= 1 ? 4 : 0; break; } } SkipWhiteSpace(value, ref position); } else { lineStyleH = 7; lineStyleV = 7; } return(Table(value, ref position, align, lineStyleH, lineStyleV, vertical)); } throw new TexParseException("Invalid command."); }
private void ProcessEscapeSequence(TexFormula formula, string value, ref int position) { position++; var command = LookForAWord(value, ref position); // Check if there's no command if (command.Length == 0) { if (position < value.Length) { var nextChar = value[position]; if (IsParserReserved(nextChar)) { formula.Add(ConvertCharacter(value, ref position, nextChar)); } } return; } //Check if the command registered in Commands if (isCommandRegistered(command)) { formula.Add(AttachScripts(formula, value, ref position, ProcessCommand(formula, value, ref position, command))); return; } //Check if the command registered in FontID var fontID = TEXPreference.main.GetFontIndexByID(command); if (fontID != -1) { SkipWhiteSpace(value, ref position); formula.Add(ParseFontStyle(value, ref position, fontID, ParseFontStyle(ReadInsideBracket(value, ref position)))); return; } SymbolAtom symbolAtom = SymbolAtom.GetAtom(command); //Check if the command registered in Symbol database if (symbolAtom != null) { // Symbol was found. if (symbolAtom.RightType == CharType.Accent && formula.RootAtom != null) { //Accent is Found Atom baseAtom = formula.RootAtom; if (baseAtom is RowAtom) { var row = (RowAtom)baseAtom; baseAtom = MatrixAtom.Last(row.Elements); row.Elements.RemoveAt(row.Elements.Count - 1); } else { formula.RootAtom = null; } formula.Add(AttachScripts(formula, value, ref position, AccentedAtom.Get(baseAtom, symbolAtom))); } else { formula.Add(AttachScripts(formula, value, ref position, symbolAtom)); } return; } //No lucks, now ... { // Command aren't defined, use it as command text style RowAtom row = RowAtom.Get(); for (int i = 0; i < command.Length; i++) { var charAtom = CharAtom.Get(command[i], TEXConfiguration.main.Typeface_Commands); row.Add(charAtom); } formula.Add(AttachScripts(formula, value, ref position, row)); } }