private bool IsFirstRecognizableCharIsRTL(string s, int i) { if (m_AssumeFirstChar != DetectionOption.Depends) { return(m_AssumeFirstChar == DetectionOption.AsRTL); } while (i < s.Length) { var c = s[i]; i++; if (c == '\\') { var f = TexFormulaParser.LookForAWord(s, ref i); if (f.Length > 1 && i < s.Length && s[i] == '[') { TexFormulaParser.ReadGroup(s, ref i, '[', ']'); } continue; } if (InternalChars.Contains(c) || IsIgnoredChar(c)) { continue; } return(IsRTLChar(c)); } return(false); }
void GetRichTag(string str, ref int i, StringBuilder dst) { if (i >= str.Length || str[i] != '<') { return; } i++; var head = TexFormulaParser.LookForAWord(str, ref i); TexFormulaParser.SkipWhiteSpace(str, ref i); var param = TexFormulaParser.ReadGroup(str, ref i, '<', '>'); dst.Append(TransparseRichTag(head, param)); dst.Append('{'); var end = str.IndexOf("</" + head + ">", i); i++; if (end < 0) { end = str.Length; } while (i < end) { var ii = i; var c = str[i++]; var n = i < str.Length ? str[i] : '\0'; if (c == '<' && char.IsLetter(n)) { var cmd = TexFormulaParser.LookForAWord(str, ref i); if (knownRichTagsHash.Contains(cmd)) { i = ii; GetRichTag(str, ref i, dst); continue; } } dst.Append(c); } if (i < str.Length) { while (str[i++] != '>') { } } dst.Append('}'); }
void TranslateLatex(string str, StringBuilder dst) { var i = 0; char n = '\0'; while (i < str.Length) { var c = str[i++]; n = i < str.Length ? str[i] : '\0'; if (c == ' ') { if (!discardSpaces) { dst.Append(c); } } else if (c == '\\') { if (TexFormulaParser.IsParserReserved(n)) { dst.Append(c); continue; } else if (char.IsLetter(n)) { var cmd = TexFormulaParser.LookForAWord(str, ref i); TexFormulaParser.SkipWhiteSpace(str, ref i); // Symbol renames if (cmd == "to") { dst.Append("\\rightarrow"); continue; } if (i >= str.Length) { dst.Append("\\" + cmd); continue; } // Lim (or other funcs) goes to over/under if even there single script if (cmd == "lim") { c = str[i]; if (c == '^' || c == '_') { dst.Append("\\" + cmd + c); } else { dst.Append("\\" + cmd); } continue; } // color but the id in braces if (cmd == "color" && (str[i] == '{')) { var arg = TexFormulaParser.ReadGroup(str, ref i, '{', '}'); if (arg.IndexOf(' ') < 0) { dst.Append("\\color[" + arg + "]"); } else { dst.Append("\\color{" + arg + "}"); } continue; } // \over... or \under.... int ou = cmd.IndexOf("over") == 0 ? 2 : (cmd.IndexOf("under") == 0 ? 1 : 0); if (ou != 0) { var second = cmd.Substring(ou == 2 ? 4 : 5); if (second == "line") { dst.Append(ou == 2 ? "\\over" : "\\under"); continue; } c = str[i]; if (c == '{') { var arg1 = "{" + TexFormulaParser.ReadGroup(str, ref i, '{', '}') + "}"; if (second == "brace") { // \overbrace or \underbrace if (i + 1 < str.Length) { c = str[i++]; n = str[i]; if ((c == '^' || c == '_') && n == '{') { // If there's script we need to think another strategy var arg2 = TexFormulaParser.ReadGroup(str, ref i, '{', '}'); var arg3 = ou == 2 ? "\\lbrace" : "\\rbrace"; if (c == '^') { dst.Append("\\nfrac{\\size[.]{" + arg2 + "}__" + arg3 + "}{" + arg1 + "}"); } else { dst.Append("\\nfrac{" + arg1 + "}{\\size[.]{" + arg2 + "}^^" + arg3 + "}"); } continue; } else { i--; } } } dst.Append(arg1); dst.Append(ou == 2 ? "^^" : "__"); dst.Append("\\" + second); continue; } } //Default behav dst.Append("\\" + cmd); } } else { dst.Append(c); } } }
// This function can be called recursively private string Parse(string original) { if (string.IsNullOrEmpty(original)) { return(original); } original = original.Replace("\r", ""); var b = new StringBuilder(); int l = 0, e = 0, i = 0; bool onRTL = IsFirstRecognizableCharIsRTL(original, 0), commonlyRTL = onRTL; while (l < original.Length) { var c = original[l]; var p = l == 0 ? '\0' : original[l - 1]; var n = l == original.Length - 1 ? '\0' : original[l + 1]; bool ignored = IsIgnoredChar(c); // If character is a new line if (c == '\n') { if (e != l) { // This means something is left behind. Lets clear-em-up Insert(b, original.Substring(e, l - e), onRTL, commonlyRTL, ref i); e = l; } b.Append('\n'); e = ++l; i = b.Length; if (l < original.Length) { onRTL = commonlyRTL = IsFirstRecognizableCharIsRTL(original, l); } } // If character is an opening brace else if (c == '{' && p != '\\' && n != '}' && n != '\0') { if (e != l) { Insert(b, original.Substring(e, l - e), onRTL, commonlyRTL, ref i); e = l; } var substring = TexFormulaParser.ReadGroup(original, ref l, '{', '}'); e = l; var parsed = "{" + Parse(substring) + "}"; Insert(b, parsed, false, commonlyRTL, ref i); } // If character is a backslash (signals a command) (absolutely specific to TEXDraw behaviour) else if (c == '\\' && p != '\\' && char.IsLetter(n)) { if (e != l) { Insert(b, original.Substring(e, l - e), onRTL, commonlyRTL, ref i); e = l; } l++; var command = TexFormulaParser.LookForAWord(original, ref l); var param1 = string.Empty; var param2 = string.Empty; if (l >= original.Length) { break; } else if (command.Contains("frac")) { param1 = "{" + Parse(TexFormulaParser.ReadGroup(original, ref l, '{', '}')) + "}"; param2 = "{" + Parse(TexFormulaParser.ReadGroup(original, ref l, '{', '}')) + "}"; } else if (command == "rtl" || command == "ltr") { if (e != (l - 4)) { Insert(b, original.Substring(e, (l - 4) - e), onRTL, commonlyRTL, ref i); } SkipWhiteSpace(original, ref l); e = l; onRTL = commonlyRTL = command == "rtl"; continue; } else if (TexFormulaParser.isCommandRegistered(command) || TEXPreference.main.GetFontIndexByID(command) >= 0) { if (original[l] == '[') { if (command == "root") { param1 = "[" + Parse(TexFormulaParser.ReadGroup(original, ref l, '[', ']')) + "]"; } else { param1 = "[" + (TexFormulaParser.ReadGroup(original, ref l, '[', ']')) + "]"; } } if (l < original.Length && original[l] != '{' || !command.Contains("hold")) { param2 = "{" + Parse(TexFormulaParser.ReadGroup(original, ref l, '{', '}')) + "}"; } } var parsed = "\\" + command + param1 + param2; Insert(b, parsed, false, commonlyRTL, ref i); e = l; } // If character is a script sign (also specific to TEXDraw behaviour) else if (c == '_' || c == '^' && p != '\\') { if (e != l) { Insert(b, original.Substring(e, l - e), onRTL, false, ref i); e = l; } var iBackup = i; while (c == '_' || c == '^') { l++; var parsed = Parse(TexFormulaParser.ReadScriptGroup(original, ref l)); Insert(b, new string(c, 1) + parsed, onRTL, false, ref i); c = l == original.Length ? '\0' : original[l]; } e = l; if (commonlyRTL) { i = iBackup; } } // If character/space is different than current RTL mode else if ((IsRTLChar(c) != onRTL && !ignored) || (ignored && l < original.Length - 1 && (onRTL ^ commonlyRTL) && ((IsRTLChar(c = original[l + 1])) != onRTL))) { Insert(b, original.Substring(e, l - e), onRTL, commonlyRTL, ref i); onRTL = IsRTLChar(c); e = l++; } else { l++; } } Insert(b, original.Substring(e), onRTL, commonlyRTL, ref i); var result = b.ToString(); b.Length = 0; return(result); }