X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeX.cpp;h=cfa6e1d3f96d7daf691f4da19425c140b47550cc;hb=7d456a93e411ad5b6185d7342e213bfe442c0252;hp=e787e1ad5176e513bfd1d6432f9a2cd00103e910;hpb=9c55af4a223ce4db29d643251109e245665344bd;p=lyx.git diff --git a/src/LaTeX.cpp b/src/LaTeX.cpp index e787e1ad51..cfa6e1d3f9 100644 --- a/src/LaTeX.cpp +++ b/src/LaTeX.cpp @@ -92,11 +92,18 @@ bool operator!=(AuxInfo const & a, AuxInfo const & o) */ LaTeX::LaTeX(string const & latex, OutputParams const & rp, - FileName const & f, string const & p) - : cmd(latex), file(f), path(p), runparams(rp), biber(false) + FileName const & f, string const & p, string const & lp, + bool const clean_start) + : cmd(latex), file(f), path(p), lpath(lp), runparams(rp), biber(false) { num_errors = 0; - if (prefixIs(cmd, "pdf")) { // Do we use pdflatex ? + // lualatex can still produce a DVI with --output-format=dvi. However, + // we do not use that internally (we use the "dvilualatex" command) so + // it would only happen from a custom converter. Thus, it is better to + // guess that lualatex produces a PDF than to guess a DVI. + // FIXME we should base the extension on the output format, which we should + // get in a robust way, e.g. from the converter. + if (prefixIs(cmd, "pdf") || prefixIs(cmd, "lualatex") || prefixIs(cmd, "xelatex")) { depfile = FileName(file.absFileName() + ".dep-pdf"); output_file = FileName(changeExtension(file.absFileName(), ".pdf")); @@ -105,12 +112,16 @@ LaTeX::LaTeX(string const & latex, OutputParams const & rp, output_file = FileName(changeExtension(file.absFileName(), ".dvi")); } + if (clean_start) + removeAuxiliaryFiles(); } -void LaTeX::deleteFilesOnError() const +void LaTeX::removeAuxiliaryFiles() const { - // currently just a dummy function. + // Note that we do not always call this function when there is an error. + // For example, if there is an error but an output file is produced we + // still would like to output (export/view) the file. // What files do we have to delete? @@ -142,6 +153,13 @@ void LaTeX::deleteFilesOnError() const // Also remove the aux file FileName const aux(changeExtension(file.absFileName(), ".aux")); aux.removeFile(); + + // Also remove the .out file (e.g. hyperref bookmarks) (#9963) + FileName const out(changeExtension(file.absFileName(), ".out")); + out.removeFile(); + + // Remove the output file, which is often generated even if error + output_file.removeFile(); } @@ -153,6 +171,7 @@ int LaTeX::run(TeXErrors & terr) // each time the .tex file changes. { int scanres = NO_ERRORS; + int bscanres = NO_ERRORS; unsigned int count = 0; // number of times run num_errors = 0; // just to make sure. unsigned int const MAX_RUN = 6; @@ -163,8 +182,6 @@ int LaTeX::run(TeXErrors & terr) theBufferList().updateIncludedTeXfiles(FileName::getcwd().absFileName(), runparams); - // Never write the depfile if an error was encountered. - // 0 // first check if the file dependencies exist: // ->If it does exist @@ -225,19 +242,16 @@ int LaTeX::run(TeXErrors & terr) LYXERR(Debug::LATEX, "Run #" << count); message(runMessage(count)); - startscript(); + int exit_code = startscript(); + scanres = scanLogFile(terr); if (scanres & ERROR_RERUN) { LYXERR(Debug::LATEX, "Rerunning LaTeX"); - startscript(); + terr.clearErrors(); + exit_code = startscript(); scanres = scanLogFile(terr); } - if (scanres & ERRORS) { - deleteFilesOnError(); - return scanres; // return on error - } - vector const bibtex_info = scanAuxFiles(aux_file); if (!run_bibtex && bibtex_info_old != bibtex_info) run_bibtex = true; @@ -297,13 +311,8 @@ int LaTeX::run(TeXErrors & terr) updateBibtexDependencies(head, bibtex_info); rerun |= runBibTeX(bibtex_info, runparams); FileName const blgfile(changeExtension(file.absFileName(), ".blg")); - if (blgfile.exists()) { - int bscanres = scanBlgFile(head, terr); - if (bscanres & ERRORS) { - deleteFilesOnError(); - return bscanres; // return on error - } - } + if (blgfile.exists()) + bscanres = scanBlgFile(head, terr); } else if (!had_depfile) { /// If we run pdflatex on the file after running latex on it, /// then we do not need to run bibtex, but we do need to @@ -331,10 +340,6 @@ int LaTeX::run(TeXErrors & terr) message(runMessage(count)); startscript(); scanres = scanLogFile(terr); - if (scanres & ERRORS) { - deleteFilesOnError(); - return scanres; // return on error - } // update the depedencies deplog(head); // reads the latex log @@ -357,13 +362,8 @@ int LaTeX::run(TeXErrors & terr) updateBibtexDependencies(head, bibtex_info); rerun |= runBibTeX(bibtex_info, runparams); FileName const blgfile(changeExtension(file.absFileName(), ".blg")); - if (blgfile.exists()) { - int bscanres = scanBlgFile(head, terr); - if (bscanres & ERRORS) { - deleteFilesOnError(); - return bscanres; // return on error - } - } + if (blgfile.exists()) + bscanres = scanBlgFile(head, terr); } // 4 @@ -410,10 +410,6 @@ int LaTeX::run(TeXErrors & terr) message(runMessage(count)); startscript(); scanres = scanLogFile(terr); - if (scanres & ERRORS) { - deleteFilesOnError(); - return scanres; // return on error - } // keep this updated head.update(); @@ -421,7 +417,19 @@ int LaTeX::run(TeXErrors & terr) // Write the dependencies to file. head.write(depfile); + + if (exit_code) { + // add flag here, just before return, instead of when exit_code + // is defined because scanres is sometimes overwritten above + // (e.g. rerun) + scanres |= NONZERO_ERROR; + } + LYXERR(Debug::LATEX, "Done."); + + if (bscanres & ERRORS) + return bscanres; // return on error + return scanres; } @@ -433,7 +441,7 @@ int LaTeX::startscript() + quoteName(onlyFileName(file.toFilesystemEncoding())) + " > " + os::nulldev(); Systemcall one; - return one.startscript(Systemcall::Wait, tmp, path); + return one.startscript(Systemcall::Wait, tmp, path, lpath); } @@ -460,7 +468,7 @@ bool LaTeX::runMakeIndex(string const & f, OutputParams const & runparams, tmp += quoteName(f); tmp += params; Systemcall one; - one.startscript(Systemcall::Wait, tmp, path); + one.startscript(Systemcall::Wait, tmp, path, lpath); return true; } @@ -476,7 +484,7 @@ bool LaTeX::runMakeIndexNomencl(FileName const & file, tmp += " -o " + onlyFileName(changeExtension(file.toFilesystemEncoding(), nls)); Systemcall one; - one.startscript(Systemcall::Wait, tmp, path); + one.startscript(Systemcall::Wait, tmp, path, lpath); return true; } @@ -616,7 +624,7 @@ bool LaTeX::runBibTeX(vector const & bibtex_info, tmp += quoteName(onlyFileName(removeExtension( it->aux_file.absFileName()))); Systemcall one; - one.startscript(Systemcall::Wait, tmp, path); + one.startscript(Systemcall::Wait, tmp, path, lpath); } // Return whether bibtex was run return result; @@ -809,7 +817,10 @@ int LaTeX::scanLogFile(TeXErrors & terr) if (!getline(ifs, tmp)) break; tmp = rtrim(tmp, "\r"); - if (++count > 10) + // 15 is somewhat arbitrarily chosen, based on practice. + // We used 10 for 14 years and increased it to 15 when we + // saw one case. + if (++count > 15) break; } while (!prefixIs(tmp, "l.")); if (prefixIs(tmp, "l.")) { @@ -873,20 +884,29 @@ int LaTeX::scanLogFile(TeXErrors & terr) } else if (contains(token, "Rerun to get citations")) { // Natbib seems to use this. retval |= UNDEF_CIT; - } else if (contains(token, "No pages of output")) { - // A dvi file was not created + } else if (contains(token, "No pages of output") + || contains(token, "no pages of output")) { + // No output file (e.g. the DVI or PDF) was created retval |= NO_OUTPUT; } else if (contains(token, "That makes 100 errors")) { // More than 100 errors were reprted retval |= TOO_MANY_ERRORS; - } else if (prefixIs(token, "!pdfTeX error:")){ + } else if (prefixIs(token, "!pdfTeX error:")) { // otherwise we dont catch e.g.: // !pdfTeX error: pdflatex (file feyn10): Font feyn10 at 600 not found retval |= ERRORS; - terr.insertError(0, - from_local8bit("pdfTeX Error"), - from_local8bit(token), - child_name); + terr.insertError(0, + from_local8bit("pdfTeX Error"), + from_local8bit(token), + child_name); + } else if (prefixIs(token, "Missing character: There is no ")) { + // XeTeX/LuaTeX error about missing glyph in selected font + // (bug 9610) + retval |= LATEX_ERROR; + terr.insertError(0, + from_local8bit("Missing glyphs!"), + from_local8bit(token), + child_name); } } } @@ -942,8 +962,7 @@ bool handleFoundFile(string const & ff, DepTable & head) return true; // strip off part after last space and try again string tmp = strippedfile; - string const stripoff = - rsplit(tmp, strippedfile, ' '); + rsplit(tmp, strippedfile, ' '); absname.set(strippedfile); if (insertIfExists(absname, head)) return true; @@ -968,8 +987,7 @@ bool handleFoundFile(string const & ff, DepTable & head) break; // strip off part after last space and try again string strippedfile; - string const stripoff = - rsplit(foundfile, strippedfile, ' '); + rsplit(foundfile, strippedfile, ' '); foundfile = strippedfile; onlyfile = onlyFileName(strippedfile); absname = makeAbsPath(onlyfile);