/** * Updates the stack that determines which file we are currently * parsing, so that errors can be annotated in the correct file. * * @param logLine A line from latex' output containing which file we are in */ private static void updateParsedFile(String logLine, TexCompiler.Job job, Stack <string> parsingStack, List <TexError> ErrorList, ref bool alreadyShowError) { if (logLine.IndexOf('(') == -1 && logLine.IndexOf(')') == -1) { return; } for (int i = 0; i < logLine.Length; i++) { if (logLine[i] == '(') { int j; for (j = i + 1; j < logLine.Length && isAllowedinName(logLine[j]); j++) { ; } parsingStack.Push(logLine.Substring(i, j - i).Trim()); i = j - 1; } else if (logLine[i] == ')' && !(parsingStack.Count == 0)) { parsingStack.Pop(); } else if (logLine[i] == ')' && !alreadyShowError) { alreadyShowError = true; // There was a parsing error, this is very rare string err = "Error while parsing the LaTeX output. " + "Please consult the console output"; GlobalUI.UI.AddStatusLine(null, err, true); addProblemMarker(err, "file", 0, Severity.ERROR, job, ErrorList); } } }
public void TestSetup() { tc = new TexCompiler(); tc.JobDone += (s, e) => { LastReceivedJob = e.job; LastReceivedEA = e; JobFailed_Reported = e.ExitCode != 0; }; LastReceivedJob = null; LastReceivedEA = null; JobFailed_Reported = false; }
public void AddJobTest_BBreadout() { // Check that the bounding box is read out and is approximately correct LastReceivedJob = null; tc.AddJobExclusive(NonStandAloneCode, null, true, 111); tc.AddJobExclusive(NonStandAloneCode, null, true, 111); Assert.AreNotEqual(LastReceivedJob, null); Assert.AreEqual(LastReceivedJob.DocumentID, 111); Assert.That(LastReceivedJob.BB.Width, Is.EqualTo(3).Within(0.5)); Assert.That(LastReceivedJob.BB.Height, Is.EqualTo(3).Within(0.5)); }
public void LocksUpOnPdfInUseTest() { // lock the pdf, and check that still the compiler returns, and not produces deadlock LastReceivedJob = null; // compile, now pdf should be in place tc.AddJobExclusive(NonStandAloneCode, "temp3.tex", true, 113); // lock the pdf and recompile using (FileStream fs = new FileStream("temp3.pdf", FileMode.OpenOrCreate)) { // tc.timeout = 6000; tc.AddJobExclusive(NonStandAloneCode, "temp3.tex", true, 113); } Assert.AreNotEqual(LastReceivedJob, null); Assert.AreEqual(LastReceivedJob.DocumentID, 113); Assert.IsTrue(LastReceivedEA.OutputParseResult.Errors.Count() > 0); Assert.IsTrue(JobFailed_Reported); }
public void TestSetup() { job = new TexCompiler.Job() { path = @"C:\Users\thomas\AppData\Local\Temp\mydummyfile.tex" }; }
public void AddJobTest_BBreadout() { // Check that the bounding box is read out and is approximately correct LastReceivedJob = null; tc.AddJobExclusive(NonStandAloneCode, null, true, 111); tc.AddJobExclusive(NonStandAloneCode, null, true, 111); Assert.AreNotEqual(LastReceivedJob, null); Assert.AreEqual(LastReceivedJob.DocumentID, 111); Assert.IsTrue( Math.Abs( LastReceivedJob.BB.Width -3) < .5); Assert.IsTrue( Math.Abs( LastReceivedJob.BB.Height - 3) < .5); }
/// <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> /// Private function that is called for each found problem in output of pdflatex when /// calling parseOutput(). addProblemMarker() fits the arguments into addProblemEventArgs /// so that addProblemEventHandler addProblem can be triggered. /// </summary> private static void addProblemMarker(String error, String causingSourceFile, int linenr, Severity severity, TexCompiler.Job job, List <TexError> AddToThisList) { // if (OnTexError != null) // { TexError e = new TexError(); e.error = error; e.causingSourceFile = causingSourceFile; e.Line = linenr; if (job != null) { if (e.causingSourceFile == null) { e.inincludefile = true; } else { e.inincludefile = (String.Compare(e.causingSourceFile.Trim().Replace('/', '\\'), System.IO.Path.GetFullPath(job.path), true) != 0); } if (!e.inincludefile && linenr > 0) { e.Line = job.TempFileLineToEditorLine(e.Line); } if (!e.inincludefile && e.causingSourceFile != null) { // trim preview file ending. e.causingSourceFile = e.causingSourceFile.Trim(); if (e.causingSourceFile.EndsWith(Consts.PreviewFilename + Consts.PreviewFilenameExt)) { e.causingSourceFile = e.SourceFileName.Substring(0, (e.SourceFileName.Length - Consts.PreviewFilename.Length - Consts.PreviewFilenameExt.Length)); } } } e.Pos = -1; e.severity = severity; AddToThisList.Add(e); // OnTexError(this, e, job); // } }
/// <summary> /// Private function that is called for each found problem in output of pdflatex when /// calling parseOutput(). addProblemMarker() fits the arguments into addProblemEventArgs /// so that addProblemEventHandler addProblem can be triggered. /// </summary> private void addProblemMarker(String error, String causingSourceFile, int linenr, Severity severity, TexCompiler.Job job) { if (OnTexError != null) { TexError e = new TexError(); e.error = error; e.causingSourceFile = causingSourceFile; e.linenr = linenr; if (job != null) { if (e.causingSourceFile == null) { e.inincludefile = true; } else { e.inincludefile = (String.Compare(e.causingSourceFile.Trim(), System.IO.Path.GetFullPath(job.path), true) != 0); } if (!e.inincludefile && linenr > 0) { e.linenr = job.TempFileLineToEditorLine(e.linenr); } if (!e.inincludefile) { //trim preview file ending. e.causingSourceFile = e.SourceFileName.Substring(0, (e.SourceFileName.Length - Helper.GetPreviewFilename().Length - Helper.GetPreviewFilenameExt().Length)); } } e.pos = -1; e.severity = severity; OnTexError(this, e, job); } }