-/* This file is part of
- * ======================================================
+/**
+ * \file LaTeX.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
*
- * LyX, The Document Processor
- * Copyright 1995 Matthias Ettrich
- * Copyright 1995-2001 The LyX Team.
+ * \author Alfredo Braunstein
+ * \author Lars Gullik Bjønnes
+ * \author Jean-Marc Lasgouttes
+ * \author Angus Leeming
+ * \author Dekel Tsur
*
- * This file is Copyright 1996-2001
- * Lars Gullik Bjønnes
- *
- * ======================================================
+ * Full author contact details are available in file CREDITS.
*/
#include <config.h>
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
#include "LaTeX.h"
#include "bufferlist.h"
#include "gettext.h"
-#include "lyxfunc.h"
#include "debug.h"
+#include "DepTable.h"
#include "support/filetools.h"
#include "support/FileInfo.h"
+#include "support/tostr.h"
#include "support/lstrings.h"
#include "support/lyxlib.h"
#include "support/systemcall.h"
#include <fstream>
#include <cstdio> // sscanf
+using namespace lyx::support;
+
#ifndef CXX_GLOBAL_CSTD
using std::sscanf;
#endif
using std::set;
using boost::regex;
using boost::regex_match;
+
+#ifndef USE_INCLUDED_STRING
using boost::smatch;
+#else
+using boost::cmatch;
+#endif
// TODO: in no particular order
// - get rid of the extern BufferList and the call to
extern BufferList bufferlist;
+namespace {
+
+string runMessage(unsigned int count)
+{
+ return bformat(_("Waiting for LaTeX run number %1$s"), tostr(count));
+}
+
+};
+
/*
* CLASS TEXERRORS
*/
errors.push_back(newerr);
}
+
+bool operator==(Aux_Info const & a, Aux_Info const & o)
+{
+ 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)
+{
+ return !(a == o);
+}
+
+
/*
* CLASS LaTeX
*/
-LaTeX::LaTeX(string const & latex, string const & f, string const & p)
- : cmd(latex), file(f), path(p)
+LaTeX::LaTeX(string const & latex, LatexRunParams const & rp,
+ string const & f, string const & p)
+ : cmd(latex), file(f), path(p), runparams(rp)
{
num_errors = 0;
depfile = file + ".dep";
// What files do we have to delete?
// This will at least make latex do all the runs
- lyx::unlink(depfile);
+ unlink(depfile);
// but the reason for the error might be in a generated file...
- string ofname = OnlyFilename(file);
+ string const ofname = OnlyFilename(file);
// bibtex file
- string bbl = ChangeExtension(ofname, ".bbl");
- lyx::unlink(bbl);
+ string const bbl = ChangeExtension(ofname, ".bbl");
+ unlink(bbl);
// makeindex file
- string ind = ChangeExtension(ofname, ".ind");
- lyx::unlink(ind);
+ string const ind = ChangeExtension(ofname, ".ind");
+ unlink(ind);
// Also remove the aux file
- string aux = ChangeExtension(ofname, ".aux");
- lyx::unlink(aux);
+ string const aux = ChangeExtension(ofname, ".aux");
+ unlink(aux);
}
-int LaTeX::run(TeXErrors & terr, LyXFunc * lfun)
+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
int scanres = NO_ERRORS;
unsigned int count = 0; // number of times run
num_errors = 0; // just to make sure.
- const unsigned int MAX_RUN = 6;
+ unsigned int const MAX_RUN = 6;
DepTable head; // empty head
bool rerun = false; // rerun requested
// The class LaTeX does not know the temp path.
- bufferlist.updateIncludedTeXfiles(lyx::getcwd()); //GetCWD());
+ bufferlist.updateIncludedTeXfiles(getcwd(), runparams);
// Never write the depfile if an error was encountered.
if (had_depfile) {
lyxerr[Debug::DEPEND] << "Dependency file exists" << endl;
// Read the dep file:
- head.read(depfile);
+ had_depfile = head.read(depfile);
+ }
+
+ if (had_depfile) {
// Update the checksums
head.update();
// Can't just check if anything has changed because it might have aborted
run_bibtex = true;
} else
lyxerr[Debug::DEPEND]
- << "Dependency file does not exist" << endl;
+ << "Dependency file does not exist, or has wrong format" << endl;
/// We scan the aux file even when had_depfile = false,
/// because we can run pdflatex on the file after running latex on it,
++count;
lyxerr[Debug::LATEX] << "Run #" << count << endl;
- if (lfun) {
- ostringstream str;
- str << _("LaTeX run number") << ' ' << count;
- // check lyxstring string stream and gcc 3.1 before fixing
- lfun->dispatch(LFUN_MESSAGE, string(str.str().c_str()));
- }
-
- this->operator()();
+ message(runMessage(count));
+
+ startscript();
scanres = scanLogFile(terr);
if (scanres & ERROR_RERUN) {
lyxerr[Debug::LATEX] << "Rerunning LaTeX" << endl;
- this->operator()();
+ startscript();
scanres = scanLogFile(terr);
}
if (head.haschanged(OnlyFilename(ChangeExtension(file, ".idx")))) {
// no checks for now
lyxerr[Debug::LATEX] << "Running MakeIndex." << endl;
- if (lfun) {
- lfun->dispatch(LFUN_MESSAGE, string(_("Running MakeIndex.")));
- }
-
+ message(_("Running MakeIndex."));
rerun = runMakeIndex(OnlyFilename(ChangeExtension(file, ".idx")));
}
// tags is found -> run bibtex and set rerun = true;
// no checks for now
lyxerr[Debug::LATEX] << "Running BibTeX." << endl;
- if (lfun) {
- lfun->dispatch(LFUN_MESSAGE, string(_("Running BibTeX.")));
- }
-
+ message(_("Running BibTeX."));
updateBibtexDependencies(head, bibtex_info);
rerun |= runBibTeX(bibtex_info);
} else if (!had_depfile) {
<< "Dep. file has changed or rerun requested" << endl;
lyxerr[Debug::LATEX]
<< "Run #" << count << endl;
- if (lfun) {
- ostringstream str;
- str << _("LaTeX run number") << ' ' << count;
- // check lyxstring string stream and gcc 3.1 before fixing
- lfun->dispatch(LFUN_MESSAGE, string(str.str().c_str()));
- }
-
- this->operator()();
+ message(runMessage(count));
+ startscript();
scanres = scanLogFile(terr);
if (scanres & ERRORS) {
deleteFilesOnError();
if (head.haschanged(OnlyFilename(ChangeExtension(file, ".idx")))) {
// no checks for now
lyxerr[Debug::LATEX] << "Running MakeIndex." << endl;
- if (lfun) {
- lfun->dispatch(LFUN_MESSAGE, string(_("Running MakeIndex.")));
- }
-
+ message(_("Running MakeIndex."));
rerun = runMakeIndex(OnlyFilename(ChangeExtension(file, ".idx")));
}
rerun = false;
++count;
lyxerr[Debug::LATEX] << "Run #" << count << endl;
- if (lfun) {
- ostringstream str;
- str << _("LaTeX run number") << ' ' << count;
- // check lyxstring string stream and gcc 3.1 before fixing
- lfun->dispatch(LFUN_MESSAGE, string(str.str().c_str()));
- }
-
- this->operator()();
+ message(runMessage(count));
+ startscript();
scanres = scanLogFile(terr);
if (scanres & ERRORS) {
deleteFilesOnError();
}
-int LaTeX::operator()()
+int LaTeX::startscript()
{
#ifndef __EMX__
string tmp = cmd + ' ' + QuoteName(file) + " > /dev/null";
result.push_back(scanAuxFile(file));
for (int i = 1; i < 1000; ++i) {
- string file2 = ChangeExtension(file, "") + "." + tostr(i)
+ string file2 = ChangeExtension(file, "") + '.' + tostr(i)
+ ".aux";
FileInfo fi(file2);
if (!fi.exist())
regex reg4("\\\\@input\\{([^}]+)\\}");
while (getline(ifs, token)) {
- token = strip(token, '\r');
+ token = rtrim(token, "\r");
+#ifndef USE_INCLUDED_STRING
smatch sub;
- if (regex_match(token, sub, reg1)) {
- string data = sub[1];
+#else
+ cmatch sub;
+#endif
+ if (regex_match(STRCONV(token), sub, reg1)) {
+ string data = STRCONV(sub.str(1));
while (!data.empty()) {
string citation;
data = split(data, citation, ',');
<< citation << endl;
aux_info.citations.insert(citation);
}
- } else if (regex_match(token, sub, reg2)) {
- string data = sub[1];
+ } else if (regex_match(STRCONV(token), sub, reg2)) {
+ string data = sub.STRCONV(str(1));
// data is now all the bib files separated by ','
// get them one by one and pass them to the helper
while (!data.empty()) {
string database;
data = split(data, database, ',');
database = ChangeExtension(database, "bib");
- lyxerr[Debug::LATEX] << "Bibtex database: `"
- << database << "'" << endl;
+ lyxerr[Debug::LATEX] << "BibTeX database: `"
+ << database << '\'' << endl;
aux_info.databases.insert(database);
}
- } else if (regex_match(token, sub, reg3)) {
- string style = sub[1];
+ } else if (regex_match(STRCONV(token), sub, reg3)) {
+ string style = STRCONV(sub.str(1));
// token is now the style file
// pass it to the helper
style = ChangeExtension(style, "bst");
- lyxerr[Debug::LATEX] << "Bibtex style: `"
- << style << "'" << endl;
+ lyxerr[Debug::LATEX] << "BibTeX style: `"
+ << style << '\'' << endl;
aux_info.styles.insert(style);
- } else if (regex_match(token, sub, reg4)) {
- string file2 = sub[1];
+ } else if (regex_match(STRCONV(token), sub, reg4)) {
+ string const file2 = STRCONV(sub.str(1));
scanAuxFile(file2, aux_info);
}
}
<< "We should rerun." << endl;
retval |= RERUN;
}
- } else if (prefixIs(token, "(")) {
+ } else if (token[0] == '(') {
if (contains(token, "Rerun LaTeX") ||
contains(token, "Rerun to get")) {
// Used by natbib
string foundfile;
string token;
getline(ifs, token);
- token = strip(token, '\r');
+ token = rtrim(token, "\r");
if (token.empty()) continue;
+#ifndef USE_INCLUDED_STRING
smatch sub;
- if (regex_match(token, sub, reg1)) {
- foundfile = sub[1];
- } else if (regex_match(token, sub, reg2)) {
- foundfile = sub[1];
- } else if (regex_match(token, sub, reg3)) {
- foundfile = sub[1];
- } else if (regex_match(token, sub, reg4)) {
- foundfile = sub[1];
- } else if (regex_match(token, sub, reg5)) {
- foundfile = sub[1];
+#else
+ cmatch sub;
+#endif
+ if (regex_match(STRCONV(token), sub, reg1)) {
+ foundfile = STRCONV(sub.str(1));
+ } else if (regex_match(STRCONV(token), sub, reg2)) {
+ foundfile = STRCONV(sub.str(1));
+ } else if (regex_match(STRCONV(token), sub, reg3)) {
+ foundfile = STRCONV(sub.str(1));
+ } else if (regex_match(STRCONV(token), sub, reg4)) {
+ foundfile = STRCONV(sub.str(1));
+ } else if (regex_match(STRCONV(token), sub, reg5)) {
+ foundfile = STRCONV(sub.str(1));
} else {
continue;
}
// (2) foundfile is in the tmpdir
// insert it into head
else if (FileInfo(OnlyFilename(foundfile)).exist()) {
- if (regex_match(foundfile, unwanted)) {
+ if (regex_match(STRCONV(foundfile), unwanted)) {
lyxerr[Debug::DEPEND]
<< "We don't want "
<< OnlyFilename(foundfile)