static Dictionary <string, int> CountCommands(Dictionary <string, int> commands, List <LatexToken> command, bool mathOnly = false, bool isInMath = false) { for (int i = 0; i < command.Count; i++) { LatexToken token = command[i]; if (token.Type == LatexTokenType.Command && (isInMath || !mathOnly)) { string cmd = token.Value; if (token.Children.Count > 0 && token.Children[0].Type == LatexTokenType.CurlyBraces && token.Children[0].Children.Count > 0) { cmd += "{" + token.Children[0].Children[0].Value + "}"; } if (!commands.ContainsKey(cmd)) { commands.Add(cmd, 0); } commands[cmd]++; } if (token.Type == LatexTokenType.Math) { CountCommands(commands, token.Children, mathOnly, true); } else { CountCommands(commands, token.Children, mathOnly, isInMath); } } return(commands); }
static void FlattenBegin(List <LatexToken> input, string key) { int beginIndex = -1; int endIndex = -1; for (int i = 0; i < input.Count; i++) { LatexToken token = input[i]; if (token.Children.Count != 0 && token.Children[0].Children.Count != 0) { if (token.Type == LatexTokenType.Command && token.Value == "\\begin" && token.Children[0].Type == LatexTokenType.CurlyBraces && token.Children[0].Children[0].Value == key) { if (beginIndex != -1) { throw new ArgumentException("Found nested math env."); } beginIndex = i; } if (token.Type == LatexTokenType.Command && token.Value == "\\end" && token.Children[0].Type == LatexTokenType.CurlyBraces && token.Children[0].Children[0].Value == key) { if (beginIndex == -1) { throw new ArgumentException("Found end math at wrong level."); } endIndex = i; List <LatexToken> newChildren = input.Skip(beginIndex + 1).Take(endIndex - beginIndex - 1).ToList(); foreach (LatexToken toRemove in newChildren) { input.Remove(toRemove); } input.RemoveAt(beginIndex); input.RemoveAt(beginIndex); input.Insert(beginIndex, new LatexToken() { Type = LatexTokenType.Math, Children = newChildren }); i = beginIndex; token = input[i]; beginIndex = -1; endIndex = -1; } } if (token.Children != null) { FlattenBegin(token.Children, key); } } }
public List <LatexToken> ReadTokens(char[] terminationChars) { List <LatexToken> results = new List <LatexToken>(); while (true) { int current = this.Read(); if (current == -1) { return(results); } if (terminationChars.Contains((char)current)) { return(results); } else if (current == '\\') { if (escapeChars.Contains((char)this.Peek())) { string value = ReadPlaintext((char)current, false, true); if (results.Any() && results.Last().Type == LatexTokenType.Plaintext) { results.Last().Value += value; } else if (value != "") { results.Add(new LatexToken() { Type = LatexTokenType.Plaintext, Value = value }); } } else if (((char)this.Peek()) == '[') { results.Add(new LatexToken() { Type = LatexTokenType.SquareMathBegin }); this.Read(); } else if (((char)this.Peek()) == ']') { List <LatexToken> mathChildren; int index = results.FindIndex(x => x.Type == LatexTokenType.SquareMathBegin); if (index == -1) { throw new FormatException("Could not find square math begin at same layer."); } mathChildren = results.Skip(index + 1).ToList(); results = results.Take(index).ToList(); results.Add(new LatexToken() { Type = LatexTokenType.Math, Children = mathChildren }); this.Read(); } else { string value = ReadPlaintext((char)current, true); if (value != "") { results.Add(new LatexToken() { Type = LatexTokenType.Command, Value = value }); } } } else if (current == '$') { bool dd = false; if (((char)this.Peek()) == '$') { dd = true; this.Read(); } results.Add(new LatexToken() { Children = ReadTokens(new char[] { '$' }), Type = LatexTokenType.Math }); if (dd) { this.Read(); } } else if (current == '[' && results.Any() && results.Last().Type == LatexTokenType.Command && results.Last().Value != "\\in" && results.Last().Value != "\\to") { LatexToken newCommand = new LatexToken() { Children = ReadTokens(new char[] { ']' }), Type = LatexTokenType.SquareBraces }; results.Last().Children.Add(newCommand); } else if (current == '{') { LatexToken newCommand = new LatexToken() { Children = ReadTokens(new char[] { '}' }), Type = LatexTokenType.CurlyBraces }; if (results.Any() && results.Last().Type == LatexTokenType.Command) { results.Last().Children.Add(newCommand); } else { results.Add(newCommand); } } else if (current == '%') { ReadLine(); //results.Add(new LatexToken() { Value = ReadLine(), Type = LatexTokenType.Comment }); } else { string value = ReadPlaintext((char)current, false); if (results.Any() && results.Last().Type == LatexTokenType.Plaintext) { results.Last().Value += value; } else if (value != "") { results.Add(new LatexToken() { Type = LatexTokenType.Plaintext, Value = value }); } } } }
static Dictionary <string, List <LatexToken> > FindDefines(Dictionary <string, List <LatexToken> > defines, List <LatexToken> document) { for (int i = 0; i < document.Count; i++) { LatexToken token = document[i]; if (token.Type == LatexTokenType.Command && token.Value == "\\newcommand") { try { string command; List <LatexToken> newToken; if (i + 1 >= document.Count || document[i + 1].Value != "*") { if (token.Children.Count > 0) { command = token.Children[0].Children[0].Value; newToken = token.Children[1].Children; } else { command = document[i + 1].Value; newToken = document[i + 1].Children[0].Children; } } else { if (document[i + 2].Type == LatexTokenType.CurlyBraces) { command = document[i + 2].Children[0].Value; newToken = document[i + 3].Children; } else { command = document[i + 2].Value; newToken = document[i + 2].Children[0].Children; } } if (!defines.ContainsKey(command)) { defines.Add(command, newToken); } } catch (Exception ex) { } token.Value = "$handlednewcommand$"; } if (token.Type == LatexTokenType.Command && token.Value == "\\def") { try { if (document[i + 1].Type != LatexTokenType.Command) { throw new InvalidOperationException("Expected Def declaration"); } string command = document[i + 1].Value; var braces = document[i + 1].Children.Find(x => x.Type == LatexTokenType.CurlyBraces); if (braces == null) { throw new InvalidOperationException("Expected Def declaration"); } List <LatexToken> newToken = braces.Children; if (!defines.ContainsKey(command)) { defines.Add(command, newToken); } } catch (Exception ex) { } token.Value = "$handledef$"; } FindDefines(defines, token.Children); } return(defines); }