mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 21:21:32 +00:00
- Fix the bug that bibtex was not always run when needed.
- Fix the babel error (after changing the language of the document) bug. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@1444 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
360aadd00b
commit
db2a042267
@ -1,3 +1,9 @@
|
|||||||
|
2001-02-02 Dekel Tsur <dekelts@tau.ac.il>
|
||||||
|
|
||||||
|
* LaTeX.C (scanAuxFile): A rewrite of this method. It now returns
|
||||||
|
all the citation/databases/styles in the auxilary file.
|
||||||
|
(run): Rerun latex if there was a babel language error.
|
||||||
|
|
||||||
2001-02-01 Dekel Tsur <dekelts@tau.ac.il>
|
2001-02-01 Dekel Tsur <dekelts@tau.ac.il>
|
||||||
|
|
||||||
* text.C (Backspace): Preserve the font when changing newline char
|
* text.C (Backspace): Preserve the font when changing newline char
|
||||||
|
254
src/LaTeX.C
254
src/LaTeX.C
@ -37,6 +37,7 @@ using std::ifstream;
|
|||||||
using std::getline;
|
using std::getline;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
using std::set;
|
||||||
|
|
||||||
// TODO: in no particular order
|
// TODO: in no particular order
|
||||||
// - get rid of the extern BufferList and the call to
|
// - get rid of the extern BufferList and the call to
|
||||||
@ -139,56 +140,58 @@ int LaTeX::run(TeXErrors & terr, MiniBuffer * minib)
|
|||||||
// run latex once (we need to run latex once anyway) and
|
// run latex once (we need to run latex once anyway) and
|
||||||
// remake the dependency file.
|
// remake the dependency file.
|
||||||
//
|
//
|
||||||
|
|
||||||
FileInfo fi(depfile);
|
FileInfo fi(depfile);
|
||||||
|
bool had_depfile = fi.exist();
|
||||||
bool run_bibtex = false;
|
bool run_bibtex = false;
|
||||||
if (fi.exist()) {
|
string aux_file = OnlyFilename(ChangeExtension(file, "aux"));
|
||||||
|
|
||||||
|
if (had_depfile) {
|
||||||
|
lyxerr[Debug::DEPEND] << "Dependency file exists" << endl;
|
||||||
// Read the dep file:
|
// Read the dep file:
|
||||||
head.read(depfile);
|
head.read(depfile);
|
||||||
// Update the checksums
|
// Update the checksums
|
||||||
head.update();
|
head.update();
|
||||||
|
if (!head.sumchange()) {
|
||||||
lyxerr[Debug::DEPEND] << "Dependency file exists" << endl;
|
|
||||||
if (head.sumchange()) {
|
|
||||||
++count;
|
|
||||||
lyxerr[Debug::DEPEND]
|
|
||||||
<< "Dependency file has changed" << endl;
|
|
||||||
lyxerr[Debug::LATEX]
|
|
||||||
<< "Run #" << count << endl;
|
|
||||||
WriteStatus(minib,
|
|
||||||
string(_("LaTeX run number ")) + tostr(count));
|
|
||||||
this->operator()();
|
|
||||||
scanres = scanLogFile(terr);
|
|
||||||
if (scanres & LaTeX::ERRORS) {
|
|
||||||
deleteFilesOnError();
|
|
||||||
return scanres; // return on error
|
|
||||||
}
|
|
||||||
run_bibtex = scanAux(head);
|
|
||||||
if (run_bibtex)
|
|
||||||
lyxerr[Debug::DEPEND]
|
|
||||||
<< "Bibtex demands rerun" << endl;
|
|
||||||
} else {
|
|
||||||
lyxerr[Debug::DEPEND] << "return no_change" << endl;
|
lyxerr[Debug::DEPEND] << "return no_change" << endl;
|
||||||
return LaTeX::NO_CHANGE;
|
return LaTeX::NO_CHANGE;
|
||||||
}
|
}
|
||||||
} else {
|
lyxerr[Debug::DEPEND]
|
||||||
++count;
|
<< "Dependency file has changed" << endl;
|
||||||
|
|
||||||
|
if (head.extchanged(".bib") || head.extchanged(".bst"))
|
||||||
|
run_bibtex = true;
|
||||||
|
} else
|
||||||
lyxerr[Debug::DEPEND]
|
lyxerr[Debug::DEPEND]
|
||||||
<< "Dependency file does not exist" << endl;
|
<< "Dependency file does not exist" << endl;
|
||||||
|
|
||||||
lyxerr[Debug::LATEX]
|
/// We scan the aux file even when had_depfile = false,
|
||||||
<< "Run #" << count << endl;
|
/// because we can run pdflatex on the file after running latex on it,
|
||||||
head.insert(file, true);
|
/// in which case we will not need to run bibtex again.
|
||||||
WriteStatus(minib,
|
vector<Aux_Info> bibtex_info_old;
|
||||||
string(_("LaTeX run number ")) + tostr(count));
|
if (!run_bibtex)
|
||||||
|
bibtex_info_old = scanAuxFiles(aux_file);
|
||||||
|
|
||||||
|
++count;
|
||||||
|
lyxerr[Debug::LATEX] << "Run #" << count << endl;
|
||||||
|
WriteStatus(minib, string(_("LaTeX run number ")) + tostr(count));
|
||||||
|
this->operator()();
|
||||||
|
scanres = scanLogFile(terr);
|
||||||
|
if (scanres & LaTeX::ERROR_RERUN) {
|
||||||
|
lyxerr[Debug::LATEX] << "Rerunning LaTeX" << endl;
|
||||||
this->operator()();
|
this->operator()();
|
||||||
scanres = scanLogFile(terr);
|
scanres = scanLogFile(terr);
|
||||||
if (scanres & LaTeX::ERRORS) {
|
|
||||||
deleteFilesOnError();
|
|
||||||
return scanres; // return on error
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scanres & LaTeX::ERRORS) {
|
||||||
|
deleteFilesOnError();
|
||||||
|
return scanres; // return on error
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<Aux_Info> const bibtex_info = scanAuxFiles(aux_file);
|
||||||
|
if (!run_bibtex && bibtex_info_old != bibtex_info)
|
||||||
|
run_bibtex = true;
|
||||||
|
|
||||||
// update the dependencies.
|
// update the dependencies.
|
||||||
deplog(head); // reads the latex log
|
deplog(head); // reads the latex log
|
||||||
head.update();
|
head.update();
|
||||||
@ -218,8 +221,13 @@ int LaTeX::run(TeXErrors & terr, MiniBuffer * minib)
|
|||||||
// no checks for now
|
// no checks for now
|
||||||
lyxerr[Debug::LATEX] << "Running BibTeX." << endl;
|
lyxerr[Debug::LATEX] << "Running BibTeX." << endl;
|
||||||
WriteStatus(minib, _("Running BibTeX."));
|
WriteStatus(minib, _("Running BibTeX."));
|
||||||
rerun = runBibTeX(head);
|
updateBibtexDependencies(head, bibtex_info);
|
||||||
}
|
rerun |= runBibTeX(bibtex_info);
|
||||||
|
} 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
|
||||||
|
/// insert the .bib and .bst files into the .dep-pdf file.
|
||||||
|
updateBibtexDependencies(head, bibtex_info);
|
||||||
|
|
||||||
// 1
|
// 1
|
||||||
// we know on this point that latex has been run once (or we just
|
// we know on this point that latex has been run once (or we just
|
||||||
@ -337,146 +345,136 @@ bool LaTeX::runMakeIndex(string const & f)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scanAux may return a wrong result if there are more than two bibliographies,
|
|
||||||
// and after LaTeX-ing the file, the user changes the order of the bibliography
|
|
||||||
// and run LaTeX again. However, in this case, bibtopic prints a warning message which
|
|
||||||
// is caught by scanLogFile.
|
|
||||||
bool LaTeX::scanAux(DepTable & dep)
|
|
||||||
{
|
|
||||||
// if any of the bib file has changed we don't have to
|
|
||||||
// check the .aux file.
|
|
||||||
if (dep.extchanged(".bib")
|
|
||||||
|| dep.extchanged(".bst")) return true;
|
|
||||||
|
|
||||||
string aux = OnlyFilename(ChangeExtension(file, ".aux"));
|
|
||||||
return !scanAuxFiles(aux, dep, false).empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<string> const
|
vector<Aux_Info> const
|
||||||
LaTeX::scanAuxFiles(string const & file, DepTable & dep, bool insert)
|
LaTeX::scanAuxFiles(string const & file)
|
||||||
{
|
{
|
||||||
vector<string> result;
|
vector<Aux_Info> result;
|
||||||
if (scanAuxFile(file, dep, insert)) {
|
|
||||||
result.push_back(file);
|
result.push_back(scanAuxFile(file));
|
||||||
if (!insert)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 1; i < 1000; ++i) {
|
for (int i = 1; i < 1000; ++i) {
|
||||||
string file2 = ChangeExtension(file, "") + "." + tostr(i)
|
string file2 = ChangeExtension(file, "") + "." + tostr(i)
|
||||||
+ ".aux";
|
+ ".aux";
|
||||||
FileInfo fi(file2);
|
FileInfo fi(file2);
|
||||||
if (!fi.exist())
|
if (!fi.exist())
|
||||||
return result;
|
break;
|
||||||
if (scanAuxFile(file2, dep, insert)) {
|
result.push_back(scanAuxFile(file2));
|
||||||
result.push_back(file2);
|
|
||||||
if (!insert)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// If insert = true, then scanAuxFile returns true iff the aux file contains
|
Aux_Info const LaTeX::scanAuxFile(string const & file)
|
||||||
// a bibtex database (i.e. a \bibdata command), or it inputs another auxfile which
|
{
|
||||||
// contains a bibtex database.
|
Aux_Info result;
|
||||||
// Also the dep is updated for all bibtex databases and bibtex styles in the aux
|
result.aux_file = file;
|
||||||
// file.
|
scanAuxFile(file, result);
|
||||||
// Ideally, scanAuxFile should return true iff one of the bibtex database/styles has
|
return result;
|
||||||
// changes from previous run, or a new bibtex database/styles was added to the aux file.
|
}
|
||||||
// However, it is probably not worth the effort.
|
|
||||||
//
|
|
||||||
// If insert = false, then scanAuxFile returns true iff the aux file contains a
|
void LaTeX::scanAuxFile(string const & file, Aux_Info & aux_info)
|
||||||
// bibtex database or a bibtex style that do not appear in dep.
|
|
||||||
//
|
|
||||||
bool LaTeX::scanAuxFile(string const & file, DepTable & dep, bool insert)
|
|
||||||
{
|
{
|
||||||
lyxerr[Debug::LATEX] << "Scanning aux file: " << file << endl;
|
lyxerr[Debug::LATEX] << "Scanning aux file: " << file << endl;
|
||||||
|
|
||||||
ifstream ifs(file.c_str());
|
ifstream ifs(file.c_str());
|
||||||
string token;
|
string token;
|
||||||
LRegex reg1("\\\\bibdata\\{([^}]+)\\}");
|
LRegex reg1("\\\\citation\\{([^}]+)\\}");
|
||||||
LRegex reg2("\\\\bibstyle\\{([^}]+)\\}");
|
LRegex reg2("\\\\bibdata\\{([^}]+)\\}");
|
||||||
LRegex reg3("\\\\@input\\{([^}]+)\\}");
|
LRegex reg3("\\\\bibstyle\\{([^}]+)\\}");
|
||||||
bool result = false;
|
LRegex reg4("\\\\@input\\{([^}]+)\\}");
|
||||||
|
|
||||||
while (getline(ifs, token)) {
|
while (getline(ifs, token)) {
|
||||||
if (reg1.exact_match(token)) {
|
if (reg1.exact_match(token)) {
|
||||||
if (insert)
|
|
||||||
result = true;
|
|
||||||
LRegex::SubMatches const & sub = reg1.exec(token);
|
LRegex::SubMatches const & sub = reg1.exec(token);
|
||||||
|
string data = LSubstring(token, sub[1].first,
|
||||||
|
sub[1].second);
|
||||||
|
while (!data.empty()) {
|
||||||
|
string citation;
|
||||||
|
data = split(data, citation, ',');
|
||||||
|
lyxerr[Debug::LATEX] << "Citation: "
|
||||||
|
<< citation << endl;
|
||||||
|
aux_info.citations.insert(citation);
|
||||||
|
}
|
||||||
|
} else if (reg2.exact_match(token)) {
|
||||||
|
LRegex::SubMatches const & sub = reg2.exec(token);
|
||||||
string data = LSubstring(token, sub[1].first,
|
string data = LSubstring(token, sub[1].first,
|
||||||
sub[1].second);
|
sub[1].second);
|
||||||
// data is now all the bib files separated by ','
|
// data is now all the bib files separated by ','
|
||||||
// get them one by one and pass them to the helper
|
// get them one by one and pass them to the helper
|
||||||
while (!data.empty()) {
|
while (!data.empty()) {
|
||||||
string l;
|
string database;
|
||||||
data = split(data, l, ',');
|
data = split(data, database, ',');
|
||||||
string full_l =
|
database = ChangeExtension(database, "bib");
|
||||||
findtexfile(ChangeExtension(l, "bib"),
|
|
||||||
"bib");
|
|
||||||
lyxerr[Debug::LATEX] << "Bibtex database: `"
|
lyxerr[Debug::LATEX] << "Bibtex database: `"
|
||||||
<< full_l << "'" << endl;
|
<< database << "'" << endl;
|
||||||
if (!full_l.empty()) {
|
aux_info.databases.insert(database);
|
||||||
if (insert)
|
|
||||||
// add full_l to the dep file.
|
|
||||||
dep.insert(full_l, true);
|
|
||||||
else
|
|
||||||
if (!dep.exist(full_l))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (reg2.exact_match(token)) {
|
} else if (reg3.exact_match(token)) {
|
||||||
LRegex::SubMatches const & sub = reg2.exec(token);
|
LRegex::SubMatches const & sub = reg3.exec(token);
|
||||||
string style = LSubstring(token, sub[1].first,
|
string style = LSubstring(token, sub[1].first,
|
||||||
sub[1].second);
|
sub[1].second);
|
||||||
// token is now the style file
|
// token is now the style file
|
||||||
// pass it to the helper
|
// pass it to the helper
|
||||||
string full_l =
|
style = ChangeExtension(style, "bst");
|
||||||
findtexfile(ChangeExtension(style, "bst"),
|
|
||||||
"bst");
|
|
||||||
lyxerr[Debug::LATEX] << "Bibtex style: `"
|
lyxerr[Debug::LATEX] << "Bibtex style: `"
|
||||||
<< full_l << "'" << endl;
|
<< style << "'" << endl;
|
||||||
if (!full_l.empty()) {
|
aux_info.styles.insert(style);
|
||||||
if (insert)
|
} else if (reg4.exact_match(token)) {
|
||||||
// add full_l to the dep file.
|
LRegex::SubMatches const & sub = reg4.exec(token);
|
||||||
dep.insert(full_l, true);
|
|
||||||
else
|
|
||||||
if (!dep.exist(full_l))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (reg3.exact_match(token)) {
|
|
||||||
LRegex::SubMatches const & sub = reg3.exec(token);
|
|
||||||
string file2 = LSubstring(token, sub[1].first,
|
string file2 = LSubstring(token, sub[1].first,
|
||||||
sub[1].second);
|
sub[1].second);
|
||||||
result |= scanAuxFile(file2, dep, insert);
|
scanAuxFile(file2, aux_info);
|
||||||
if (result && !insert)
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LaTeX::runBibTeX(DepTable & dep)
|
void LaTeX::updateBibtexDependencies(DepTable & dep,
|
||||||
|
vector<Aux_Info> const & bibtex_info)
|
||||||
{
|
{
|
||||||
// Since a run of Bibtex mandates more latex runs it is ok to
|
// Since a run of Bibtex mandates more latex runs it is ok to
|
||||||
// remove all ".bib" and ".bst" files, it is also required to
|
// remove all ".bib" and ".bst" files.
|
||||||
// discover style and database changes.
|
|
||||||
dep.remove_files_with_extension(".bib");
|
dep.remove_files_with_extension(".bib");
|
||||||
dep.remove_files_with_extension(".bst");
|
dep.remove_files_with_extension(".bst");
|
||||||
string aux = OnlyFilename(ChangeExtension(file, ".aux"));
|
string aux = OnlyFilename(ChangeExtension(file, ".aux"));
|
||||||
vector<string> const aux_files = scanAuxFiles(aux, dep, true);
|
|
||||||
// Run bibtex on each of the aux files in
|
for (vector<Aux_Info>::const_iterator it = bibtex_info.begin();
|
||||||
for (vector<string>::const_iterator it = aux_files.begin();
|
it != bibtex_info.end(); ++it) {
|
||||||
it != aux_files.end(); ++it) {
|
for (set<string>::const_iterator it2 = it->databases.begin();
|
||||||
|
it2 != it->databases.end(); ++it2) {
|
||||||
|
string file = findtexfile(*it2, "bib");
|
||||||
|
if (!file.empty())
|
||||||
|
dep.insert(file, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (set<string>::const_iterator it2 = it->styles.begin();
|
||||||
|
it2 != it->styles.end(); ++it2) {
|
||||||
|
string file = findtexfile(*it2, "bst");
|
||||||
|
if (!file.empty())
|
||||||
|
dep.insert(file, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LaTeX::runBibTeX(vector<Aux_Info> const & bibtex_info)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
for (vector<Aux_Info>::const_iterator it = bibtex_info.begin();
|
||||||
|
it != bibtex_info.end(); ++it) {
|
||||||
|
if (it->databases.empty())
|
||||||
|
continue;
|
||||||
|
result = true;
|
||||||
|
|
||||||
string tmp = "bibtex ";
|
string tmp = "bibtex ";
|
||||||
tmp += OnlyFilename(ChangeExtension(*it, string()));
|
tmp += OnlyFilename(ChangeExtension(it->aux_file, string()));
|
||||||
Systemcalls one;
|
Systemcalls one;
|
||||||
one.startscript(Systemcalls::System, tmp);
|
one.startscript(Systemcalls::System, tmp);
|
||||||
}
|
}
|
||||||
// Return whether bibtex was run
|
// Return whether bibtex was run
|
||||||
return !aux_files.empty();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -546,6 +544,8 @@ int LaTeX::scanLogFile(TeXErrors & terr)
|
|||||||
if (prefixIs(tmp, "l.")) {
|
if (prefixIs(tmp, "l.")) {
|
||||||
// we have a latex error
|
// we have a latex error
|
||||||
retval |= TEX_ERROR;
|
retval |= TEX_ERROR;
|
||||||
|
if (contains(desc, "Package babel Error: You haven't defined the language"))
|
||||||
|
retval |= ERROR_RERUN;
|
||||||
// get the line number:
|
// get the line number:
|
||||||
int line = 0;
|
int line = 0;
|
||||||
sscanf(tmp.c_str(), "l.%d", &line);
|
sscanf(tmp.c_str(), "l.%d", &line);
|
||||||
|
37
src/LaTeX.h
37
src/LaTeX.h
@ -22,6 +22,7 @@
|
|||||||
#include "LString.h"
|
#include "LString.h"
|
||||||
#include "DepTable.h"
|
#include "DepTable.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
@ -61,6 +62,26 @@ private:
|
|||||||
Errors errors;
|
Errors errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Aux_Info {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
Aux_Info() {}
|
||||||
|
///
|
||||||
|
string aux_file;
|
||||||
|
///
|
||||||
|
std::set<string> citations;
|
||||||
|
///
|
||||||
|
std::set<string> databases;
|
||||||
|
///
|
||||||
|
std::set<string> styles;
|
||||||
|
///
|
||||||
|
operator==(Aux_Info const & o) const {
|
||||||
|
return aux_file == o.aux_file &&
|
||||||
|
citations == o.citations &&
|
||||||
|
databases == o.databases &&
|
||||||
|
styles == o.styles;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
class LaTeX : public noncopyable {
|
class LaTeX : public noncopyable {
|
||||||
@ -100,6 +121,8 @@ public:
|
|||||||
///
|
///
|
||||||
TOO_MANY_ERRORS = 4096,
|
TOO_MANY_ERRORS = 4096,
|
||||||
///
|
///
|
||||||
|
ERROR_RERUN = 8192,
|
||||||
|
///
|
||||||
ERRORS = TEX_ERROR + LATEX_ERROR,
|
ERRORS = TEX_ERROR + LATEX_ERROR,
|
||||||
///
|
///
|
||||||
WARNINGS = TEX_WARNING + LATEX_WARNING + PACKAGE_WARNING
|
WARNINGS = TEX_WARNING + LATEX_WARNING + PACKAGE_WARNING
|
||||||
@ -138,15 +161,19 @@ protected:
|
|||||||
bool runMakeIndex(string const &);
|
bool runMakeIndex(string const &);
|
||||||
|
|
||||||
///
|
///
|
||||||
bool scanAux(DepTable &);
|
std::vector<Aux_Info> const scanAuxFiles(string const &);
|
||||||
|
|
||||||
///
|
///
|
||||||
std::vector<string> const
|
Aux_Info const scanAuxFile(string const &);
|
||||||
scanAuxFiles(string const &, DepTable &, bool);
|
|
||||||
///
|
///
|
||||||
bool scanAuxFile(string const &, DepTable &, bool);
|
void scanAuxFile(string const &, Aux_Info &);
|
||||||
|
|
||||||
///
|
///
|
||||||
bool runBibTeX(DepTable &);
|
void updateBibtexDependencies(DepTable &, vector<Aux_Info> const &);
|
||||||
|
|
||||||
|
///
|
||||||
|
bool runBibTeX(vector<Aux_Info> const &);
|
||||||
|
|
||||||
///
|
///
|
||||||
void deleteFilesOnError() const;
|
void deleteFilesOnError() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user