]> git.lyx.org Git - lyx.git/blobdiff - src/LaTeX.cpp
Revert previous commit, which committed too much.
[lyx.git] / src / LaTeX.cpp
index 3e8729adf13313888d9f0defdf7c85339f84e66d..04a86f795a95cd6de5b36fc98e4e3cd03a22662d 100644 (file)
@@ -32,6 +32,7 @@
 #include "support/regex.h"
 
 #include <fstream>
+#include <stack>
 
 
 using namespace std;
@@ -64,9 +65,10 @@ docstring runMessage(unsigned int count)
  */
 
 void TeXErrors::insertError(int line, docstring const & error_desc,
-                           docstring const & error_text)
+                           docstring const & error_text,
+                           string const & child_name)
 {
-       Error newerr(line, error_desc, error_text);
+       Error newerr(line, error_desc, error_text, child_name);
        errors.push_back(newerr);
 }
 
@@ -91,8 +93,8 @@ bool operator!=(AuxInfo const & a, AuxInfo const & o)
  */
 
 LaTeX::LaTeX(string const & latex, OutputParams const & rp,
-            FileName const & f)
-       : cmd(latex), file(f), runparams(rp)
+            FileName const & f, string const & p)
+       : cmd(latex), file(f), path(p), runparams(rp)
 {
        num_errors = 0;
        if (prefixIs(cmd, "pdf")) { // Do we use pdflatex ?
@@ -419,7 +421,7 @@ int LaTeX::startscript()
                     + quoteName(onlyFileName(file.toFilesystemEncoding()))
                     + " > " + os::nulldev();
        Systemcall one;
-       return one.startscript(Systemcall::Wait, tmp);
+       return one.startscript(Systemcall::Wait, tmp, path);
 }
 
 
@@ -446,7 +448,7 @@ bool LaTeX::runMakeIndex(string const & f, OutputParams const & runparams,
        tmp += quoteName(f);
        tmp += params;
        Systemcall one;
-       one.startscript(Systemcall::Wait, tmp);
+       one.startscript(Systemcall::Wait, tmp, path);
        return true;
 }
 
@@ -462,7 +464,7 @@ bool LaTeX::runMakeIndexNomencl(FileName const & file,
        tmp += " -o "
                + onlyFileName(changeExtension(file.toFilesystemEncoding(), nls));
        Systemcall one;
-       one.startscript(Systemcall::Wait, tmp);
+       one.startscript(Systemcall::Wait, tmp, path);
        return true;
 }
 
@@ -602,7 +604,7 @@ bool LaTeX::runBibTeX(vector<AuxInfo> const & bibtex_info,
                tmp += quoteName(onlyFileName(removeExtension(
                                it->aux_file.absFileName())));
                Systemcall one;
-               one.startscript(Systemcall::Wait, tmp);
+               one.startscript(Systemcall::Wait, tmp, path);
        }
        // Return whether bibtex was run
        return result;
@@ -621,9 +623,13 @@ int LaTeX::scanLogFile(TeXErrors & terr)
        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).*");
        // Flag for 'File ended while scanning' message.
        // We need to wait for subsequent processing.
        string wait_for_error;
+       string child_name;
+       int pnest = 0;
+       stack <pair<string, int> > child;
 
        string token;
        while (getline(ifs, token)) {
@@ -640,6 +646,29 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                if (token.empty())
                        continue;
 
+               // Track child documents
+               for (size_t i = 0; i < token.length(); ++i) {
+                       if (token[i] == '(') {
+                               ++pnest;
+                               size_t j = token.find('(', i + 1);
+                               size_t len = j == string::npos
+                                               ? token.substr(i + 1).length()
+                                               : j - i - 1;
+                               if (regex_match(token.substr(i + 1, len),
+                                                       sub, child_file)) {
+                                       string const name = sub.str(1);
+                                       child.push(make_pair(name, pnest));
+                                       i += len;
+                               }
+                       } else if (token[i] == ')') {
+                               if (!child.empty()
+                                   && child.top().second == pnest)
+                                       child.pop();
+                               --pnest;
+                       }
+               }
+               child_name = child.empty() ? empty_string() : child.top().first;
+
                if (contains(token, "file:line:error style messages enabled"))
                        fle_style = true;
 
@@ -716,11 +745,24 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                        if (contains(token, "LaTeX Error:"))
                                retval |= LATEX_ERROR;
 
-                       // bug 6445. At this point its not clear we finish with error.
                        if (prefixIs(token, "! File ended while scanning")){
-                               wait_for_error = desc;
-                               continue;
+                               if (prefixIs(token, "! File ended while scanning use of \\Hy@setref@link.")){
+                                       // bug 7344. We must rerun LaTeX if hyperref has been toggled.
+                                       retval |= ERROR_RERUN;
+                                       LYXERR(Debug::LATEX, "Force rerun.");
+                               } else {
+                                       // bug 6445. At this point its not clear we finish with error.
+                                       wait_for_error = desc;
+                                       continue;
+                               }
+                       }
+
+                       if (prefixIs(token, "! Paragraph ended before \\Hy@setref@link was complete.")){
+                                       // bug 7344. We must rerun LaTeX if hyperref has been toggled.
+                                       retval |= ERROR_RERUN;
+                                       LYXERR(Debug::LATEX, "Force rerun.");
                        }
+
                        if (!wait_for_error.empty() && prefixIs(token, "! Emergency stop.")){
                                retval |= LATEX_ERROR;
                                string errstr;
@@ -729,6 +771,7 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                                do {
                                        if (!getline(ifs, tmp))
                                                break;
+                                       tmp = rtrim(tmp, "\r");
                                        errstr += "\n" + tmp;
                                        if (++count > 5)
                                                break;
@@ -736,7 +779,8 @@ int LaTeX::scanLogFile(TeXErrors & terr)
 
                                terr.insertError(0,
                                                 from_local8bit("Emergency stop"),
-                                                from_local8bit(errstr));
+                                                from_local8bit(errstr),
+                                                child_name);
                        }
 
                        // get the next line
@@ -745,6 +789,7 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                        do {
                                if (!getline(ifs, tmp))
                                        break;
+                               tmp = rtrim(tmp, "\r");
                                if (++count > 10)
                                        break;
                        } while (!prefixIs(tmp, "l."));
@@ -763,6 +808,7 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                                string errstr(tmp, tmp.find(' '));
                                errstr += '\n';
                                getline(ifs, tmp);
+                               tmp = rtrim(tmp, "\r");
                                while (!contains(errstr, "l.")
                                       && !tmp.empty()
                                       && !prefixIs(tmp, "! ")
@@ -770,6 +816,7 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                                        errstr += tmp;
                                        errstr += "\n";
                                        getline(ifs, tmp);
+                                       tmp = rtrim(tmp, "\r");
                                }
                                LYXERR(Debug::LATEX, "line: " << line << '\n'
                                        << "Desc: " << desc << '\n' << "Text: " << errstr);
@@ -790,7 +837,8 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                                        // assume here it can be wrong.
                                        terr.insertError(line,
                                                         from_local8bit(desc),
-                                                        from_local8bit(errstr));
+                                                        from_local8bit(errstr),
+                                                        child_name);
                                        ++num_errors;
                                }
                        }
@@ -816,7 +864,8 @@ int LaTeX::scanLogFile(TeXErrors & terr)
                                retval |= ERRORS;
                                        terr.insertError(0,
                                                         from_local8bit("pdfTeX Error"),
-                                                        from_local8bit(token));
+                                                        from_local8bit(token),
+                                                        child_name);
                        }
                }
        }
@@ -997,6 +1046,10 @@ void LaTeX::deplog(DepTable & head)
                        continue;
                }
 
+               // FIXME UNICODE: We assume that the file names in the log
+               // file are in the file system encoding.
+               token = to_utf8(from_filesystem8bit(token));
+
                // Sometimes, filenames are broken across lines.
                // We care for that and save suspicious lines.
                // Here we exclude some cases where we are sure
@@ -1026,10 +1079,6 @@ void LaTeX::deplog(DepTable & head)
 
                smatch sub;
 
-               // FIXME UNICODE: We assume that the file names in the log
-               // file are in the file system encoding.
-               token = to_utf8(from_filesystem8bit(token));
-
                // (1) "File: file.ext"
                if (regex_match(token, sub, reg1)) {
                        // check for dot