The branch, 2.0.x, has been updated. - Log -----------------------------------------------------------------
commit 212af25fb26b8a5dc0e46ca111d03952d4a256a0 Merge: 7441db9 f8a46c4 Author: Juergen Spitzmueller <[email protected]> Date: Tue Sep 18 08:34:05 2012 +0200 Merge branch '2.0.x' of git.lyx.org:lyx into 2.0.x commit 7441db90534a28f1e7d2ae5c005a9613617f11a3 Author: Juergen Spitzmueller <[email protected]> Date: Mon Sep 17 08:59:41 2012 +0200 Calibrate log file parser Filenames embraced in <...> can occur anywhere on the line and multiple times. This fixes for me the case that graphics included via ERT were not tracked. It also fixes #8336. (cherry picked from commit e8a01d099a7ecbe5059cbdf0aa0aab16e9862cf6) diff --git a/src/LaTeX.cpp b/src/LaTeX.cpp index 110d21c..ac3f87f 100644 --- a/src/LaTeX.cpp +++ b/src/LaTeX.cpp @@ -995,6 +995,68 @@ bool completeFilename(string const & ff, DepTable & head) return handleFoundFile(ff, head); } + +int iterateLine(string const token, regex const reg, string const closing, + int fragment_pos, DepTable & head) +{ + smatch what; + string::const_iterator first = token.begin(); + string::const_iterator end = token.end(); + bool fragment = false; + string last_match; + + while (regex_search(first, end, what, reg)) { + // if we have a dot, try to handle as file + if (contains(what.str(1), '.')) { + first = what[0].second; + if (what.str(2) == closing) { + handleFoundFile(what.str(1), head); + // since we had a closing bracket, + // do not investigate further + fragment = false; + } else + // if we have no closing bracket, + // try to handle as file nevertheless + fragment = !handleFoundFile( + what.str(1) + what.str(2), head); + } + // if we do not have a dot, check if the line has + // a closing bracket (else, we suspect a line break) + else if (what.str(2) != closing) { + first = what[0].second; + fragment = true; + } else { + // we have a closing bracket, so the content + // is not a file name. + // no need to investigate further + first = what[0].second; + fragment = false; + } + last_match = what.str(1); + } + + // We need to consider the result from previous line iterations: + // We might not find a fragment here, but another one might follow + // E.g.: (filename.ext) <filenam + // Vice versa, we consider the search completed if a real match + // follows a potential fragment from a previous iteration. + // E.g. <some text we considered a fragment (filename.ext) + // result = -1 means we did not find a fragment! + int result = -1; + int last_match_pos = -1; + 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) + result = last_match_pos; + else + result = fragment_pos; + } else + if (last_match_pos < fragment_pos) + result = fragment_pos; + return result; +} + } // anon namespace @@ -1015,8 +1077,6 @@ void LaTeX::deplog(DepTable & head) // but instead only a line like this into the log: // Writing index file sample.idx static regex const reg4("Writing index file (.+).*"); - // files also can be enclosed in <...> - static regex const reg5("[^<]*<([^>]+)(.).*"); static regex const regoldnomencl("Writing glossary file (.+).*"); static regex const regnomencl("Writing nomenclature file (.+).*"); // If a toc should be created, MikTex does not write a line like @@ -1026,7 +1086,9 @@ void LaTeX::deplog(DepTable & head) // This line is also written by tetex. // This line is not present if no toc should be created. static regex const miktexTocReg("\\\\tf@toc=\\\\write.*"); - // (...) somewhere on the line + // file names can be enclosed in <...> (anywhere on the line) + static regex const reg5(".*<[^>]+.*"); + // and also (...) anywhere on the line static regex const reg6(".*\\([^)]+.*"); FileName const fn = makeAbsPath(logfile); @@ -1114,20 +1176,12 @@ void LaTeX::deplog(DepTable & head) } else if (regex_match(token, sub, reg4)) // fragmential file name? fragment = !completeFilename(sub.str(1), head); - // (5) "<file.ext>" - else if (regex_match(token, sub, reg5)) { - // search for closing '>' and dot ('*.*>') at the eol - if (contains(sub.str(1), '.') && sub.str(2) == ">") - fragment = !handleFoundFile(sub.str(1), head); - else - // potential fragment - fragment = true; - // (6) "Writing nomenclature file file.ext" - } else if (regex_match(token, sub, regnomencl) || + // (5) "Writing nomenclature file file.ext" + else if (regex_match(token, sub, regnomencl) || regex_match(token, sub, regoldnomencl)) // fragmental file name? fragment= !completeFilename(sub.str(1), head); - // (7) "\tf@toc=\write<nr>" (for MikTeX) + // (6) "\tf@toc=\write<nr>" (for MikTeX) else if (regex_match(token, sub, miktexTocReg)) fragment = !handleFoundFile(onlyFileName(changeExtension( file.absFileName(), ".toc")), head); @@ -1135,46 +1189,29 @@ void LaTeX::deplog(DepTable & head) // not found, but we won't check further fragment = false; - // (8) "(file.ext" - // note that we can have several of these on one line + int fragment_pos = -1; + // (7) "<file.ext>" + // We can have several of these on one line + // (and in addition to those above) + if (regex_match(token, sub, reg5)) { + // search for strings in <...> + static regex reg5_1("<([^>]+)(.)"); + fragment_pos = iterateLine(token, reg5_1, ">", + fragment_pos, head); + fragment = (fragment_pos != -1); + } + + // (8) "(file.ext)" + // We can have several of these on one line // this must be queried separated, because of // cases such as "File: file.ext (type eps)" // where "File: file.ext" would be skipped if (regex_match(token, sub, reg6)) { // search for strings in (...) static regex reg6_1("\\(([^()]+)(.)"); - smatch what; - string::const_iterator first = token.begin(); - string::const_iterator end = token.end(); - - while (regex_search(first, end, what, reg6_1)) { - // if we have a dot, try to handle as file - if (contains(what.str(1), '.')) { - first = what[0].second; - if (what.str(2) == ")") { - handleFoundFile(what.str(1), head); - // since we had a closing bracket, - // do not investigate further - fragment = false; - } else - // if we have no closing bracket, - // try to handle as file nevertheless - fragment = !handleFoundFile( - what.str(1) + what.str(2), head); - } - // if we do not have a dot, check if the line has - // a closing bracket (else, we suspect a line break) - else if (what.str(2) != ")") { - first = what[0].second; - fragment = true; - } else { - // we have a closing bracket, so the content - // is not a file name. - // no need to investigate further - first = what[0].second; - fragment = false; - } - } + fragment_pos = iterateLine(token, reg6_1, ")", + fragment_pos, head); + fragment = (fragment_pos != -1); } if (fragment) diff --git a/status.20x b/status.20x index 83aefe6..5eb8dc2 100644 --- a/status.20x +++ b/status.20x @@ -97,6 +97,9 @@ What's new - Embrace babel settings to \makeatletter ... \makeatother if they contain an @ glyph. +- Improve the external file monitor. LyX should now also honor changes in + graphics that are included via ERT or generated via knitr (bug 8336). + - Fix LaTeX errors with right-to-left text when using XeTeX/Polyglossia (part of bug 8251). commit 991af815884b855aac7233d88f3d10c561432808 Author: Juergen Spitzmueller <[email protected]> Date: Sun Sep 16 13:05:55 2012 +0200 Clarify the logic of fragmental file name checking No change in functionality. (cherry picked from commit ba792c4d35a7657dbfa7522991ee80229bcb6573) diff --git a/src/LaTeX.cpp b/src/LaTeX.cpp index 035e0f5..110d21c 100644 --- a/src/LaTeX.cpp +++ b/src/LaTeX.cpp @@ -984,8 +984,10 @@ bool handleFoundFile(string const & ff, DepTable & head) } -bool checkLineBreak(string const & ff, DepTable & head) +bool completeFilename(string const & ff, DepTable & head) { + // If we do not find a dot, we suspect + // a fragmental file name if (!contains(ff, '.')) return false; @@ -1014,7 +1016,7 @@ void LaTeX::deplog(DepTable & head) // Writing index file sample.idx static regex const reg4("Writing index file (.+).*"); // files also can be enclosed in <...> - static regex const reg5("<([^>]+)(.).*"); + static regex const reg5("[^<]*<([^>]+)(.).*"); static regex const regoldnomencl("Writing glossary file (.+).*"); static regex const regnomencl("Writing nomenclature file (.+).*"); // If a toc should be created, MikTex does not write a line like @@ -1024,6 +1026,7 @@ void LaTeX::deplog(DepTable & head) // This line is also written by tetex. // This line is not present if no toc should be created. static regex const miktexTocReg("\\\\tf@toc=\\\\write.*"); + // (...) somewhere on the line static regex const reg6(".*\\([^)]+.*"); FileName const fn = makeAbsPath(logfile); @@ -1031,10 +1034,12 @@ void LaTeX::deplog(DepTable & head) string lastline; while (ifs) { // Ok, the scanning of files here is not sufficient. - // Sometimes files are named by "File:� xxx" only - // So I think we should use some regexps to find files instead. + // Sometimes files are named by "File: xxx" only + // Therefore we use some regexps to find files instead. // Note: all file names and paths might contains spaces. - bool found_file = false; + // Also, file names might be broken across lines. Therefore + // we mark (potential) fragments and merge those lines. + bool fragment = false; string token; getline(ifs, token); // MikTeX sometimes inserts \0 in the log file. They can't be @@ -1083,54 +1088,52 @@ void LaTeX::deplog(DepTable & head) // (1) "File: file.ext" if (regex_match(token, sub, reg1)) { - // check for dot - found_file = checkLineBreak(sub.str(1), head); + // is this a fragmental file name? + fragment = !completeFilename(sub.str(1), head); // However, ... if (suffixIs(token, ")")) - // no line break for sure - // pretend we've been successfully searching - found_file = true; + // no fragment for sure + fragment = false; // (2) "No file file.ext" } else if (regex_match(token, sub, reg2)) { // file names must contains a dot, line ends with dot if (contains(sub.str(1), '.') && sub.str(2) == ".") - found_file = handleFoundFile(sub.str(1), head); + fragment = !handleFoundFile(sub.str(1), head); else // we suspect a line break - found_file = false; + fragment = true; // (3) "\openout<nr> = `file.ext'." } else if (regex_match(token, sub, reg3)) { // search for closing '. at the end of the line if (sub.str(2) == "\'.") - found_file = handleFoundFile(sub.str(1), head); + fragment = !handleFoundFile(sub.str(1), head); else - // probable line break - found_file = false; + // potential fragment + fragment = true; // (4) "Writing index file file.ext" } else if (regex_match(token, sub, reg4)) - // check for dot - found_file = checkLineBreak(sub.str(1), head); + // fragmential file name? + fragment = !completeFilename(sub.str(1), head); // (5) "<file.ext>" else if (regex_match(token, sub, reg5)) { // search for closing '>' and dot ('*.*>') at the eol if (contains(sub.str(1), '.') && sub.str(2) == ">") - found_file = handleFoundFile(sub.str(1), head); + fragment = !handleFoundFile(sub.str(1), head); else - // probable line break - found_file = false; + // potential fragment + fragment = true; // (6) "Writing nomenclature file file.ext" } else if (regex_match(token, sub, regnomencl) || regex_match(token, sub, regoldnomencl)) - // check for dot - found_file = checkLineBreak(sub.str(1), head); + // fragmental file name? + fragment= !completeFilename(sub.str(1), head); // (7) "\tf@toc=\write<nr>" (for MikTeX) else if (regex_match(token, sub, miktexTocReg)) - found_file = handleFoundFile(onlyFileName(changeExtension( + fragment = !handleFoundFile(onlyFileName(changeExtension( file.absFileName(), ".toc")), head); else // not found, but we won't check further - // pretend we've been successfully searching - found_file = true; + fragment = false; // (8) "(file.ext" // note that we can have several of these on one line @@ -1152,31 +1155,30 @@ void LaTeX::deplog(DepTable & head) handleFoundFile(what.str(1), head); // since we had a closing bracket, // do not investigate further - found_file = true; + fragment = false; } else // if we have no closing bracket, // try to handle as file nevertheless - found_file = handleFoundFile( + fragment = !handleFoundFile( what.str(1) + what.str(2), head); } // if we do not have a dot, check if the line has // a closing bracket (else, we suspect a line break) else if (what.str(2) != ")") { first = what[0].second; - found_file = false; + fragment = true; } else { // we have a closing bracket, so the content // is not a file name. // no need to investigate further - // pretend we've been successfully searching first = what[0].second; - found_file = true; + fragment = false; } } } - if (!found_file) - // probable linebreak: + if (fragment) + // probable linebreak within file name: // save this line lastline = token; else ----------------------------------------------------------------------- Summary of changes: src/LaTeX.cpp | 181 ++++++++++++++++++++++++++++++++++---------------------- status.20x | 3 + 2 files changed, 113 insertions(+), 71 deletions(-) hooks/post-receive -- The LyX Source Repository
