X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBiblioInfo.cpp;h=c723b9ad398465f483b5a24d399042ffd9a0f61e;hb=5443d7d4ebb5785439fc4987fd524f20c4520b3f;hp=9083247ea8bc2d63c7059172152f66f8f52e9075;hpb=1eba2c92dae1f1094e4d47a7775f3f99a1cdd93d;p=lyx.git diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp index 9083247ea8..c723b9ad39 100644 --- a/src/BiblioInfo.cpp +++ b/src/BiblioInfo.cpp @@ -236,6 +236,8 @@ docstring constructName(docstring const & name, string const scheme) static regex const reg2("(.*)(\\{%suffix%\\[\\[)([^\\]]+)(\\]\\]\\})(.*)"); static regex const reg3("(.*)(\\{%prefix%\\[\\[)([^\\]]+)(\\]\\]\\})(.*)"); smatch sub; + // Changing the first parameter of regex_match() may corrupt the + // second one. In this case we use the temporary string tmp. if (regex_match(scheme, sub, reg1)) { res = sub.str(1); if (!prename.empty()) @@ -243,16 +245,16 @@ docstring constructName(docstring const & name, string const scheme) res += sub.str(5); } if (regex_match(res, sub, reg2)) { - res = sub.str(1); + string tmp = sub.str(1); if (!suffix.empty()) - res += sub.str(3); - res += sub.str(5); + tmp += sub.str(3); + res = tmp + sub.str(5); } if (regex_match(res, sub, reg3)) { - res = sub.str(1); + string tmp = sub.str(1); if (!prefix.empty()) - res += sub.str(3); - res += sub.str(5); + tmp += sub.str(3); + res = tmp + sub.str(5); } docstring result = from_ascii(res); result = subst(result, from_ascii("%prename%"), prename); @@ -378,7 +380,18 @@ docstring convertLaTeXCommands(docstring const & str) continue; } - // we just ignore braces + // Change text mode accents in the form + // {\v a} to \v{a} (see #9340). + // FIXME: This is a sort of mini-tex2lyx. + // Use the real tex2lyx instead! + static lyx::regex const tma_reg("^\\{\\\\[bcCdfGhHkrtuUv]\\s\\w\\}"); + if (lyx::regex_search(to_utf8(val), tma_reg)) { + val = val.substr(1); + val.replace(2, 1, from_ascii("{")); + continue; + } + + // Apart from the above, we just ignore braces if (ch == '{' || ch == '}') { val = val.substr(1); continue; @@ -465,7 +478,7 @@ docstring processRichtext(docstring const & str, bool richtext) return ret; } -} // anon namespace +} // namespace ////////////////////////////////////////////////////////////////////// @@ -475,7 +488,7 @@ docstring processRichtext(docstring const & str, bool richtext) ////////////////////////////////////////////////////////////////////// BibTeXInfo::BibTeXInfo(docstring const & key, docstring const & type) - : is_bibtex_(true), bib_key_(key), entry_type_(type), info_(), + : is_bibtex_(true), bib_key_(key), num_bib_key_(0), entry_type_(type), info_(), modifier_(0) {} @@ -492,8 +505,8 @@ docstring const BibTeXInfo::getAuthorOrEditorList(Buffer const * buf, } -docstring const BibTeXInfo::getAuthorList(Buffer const * buf, - docstring const & author, bool const full, bool const forceshort, +docstring const BibTeXInfo::getAuthorList(Buffer const * buf, + docstring const & author, bool const full, bool const forceshort, bool const allnames, bool const beginning) const { // Maxnames treshold depend on engine @@ -511,6 +524,12 @@ docstring const BibTeXInfo::getAuthorList(Buffer const * buf, // in this case, we didn't find a "(", // so we don't have author (year) return docstring(); + if (full) { + // Natbib syntax is "Jones et al.(1990)Jones, Baker, and Williams" + docstring const fullauthors = trim(rsplit(remainder, ')')); + if (!fullauthors.empty()) + return fullauthors; + } return authors; } @@ -528,16 +547,16 @@ docstring const BibTeXInfo::getAuthorList(Buffer const * buf, // These are defined in the styles string const etal = - buf ? buf->params().documentClass().getCiteMacro(engine_type, "_etal") + buf ? buf->params().documentClass().getCiteMacro(engine_type, "B_etal") : " et al."; string const namesep = - buf ? buf->params().documentClass().getCiteMacro(engine_type, "_namesep") + buf ? buf->params().documentClass().getCiteMacro(engine_type, "B_namesep") : ", "; string const lastnamesep = - buf ? buf->params().documentClass().getCiteMacro(engine_type, "_lastnamesep") + buf ? buf->params().documentClass().getCiteMacro(engine_type, "B_lastnamesep") : ", and "; string const pairnamesep = - buf ? buf->params().documentClass().getCiteMacro(engine_type, "_pairnamesep") + buf ? buf->params().documentClass().getCiteMacro(engine_type, "B_pairnamesep") : " and "; string firstnameform = buf ? buf->params().documentClass().getCiteMacro(engine_type, "!firstnameform") @@ -745,11 +764,11 @@ docstring parseOptions(docstring const & format, string & optkey, } -} // anon namespace +} // namespace /* FIXME Bug #9131 revealed an oddity in how we are generating citation information -when more than one key is given. We end up building a longer and longer format +when more than one key is given. We end up building a longer and longer format string as we go, which we then have to re-parse, over and over and over again, rather than generating the information for the individual keys and then putting all of that together. We do that to deal with the way separators work, from what @@ -798,13 +817,20 @@ docstring BibTeXInfo::expandFormat(docstring const & format, fmt = from_utf8(val) + fmt.substr(1); counter += 1; continue; - } else if (key[0] == '_') { - // a translatable bit + } else if (prefixIs(key, "B_")) { + // a translatable bit (to the Buffer language) string const val = buf.params().documentClass().getCiteMacro(engine_type, key); docstring const trans = translateIfPossible(from_utf8(val), buf.params().language->code()); ret << trans; + } else if (key[0] == '_') { + // a translatable bit (to the GUI language) + string const val = + buf.params().documentClass().getCiteMacro(engine_type, key); + docstring const trans = + translateIfPossible(from_utf8(val)); + ret << trans; } else { docstring const val = getValueForKey(key, buf, ci, xrefs, max_keysize); @@ -1103,11 +1129,33 @@ docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf, ret = ci.textBefore; else if (key == "textafter") ret = ci.textAfter; - else if (key == "curpretext") - ret = ci.getPretexts()[bib_key_]; - else if (key == "curposttext") - ret = ci.getPosttexts()[bib_key_]; - else if (key == "year") + else if (key == "curpretext") { + vector> pres = ci.getPretexts(); + vector>::iterator it = pres.begin(); + int numkey = 1; + for (; it != pres.end() ; ++it) { + if ((*it).first == bib_key_ && numkey == num_bib_key_) { + ret = (*it).second; + pres.erase(it); + break; + } + if ((*it).first == bib_key_) + ++numkey; + } + } else if (key == "curposttext") { + vector> posts = ci.getPosttexts(); + vector>::iterator it = posts.begin(); + int numkey = 1; + for (; it != posts.end() ; ++it) { + if ((*it).first == bib_key_ && numkey == num_bib_key_) { + ret = (*it).second; + posts.erase(it); + break; + } + if ((*it).first == bib_key_) + ++numkey; + } + } else if (key == "year") ret = getYear(); } @@ -1137,7 +1185,7 @@ public: } }; -} // namespace anon +} // namespace vector const BiblioInfo::getXRefs(BibTeXInfo const & data, bool const nested) const @@ -1248,10 +1296,8 @@ docstring const BiblioInfo::getYear(docstring const & key, bool use_modifier) co if (xrefs.empty()) // no luck return docstring(); - vector::const_iterator it = xrefs.begin(); - vector::const_iterator en = xrefs.end(); - for (; it != en; ++it) { - BiblioInfo::const_iterator const xrefit = find(*it); + for (docstring const & xref : xrefs) { + BiblioInfo::const_iterator const xrefit = find(xref); if (xrefit == end()) continue; BibTeXInfo const & xref_data = xrefit->second; @@ -1285,14 +1331,10 @@ docstring const BiblioInfo::getInfo(docstring const & key, BibTeXInfo const & data = it->second; BibTeXInfoList xrefptrs; vector const xrefs = getXRefs(data); - if (!xrefs.empty()) { - vector::const_iterator it = xrefs.begin(); - vector::const_iterator en = xrefs.end(); - for (; it != en; ++it) { - BiblioInfo::const_iterator const xrefit = find(*it); - if (xrefit != end()) - xrefptrs.push_back(&(xrefit->second)); - } + for (docstring const & xref : getXRefs(data)) { + BiblioInfo::const_iterator const xrefit = find(xref); + if (xrefit != end()) + xrefptrs.push_back(&(xrefit->second)); } return data.getInfo(xrefptrs, buf, ci); } @@ -1306,9 +1348,15 @@ docstring const BiblioInfo::getLabel(vector keys, LASSERT(max_size >= 16, max_size = 16); // we can't display more than 10 of these, anyway + // but since we truncate in the middle, + // we need to split into two halfs. bool const too_many_keys = keys.size() > 10; - if (too_many_keys) - keys.resize(10); + vector lkeys; + if (too_many_keys) { + lkeys.insert(lkeys.end(), keys.end() - 5, keys.end()); + keys.resize(5); + keys.insert(keys.end(), lkeys.begin(), lkeys.end()); + } CiteEngineType const engine_type = buf.params().citeEngineType(); DocumentClass const & dc = buf.params().documentClass(); @@ -1316,7 +1364,14 @@ docstring const BiblioInfo::getLabel(vector keys, docstring ret = format; vector::const_iterator key = keys.begin(); vector::const_iterator ken = keys.end(); + vector handled_keys; for (int i = 0; key != ken; ++key, ++i) { + handled_keys.push_back(*key); + int n = 0; + for (auto const k : handled_keys) { + if (k == *key) + ++n; + } BiblioInfo::const_iterator it = find(*key); BibTeXInfo empty_data; empty_data.key(*key); @@ -1324,23 +1379,18 @@ docstring const BiblioInfo::getLabel(vector keys, vector xrefptrs; if (it != end()) { data = it->second; - vector const xrefs = getXRefs(data); - if (!xrefs.empty()) { - vector::const_iterator it = xrefs.begin(); - vector::const_iterator en = xrefs.end(); - for (; it != en; ++it) { - BiblioInfo::const_iterator const xrefit = find(*it); - if (xrefit != end()) - xrefptrs.push_back(&(xrefit->second)); - } + for (docstring const & xref : getXRefs(data)) { + BiblioInfo::const_iterator const xrefit = find(xref); + if (xrefit != end()) + xrefptrs.push_back(&(xrefit->second)); } } + data.numKey(n); ret = data.getLabel(xrefptrs, buf, ret, ci, key + 1 != ken, i == 1); } - if (too_many_keys) - ret.push_back(0x2026);//HORIZONTAL ELLIPSIS - support::truncateWithEllipsis(ret, max_size); + support::truncateWithEllipsis(ret, max_size, true); + return ret; } @@ -1356,21 +1406,21 @@ bool BiblioInfo::isBibtex(docstring const & key) const } -vector const BiblioInfo::getCiteStrings( +BiblioInfo::CiteStringMap const BiblioInfo::getCiteStrings( vector const & keys, vector const & styles, Buffer const & buf, CiteItem const & ci) const { if (empty()) - return vector(); + return vector>(); string style; - vector vec(styles.size()); - for (size_t i = 0; i != vec.size(); ++i) { + CiteStringMap csm(styles.size()); + for (size_t i = 0; i != csm.size(); ++i) { style = styles[i].name; - vec[i] = getLabel(keys, buf, style, ci); + csm[i] = make_pair(from_ascii(style), getLabel(keys, buf, style, ci)); } - return vec; + return csm; } @@ -1398,7 +1448,7 @@ bool lSorter(BibTeXInfo const * lhs, BibTeXInfo const * rhs) || (lauth == rauth && lyear == ryear && ltitl < rtitl); } -} +} // namespace void BiblioInfo::collectCitedEntries(Buffer const & buf)