/// <summary> /// clears the current code /// </summary> // public void Clear() // { // WholeOutput = ""; // } /* public TexOutputParser() { parsingStack = new Stack<string>(); parseNewOutput(); } private void parseNewOutput() { parsingStack.Clear(); alreadyShowError = false; citeNotfound = false; hasProblem = false; error = ""; occurance = ""; linenr = -1; severity = Severity.WARNING; errorsFound = false; WholeOutput = ""; } */ public static ParseResult parseOutput( string WholeOutput, TexCompiler.Job job) { List<TexError> ErrorList = new List<TexError>(); ParseResult ret = new ParseResult() { Errors= ErrorList, ErrorsFound=false }; //if WholeOutput is not complete, ignore it. However, this should NEVER happen. if (!WholeOutput.Contains("Transcript written on")) { ret.ErrorsFound = true; return ret; } Stack<String> parsingStack = new Stack<string>(); bool alreadyShowError = false; bool citeNotfound = false; bool hasProblem = false; string error = ""; string occurance = ""; int linenr = -1; Severity severity = Severity.WARNING; bool errorsFound = false; WholeOutput = DebreakLines(WholeOutput); //take WholeOutput and use each line as token StringTokenizer st = new StringTokenizer(WholeOutput, Environment.NewLine); Regex LATEXERROR = new Regex("^! LaTeX Error: (.*)$"); Regex LATEXCERROR = new Regex("^(.+?\\.\\w{3}):(\\d+): (.+)$"); Regex TEXERROR = new Regex("^!\\s+(.*)$"); Regex FULLBOX = new Regex("^(?:Over|Under)full \\\\[hv]box .* at lines? (\\d+)-?-?(\\d+)?"); Regex WARNING = new Regex("^.+[Ww]arning.*: (.*)$"); Regex ATLINE = new Regex("^l\\.(\\d+)(.*)$"); Regex ATLINE2 = new Regex(".* line (\\d+).*"); Regex NOBIBFILE = new Regex("^No file .+\\.bbl\\.$"); Regex NOTOCFILE = new Regex("^No file .+\\.toc\\.$"); String line = ""; while (st.hasMoreTokens()) { line = st.nextToken(); #region Skipped /* //This is assumed to be performed before adding lines to WholeOutput by calling addLine() //Add more lines if line length is a multiple of 79 and //it does not end with ... while (!line.endsWith("...") && st.hasMoreTokens() && line.length() % MAX_LINE_LENGTH == 0) { line = line + st.nextToken(); } */ #endregion //not sure what this is good for line = line.Replace(" {2,}", " ").Trim(); Match m = LATEXCERROR.Match(line); if (m.Success) { //C-Style LaTeX error addProblemMarker(m.Groups[3].Value, m.Groups[1].Value, Convert.ToInt32(m.Groups[2]), Severity.ERROR, job, ErrorList); //Maybe parsingStack is empty... if (parsingStack.Count == 0) { //Add the file to the stack parsingStack.Push("(" + m.Groups[1]); } continue; } m = TEXERROR.Match(line); if (m.Success && line.IndexOf("warning", StringComparison.InvariantCultureIgnoreCase) == -1) { if (hasProblem) { // We have a not reported problem addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; } hasProblem = true; errorsFound = true; severity = Severity.ERROR; occurance = determineSourceFile(parsingStack); Match m2 = LATEXERROR.Match(line); if (m2.Success) { // LaTex error error = m2.Groups[1].Value; ; String part2 = st.nextToken().Trim(); if (part2 != "" && Char.IsLower(part2[0])) { error += ' ' + part2; } updateParsedFile(part2, job, parsingStack, ErrorList, ref alreadyShowError); continue; } if (line.StartsWith("! Undefined control sequence.")) { // Undefined Control Sequence error = "Undefined control sequence: "; continue; } m2 = WARNING.Match(line); if (m2.Success) severity = Severity.WARNING; error = m.Groups[1].Value; continue; } m = WARNING.Match(line); if (m.Success) { if (hasProblem) { // We have a not reported problem addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; hasProblem = false; } if (line.IndexOf("Label(s) may have changed.") > -1) { // prepare to re-run latex /*TexlipseProperties.setSessionProperty(resource.getProject(), TexlipseProperties.SESSION_LATEX_RERUN, "true");*/ GlobalUI.UI.AddStatusLine(null, "SHOULD RERUN LATEX.", true); continue; } else if (line.IndexOf("There were undefined") > -1) { if (citeNotfound) { // prepare to run bibtex /*TexlipseProperties.setSessionProperty(resource.getProject(), TexlipseProperties.SESSION_BIBTEX_RERUN, "true");*/ GlobalUI.UI.AddStatusLine(null, "SHOULD RERUN BIBTEX.", true); } continue; } // Ignore undefined references or citations because they are // found by the parser if (line.IndexOf("Warning: Reference `") > -1) continue; if (line.IndexOf("Warning: Citation `") > -1) { citeNotfound = true; continue; } severity = Severity.WARNING; occurance = determineSourceFile(parsingStack); hasProblem = true; if (line.StartsWith("LaTeX Warning: ") || line.IndexOf("pdfTeX warning") != -1) { error = m.Groups[1].Value; //Try to get the line number Match pm = ATLINE2.Match(line); if (pm.Success) { linenr = Convert.ToInt32(pm.Groups[1].Value); } String nextLine = st.nextToken().Replace(" {2,}", " "); pm = ATLINE2.Match(nextLine); if (pm.Success) { linenr = Convert.ToInt32(pm.Groups[1].Value); } updateParsedFile(nextLine, job, parsingStack, ErrorList, ref alreadyShowError); error += nextLine; if (linenr != -1) { addProblemMarker(line, occurance, linenr, severity, job, ErrorList); hasProblem = false; linenr = -1; } continue; } else { error = m.Groups[1].Value; //Try to get the line number Match pm = ATLINE2.Match(line); if (pm.Success) { linenr = Convert.ToInt32((pm.Groups[1].Value)); } continue; } } m = FULLBOX.Match(line); if (m.Success) { if (hasProblem) { // We have a not reported problem addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; hasProblem = false; } severity = Severity.WARNING; occurance = determineSourceFile(parsingStack); error = line; linenr = Convert.ToInt32(m.Groups[1].Value); addProblemMarker(line, occurance, linenr, severity, job, ErrorList); hasProblem = false; linenr = -1; continue; } m = NOBIBFILE.Match(line); if (m.Success) { // prepare to run bibtex GlobalUI.UI.AddStatusLine(null, "SHOULD RUN BIBTEX.", true); continue; } m = NOTOCFILE.Match(line); if (m.Success) { // prepare to re-run latex GlobalUI.UI.AddStatusLine(null, "SHOULD RERUN LATEX.", true); continue; } m = ATLINE.Match(line); if (hasProblem && m.Success) { linenr = Convert.ToInt32(m.Groups[1].Value); String part2 = st.nextToken(); int index = line.IndexOf(' '); if (index > -1) { error += " " + line.Substring(index).Trim() + " (followed by: " + part2.Trim() + ")"; addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; hasProblem = false; continue; } } m = ATLINE2.Match(line); if (hasProblem && m.Success) { linenr = Convert.ToInt32(m.Groups[1].Value); addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; hasProblem = false; continue; } updateParsedFile(line, job, parsingStack, ErrorList, ref alreadyShowError); } if (hasProblem) { // We have a not reported problem // do not add "==> Fatal error blabla " to error list (is not an error) //addProblemMarker(error, occurance, linenr, severity); //hasProblem = false; } ret.ErrorsFound = errorsFound; return ret; }
/// <summary> /// clears the current code /// </summary> // public void Clear() // { // WholeOutput = ""; // } /* public TexOutputParser() * { * parsingStack = new Stack<string>(); * parseNewOutput(); * } * private void parseNewOutput() * { * parsingStack.Clear(); * alreadyShowError = false; * citeNotfound = false; * hasProblem = false; * error = ""; * occurance = ""; * linenr = -1; * severity = Severity.WARNING; * errorsFound = false; * WholeOutput = ""; * } */ public static ParseResult parseOutput(string WholeOutput, TexCompiler.Job job) { List <TexError> ErrorList = new List <TexError>(); ParseResult ret = new ParseResult() { Errors = ErrorList, ErrorsFound = false }; //if WholeOutput is not complete, ignore it. However, this should NEVER happen. if (!WholeOutput.Contains("Transcript written on")) { ret.ErrorsFound = true; return(ret); } Stack <String> parsingStack = new Stack <string>(); bool alreadyShowError = false; bool citeNotfound = false; bool hasProblem = false; string error = ""; string occurance = ""; int linenr = -1; Severity severity = Severity.WARNING; bool errorsFound = false; WholeOutput = DebreakLines(WholeOutput); //take WholeOutput and use each line as token StringTokenizer st = new StringTokenizer(WholeOutput, Environment.NewLine); Regex LATEXERROR = new Regex("^! LaTeX Error: (.*)$"); Regex LATEXCERROR = new Regex("^(.+?\\.\\w{3}):(\\d+): (.+)$"); Regex TEXERROR = new Regex("^!\\s+(.*)$"); Regex FULLBOX = new Regex("^(?:Over|Under)full \\\\[hv]box .* at lines? (\\d+)-?-?(\\d+)?"); Regex WARNING = new Regex("^.+[Ww]arning.*: (.*)$"); Regex ATLINE = new Regex("^l\\.(\\d+)(.*)$"); Regex ATLINE2 = new Regex(".* line (\\d+).*"); Regex NOBIBFILE = new Regex("^No file .+\\.bbl\\.$"); Regex NOTOCFILE = new Regex("^No file .+\\.toc\\.$"); String line = ""; while (st.hasMoreTokens()) { line = st.nextToken(); #region Skipped /* //This is assumed to be performed before adding lines to WholeOutput by calling addLine() * //Add more lines if line length is a multiple of 79 and * //it does not end with ... * while (!line.endsWith("...") && st.hasMoreTokens() * && line.length() % MAX_LINE_LENGTH == 0) * { * line = line + st.nextToken(); * } */ #endregion //not sure what this is good for line = line.Replace(" {2,}", " ").Trim(); Match m = LATEXCERROR.Match(line); if (m.Success) { //C-Style LaTeX error addProblemMarker(m.Groups[3].Value, m.Groups[1].Value, Convert.ToInt32(m.Groups[2]), Severity.ERROR, job, ErrorList); //Maybe parsingStack is empty... if (parsingStack.Count == 0) { //Add the file to the stack parsingStack.Push("(" + m.Groups[1]); } continue; } m = TEXERROR.Match(line); if (m.Success && line.IndexOf("warning", StringComparison.InvariantCultureIgnoreCase) == -1) { if (hasProblem) { // We have a not reported problem addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; } hasProblem = true; errorsFound = true; severity = Severity.ERROR; occurance = determineSourceFile(parsingStack); Match m2 = LATEXERROR.Match(line); if (m2.Success) { // LaTex error error = m2.Groups[1].Value;; String part2 = st.nextToken().Trim(); if (part2 != "" && Char.IsLower(part2[0])) { error += ' ' + part2; } updateParsedFile(part2, job, parsingStack, ErrorList, ref alreadyShowError); continue; } if (line.StartsWith("! Undefined control sequence.")) { // Undefined Control Sequence error = "Undefined control sequence: "; continue; } m2 = WARNING.Match(line); if (m2.Success) { severity = Severity.WARNING; } error = m.Groups[1].Value; continue; } m = WARNING.Match(line); if (m.Success) { if (hasProblem) { // We have a not reported problem addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; hasProblem = false; } if (line.IndexOf("Label(s) may have changed.") > -1) { // prepare to re-run latex /*TexlipseProperties.setSessionProperty(resource.getProject(), * TexlipseProperties.SESSION_LATEX_RERUN, "true");*/ GlobalUI.UI.AddStatusLine(null, "SHOULD RERUN LATEX.", true); continue; } else if (line.IndexOf("There were undefined") > -1) { if (citeNotfound) { // prepare to run bibtex /*TexlipseProperties.setSessionProperty(resource.getProject(), * TexlipseProperties.SESSION_BIBTEX_RERUN, "true");*/ GlobalUI.UI.AddStatusLine(null, "SHOULD RERUN BIBTEX.", true); } continue; } // Ignore undefined references or citations because they are // found by the parser if (line.IndexOf("Warning: Reference `") > -1) { continue; } if (line.IndexOf("Warning: Citation `") > -1) { citeNotfound = true; continue; } severity = Severity.WARNING; occurance = determineSourceFile(parsingStack); hasProblem = true; if (line.StartsWith("LaTeX Warning: ") || line.IndexOf("pdfTeX warning") != -1) { error = m.Groups[1].Value; //Try to get the line number Match pm = ATLINE2.Match(line); if (pm.Success) { linenr = Convert.ToInt32(pm.Groups[1].Value); } String nextLine = st.nextToken().Replace(" {2,}", " "); pm = ATLINE2.Match(nextLine); if (pm.Success) { linenr = Convert.ToInt32(pm.Groups[1].Value); } updateParsedFile(nextLine, job, parsingStack, ErrorList, ref alreadyShowError); error += nextLine; if (linenr != -1) { addProblemMarker(line, occurance, linenr, severity, job, ErrorList); hasProblem = false; linenr = -1; } continue; } else { error = m.Groups[1].Value; //Try to get the line number Match pm = ATLINE2.Match(line); if (pm.Success) { linenr = Convert.ToInt32((pm.Groups[1].Value)); } continue; } } m = FULLBOX.Match(line); if (m.Success) { if (hasProblem) { // We have a not reported problem addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; hasProblem = false; } severity = Severity.WARNING; occurance = determineSourceFile(parsingStack); error = line; linenr = Convert.ToInt32(m.Groups[1].Value); addProblemMarker(line, occurance, linenr, severity, job, ErrorList); hasProblem = false; linenr = -1; continue; } m = NOBIBFILE.Match(line); if (m.Success) { // prepare to run bibtex GlobalUI.UI.AddStatusLine(null, "SHOULD RUN BIBTEX.", true); continue; } m = NOTOCFILE.Match(line); if (m.Success) { // prepare to re-run latex GlobalUI.UI.AddStatusLine(null, "SHOULD RERUN LATEX.", true); continue; } m = ATLINE.Match(line); if (hasProblem && m.Success) { linenr = Convert.ToInt32(m.Groups[1].Value); String part2 = st.nextToken(); int index = line.IndexOf(' '); if (index > -1) { error += " " + line.Substring(index).Trim() + " (followed by: " + part2.Trim() + ")"; addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; hasProblem = false; continue; } } m = ATLINE2.Match(line); if (hasProblem && m.Success) { linenr = Convert.ToInt32(m.Groups[1].Value); addProblemMarker(error, occurance, linenr, severity, job, ErrorList); linenr = -1; hasProblem = false; continue; } updateParsedFile(line, job, parsingStack, ErrorList, ref alreadyShowError); } if (hasProblem) { // We have a not reported problem // do not add "==> Fatal error blabla " to error list (is not an error) //addProblemMarker(error, occurance, linenr, severity); //hasProblem = false; } ret.ErrorsFound = errorsFound; return(ret); }