// nlatexdb Version 0.03 // Database Access in LaTeX // Copyright (C) 2011 Robin Höns, Integranova GmbH // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // For more information see the web page http://hoens.net/robin using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace nlatexdb { class CommandParser { public delegate void ExecCommand(List> pars); public CommandParser(string commandname, int nbbraces, bool lastbraceislatex, ExecCommand cmd) { m_commandsearch = String.Concat("\\", commandname, "{"); m_nbbraces = nbbraces; m_lastbraceislatex = lastbraceislatex; m_cmd = cmd; } public int FirstIndexIn(string line, int commentbegin) { if (commentbegin >= 0) { return line.IndexOf(m_commandsearch, 0, commentbegin); } return line.IndexOf(m_commandsearch); } public int StartProcess(string line, int foundindex) { int myindex = foundindex + m_commandsearch.Length; m_bracedepth = 1; m_bracescompleted = 0; m_pars = new List>(); m_pars.Add(new List()); return FindBraces(line, myindex); } public int ProcessLine(string line) { return FindBraces(line, 0); } private int FindBraces(string line, int startindex) { int i = startindex; StringBuilder sb = new StringBuilder(); bool backslash = false; while (i < line.Length) { if (backslash) { backslash = false; } else if (line[i] == '\\') { backslash = true; } else if (line[i] == '%') { // Ein Kommentarzeichen. Der Rest der Zeile wird ignoriert, wenn wir in Latex sind if (m_lastbraceislatex && (m_bracescompleted == m_nbbraces - 1)) { sb.Append(line.Substring(i)); i = line.Length; break; } } else if (line[i] == '{') { m_bracedepth++; } else if (line[i] == '}') { m_bracedepth--; if (m_bracedepth == 0) { m_pars[m_bracescompleted].Add(sb.ToString()); m_bracescompleted++; if (m_bracescompleted == m_nbbraces) { // Alles fertig geparst. Rufe Kommando auf m_cmd(m_pars); // return Index nach Befehl i++; return i; } else { // nächstes Klammerpaar. Hier MUSS jetzt wieder eine Klammer aufgehen! i++; if (line[i] != '{') { throw new ParseErrorException("Expecting '{' directly after '}'", line, i); } m_pars.Add(new List()); m_bracedepth = 1; sb = new StringBuilder(); // Die { nicht zu sb hinzufügen, deshalb continue i++; continue; } } } sb.Append(line[i]); i++; } m_pars[m_bracescompleted].Add(sb.ToString()); return -1; // Command still active } private string m_commandsearch; private int m_nbbraces; private int m_bracedepth; private int m_bracescompleted; private bool m_lastbraceislatex; private List> m_pars; private ExecCommand m_cmd; } }