]> git.lyx.org Git - lyx.git/blobdiff - src/insets/insetbibtex.C
* src/LyXAction.C: mark goto-clear-bookmark as working without buffer
[lyx.git] / src / insets / insetbibtex.C
index a8e6905f3b2e006d710c60db2ee47ed49a404dad..fa604fddd381159f9b1e90203dcfaab0bbae44ed 100644 (file)
@@ -16,6 +16,7 @@
 #include "bufferparams.h"
 #include "dispatchresult.h"
 #include "debug.h"
+#include "encoding.h"
 #include "funcrequest.h"
 #include "gettext.h"
 #include "LaTeXFeatures.h"
@@ -32,9 +33,6 @@
 
 #include <boost/tokenizer.hpp>
 
-#include <fstream>
-#include <sstream>
-
 
 namespace lyx {
 
@@ -66,7 +64,6 @@ namespace os = support::os;
 using std::endl;
 using std::getline;
 using std::string;
-using std::ifstream;
 using std::ostream;
 using std::pair;
 using std::vector;
@@ -116,7 +113,7 @@ namespace {
 string normalize_name(Buffer const & buffer, OutputParams const & runparams,
                      string const & name, string const & ext)
 {
-       string const fname = makeAbsPath(name, buffer.filePath());
+       string const fname = makeAbsPath(name, buffer.filePath()).absFilename();
        if (absolutePath(name) || !isFileReadable(FileName(fname + ext)))
                return name;
        else if (!runparams.nice)
@@ -169,8 +166,8 @@ int InsetBibtex::latex(Buffer const & buffer, odocstream & os,
                string utf8input(to_utf8(input));
                string database =
                        normalize_name(buffer, runparams, utf8input, ".bib");
-               string const try_in_file = makeAbsPath(database + ".bib", buffer.filePath());
-               bool const not_from_texmf = isFileReadable(FileName(try_in_file));
+               FileName const try_in_file(makeAbsPath(database + ".bib", buffer.filePath()));
+               bool const not_from_texmf = isFileReadable(try_in_file);
 
                if (!runparams.inComment && !runparams.dryrun && !runparams.nice &&
                    not_from_texmf) {
@@ -178,7 +175,7 @@ int InsetBibtex::latex(Buffer const & buffer, odocstream & os,
                        // mangledFilename() needs the extension
                        DocFileName const in_file = DocFileName(try_in_file);
                        database = removeExtension(in_file.mangledFilename());
-                       FileName const out_file = FileName(makeAbsPath(database + ".bib",
+                       FileName const out_file(makeAbsPath(database + ".bib",
                                        buffer.getMasterBuffer()->temppath()));
 
                        bool const success = copy(in_file, out_file);
@@ -224,8 +221,8 @@ int InsetBibtex::latex(Buffer const & buffer, odocstream & os,
        if (!style.empty()) {
                string base =
                        normalize_name(buffer, runparams, style, ".bst");
-               string const try_in_file = makeAbsPath(base + ".bst", buffer.filePath());
-               bool const not_from_texmf = isFileReadable(FileName(try_in_file));
+               FileName const try_in_file(makeAbsPath(base + ".bst", buffer.filePath()));
+               bool const not_from_texmf = isFileReadable(try_in_file);
                // If this style does not come from texmf and we are not
                // exporting to .tex copy it to the tmp directory.
                // This prevents problems with spaces and 8bit charcaters
@@ -235,7 +232,7 @@ int InsetBibtex::latex(Buffer const & buffer, odocstream & os,
                        // use new style name
                        DocFileName const in_file = DocFileName(try_in_file);
                        base = removeExtension(in_file.mangledFilename());
-                       FileName const out_file = FileName(makeAbsPath(base + ".bst",
+                       FileName const out_file(makeAbsPath(base + ".bst",
                                        buffer.getMasterBuffer()->temppath()));
                        bool const success = copy(in_file, out_file);
                        if (!success) {
@@ -305,18 +302,18 @@ int InsetBibtex::latex(Buffer const & buffer, odocstream & os,
 }
 
 
-vector<string> const InsetBibtex::getFiles(Buffer const & buffer) const
+vector<FileName> const InsetBibtex::getFiles(Buffer const & buffer) const
 {
        Path p(buffer.filePath());
 
-       vector<string> vec;
+       vector<FileName> vec;
 
        string tmp;
        // FIXME UNICODE
        string bibfiles = to_utf8(getParam("bibfiles"));
        bibfiles = split(bibfiles, tmp, ',');
        while (!tmp.empty()) {
-               string file = findtexfile(changeExtension(tmp, "bib"), "bib");
+               FileName const file = findtexfile(changeExtension(tmp, "bib"), "bib");
                lyxerr[Debug::LATEX] << "Bibfile: " << file << endl;
 
                // If we didn't find a matching file name just fail silently
@@ -333,36 +330,48 @@ vector<string> const InsetBibtex::getFiles(Buffer const & buffer) const
 
 // This method returns a comma separated list of Bibtex entries
 void InsetBibtex::fillWithBibKeys(Buffer const & buffer,
-                                 std::vector<std::pair<string, string> > & keys) const
+               std::vector<std::pair<string, docstring> > & keys) const
 {
-       vector<string> const files = getFiles(buffer);
-       for (vector<string>::const_iterator it = files.begin();
+       vector<FileName> const files = getFiles(buffer);
+       for (vector<FileName>::const_iterator it = files.begin();
             it != files.end(); ++ it) {
                // This is a _very_ simple parser for Bibtex database
                // files. All it does is to look for lines starting
                // in @ and not being @preamble and @string entries.
                // It does NOT do any syntax checking!
-               ifstream ifs(it->c_str());
-               string linebuf0;
+
+               // Officially bibtex does only support ASCII, but in practice
+               // you can use the encoding of the main document as long as
+               // some elements like keys and names are pure ASCII. Therefore
+               // we convert the file from the buffer encoding.
+               // We don't restrict keys to ASCII in LyX, since our own
+               // InsetBibitem can generate non-ASCII keys, and nonstandard
+               // 8bit clean bibtex forks exist.
+               idocfstream ifs(it->toFilesystemEncoding().c_str(),
+                               std::ios_base::in,
+                               buffer.params().encoding().iconvName());
+               docstring linebuf0;
                while (getline(ifs, linebuf0)) {
-                       string linebuf = trim(linebuf0);
-                       if (linebuf.empty()) continue;
-                       if (prefixIs(linebuf, "@")) {
+                       docstring linebuf = trim(linebuf0);
+                       if (linebuf.empty())
+                               continue;
+                       if (prefixIs(linebuf, '@')) {
                                linebuf = subst(linebuf, '{', '(');
-                               string tmp;
+                               docstring tmp;
                                linebuf = split(linebuf, tmp, '(');
                                tmp = ascii_lowercase(tmp);
-                               if (!prefixIs(tmp, "@string")
-                                   && !prefixIs(tmp, "@preamble")) {
+                               if (!prefixIs(tmp, from_ascii("@string")) &&
+                                   !prefixIs(tmp, from_ascii("@preamble"))) {
                                        linebuf = split(linebuf, tmp, ',');
                                        tmp = ltrim(tmp, " \t");
                                        if (!tmp.empty()) {
-                                               keys.push_back(pair<string,string>(tmp,string()));
+                                               // FIXME UNICODE
+                                               keys.push_back(pair<string, docstring>(
+                                                       to_utf8(tmp), docstring()));
                                        }
                                }
-                       } else if (!keys.empty()) {
-                               keys.back().second += linebuf + "\n";
-                       }
+                       } else if (!keys.empty())
+                               keys.back().second += linebuf + '\n';
                }
        }
 }