X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLaTeX.cpp;h=db2037f8d2f4edeca588dfc09aa257998ad40f2d;hb=2098f1d8c20d51e63e670bcdc9da8996068975bf;hp=1934894058999d5f626bc595bd2cfc1f8a7cfe1d;hpb=9d0ea8aeff32833a90b3fe64df0c5518a9e241be;p=lyx.git diff --git a/src/LaTeX.cpp b/src/LaTeX.cpp index 1934894058..db2037f8d2 100644 --- a/src/LaTeX.cpp +++ b/src/LaTeX.cpp @@ -4,11 +4,11 @@ * Licence details can be found in the file COPYING. * * \author Alfredo Braunstein - * \author Lars Gullik Bjønnes + * \author Lars Gullik Bjønnes * \author Jean-Marc Lasgouttes * \author Angus Leeming * \author Dekel Tsur - * \author Jürgen Spitzmüller + * \author Jürgen Spitzmüller * * Full author contact details are available in file CREDITS. */ @@ -17,15 +17,15 @@ #include "BufferList.h" #include "LaTeX.h" -#include "support/gettext.h" #include "LyXRC.h" -#include "support/debug.h" #include "DepTable.h" -#include "support/filetools.h" +#include "support/debug.h" #include "support/convert.h" +#include "support/FileName.h" +#include "support/filetools.h" +#include "support/gettext.h" #include "support/lstrings.h" -#include "support/lyxlib.h" #include "support/Systemcall.h" #include "support/os.h" @@ -36,40 +36,11 @@ using boost::regex; using boost::smatch; -#ifndef CXX_GLOBAL_CSTD -using std::sscanf; -#endif - -using std::endl; -using std::getline; -using std::string; -using std::ifstream; -using std::set; -using std::vector; - +using namespace std; +using namespace lyx::support; namespace lyx { -using support::absolutePath; -using support::bformat; -using support::changeExtension; -using support::contains; -using support::FileName; -using support::findtexfile; -using support::getcwd; -using support::makeAbsPath; -using support::onlyFilename; -using support::prefixIs; -using support::quoteName; -using support::removeExtension; -using support::rtrim; -using support::rsplit; -using support::split; -using support::subst; -using support::suffixIs; -using support::Systemcall; -using support::trim; - namespace os = support::os; // TODO: in no particular order @@ -79,8 +50,6 @@ namespace os = support::os; // different way. // - the makeindex style files should be taken care of with // the dependency mechanism. -// - makeindex commandline options should be supported -// - somewhere support viewing of bibtex and makeindex log files. // - we should perhaps also scan the bibtex log file namespace { @@ -104,16 +73,16 @@ void TeXErrors::insertError(int line, docstring const & error_desc, } -bool operator==(Aux_Info const & a, Aux_Info const & o) +bool operator==(AuxInfo const & a, AuxInfo const & o) { - return a.aux_file == o.aux_file && - a.citations == o.citations && - a.databases == o.databases && - a.styles == o.styles; + return a.aux_file == o.aux_file + && a.citations == o.citations + && a.databases == o.databases + && a.styles == o.styles; } -bool operator!=(Aux_Info const & a, Aux_Info const & o) +bool operator!=(AuxInfo const & a, AuxInfo const & o) { return !(a == o); } @@ -177,7 +146,7 @@ int LaTeX::run(TeXErrors & terr) // We know that this function will only be run if the lyx buffer // has been changed. We also know that a newly written .tex file // is always different from the previous one because of the date - // in it. However it seems safe to run latex (at least) on time + // in it. However it seems safe to run latex (at least) one time // each time the .tex file changes. { int scanres = NO_ERRORS; @@ -188,7 +157,7 @@ int LaTeX::run(TeXErrors & terr) bool rerun = false; // rerun requested // The class LaTeX does not know the temp path. - theBufferList().updateIncludedTeXfiles(getcwd().absFilename(), + theBufferList().updateIncludedTeXfiles(FileName::getcwd().absFilename(), runparams); // Never write the depfile if an error was encountered. @@ -245,7 +214,7 @@ int LaTeX::run(TeXErrors & terr) /// We scan the aux file even when had_depfile = false, /// because we can run pdflatex on the file after running latex on it, /// in which case we will not need to run bibtex again. - vector bibtex_info_old; + vector bibtex_info_old; if (!run_bibtex) bibtex_info_old = scanAuxFiles(aux_file); @@ -266,7 +235,7 @@ int LaTeX::run(TeXErrors & terr) return scanres; // return on error } - vector const bibtex_info = scanAuxFiles(aux_file); + vector const bibtex_info = scanAuxFiles(aux_file); if (!run_bibtex && bibtex_info_old != bibtex_info) run_bibtex = true; @@ -274,7 +243,7 @@ int LaTeX::run(TeXErrors & terr) deplog(head); // reads the latex log head.update(); - // 0.5 + // 1 // At this point we must run external programs if needed. // makeindex will be run if a .idx file changed or was generated. // And if there were undefined citations or changes in references @@ -290,17 +259,17 @@ int LaTeX::run(TeXErrors & terr) if (head.haschanged(idxfile)) { // no checks for now LYXERR(Debug::LATEX, "Running MakeIndex."); - message(_("Running MakeIndex.")); + message(_("Running Index Processor.")); // onlyFilename() is needed for cygwin rerun |= runMakeIndex(onlyFilename(idxfile.absFilename()), runparams); } FileName const nlofile(changeExtension(file.absFilename(), ".nlo")); if (head.haschanged(nlofile)) - rerun |= runMakeIndexNomencl(file, runparams, ".nlo", ".nls"); + rerun |= runMakeIndexNomencl(file, ".nlo", ".nls"); FileName const glofile(changeExtension(file.absFilename(), ".glo")); if (head.haschanged(glofile)) - rerun |= runMakeIndexNomencl(file, runparams, ".glo", ".gls"); + rerun |= runMakeIndexNomencl(file, ".glo", ".gls"); // run bibtex // if (scanres & UNDEF_CIT || scanres & RERUN || run_bibtex) @@ -312,7 +281,7 @@ int LaTeX::run(TeXErrors & terr) LYXERR(Debug::LATEX, "Running BibTeX."); message(_("Running BibTeX.")); updateBibtexDependencies(head, bibtex_info); - rerun |= runBibTeX(bibtex_info); + rerun |= runBibTeX(bibtex_info, runparams); } 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 @@ -320,7 +289,7 @@ int LaTeX::run(TeXErrors & terr) updateBibtexDependencies(head, bibtex_info); } - // 1 + // 2 // we know on this point that latex has been run once (or we just // returned) and the question now is to decide if we need to run // it any more. This is done by asking if any of the files in the @@ -330,7 +299,7 @@ int LaTeX::run(TeXErrors & terr) // run latex once more and // update the dependency structure // -> if not changed: - // we does nothing at this point + // we do nothing at this point // if (rerun || head.sumchange()) { rerun = false; @@ -351,9 +320,24 @@ int LaTeX::run(TeXErrors & terr) } else { LYXERR(Debug::DEPEND, "Dep. file has NOT changed"); } + + // 3 + // rerun bibtex? + // Complex bibliography packages such as Biblatex require + // an additional bibtex cycle sometimes. + if (scanres & UNDEF_CIT) { + // Here we must scan the .aux file and look for + // "\bibdata" and/or "\bibstyle". If one of those + // tags is found -> run bibtex and set rerun = true; + // no checks for now + LYXERR(Debug::LATEX, "Running BibTeX."); + message(_("Running BibTeX.")); + updateBibtexDependencies(head, bibtex_info); + rerun |= runBibTeX(bibtex_info, runparams); + } - // 1.5 - // The inclusion of files generated by external programs like + // 4 + // The inclusion of files generated by external programs such as // makeindex or bibtex might have done changes to pagenumbering, // etc. And because of this we must run the external programs // again to make sure everything is redone correctly. @@ -364,7 +348,7 @@ int LaTeX::run(TeXErrors & terr) if (head.haschanged(idxfile)) { // no checks for now LYXERR(Debug::LATEX, "Running MakeIndex."); - message(_("Running MakeIndex.")); + message(_("Running Index Processor.")); // onlyFilename() is needed for cygwin rerun = runMakeIndex(onlyFilename(changeExtension( file.absFilename(), ".idx")), runparams); @@ -372,11 +356,11 @@ int LaTeX::run(TeXErrors & terr) // I am not pretty sure if need this twice. if (head.haschanged(nlofile)) - rerun |= runMakeIndexNomencl(file, runparams, ".nlo", ".nls"); + rerun |= runMakeIndexNomencl(file, ".nlo", ".nls"); if (head.haschanged(glofile)) - rerun |= runMakeIndexNomencl(file, runparams, ".glo", ".gls"); + rerun |= runMakeIndexNomencl(file, ".glo", ".gls"); - // 2 + // 5 // we will only run latex more if the log file asks for it. // or if the sumchange() is true. // -> rerun asked for: @@ -426,11 +410,23 @@ int LaTeX::startscript() bool LaTeX::runMakeIndex(string const & f, OutputParams const & runparams, string const & params) { + string tmp = runparams.use_japanese ? + lyxrc.jindex_command : lyxrc.index_command; + + if (!runparams.index_command.empty()) + tmp = runparams.index_command; + LYXERR(Debug::LATEX, - "idx file has been made, running makeindex on file " << f); - string tmp = lyxrc.index_command + ' '; + "idx file has been made, running index processor (" + << tmp << ") on file " << f); tmp = subst(tmp, "$$lang", runparams.document_language); + if (runparams.use_indices) { + tmp = lyxrc.splitindex_command + " -m " + quoteName(tmp); + LYXERR(Debug::LATEX, + "Multiple indices. Using splitindex command: " << tmp); + } + tmp += ' '; tmp += quoteName(f); tmp += params; Systemcall one; @@ -440,24 +436,25 @@ bool LaTeX::runMakeIndex(string const & f, OutputParams const & runparams, bool LaTeX::runMakeIndexNomencl(FileName const & file, - OutputParams const & runparams, string const & nlo, string const & nls) { LYXERR(Debug::LATEX, "Running MakeIndex for nomencl."); message(_("Running MakeIndex for nomencl.")); + string tmp = lyxrc.nomencl_command + ' '; // onlyFilename() is needed for cygwin - string const nomenclstr = " -s nomencl.ist -o " + tmp += quoteName(onlyFilename(changeExtension(file.absFilename(), nlo))); + tmp += " -o " + onlyFilename(changeExtension(file.toFilesystemEncoding(), nls)); - return runMakeIndex( - onlyFilename(changeExtension(file.absFilename(), nlo)), - runparams, nomenclstr); + Systemcall one; + one.startscript(Systemcall::Wait, tmp); + return true; } -vector const +vector const LaTeX::scanAuxFiles(FileName const & file) { - vector result; + vector result; result.push_back(scanAuxFile(file)); @@ -474,16 +471,16 @@ LaTeX::scanAuxFiles(FileName const & file) } -Aux_Info const LaTeX::scanAuxFile(FileName const & file) +AuxInfo const LaTeX::scanAuxFile(FileName const & file) { - Aux_Info result; + AuxInfo result; result.aux_file = file; scanAuxFile(file, result); return result; } -void LaTeX::scanAuxFile(FileName const & file, Aux_Info & aux_info) +void LaTeX::scanAuxFile(FileName const & file, AuxInfo & aux_info) { LYXERR(Debug::LATEX, "Scanning aux file: " << file); @@ -535,7 +532,7 @@ void LaTeX::scanAuxFile(FileName const & file, Aux_Info & aux_info) void LaTeX::updateBibtexDependencies(DepTable & dep, - vector const & bibtex_info) + vector const & bibtex_info) { // Since a run of Bibtex mandates more latex runs it is ok to // remove all ".bib" and ".bst" files. @@ -543,7 +540,7 @@ void LaTeX::updateBibtexDependencies(DepTable & dep, dep.remove_files_with_extension(".bst"); //string aux = OnlyFilename(ChangeExtension(file, ".aux")); - for (vector::const_iterator it = bibtex_info.begin(); + for (vector::const_iterator it = bibtex_info.begin(); it != bibtex_info.end(); ++it) { for (set::const_iterator it2 = it->databases.begin(); it2 != it->databases.end(); ++it2) { @@ -562,16 +559,22 @@ void LaTeX::updateBibtexDependencies(DepTable & dep, } -bool LaTeX::runBibTeX(vector const & bibtex_info) +bool LaTeX::runBibTeX(vector const & bibtex_info, + OutputParams const & runparams) { bool result = false; - for (vector::const_iterator it = bibtex_info.begin(); + for (vector::const_iterator it = bibtex_info.begin(); it != bibtex_info.end(); ++it) { if (it->databases.empty()) continue; result = true; - string tmp = lyxrc.bibtex_command + " "; + string tmp = runparams.use_japanese ? + lyxrc.jbibtex_command : lyxrc.bibtex_command; + + if (!runparams.bibtex_command.empty()) + tmp = runparams.bibtex_command; + tmp += " "; // onlyFilename() is needed for cygwin tmp += quoteName(onlyFilename(removeExtension( it->aux_file.absFilename()))); @@ -623,6 +626,12 @@ int LaTeX::scanLogFile(TeXErrors & terr) if (contains(token, "Rerun to get cross-references")) { retval |= RERUN; LYXERR(Debug::LATEX, "We should rerun."); + // package clefval needs 2 latex runs before bibtex + } else if (contains(token, "Value of") + && contains(token, "on page") + && contains(token, "undefined")) { + retval |= ERROR_RERUN; + LYXERR(Debug::LATEX, "Force rerun."); } else if (contains(token, "Citation") && contains(token, "on page") && contains(token, "undefined")) { @@ -647,6 +656,12 @@ int LaTeX::scanLogFile(TeXErrors & terr) LYXERR(Debug::LATEX, "We should rerun."); retval |= RERUN; } + } else if (prefixIs(token, "LETTRE WARNING:")) { + if (contains(token, "veuillez recompiler")) { + // lettre.cls + LYXERR(Debug::LATEX, "We should rerun."); + retval |= RERUN; + } } else if (token[0] == '(') { if (contains(token, "Rerun LaTeX") || contains(token, "Rerun to get")) { @@ -654,8 +669,10 @@ int LaTeX::scanLogFile(TeXErrors & terr) LYXERR(Debug::LATEX, "We should rerun."); retval |= RERUN; } - } else if (prefixIs(token, "! ") || - fle_style && regex_match(token, sub, file_line_error)) { + } else if (prefixIs(token, "! ") + || (fle_style + && regex_match(token, sub, file_line_error) + && !contains(token, "pdfTeX warning"))) { // Ok, we have something that looks like a TeX Error // but what do we really have. @@ -774,12 +791,13 @@ bool handleFoundFile(string const & ff, DepTable & head) // (1) foundfile is an // absolute path and should // be inserted. - if (absolutePath(foundfile)) { + FileName absname; + if (FileName::isAbsolute(foundfile)) { LYXERR(Debug::DEPEND, "AbsolutePath file: " << foundfile); // On initial insert we want to do the update at once // since this file cannot be a file generated by // the latex run. - FileName absname(foundfile); + absname.set(foundfile); if (!insertIfExists(absname, head)) { // check for spaces string strippedfile = foundfile; @@ -802,7 +820,7 @@ bool handleFoundFile(string const & ff, DepTable & head) } string onlyfile = onlyFilename(foundfile); - FileName absname(makeAbsPath(onlyfile)); + absname = makeAbsPath(onlyfile); // check for spaces while (contains(foundfile, ' ')) { @@ -900,7 +918,7 @@ 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 + // Sometimes files are named by "File: xxx" only // So I think we should use some regexps to find files instead. // Note: all file names and paths might contains spaces. bool found_file = false; @@ -1008,7 +1026,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 reg6_1("\\(([^()]+)(.)"); smatch what; string::const_iterator first = token.begin(); string::const_iterator end = token.end();