Jürgen Spitzmüller wrote:
Abdelrazak Younes wrote:
Could you test the attached patch nevertheless? Or Georg maybe?

It fails whenever different documents use different bib files of the same name (without absolute path).

Consider the following case:

- I have a file one.lyx in directory /myfiles/one/ that includes a bibfile refs.bib, which is also in that directory (and hence inserted without path).

- In directory /myfiles/two/, I have another file two.lyx, that also includes a (different) file refs.lyx, which is either included in /myfiles/two/ or situated in the TEXMF tree, so that it also is inserted without path.

When I open one.lyx and then two.lyx, not only the labels in two.lyx are broken, but also the entries in the citation dialog are wrong (i.e. the ones from /myfiles/one/refs.bib).

Since it makes sense to have bib files without path, I think that the scanning has to be buffer-dependend. Another case where it breaks is when you copy the contents of a.lyx to an empty document which is not saved yet (or saved elsewhere).


OK then, IIUC, the attached patch is correct for all use-cases:

1) if a bib file is found in the same directory of the lyx file, this is the one.

2) if not look in the cache.

3) if not in the cache, look for it with kpsewhich.

In practice, this means that we cache only files that are in the texmf tree and there is no room for confusion.

As an added bonus, the patch also avoid the use of 'Path'.

By the way, is it normal that we don't allow bib files outside the texmf tree or along the lyx file?

Abdel.

Index: insets/insetbibtex.C
===================================================================
--- insets/insetbibtex.C        (revision 16588)
+++ insets/insetbibtex.C        (working copy)
@@ -26,14 +26,27 @@
 #include "frontends/Alert.h"
 
 #include "support/filetools.h"
+#include "support/fs_extras.h"
 #include "support/lstrings.h"
 #include "support/lyxlib.h"
 #include "support/os.h"
 #include "support/path.h"
 
 #include <boost/tokenizer.hpp>
+#include <boost/filesystem/operations.hpp>
 
+#include <map>
 
+using std::endl;
+using std::getline;
+using std::string;
+using std::ostream;
+using std::map;
+using std::pair;
+using std::vector;
+
+namespace fs = boost::filesystem;
+
 namespace lyx {
 
 using support::absolutePath;
@@ -61,14 +74,7 @@
 namespace Alert = frontend::Alert;
 namespace os = support::os;
 
-using std::endl;
-using std::getline;
-using std::string;
-using std::ostream;
-using std::pair;
-using std::vector;
 
-
 InsetBibtex::InsetBibtex(InsetCommandParams const & p)
        : InsetCommand(p, "bibtex")
 {}
@@ -304,24 +310,45 @@
 
 vector<FileName> const InsetBibtex::getFiles(Buffer const & buffer) const
 {
-       Path p(buffer.filePath());
+       string const file_path = buffer.filePath();
 
        vector<FileName> vec;
 
-       string tmp;
+       typedef map<string, FileName> BibCache;
+       static map<string, FileName> bib_cache;
+
        // FIXME UNICODE
        string bibfiles = to_utf8(getParam("bibfiles"));
-       bibfiles = split(bibfiles, tmp, ',');
-       while (!tmp.empty()) {
-               FileName const file = findtexfile(changeExtension(tmp, "bib"), 
"bib");
-               lyxerr[Debug::LATEX] << "Bibfile: " << file << endl;
+       while (!bibfiles.empty()) {
+               // Get next file name
+               string bibcode;
+               bibfiles = split(bibfiles, bibcode, ',');
+               bibcode = changeExtension(bibcode, "bib");
 
+               // If the file can be found directly, we just return an
+               // absolute path version of it.
+               FileName const absfile(file_path + bibcode);
+               if (fs::exists(absfile.toFilesystemEncoding())) {
+                       vec.push_back(absfile);
+                       continue;
+               }
+
+               BibCache::const_iterator it = bib_cache.find(bibcode);
+               if (it != bib_cache.end()) {
+                       // We found it in the cache.
+                       vec.push_back(it->second);
+                       lyxerr[Debug::LATEX] << "Bibfile: " << it->second << 
endl;
+                       continue;
+               }
+
+               FileName const file = findtexfile(bibcode, "bib");
                // If we didn't find a matching file name just fail silently
-               if (!file.empty())
-                       vec.push_back(file);
+               if (file.empty())
+                       continue;
 
-               // Get next file name
-               bibfiles = split(bibfiles, tmp, ',');
+               bib_cache[bibcode] = file;
+               vec.push_back(file);
+               lyxerr[Debug::LATEX] << "Bibfile: " << file << endl;
        }
 
        return vec;

Reply via email to