diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp index bc30499b35..f162b36e82 100644 --- a/src/BiblioInfo.cpp +++ b/src/BiblioInfo.cpp @@ -482,6 +482,16 @@ docstring const BiblioInfo::getInfo(docstring const & key) const } +bool const BiblioInfo::isBibtex(docstring const & key) const +{ + BiblioInfo::const_iterator it = find(key); + if (it == end()) + return false; + return it->second.isBibTeX(); +} + + + vector const BiblioInfo::getCiteStrings( docstring const & key, Buffer const & buf) const { diff --git a/src/BiblioInfo.h b/src/BiblioInfo.h index 77c3dab729..394d9c416b 100644 --- a/src/BiblioInfo.h +++ b/src/BiblioInfo.h @@ -156,6 +156,9 @@ public: /// Empty if no info exists. /// Note that this will retrieve data from the crossref as needed. docstring const getInfo(docstring const & key) const; + /// Is this a reference from a bibtex database + /// or from a bibliography environment? + bool const isBibtex(docstring const & key) const; /** * "Translates" the available Citation Styles into strings for a given key, * either numerical or author-year depending upon the active engine. (See diff --git a/src/insets/InsetBibitem.cpp b/src/insets/InsetBibitem.cpp index ded2b8b9cc..fc158a0233 100644 --- a/src/insets/InsetBibitem.cpp +++ b/src/insets/InsetBibitem.cpp @@ -20,12 +20,14 @@ #include "BufferView.h" #include "Counters.h" #include "DispatchResult.h" +#include "Encoding.h" #include "FuncRequest.h" #include "InsetIterator.h" #include "InsetList.h" #include "Language.h" #include "Lexer.h" #include "output_xhtml.h" +#include "OutputParams.h" #include "Paragraph.h" #include "ParagraphList.h" #include "ParIterator.h" @@ -34,6 +36,7 @@ #include "frontends/alert.h" #include "support/convert.h" +#include "support/debug.h" #include "support/docstream.h" #include "support/gettext.h" #include "support/lstrings.h" @@ -172,8 +175,48 @@ int InsetBibitem::plaintext(odocstream & os, OutputParams const &) const } +int InsetBibitem::latex(odocstream & os, OutputParams const & runparams) const +{ + docstring cmd = '\\' + from_ascii(defaultCommand()); + docstring uncodable; + if (!getParam("label").empty()) { + cmd += '['; + docstring orig = getParam("label"); + for (size_t n = 0; n < orig.size(); ++n) { + try { + cmd += runparams.encoding->latexChar(orig[n]); + } catch (EncodingException & /* e */) { + LYXERR0("Uncodable character in bibitem!"); + if (runparams.dryrun) { + cmd += "<" + _("LyX Warning: ") + + _("uncodable character") + " '"; + cmd += docstring(1, orig[n]); + cmd += "'>"; + } else + uncodable += orig[n]; + } + } + cmd += ']'; + } + cmd += '{' + escape(getParam("key")) + '}'; + + os << cmd; + + if (!uncodable.empty()) { + // issue a warning about omitted characters + // FIXME: should be passed to the error dialog + frontend::Alert::warning(_("Uncodable characters in bibliography item"), + bformat(_("The following characters in one of the bibliography items are\n" + "not representable in the current encoding and have been omitted:\n%1$s."), + uncodable)); + } + + return 0; +} + + // ale070405 -docstring bibitemWidest(Buffer const & buffer) +docstring bibitemWidest(Buffer const & buffer, OutputParams const & runparams) { int w = 0; @@ -234,8 +277,22 @@ docstring bibitemWidest(Buffer const & buffer) } } - if (!lbl.empty()) - return lbl; + if (!lbl.empty()) { + docstring latex_lbl; + for (size_t n = 0; n < lbl.size(); ++n) { + try { + latex_lbl += runparams.encoding->latexChar(lbl[n]); + } catch (EncodingException & /* e */) { + if (runparams.dryrun) { + latex_lbl += "<" + _("LyX Warning: ") + + _("uncodable character") + " '"; + latex_lbl += docstring(1, lbl[n]); + latex_lbl += "'>"; + } + } + } + return latex_lbl; + } return from_ascii("99"); } diff --git a/src/insets/InsetBibitem.h b/src/insets/InsetBibitem.h index 98fdf9ff8e..74ae2f8249 100644 --- a/src/insets/InsetBibitem.h +++ b/src/insets/InsetBibitem.h @@ -63,6 +63,8 @@ private: /// docstring xhtml(XHTMLStream &, OutputParams const &) const; /// + int latex(odocstream &, OutputParams const &) const; + /// virtual void fillWithBibKeys(BiblioInfo &, InsetIterator const &) const; /// Update the counter of this inset void updateLabels(ParIterator const &, UpdateType); @@ -73,7 +75,7 @@ private: /// Inset * clone() const { return new InsetBibitem(*this); } - friend docstring bibitemWidest(Buffer const & buffer); + friend docstring bibitemWidest(Buffer const & buffer, OutputParams const &); /// The label that is set by updateLabels docstring autolabel_; /// @@ -82,7 +84,7 @@ private: /// Return the widest label in the Bibliography. -docstring bibitemWidest(Buffer const &); +docstring bibitemWidest(Buffer const &, OutputParams const &); } // namespace lyx diff --git a/src/insets/InsetCitation.cpp b/src/insets/InsetCitation.cpp index 8ea7da606d..8c97550ae1 100644 --- a/src/insets/InsetCitation.cpp +++ b/src/insets/InsetCitation.cpp @@ -547,6 +547,7 @@ void InsetCitation::tocString(odocstream & os) const int InsetCitation::latex(odocstream & os, OutputParams const & runparams) const { CiteEngine cite_engine = buffer().params().citeEngine(); + BiblioInfo const & bi = buffer().masterBibInfo(); // FIXME UNICODE docstring const cite_str = from_utf8( asValidLatexCommand(getCmdName(), cite_engine)); @@ -563,7 +564,11 @@ int InsetCitation::latex(odocstream & os, OutputParams const & runparams) const else if (!after.empty()) os << '[' << after << ']'; - os << '{' << cleanupWhitespace(getParam("key")) << '}'; + if (!bi.isBibtex(getParam("key"))) + // escape chars with bibitems + os << '{' << escape(cleanupWhitespace(getParam("key"))) << '}'; + else + os << '{' << cleanupWhitespace(getParam("key")) << '}'; if (runparams.inulemcmd) os << "}"; diff --git a/src/output_latex.cpp b/src/output_latex.cpp index a7af2199d6..5457dee3df 100644 --- a/src/output_latex.cpp +++ b/src/output_latex.cpp @@ -181,7 +181,7 @@ TeXEnvironment(Buffer const & buf, << "}\n"; } else if (style.labeltype == LABEL_BIBLIO) { if (pit->params().labelWidthString().empty()) - os << '{' << bibitemWidest(buf) << "}\n"; + os << '{' << bibitemWidest(buf, runparams) << "}\n"; else os << '{' << pit->params().labelWidthString()