]> git.lyx.org Git - lyx.git/blobdiff - src/LaTeX.cpp
tex2lyx: support for \item with opt arg in itemize environment
[lyx.git] / src / LaTeX.cpp
index ecd255f4eaec8431c4278006217812407c733f37..3436645fec13db6e717d8772bd3b151498d13702 100644 (file)
@@ -49,7 +49,6 @@ namespace os = support::os;
 //   different way.
 // - the makeindex style files should be taken care of with
 //   the dependency mechanism.
-// - we should perhaps also scan the bibtex log file
 
 namespace {
 
@@ -94,7 +93,7 @@ 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)
+       : cmd(latex), file(f), path(p), runparams(rp), biber(false)
 {
        num_errors = 0;
        if (prefixIs(cmd, "pdf")) { // Do we use pdflatex ?
@@ -184,7 +183,7 @@ int LaTeX::run(TeXErrors & terr)
 
        bool had_depfile = depfile.exists();
        bool run_bibtex = false;
-       FileName const aux_file(changeExtension(file.absFileName(), "aux"));
+       FileName const aux_file(changeExtension(file.absFileName(), ".aux"));
 
        if (had_depfile) {
                LYXERR(Debug::DEPEND, "Dependency file exists");
@@ -269,7 +268,12 @@ int LaTeX::run(TeXErrors & terr)
                                runparams);
        }
        FileName const nlofile(changeExtension(file.absFileName(), ".nlo"));
-       if (head.haschanged(nlofile))
+       // If all nomencl entries are removed, nomencl writes an empty nlo file.
+       // DepTable::hasChanged() returns false in this case, since it does not
+       // distinguish empty files from non-existing files. This is why we need
+       // the extra checks here (to trigger a rerun). Cf. discussions in #8905.
+       // FIXME: Sort out the real problem in DepTable.
+       if (head.haschanged(nlofile) || (nlofile.exists() && nlofile.isFileEmpty()))
                rerun |= runMakeIndexNomencl(file, ".nlo", ".nls");
        FileName const glofile(changeExtension(file.absFileName(), ".glo"));
        if (head.haschanged(glofile))
@@ -292,13 +296,13 @@ int LaTeX::run(TeXErrors & terr)
                message(_("Running BibTeX."));
                updateBibtexDependencies(head, bibtex_info);
                rerun |= runBibTeX(bibtex_info, runparams);
-               if (biber) {
-                       // since biber writes no info to the aux file, we have
-                       // to parse the blg file (which only exists after biber
-                       // was first issued)
-                       FileName const blgfile(changeExtension(file.absFileName(), ".blg"));
-                       if (blgfile.exists())
-                               scanBlgFile(head);
+               FileName const blgfile(changeExtension(file.absFileName(), ".blg"));
+               if (blgfile.exists()) {
+                       int bscanres = scanBlgFile(head, terr);
+                       if (bscanres & ERRORS) {
+                               deleteFilesOnError();
+                               return bscanres; // return on error
+                       }
                }
        } else if (!had_depfile) {
                /// If we run pdflatex on the file after running latex on it,
@@ -352,6 +356,14 @@ int LaTeX::run(TeXErrors & terr)
                message(_("Running BibTeX."));
                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
+                       }
+               }
        }
 
        // 4
@@ -578,7 +590,8 @@ void LaTeX::updateBibtexDependencies(DepTable & dep,
        // biber writes nothing into the aux file.
        // Instead, we have to scan the blg file
        if (biber) {
-               scanBlgFile(dep);
+               TeXErrors terr;
+               scanBlgFile(dep, terr);
        }
 }
 
@@ -621,8 +634,8 @@ int LaTeX::scanLogFile(TeXErrors & terr)
        FileName const fn = FileName(makeAbsPath(tmp));
        ifstream ifs(fn.toFilesystemEncoding().c_str());
        bool fle_style = false;
-       static regex file_line_error(".+\\.\\D+:[0-9]+: (.+)");
-       static regex child_file(".*([0-9]+[A-Za-z]*_.+\\.tex).*");
+       static regex const file_line_error(".+\\.\\D+:[0-9]+: (.+)");
+       static regex const child_file(".*([0-9]+[A-Za-z]*_.+\\.tex).*");
        // Flag for 'File ended while scanning' message.
        // We need to wait for subsequent processing.
        string wait_for_error;
@@ -694,6 +707,10 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                                   && contains(token, "on page")
                                   && contains(token, "undefined")) {
                                retval |= UNDEF_CIT;
+                       } else if (contains(token, "Citation")
+                                  && contains(token, "on input line")
+                                  && contains(token, "undefined")) {
+                               retval |= UNDEF_CIT;
                        }
                } else if (prefixIs(token, "Package")) {
                        // Package warnings
@@ -799,9 +816,11 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                                // we have a latex error
                                retval |=  TEX_ERROR;
                                if (contains(desc,
-                                   "Package babel Error: You haven't defined the language") ||
-                                   contains(desc,
-                                   "Package babel Error: You haven't loaded the option"))
+                                       "Package babel Error: You haven't defined the language")
+                                   || contains(desc,
+                                       "Package babel Error: You haven't loaded the option")
+                                   || contains(desc,
+                                       "Package babel Error: Unknown language"))
                                        retval |= ERROR_RERUN;
                                // get the line number:
                                int line = 0;
@@ -996,7 +1015,7 @@ bool completeFilename(string const & ff, DepTable & head)
 }
 
 
-int iterateLine(string const token, regex const reg, string const closing,
+int iterateLine(string const & token, regex const & reg, string const & closing,
                int fragment_pos, DepTable & head)
 {
        smatch what;
@@ -1044,7 +1063,7 @@ int iterateLine(string const token, regex const reg, string const closing,
        // result = -1 means we did not find a fragment!
        int result = -1;
        int last_match_pos = -1;
-       if (token.find(last_match) != string::npos)
+       if (!last_match.empty() && token.find(last_match) != string::npos)
                last_match_pos = int(token.find(last_match));
        if (fragment) {
                if (last_match_pos > fragment_pos)
@@ -1054,6 +1073,7 @@ int iterateLine(string const token, regex const reg, string const closing,
        } else
                if (last_match_pos < fragment_pos)
                        result = fragment_pos;
+
        return result;
 }
 
@@ -1195,7 +1215,7 @@ void LaTeX::deplog(DepTable & head)
                // (and in addition to those above)
                if (regex_match(token, sub, reg5)) {
                        // search for strings in <...>
-                       static regex reg5_1("<([^>]+)(.)");
+                       static regex const reg5_1("<([^>]+)(.)");
                        fragment_pos = iterateLine(token, reg5_1, ">",
                                                   fragment_pos, head);
                        fragment = (fragment_pos != -1);
@@ -1208,7 +1228,7 @@ void LaTeX::deplog(DepTable & head)
                // where "File: file.ext" would be skipped
                if (regex_match(token, sub, reg6)) {
                        // search for strings in (...)
-                       static regex reg6_1("\\(([^()]+)(.)");
+                       static regex const reg6_1("\\(([^()]+)(.)");
                        fragment_pos = iterateLine(token, reg6_1, ")",
                                                   fragment_pos, head);
                        fragment = (fragment_pos != -1);
@@ -1228,7 +1248,7 @@ void LaTeX::deplog(DepTable & head)
 }
 
 
-void LaTeX::scanBlgFile(DepTable & dep)
+int LaTeX::scanBlgFile(DepTable & dep, TeXErrors & terr)
 {
        FileName const blg_file(changeExtension(file.absFileName(), "blg"));
        LYXERR(Debug::LATEX, "Scanning blg file: " << blg_file);
@@ -1236,7 +1256,15 @@ void LaTeX::scanBlgFile(DepTable & dep)
        ifstream ifs(blg_file.toFilesystemEncoding().c_str());
        string token;
        static regex const reg1(".*Found (bibtex|BibTeX) data (file|source) '([^']+).*");
+       static regex const bibtexError("^(.*---line [0-9]+ of file).*$");
+       static regex const bibtexError2("^(.*---while reading file).*$");
+       static regex const bibtexError3("(A bad cross reference---).*");
+       static regex const bibtexError4("(Sorry---you've exceeded BibTeX's).*");
+       static regex const bibtexError5("\\*Please notify the BibTeX maintainer\\*");
+       static regex const biberError("^.*> (FATAL|ERROR) - (.*)$");
+       int retval = NO_ERRORS;
 
+       string prevtoken;
        while (getline(ifs, token)) {
                token = rtrim(token, "\r");
                smatch sub;
@@ -1250,7 +1278,42 @@ void LaTeX::scanBlgFile(DepTable & dep)
                                handleFoundFile(data, dep);
                        }
                }
-       } 
+               else if (regex_match(token, sub, bibtexError)
+                        || regex_match(token, sub, bibtexError2)
+                        || regex_match(token, sub, bibtexError4)
+                        || regex_match(token, sub, bibtexError5)) {
+                       retval |= BIBTEX_ERROR;
+                       string errstr = N_("BibTeX error: ") + token;
+                       string message;
+                       if ((prefixIs(token, "while executing---line")
+                            || prefixIs(token, "---line ")
+                            || prefixIs(token, "*Please notify the BibTeX"))
+                           && !prevtoken.empty()) {
+                               errstr = N_("BibTeX error: ") + prevtoken;
+                               message = prevtoken + '\n';
+                       }
+                       message += token;
+                       terr.insertError(0,
+                                        from_local8bit(errstr),
+                                        from_local8bit(message));
+               } else if (regex_match(prevtoken, sub, bibtexError3)) {
+                       retval |= BIBTEX_ERROR;
+                       string errstr = N_("BibTeX error: ") + prevtoken;
+                       string message = prevtoken + '\n' + token;
+                       terr.insertError(0,
+                                        from_local8bit(errstr),
+                                        from_local8bit(message));
+               } else if (regex_match(token, sub, biberError)) {
+                       retval |= BIBTEX_ERROR;
+                       string errstr = N_("Biber error: ") + sub.str(2);
+                       string message = token;
+                       terr.insertError(0,
+                                        from_local8bit(errstr),
+                                        from_local8bit(message));
+               }
+               prevtoken = token;
+       }
+       return retval;
 }