]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetBibtex.cpp
cprotect: don't consider content in Notes, deactivated branches etc.
[lyx.git] / src / insets / InsetBibtex.cpp
index 4ead8663492ef6ac631715b5997323210af1052b..0db4555ce0f0d31bd5bb394d6bf2fbe4f03a041b 100644 (file)
@@ -59,19 +59,7 @@ namespace os = support::os;
 
 InsetBibtex::InsetBibtex(Buffer * buf, InsetCommandParams const & p)
        : InsetCommand(buf, p)
-{
-       buffer().invalidateBibfileCache();
-       buffer().removeBiblioTempFiles();
-}
-
-
-InsetBibtex::~InsetBibtex()
-{
-       if (isBufferLoaded()) {
-               buffer().invalidateBibfileCache();
-               buffer().removeBiblioTempFiles();
-       }
-}
+{}
 
 
 ParamInfo const & InsetBibtex::findInfo(string const & /* cmdName */)
@@ -113,8 +101,6 @@ void InsetBibtex::doDispatch(Cursor & cur, FuncRequest & cmd)
 
                cur.recordUndo();
                setParams(p);
-               buffer().invalidateBibfileCache();
-               buffer().removeBiblioTempFiles();
                cur.forceBufferUpdate();
                break;
        }
@@ -149,7 +135,7 @@ void InsetBibtex::editDatabases() const
 
        int nr_databases = bibfilelist.size();
        if (nr_databases > 1) {
-                       docstring const engine = usingBiblatex() ? _("Biblatex") : _("BibTex");
+                       docstring const engine = usingBiblatex() ? _("Biblatex") : _("BibTeX");
                        docstring message = bformat(_("The %1$s[[BibTeX/Biblatex]] inset includes %2$s databases.\n"
                                                       "If you proceed, all of them will be opened."),
                                                        engine, convert<docstring>(nr_databases));
@@ -164,15 +150,15 @@ void InsetBibtex::editDatabases() const
        vector<docstring>::const_iterator en = bibfilelist.end();
        for (; it != en; ++it) {
                FileName const bibfile = getBibTeXPath(*it, buffer());
-               formats.edit(buffer(), bibfile,
-                    formats.getFormatFromFile(bibfile));
+               theFormats().edit(buffer(), bibfile,
+                    theFormats().getFormatFromFile(bibfile));
        }
 }
 
 
 bool InsetBibtex::usingBiblatex() const
 {
-       return buffer().params().useBiblatex();
+       return buffer().masterParams().useBiblatex();
 }
 
 
@@ -206,12 +192,12 @@ docstring InsetBibtex::toolTip(BufferView const & /*bv*/, int /*x*/, int /*y*/)
                        style = split(style, bibtotoc, char_type(','));
        }
 
+       docstring const btprint = getParam("btprint");
        if (!usingBiblatex()) {
                tip += _("Style File:");
                tip += "<ul><li>" + (style.empty() ? _("none") : style) + "</li></ul>";
 
                tip += _("Lists:") + " ";
-               docstring btprint = getParam("btprint");
                if (btprint == "btPrintAll")
                        tip += _("all references");
                else if (btprint == "btPrintNotCited")
@@ -222,9 +208,24 @@ docstring InsetBibtex::toolTip(BufferView const & /*bv*/, int /*x*/, int /*y*/)
                        tip += ", ";
                        tip += _("included in TOC");
                }
+               if (!buffer().parent()
+                   && buffer().params().multibib == "child") {
+                       tip += "<br />";
+                       tip += _("Note: This bibliography is not output, since bibliographies in the master file "
+                                "are not allowed with the setting 'Multiple bibliographies per child document'");
+               }
        } else {
-               if (toc)
-                       tip += _("Included in TOC");
+               tip += _("Lists:") + " ";
+               if (btprint == "bibbysection")
+                       tip += _("all reference units");
+               else if (btprint == "btPrintAll")
+                       tip += _("all references");
+               else
+                       tip += _("all cited references");
+               if (toc) {
+                       tip += ", ";
+                       tip += _("included in TOC");
+               }
                if (!getParam("biblatexopts").empty()) {
                        if (toc)
                                tip += "<br />";
@@ -250,6 +251,13 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
        // 4. \end{btSect}
        // With Biblatex:
        // \printbibliography[biblatexopts]
+       // or
+       // \bibbysection[biblatexopts] - if btprint is "bibbysection"
+
+       // chapterbib does not allow bibliographies in the master
+       if (!usingBiblatex() && !runparams.is_child
+           && buffer().params().multibib == "child")
+               return;
 
        string style = to_utf8(getParam("options")); // maybe empty! and with bibtotoc
        string bibtotoc;
@@ -269,7 +277,10 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
                docstring btprint = getParam("btprint");
                if (btprint == "btPrintAll")
                        os << "\\nocite{*}\n";
-               os << "\\printbibliography";
+               if (btprint == "bibbysection" && !buffer().masterParams().multibib.empty())
+                       os << "\\bibbysection";
+               else
+                       os << "\\printbibliography";
                if (!opts.empty())
                        os << "[" << opts << "]";
                os << "\n";
@@ -279,9 +290,9 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
                        buffer().prepareBibFilePaths(runparams, getBibFiles(), false);
                // Style options
                if (style == "default")
-                       style = buffer().params().defaultBiblioStyle();
-               if (!style.empty() && !buffer().params().use_bibtopic) {
-                       string base = buffer().prepareFileNameForLaTeX(style, ".bst", runparams.nice);
+                       style = buffer().masterParams().defaultBiblioStyle();
+               if (!style.empty() && !buffer().masterParams().useBibtopic()) {
+                       string base = buffer().masterBuffer()->prepareFileNameForLaTeX(style, ".bst", runparams.nice);
                        FileName const try_in_file =
                                makeAbsPath(base + ".bst", buffer().filePath());
                        bool const not_from_texmf = try_in_file.isReadableFile();
@@ -316,7 +327,7 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
                                                      "BibTeX will be unable to find it."));
                }
                // Handle the bibtopic case
-               if (!db_out.empty() && buffer().params().use_bibtopic) {
+               if (!db_out.empty() && buffer().masterParams().useBibtopic()) {
                        os << "\\begin{btSect}";
                        if (!style.empty())
                                os << "[" << style << "]";
@@ -329,17 +340,17 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
                           << "\\end{btSect}\n";
                }
                // bibtotoc option
-               if (!bibtotoc.empty() && !buffer().params().use_bibtopic) {
+               if (!bibtotoc.empty() && !buffer().masterParams().useBibtopic()) {
                        // set label for hyperref, see http://www.lyx.org/trac/ticket/6470
-                       if (buffer().params().pdfoptions().use_hyperref)
+                       if (buffer().masterParams().pdfoptions().use_hyperref)
                                        os << "\\phantomsection";
-                       if (buffer().params().documentClass().hasLaTeXLayout("chapter"))
+                       if (buffer().masterParams().documentClass().hasLaTeXLayout("chapter"))
                                os << "\\addcontentsline{toc}{chapter}{\\bibname}";
-                       else if (buffer().params().documentClass().hasLaTeXLayout("section"))
+                       else if (buffer().masterParams().documentClass().hasLaTeXLayout("section"))
                                os << "\\addcontentsline{toc}{section}{\\refname}";
                }
                // The bibliography command
-               if (!db_out.empty() && !buffer().params().use_bibtopic) {
+               if (!db_out.empty() && !buffer().masterParams().useBibtopic()) {
                        docstring btprint = getParam("btprint");
                        if (btprint == "btPrintAll") {
                                os << "\\nocite{*}\n";
@@ -350,15 +361,15 @@ void InsetBibtex::latex(otexstream & os, OutputParams const & runparams) const
 }
 
 
-support::FileNamePairList InsetBibtex::getBibFiles() const
+FileNamePairList InsetBibtex::getBibFiles() const
 {
        FileName path(buffer().filePath());
-       support::PathChanger p(path);
+       PathChanger p(path);
 
        // We need to store both the real FileName and the way it is entered
        // (with full path, rel path or as a single file name).
        // The latter is needed for biblatex's central bibfile macro.
-       support::FileNamePairList vec;
+       FileNamePairList vec;
 
        vector<docstring> bibfilelist = getVectorFromString(getParam("bibfiles"));
        vector<docstring>::const_iterator it = bibfilelist.begin();
@@ -373,7 +384,6 @@ support::FileNamePairList InsetBibtex::getBibFiles() const
        }
 
        return vec;
-
 }
 
 namespace {
@@ -449,11 +459,9 @@ namespace {
                        return false;
 
                // read value
-               bool legalChar = true;
                while (ifs && !isSpace(ch) &&
-                                                delimChars.find(ch) == docstring::npos &&
-                                                (legalChar = (illegalChars.find(ch) == docstring::npos))
-                                       )
+                      delimChars.find(ch) == docstring::npos &&
+                      illegalChars.find(ch) == docstring::npos)
                {
                        if (chCase == makeLowerCase)
                                val += lowercase(ch);
@@ -462,7 +470,7 @@ namespace {
                        ifs.get(ch);
                }
 
-               if (!legalChar) {
+               if (illegalChars.find(ch) != docstring::npos) {
                        ifs.putback(ch);
                        return false;
                }
@@ -614,16 +622,16 @@ namespace {
 
                return true;
        }
-}
+} // namespace
 
 
-void InsetBibtex::collectBibKeys(InsetIterator const & /*di*/) const
+void InsetBibtex::collectBibKeys(InsetIterator const & /*di*/, FileNameList & checkedFiles) const
 {
-       parseBibTeXFiles();
+       parseBibTeXFiles(checkedFiles);
 }
 
 
-void InsetBibtex::parseBibTeXFiles() const
+void InsetBibtex::parseBibTeXFiles(FileNameList & checkedFiles) const
 {
        // This bibtex parser is a first step to parse bibtex files
        // more precisely.
@@ -646,12 +654,19 @@ void InsetBibtex::parseBibTeXFiles() const
 
        BiblioInfo keylist;
 
-       support::FileNamePairList const files = getBibFiles();
-       support::FileNamePairList::const_iterator it = files.begin();
-       support::FileNamePairList::const_iterator en = files.end();
+       FileNamePairList const files = getBibFiles();
+       FileNamePairList::const_iterator it = files.begin();
+       FileNamePairList::const_iterator en = files.end();
        for (; it != en; ++ it) {
-               ifdocstream ifs(it->second.toFilesystemEncoding().c_str(),
-                       ios_base::in, buffer().params().encoding().iconvName());
+               FileName const bibfile = it->second;
+               if (find(checkedFiles.begin(), checkedFiles.end(), bibfile) != checkedFiles.end())
+                       // already checked this one. Skip.
+                       continue;
+               else
+                       // record that we check this.
+                       checkedFiles.push_back(bibfile);
+               ifdocstream ifs(bibfile.toFilesystemEncoding().c_str(),
+                       ios_base::in, buffer().masterParams().encoding().iconvName());
 
                char_type ch;
                VarMap strings;
@@ -862,8 +877,11 @@ bool InsetBibtex::delDatabase(docstring const & db)
 
 void InsetBibtex::validate(LaTeXFeatures & features) const
 {
-       if (features.bufferParams().use_bibtopic)
+       BufferParams const & mparams = features.buffer().masterParams();
+       if (mparams.useBibtopic())
                features.require("bibtopic");
+       else if (!mparams.useBiblatex() && mparams.multibib == "child")
+               features.require("chapterbib");
        // FIXME XHTML
        // It'd be better to be able to get this from an InsetLayout, but at present
        // InsetLayouts do not seem really to work for things that aren't InsetTexts.
@@ -874,6 +892,11 @@ void InsetBibtex::validate(LaTeXFeatures & features) const
 }
 
 
+void InsetBibtex::updateBuffer(ParIterator const &, UpdateType) {
+       buffer().registerBibfiles(getBibFiles());
+}
+
+
 int InsetBibtex::plaintext(odocstringstream & os,
        OutputParams const & op, size_t max_length) const
 {
@@ -927,7 +950,7 @@ docstring InsetBibtex::xhtml(XHTMLStream & xs, OutputParams const &) const
 {
        BiblioInfo const & bibinfo = buffer().masterBibInfo();
        bool const all_entries = getParam("btprint") == "btPrintAll";
-       vector<docstring> const & cites = 
+       vector<docstring> const & cites =
            all_entries ? bibinfo.getKeys() : bibinfo.citedEntries();
 
        docstring const reflabel = buffer().B_("References");
@@ -952,17 +975,17 @@ docstring InsetBibtex::xhtml(XHTMLStream & xs, OutputParams const &) const
                        continue;
 
                BibTeXInfo const & entry = biit->second;
-               string const attr = "class='bibtexentry' id='LyXCite-" 
+               string const attr = "class='bibtexentry' id='LyXCite-"
                    + to_utf8(html::cleanAttr(entry.key())) + "'";
                xs << html::StartTag("div", attr);
-               
+
                // don't print labels if we're outputting all entries
                if (!all_entries) {
                        xs << html::StartTag("span", "class='bibtexlabel'")
                                << entry.label()
                                << html::EndTag("span");
                }
-               
+
                // FIXME Right now, we are calling BibInfo::getInfo on the key,
                // which will give us all the cross-referenced info. But for every
                // entry, so there's a lot of repitition. This should be fixed.