X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetCitation.cpp;h=93e79263f6f64f331457a3aee8a2b1611424a5e2;hb=26006c8ffca453dafc4aff95381f42b9f91e4d8a;hp=260bd41bf23aef70e81c2d1524ca8bdff70c2d61;hpb=0cb39e6f8b5f48a2da892f0f515e8ccfd7aa5921;p=lyx.git diff --git a/src/insets/InsetCitation.cpp b/src/insets/InsetCitation.cpp index 260bd41bf2..93e79263f6 100644 --- a/src/insets/InsetCitation.cpp +++ b/src/insets/InsetCitation.cpp @@ -4,7 +4,7 @@ * Licence details can be found in the file COPYING. * * \author Angus Leeming - * \author Herbert Voß + * \author Herbert Voß * * Full author contact details are available in file CREDITS. */ @@ -16,15 +16,17 @@ #include "Buffer.h" #include "buffer_funcs.h" #include "BufferParams.h" +#include "BufferView.h" #include "DispatchResult.h" -#include "EmbeddedFiles.h" #include "FuncRequest.h" #include "LaTeXFeatures.h" +#include "output_xhtml.h" #include "ParIterator.h" #include "TocBackend.h" #include "support/debug.h" #include "support/docstream.h" +#include "support/FileNameList.h" #include "support/gettext.h" #include "support/lstrings.h" @@ -64,28 +66,28 @@ vector const & possibleCiteCommands() // FIXME See the header for the issue. -string defaultCiteCommand(biblio::CiteEngine engine) +string defaultCiteCommand(CiteEngine engine) { string str; switch (engine) { - case biblio::ENGINE_BASIC: + case ENGINE_BASIC: str = "cite"; break; - case biblio::ENGINE_NATBIB_AUTHORYEAR: + case ENGINE_NATBIB_AUTHORYEAR: str = "citet"; break; - case biblio::ENGINE_NATBIB_NUMERICAL: + case ENGINE_NATBIB_NUMERICAL: str = "citep"; break; - case biblio::ENGINE_JURABIB: + case ENGINE_JURABIB: str = "cite"; break; } return str; } - -string asValidLatexCommand(string const & input, biblio::CiteEngine const engine) + +string asValidLatexCommand(string const & input, CiteEngine const engine) { string const default_str = defaultCiteCommand(engine); if (!InsetCitation::isCompatibleCommand(input)) @@ -93,14 +95,17 @@ string asValidLatexCommand(string const & input, biblio::CiteEngine const engine string output; switch (engine) { - case biblio::ENGINE_BASIC: - output = input; + case ENGINE_BASIC: + if (input == "nocite") + output = input; + else + output = default_str; break; - case biblio::ENGINE_NATBIB_AUTHORYEAR: - case biblio::ENGINE_NATBIB_NUMERICAL: - if (input == "cite" || input == "citefield" || - input == "citetitle" || input == "cite*") + case ENGINE_NATBIB_AUTHORYEAR: + case ENGINE_NATBIB_NUMERICAL: + if (input == "cite" || input == "citefield" + || input == "citetitle" || input == "cite*") output = default_str; else if (prefixIs(input, "foot")) output = input.substr(4); @@ -108,7 +113,7 @@ string asValidLatexCommand(string const & input, biblio::CiteEngine const engine output = input; break; - case biblio::ENGINE_JURABIB: { + case ENGINE_JURABIB: { // Jurabib does not support the 'uppercase' natbib style. if (input[0] == 'C') output = string(1, 'c') + input.substr(1); @@ -131,43 +136,13 @@ string asValidLatexCommand(string const & input, biblio::CiteEngine const engine docstring complexLabel(Buffer const & buffer, string const & citeType, docstring const & keyList, docstring const & before, docstring const & after, - biblio::CiteEngine engine) + CiteEngine engine) { // Only start the process off after the buffer is loaded from file. if (!buffer.isFullyLoaded()) return docstring(); - // Cache the labels - typedef map CachedMap; - static CachedMap cached_keys; - - // and cache the timestamp of the bibliography files. - static map bibfileStatus; - - BiblioInfo biblist; - - EmbeddedFileList const & bibfilesCache = buffer.getBibfilesCache(); - // compare the cached timestamps with the actual ones. - bool changed = false; - for (EmbeddedFileList::const_iterator it = bibfilesCache.begin(); - it != bibfilesCache.end(); ++ it) { - FileName const f = *it; - time_t lastw = f.lastModified(); - if (lastw != bibfileStatus[f]) { - changed = true; - bibfileStatus[f] = lastw; - } - } - - // build the list only if the bibfiles have been changed - if (cached_keys[&buffer].empty() || bibfileStatus.empty() || changed) { - biblist.fillWithBibKeys(&buffer); - cached_keys[&buffer] = biblist; - } else { - // use the cached keys - biblist = cached_keys[&buffer]; - } - + BiblioInfo const & biblist = buffer.masterBibInfo(); if (biblist.empty()) return docstring(); @@ -221,8 +196,8 @@ docstring complexLabel(Buffer const & buffer, // One day, these might be tunable (as they are in BibTeX). char op, cp; // opening and closing parenthesis. - char * sep; // punctuation mark separating citation entries. - if (engine == biblio::ENGINE_BASIC) { + const char * sep; // punctuation mark separating citation entries. + if (engine == ENGINE_BASIC) { op = '['; cp = ']'; sep = ","; @@ -252,9 +227,9 @@ docstring complexLabel(Buffer const & buffer, // authors1/; ... ; // authors_last, if (cite_type == "cite") { - if (engine == biblio::ENGINE_BASIC) { + if (engine == ENGINE_BASIC) { label += *it + sep_str; - } else if (engine == biblio::ENGINE_JURABIB) { + } else if (engine == ENGINE_JURABIB) { if (it == keys.begin()) label += author + before_str + sep_str; else @@ -269,25 +244,25 @@ docstring complexLabel(Buffer const & buffer, // authors_last ( year, ) } else if (cite_type == "citet") { switch (engine) { - case biblio::ENGINE_NATBIB_AUTHORYEAR: + case ENGINE_NATBIB_AUTHORYEAR: label += author + op_str + before_str + year + cp + sep_str; break; - case biblio::ENGINE_NATBIB_NUMERICAL: + case ENGINE_NATBIB_NUMERICAL: label += author + op_str + before_str + '#' + *it + cp + sep_str; break; - case biblio::ENGINE_JURABIB: + case ENGINE_JURABIB: label += before_str + author + op_str + year + cp + sep_str; break; - case biblio::ENGINE_BASIC: + case ENGINE_BASIC: break; } // author, year; author, year; ... } else if (cite_type == "citep" || cite_type == "citealp") { - if (engine == biblio::ENGINE_NATBIB_NUMERICAL) { + if (engine == ENGINE_NATBIB_NUMERICAL) { label += *it + sep_str; } else { label += author + ", " + year + sep_str; @@ -297,18 +272,18 @@ docstring complexLabel(Buffer const & buffer, // authors_last year, ) } else if (cite_type == "citealt") { switch (engine) { - case biblio::ENGINE_NATBIB_AUTHORYEAR: + case ENGINE_NATBIB_AUTHORYEAR: label += author + ' ' + before_str + year + sep_str; break; - case biblio::ENGINE_NATBIB_NUMERICAL: + case ENGINE_NATBIB_NUMERICAL: label += author + ' ' + before_str + '#' + *it + sep_str; break; - case biblio::ENGINE_JURABIB: + case ENGINE_JURABIB: label += before_str + author + ' ' + year + sep_str; break; - case biblio::ENGINE_BASIC: + case ENGINE_BASIC: break; } @@ -330,7 +305,7 @@ docstring complexLabel(Buffer const & buffer, label.insert(label.size() - 1, after_str); } else { bool const add = - !(engine == biblio::ENGINE_NATBIB_NUMERICAL && + !(engine == ENGINE_NATBIB_NUMERICAL && (cite_type == "citeauthor" || cite_type == "citeyear")); if (add) @@ -345,7 +320,7 @@ docstring complexLabel(Buffer const & buffer, } if (cite_type == "citep" || cite_type == "citeyearpar" || - (cite_type == "cite" && engine == biblio::ENGINE_BASIC) ) + (cite_type == "cite" && engine == ENGINE_BASIC) ) label = op + label + cp; return label; @@ -381,8 +356,8 @@ docstring basicLabel(docstring const & keyList, docstring const & after) ParamInfo InsetCitation::param_info_; -InsetCitation::InsetCitation(InsetCommandParams const & p) - : InsetCommand(p, "citation") +InsetCitation::InsetCitation(Buffer * buf, InsetCommandParams const & p) + : InsetCommand(buf, p, "citation") {} @@ -409,13 +384,45 @@ bool InsetCitation::isCompatibleCommand(string const & cmd) } +docstring InsetCitation::toolTip(BufferView const & bv, int, int) const +{ + Buffer const & buf = bv.buffer(); + // Only after the buffer is loaded from file... + if (!buf.isFullyLoaded()) + return docstring(); + + BiblioInfo const & bi = buf.masterBibInfo(); + if (bi.empty()) + return _("No bibliography defined!"); + + docstring const & key = getParam("key"); + if (key.empty()) + return _("No citations selected!"); + + vector keys = getVectorFromString(key); + vector::const_iterator it = keys.begin(); + vector::const_iterator en = keys.end(); + docstring tip; + for (; it != en; ++it) { + docstring const key_info = bi.getInfo(*it); + if (key_info.empty()) + continue; + if (!tip.empty()) + tip += "\n"; + tip += wrap(key_info, -4); + } + return tip; +} + + + docstring InsetCitation::generateLabel() const { - docstring const before = getParam("before"); - docstring const after = getParam("after"); + docstring const & before = getParam("before"); + docstring const & after = getParam("after"); docstring label; - biblio::CiteEngine const engine = buffer().params().citeEngine(); + CiteEngine const engine = buffer().params().citeEngine(); label = complexLabel(buffer(), getCmdName(), getParam("key"), before, after, engine); @@ -435,7 +442,7 @@ docstring InsetCitation::screenLabel() const void InsetCitation::updateLabels(ParIterator const &) { - biblio::CiteEngine const engine = buffer().params().citeEngine(); + CiteEngine const engine = buffer().params().citeEngine(); if (cache.params == params() && cache.engine == engine) return; @@ -457,10 +464,10 @@ void InsetCitation::updateLabels(ParIterator const &) } -void InsetCitation::addToToc(ParConstIterator const & cpit) const +void InsetCitation::addToToc(DocIterator const & cpit) { Toc & toc = buffer().tocBackend().toc("citation"); - toc.push_back(TocItem(cpit, 0, cache.screen_label)); + toc.push_back(TocItem(cpit, 0, getParam("key"))); } @@ -498,7 +505,49 @@ int InsetCitation::docbook(odocstream & os, OutputParams const &) const } -void InsetCitation::textString(odocstream & os) const +docstring InsetCitation::xhtml(XHTMLStream & xs, OutputParams const &) const +{ + BiblioInfo const & bi = buffer().masterBibInfo(); + docstring const & key_list = getParam("key"); + if (key_list.empty()) + return docstring(); + + // FIXME We shuld do a better job outputing different things for the + // different citation styles. For now, we use square brackets for every + // case. + xs << "["; + docstring const & before = getParam("before"); + if (!before.empty()) + xs << before << " "; + + vector const keys = getVectorFromString(key_list); + vector::const_iterator it = keys.begin(); + vector::const_iterator const en = keys.end(); + bool first = true; + for (; it != en; ++it) { + BiblioInfo::const_iterator const bt = bi.find(*it); + if (bt == bi.end()) + continue; + BibTeXInfo const & bibinfo = bt->second; + if (!first) { + xs << ", "; + first = false; + } + docstring const & label = bibinfo.label(); + docstring const & target = label.empty() ? *it : label; + string const attr = "href='#" + to_utf8(*it) + "'"; + xs << StartTag("a", attr) << target << EndTag("a"); + } + + docstring const & after = getParam("after"); + if (!after.empty()) + xs << ", " << after; + xs << "]"; + return docstring(); +} + + +void InsetCitation::tocString(odocstream & os) const { plaintext(os, OutputParams(0)); } @@ -508,24 +557,30 @@ void InsetCitation::textString(odocstream & os) const // the \cite command is valid. Eg, the user has natbib enabled, inputs some // citations and then changes his mind, turning natbib support off. The output // should revert to \cite[]{} -int InsetCitation::latex(odocstream & os, OutputParams const &) const +int InsetCitation::latex(odocstream & os, OutputParams const & runparams) const { - biblio::CiteEngine cite_engine = buffer().params().citeEngine(); + CiteEngine cite_engine = buffer().params().citeEngine(); // FIXME UNICODE docstring const cite_str = from_utf8( asValidLatexCommand(getCmdName(), cite_engine)); + if (runparams.inulemcmd) + os << "\\mbox{"; + os << "\\" << cite_str; docstring const & before = getParam("before"); docstring const & after = getParam("after"); - if (!before.empty() && cite_engine != biblio::ENGINE_BASIC) + if (!before.empty() && cite_engine != ENGINE_BASIC) os << '[' << before << "][" << after << ']'; else if (!after.empty()) os << '[' << after << ']'; os << '{' << cleanupWhitespace(getParam("key")) << '}'; + if (runparams.inulemcmd) + os << "}"; + return 0; } @@ -533,17 +588,23 @@ int InsetCitation::latex(odocstream & os, OutputParams const &) const void InsetCitation::validate(LaTeXFeatures & features) const { switch (features.bufferParams().citeEngine()) { - case biblio::ENGINE_BASIC: + case ENGINE_BASIC: break; - case biblio::ENGINE_NATBIB_AUTHORYEAR: - case biblio::ENGINE_NATBIB_NUMERICAL: + case ENGINE_NATBIB_AUTHORYEAR: + case ENGINE_NATBIB_NUMERICAL: features.require("natbib"); break; - case biblio::ENGINE_JURABIB: + case ENGINE_JURABIB: features.require("jurabib"); break; } } +docstring InsetCitation::contextMenu(BufferView const &, int, int) const +{ + return from_ascii("context-citation"); +} + + } // namespace lyx