X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBiblioInfo.cpp;h=7005519ac3f8978a535e8f4c258a2b7402b71e06;hb=45e8ea4acc557dd54e062750f47ff569b5b98c43;hp=4c2f5497db0242cd74133b2e02e8693fd88448a7;hpb=3883b85f49054c109cb8a9a293721a5e41edb68d;p=lyx.git diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp index 4c2f5497db..7005519ac3 100644 --- a/src/BiblioInfo.cpp +++ b/src/BiblioInfo.cpp @@ -488,8 +488,8 @@ docstring processRichtext(docstring const & str, bool richtext) ////////////////////////////////////////////////////////////////////// BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type) - : is_bibtex_(true), bib_key_(key), num_bib_key_(0), entry_type_(type), info_(), - modifier_(0) + : is_bibtex_(true), bib_key_(key), num_bib_key_(0), entry_type_(type), + info_(), format_(), modifier_(0) {} @@ -651,6 +651,75 @@ docstring const BibTeXInfo::getYear() const } +void BibTeXInfo::getLocators(docstring & doi, docstring & url, docstring & file) const +{ + if (is_bibtex_) { + // get "doi" entry from citation record + doi = operator[]("doi"); + if (!doi.empty() && !prefixIs(doi,from_ascii("http"))) + doi = "https://doi.org/" + doi; + // get "url" entry from citation record + url = operator[]("url"); + // get "file" entry from citation record + file = operator[]("file"); + + // Jabref case, field has a format: + // Description:Location:Filetype;Description:Location:Filetype... + // We will grab only first pdf + if (!file.empty()) { + docstring ret, filedest, tmp; + ret = split(file, tmp, ':'); + tmp = split(ret, filedest, ':'); + //TODO howto deal with relative directories? + FileName f(to_utf8(filedest)); + if (f.exists()) + file = "file:///" + filedest; + } + + // kbibtex case, format: + // file1.pdf;file2.pdf + // We will grab only first pdf + docstring kfile; + if (file.empty()) + kfile = operator[]("localfile"); + if (!kfile.empty()) { + docstring filedest, tmp; + tmp = split(kfile, filedest, ';'); + //TODO howto deal with relative directories? + FileName f(to_utf8(filedest)); + if (f.exists()) + file = "file:///" + filedest; + } + + if (!url.empty()) + return; + + // try biblatex specific fields, see its manual + // 3.13.7 "Electronic Publishing Informationl" + docstring eprinttype = operator[]("eprinttype"); + docstring eprint = operator[]("eprint"); + if (eprint.empty()) + return; + + if (eprinttype == "arxiv") + url = "https://arxiv.org/abs/" + eprint; + if (eprinttype == "jstor") + url = "https://www.jstor.org/stable/" + eprint; + if (eprinttype == "pubmed") + url = "http://www.ncbi.nlm.nih.gov/pubmed/" + eprint; + if (eprinttype == "hdl") + url = "https://hdl.handle.net/" + eprint; + if (eprinttype == "googlebooks") + url = "http://books.google.com/books?id=" + eprint; + + return; + } + + // Here can be handled the bibliography environment. All one could do + // here is let LyX scan the entry for URL or HRef insets. +} + + namespace { docstring parseOptions(docstring const & format, string & optkey, @@ -927,12 +996,27 @@ docstring BibTeXInfo::expandFormat(docstring const & format, docstring const & BibTeXInfo::getInfo(BibTeXInfoList const & xrefs, - Buffer const & buf, CiteItem const & ci) const + Buffer const & buf, CiteItem const & ci, docstring const & format_in) const { bool const richtext = ci.richtext; - if (!richtext && !info_.empty()) + CiteEngineType const engine_type = buf.params().citeEngineType(); + DocumentClass const & dc = buf.params().documentClass(); + docstring const & format = format_in.empty()? + from_utf8(dc.getCiteFormat(engine_type, to_utf8(entry_type_))) + : format_in; + + if (format != format_) { + // clear caches since format changed + info_.clear(); + info_richtext_.clear(); + format_ = format; + } + + if (!richtext && !info_.empty()) { + info_ = convertLaTeXCommands(processRichtext(info_, false)); return info_; + } if (richtext && !info_richtext_.empty()) return info_richtext_; @@ -942,10 +1026,6 @@ docstring const & BibTeXInfo::getInfo(BibTeXInfoList const & xrefs, return info_; } - CiteEngineType const engine_type = buf.params().citeEngineType(); - DocumentClass const & dc = buf.params().documentClass(); - docstring const & format = - from_utf8(dc.getCiteFormat(engine_type, to_utf8(entry_type_))); int counter = 0; info_ = expandFormat(format, xrefs, counter, buf, ci, false, false); @@ -1269,6 +1349,15 @@ docstring const BiblioInfo::getCiteNumber(docstring const & key) const return data.citeNumber(); } +void BiblioInfo::getLocators(docstring const & key, docstring & doi, docstring & url, docstring & file) const +{ + BiblioInfo::const_iterator it = find(key); + if (it == end()) + return; + BibTeXInfo const & data = it->second; + data.getLocators(doi,url,file); +} + docstring const BiblioInfo::getYear(docstring const & key, bool use_modifier) const { @@ -1310,7 +1399,7 @@ docstring const BiblioInfo::getYear(docstring const & key, Buffer const & buf, b docstring const BiblioInfo::getInfo(docstring const & key, - Buffer const & buf, CiteItem const & ci) const + Buffer const & buf, CiteItem const & ci, docstring const & format) const { BiblioInfo::const_iterator it = find(key); if (it == end()) @@ -1322,7 +1411,7 @@ docstring const BiblioInfo::getInfo(docstring const & key, if (xrefit != end()) xrefptrs.push_back(&(xrefit->second)); } - return data.getInfo(xrefptrs, buf, ci); + return data.getInfo(xrefptrs, buf, ci, format); } @@ -1594,74 +1683,74 @@ string citationStyleToString(const CitationStyle & cs, bool const latex) docstring authorsToDocBookAuthorGroup(docstring const & authorsString, XMLStream & xs, Buffer const & buf) { - // This function closely mimics getAuthorList, but produces DocBook instead of text. - // It has been greatly simplified, as the complete list of authors is always produced. No separators are required, - // as the output has a database-like shape. - // constructName has also been merged within, as it becomes really simple and leads to no copy-paste. - - if (authorsString.empty()) { - return docstring(); - } - - // Split the input list of authors into individual authors. - vector const authors = getAuthors(authorsString); - - // Retrieve the "et al." variation. - string const etal = buf.params().documentClass().getCiteMacro(buf.params().citeEngineType(), "_etal"); - - // Output the list of authors. - xs << xml::StartTag("authorgroup"); - auto it = authors.cbegin(); - auto en = authors.cend(); - for (size_t i = 0; it != en; ++it, ++i) { - xs << xml::StartTag("author"); - xs << xml::CR(); - xs << xml::StartTag("personname"); - xs << xml::CR(); - docstring name = *it; - - // All authors go in a . If more structure is known, use it; otherwise (just "et al."), print it as such. - if (name == "others") { - xs << buf.B_(etal); - } else { - name_parts parts = nameParts(name); - if (! parts.prefix.empty()) { - xs << xml::StartTag("honorific"); - xs << parts.prefix; - xs << xml::EndTag("honorific"); - xs << xml::CR(); - } - if (! parts.prename.empty()) { - xs << xml::StartTag("firstname"); - xs << parts.prename; - xs << xml::EndTag("firstname"); - xs << xml::CR(); - } - if (! parts.surname.empty()) { - xs << xml::StartTag("surname"); - xs << parts.surname; - xs << xml::EndTag("surname"); - xs << xml::CR(); - } - if (! parts.suffix.empty()) { - xs << xml::StartTag("othername", "role=\"suffix\""); - xs << parts.suffix; - xs << xml::EndTag("othername"); - xs << xml::CR(); - } - } - - xs << xml::EndTag("personname"); - xs << xml::CR(); - xs << xml::EndTag("author"); - xs << xml::CR(); - - // Could add an affiliation after , but not stored in BibTeX. - } - xs << xml::EndTag("authorgroup"); - xs << xml::CR(); - - return docstring(); + // This function closely mimics getAuthorList, but produces DocBook instead of text. + // It has been greatly simplified, as the complete list of authors is always produced. No separators are required, + // as the output has a database-like shape. + // constructName has also been merged within, as it becomes really simple and leads to no copy-paste. + + if (authorsString.empty()) { + return docstring(); + } + + // Split the input list of authors into individual authors. + vector const authors = getAuthors(authorsString); + + // Retrieve the "et al." variation. + string const etal = buf.params().documentClass().getCiteMacro(buf.params().citeEngineType(), "_etal"); + + // Output the list of authors. + xs << xml::StartTag("authorgroup"); + auto it = authors.cbegin(); + auto en = authors.cend(); + for (size_t i = 0; it != en; ++it, ++i) { + xs << xml::StartTag("author"); + xs << xml::CR(); + xs << xml::StartTag("personname"); + xs << xml::CR(); + docstring name = *it; + + // All authors go in a . If more structure is known, use it; otherwise (just "et al."), print it as such. + if (name == "others") { + xs << buf.B_(etal); + } else { + name_parts parts = nameParts(name); + if (! parts.prefix.empty()) { + xs << xml::StartTag("honorific"); + xs << parts.prefix; + xs << xml::EndTag("honorific"); + xs << xml::CR(); + } + if (! parts.prename.empty()) { + xs << xml::StartTag("firstname"); + xs << parts.prename; + xs << xml::EndTag("firstname"); + xs << xml::CR(); + } + if (! parts.surname.empty()) { + xs << xml::StartTag("surname"); + xs << parts.surname; + xs << xml::EndTag("surname"); + xs << xml::CR(); + } + if (! parts.suffix.empty()) { + xs << xml::StartTag("othername", "role=\"suffix\""); + xs << parts.suffix; + xs << xml::EndTag("othername"); + xs << xml::CR(); + } + } + + xs << xml::EndTag("personname"); + xs << xml::CR(); + xs << xml::EndTag("author"); + xs << xml::CR(); + + // Could add an affiliation after , but not stored in BibTeX. + } + xs << xml::EndTag("authorgroup"); + xs << xml::CR(); + + return docstring(); } } // namespace lyx