X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeX.cpp;h=f5b6d20d3029f42add5f1207e9e3f6195c542f9b;hb=89d9334e03c311a4a7585f40ad81880304d174d4;hp=0401e64ca5e59cf0fdafd72ec82aead6fcc3928e;hpb=02d2e4aa3279b872c9786718dab4f95fd44e900a;p=lyx.git diff --git a/src/LaTeX.cpp b/src/LaTeX.cpp index 0401e64ca5..f5b6d20d30 100644 --- a/src/LaTeX.cpp +++ b/src/LaTeX.cpp @@ -23,6 +23,7 @@ #include "LyX.h" #include "DepTable.h" #include "Encoding.h" +#include "Language.h" #include "support/debug.h" #include "support/convert.h" @@ -238,7 +239,7 @@ int LaTeX::run(TeXErrors & terr) // Also remove all children which are included Buffer const * buf = theBufferList().getBufferFromTmp(file.absFileName()); if (buf && buf->params().maintain_unincluded_children == BufferParams::CM_Mostly) { - for (auto const incfile : buf->params().getIncludedChildren()) { + for (auto const & incfile : buf->params().getIncludedChildren()) { string const incm = DocFileName(changeExtension(makeAbsPath(incfile, path) .absFileName(), ".tex")).mangledFileName(); @@ -281,16 +282,16 @@ int LaTeX::run(TeXErrors & terr) message(runMessage(count)); int exit_code = startscript(); - if (exit_code == Systemcall::KILLED) - return Systemcall::KILLED; + if (exit_code == Systemcall::KILLED || exit_code == Systemcall::TIMEOUT) + return exit_code; scanres = scanLogFile(terr); if (scanres & ERROR_RERUN) { LYXERR(Debug::LATEX, "Rerunning LaTeX"); terr.clearErrors(); exit_code = startscript(); - if (exit_code == Systemcall::KILLED) - return Systemcall::KILLED; + if (exit_code == Systemcall::KILLED || exit_code == Systemcall::TIMEOUT) + return exit_code; scanres = scanLogFile(terr); } @@ -322,8 +323,8 @@ int LaTeX::run(TeXErrors & terr) // onlyFileName() is needed for cygwin int const ret = runMakeIndex(onlyFileName(idxfile.absFileName()), runparams); - if (ret == Systemcall::KILLED) - return Systemcall::KILLED; + if (ret == Systemcall::KILLED || ret == Systemcall::TIMEOUT) + return ret; FileName const ilgfile(changeExtension(file.absFileName(), ".ilg")); if (ilgfile.exists()) iscanres = scanIlgFile(terr); @@ -338,8 +339,8 @@ int LaTeX::run(TeXErrors & terr) // FIXME: Sort out the real problem in DepTable. if (head.haschanged(nlofile) || (nlofile.exists() && nlofile.isFileEmpty())) { int const ret = runMakeIndexNomencl(file, ".nlo", ".nls"); - if (ret == Systemcall::KILLED) - return Systemcall::KILLED; + if (ret == Systemcall::KILLED || ret == Systemcall::TIMEOUT) + return ret; rerun = true; } @@ -375,8 +376,8 @@ int LaTeX::run(TeXErrors & terr) updateBibtexDependencies(head, bibtex_info); int exit_code; rerun |= runBibTeX(bibtex_info, runparams, exit_code); - if (exit_code == Systemcall::KILLED) - return Systemcall::KILLED; + if (exit_code == Systemcall::KILLED || exit_code == Systemcall::TIMEOUT) + return exit_code; FileName const blgfile(changeExtension(file.absFileName(), ".blg")); if (blgfile.exists()) bscanres = scanBlgFile(head, terr); @@ -406,8 +407,8 @@ int LaTeX::run(TeXErrors & terr) LYXERR(Debug::LATEX, "Run #" << count); message(runMessage(count)); int exit_code = startscript(); - if (exit_code == Systemcall::KILLED) - return Systemcall::KILLED; + if (exit_code == Systemcall::KILLED || exit_code == Systemcall::TIMEOUT) + return exit_code; scanres = scanLogFile(terr); // update the depedencies @@ -436,8 +437,8 @@ int LaTeX::run(TeXErrors & terr) updateBibtexDependencies(head, bibtex_info); int exit_code; rerun |= runBibTeX(bibtex_info, runparams, exit_code); - if (exit_code == Systemcall::KILLED) - return Systemcall::KILLED; + if (exit_code == Systemcall::KILLED || exit_code == Systemcall::TIMEOUT) + return exit_code; FileName const blgfile(changeExtension(file.absFileName(), ".blg")); if (blgfile.exists()) bscanres = scanBlgFile(head, terr); @@ -459,8 +460,8 @@ int LaTeX::run(TeXErrors & terr) // onlyFileName() is needed for cygwin int const ret = runMakeIndex(onlyFileName(changeExtension( file.absFileName(), ".idx")), runparams); - if (ret == Systemcall::KILLED) - return Systemcall::KILLED; + if (ret == Systemcall::KILLED || ret == Systemcall::TIMEOUT) + return ret; FileName const ilgfile(changeExtension(file.absFileName(), ".ilg")); if (ilgfile.exists()) iscanres = scanIlgFile(terr); @@ -541,13 +542,15 @@ int LaTeX::runMakeIndex(string const & f, OutputParams const & rp, if (!rp.index_command.empty()) tmp = rp.index_command; + + Language const * doc_lang = languages.getLanguage(rp.document_language); if (contains(tmp, "$$x")) { // This adds appropriate [te]xindy options // such as language and codepage (for the // main document language/encoding) as well // as input markup (latex or xelatex) - string xdyopts = rp.xindy_language; + string xdyopts = doc_lang ? doc_lang->xindy() : string(); if (!xdyopts.empty()) xdyopts = "-L " + xdyopts; if (rp.isFullUnicode() && rp.encoding->package() == Encoding::none) { @@ -580,7 +583,10 @@ int LaTeX::runMakeIndex(string const & f, OutputParams const & rp, "idx file has been made, running index processor (" << tmp << ") on file " << f); - tmp = subst(tmp, "$$lang", rp.document_language); + if (doc_lang) { + tmp = subst(tmp, "$$lang", doc_lang->babel()); + tmp = subst(tmp, "$$lcode", doc_lang->code()); + } if (rp.use_indices) { tmp = lyxrc.splitindex_command + " -m " + quoteName(tmp); LYXERR(Debug::LATEX, @@ -807,6 +813,7 @@ int LaTeX::scanLogFile(TeXErrors & terr) terr.clearRefs(); string token; + string ml_token; while (getline(ifs, token)) { // MikTeX sometimes inserts \0 in the log file. They can't be // removed directly with the existing string utility @@ -821,6 +828,9 @@ int LaTeX::scanLogFile(TeXErrors & terr) if (token.empty()) continue; + if (!ml_token.empty()) + ml_token += token; + // Track child documents for (size_t i = 0; i < token.length(); ++i) { if (token[i] == '(') { @@ -862,8 +872,10 @@ int LaTeX::scanLogFile(TeXErrors & terr) prefixIs(token, "Package biblatex Warning: The following entry could not be found"))) retval |= UNDEF_CIT; - if (prefixIs(token, "LaTeX Warning:") || - prefixIs(token, "! pdfTeX warning")) { + if (prefixIs(token, "LaTeX Warning:") + || prefixIs(token, "! pdfTeX warning") + || prefixIs(ml_token, "LaTeX Warning:") + || prefixIs(ml_token, "! pdfTeX warning")) { // Here shall we handle different // types of warnings retval |= LATEX_WARNING; @@ -893,8 +905,37 @@ int LaTeX::scanLogFile(TeXErrors & terr) terr.insertRef(getLineNumber(token), from_ascii("Citation undefined"), from_utf8(token), child_name); //"Reference `X' on page Y undefined on input line Z." - } else if (contains(token, "Reference") - //&& contains(token, "on input line")) //often split to new line + // This warning might be broken accross multiple lines with long labels. + // Thus we check that + } else if (contains(token, "Reference `") && !contains(token, "on input line")) { + // Rest of warning in next line(s) + // Save to ml_token + ml_token = token; + } else if (!ml_token.empty() && contains(ml_token, "Reference `") + && !contains(ml_token, "on input line")) { + // not finished yet. Continue with next line. + continue; + } else if (!ml_token.empty() && contains(ml_token, "Reference `") + && contains(ml_token, "on input line")) { + // We have collected the whole warning now. + if (!contains(ml_token, "undefined")) { + // Not the warning we are looking for + ml_token.clear(); + continue; + } + if (regex_match(ml_token, sub, undef_ref)) { + string const ref = sub.str(1); + Buffer const * buf = theBufferList().getBufferFromTmp(file.absFileName()); + if (!buf || !buf->masterBuffer()->activeLabel(from_utf8(ref))) { + terr.insertRef(getLineNumber(ml_token), from_ascii("Reference undefined"), + from_utf8(ml_token), child_name); + retval |= UNDEF_UNKNOWN_REF; + } + } + ml_token.clear(); + retval |= UNDEF_REF; + } else if (contains(token, "Reference `") + && contains(token, "on input line") && contains(token, "undefined")) { if (regex_match(token, sub, undef_ref)) { string const ref = sub.str(1); @@ -906,19 +947,11 @@ int LaTeX::scanLogFile(TeXErrors & terr) } } retval |= UNDEF_REF; - - //If label is too long pdlaftex log line splitting will make the above fail - //so we catch at least this generic statement occuring for both CIT & REF. + // In case the above checks fail we catch at least this generic statement + // occuring for both CIT & REF. } else if (!runparams.includeall && contains(token, "There were undefined references.")) { - if (!(retval & UNDEF_CIT)) { //if not handled already - if (regex_match(token, sub, undef_ref)) { - string const ref = sub.str(1); - Buffer const * buf = theBufferList().getBufferFromTmp(file.absFileName()); - if (!buf || !buf->masterBuffer()->activeLabel(from_utf8(ref))) - retval |= UNDEF_UNKNOWN_REF; - } + if (!(retval & UNDEF_CIT)) //if not handled already retval |= UNDEF_REF; - } } } else if (prefixIs(token, "Package")) { @@ -1024,10 +1057,15 @@ int LaTeX::scanLogFile(TeXErrors & terr) // get the next line int count = 0; + // We also collect intermediate lines + // This is needed for errors in preamble + string intermediate; do { if (!getline(ifs, tmp)) break; tmp = rtrim(tmp, "\r"); + if (!prefixIs(tmp, "l.")) + intermediate += tmp; // 15 is somewhat arbitrarily chosen, based on practice. // We used 10 for 14 years and increased it to 15 when we // saw one case. @@ -1049,6 +1087,15 @@ int LaTeX::scanLogFile(TeXErrors & terr) sscanf(tmp.c_str(), "l.%d", &line); // get the rest of the message: string errstr(tmp, tmp.find(' ')); + bool preamble_error = false; + if (suffixIs(errstr, "\\begin{document}")) { + // this is an error in preamble + // the real error is in the + // intermediate lines + errstr = intermediate; + tmp = intermediate; + preamble_error = true; + } errstr += '\n'; getline(ifs, tmp); tmp = rtrim(tmp, "\r"); @@ -1061,6 +1108,9 @@ int LaTeX::scanLogFile(TeXErrors & terr) getline(ifs, tmp); tmp = rtrim(tmp, "\r"); } + if (preamble_error) + // Add a note that the error is to be found in preamble + errstr += "\n" + to_utf8(_("(NOTE: The erroneous command is in the preamble)")); LYXERR(Debug::LATEX, "line: " << line << '\n' << "Desc: " << desc << '\n' << "Text: " << errstr); if (line == last_line)