X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fcontrollers%2Fbiblio.C;h=9a6a8fabb4c20f1e2ae74fd06a302518f6510f03;hb=96e9048c24b7ec1b4cbdf9f470fcea8bf900b8d0;hp=febb0f94c5df55bfd0781d89c8f9e171709eadf3;hpb=e926eeb39d80d18be34ec3d892ace61a2627fc65;p=lyx.git diff --git a/src/frontends/controllers/biblio.C b/src/frontends/controllers/biblio.C index febb0f94c5..9a6a8fabb4 100644 --- a/src/frontends/controllers/biblio.C +++ b/src/frontends/controllers/biblio.C @@ -11,6 +11,8 @@ * \author Angus Leeming */ +#include + #include #include @@ -18,15 +20,9 @@ #pragma implementation #endif -#include - -/* -#include "buffer.h" -#include "Dialogs.h" -#include "LyXView.h" -*/ #include "LString.h" #include "biblio.h" +#include "gettext.h" // for _() #include "helper_funcs.h" #include "support/lstrings.h" #include "support/LAssert.h" @@ -34,109 +30,44 @@ using std::find; using std::min; -using std::pair; using std::vector; using std::sort; namespace biblio { +namespace { -// A functor for use with std::sort, leading to case insensitive sorting -struct compareNoCase: public std::binary_function -{ - bool operator()(string const & s1, string const & s2) const { - return compare_no_case(s1, s2) < 0; - } -}; - -vector const getKeys(InfoMap const & map) -{ - vector bibkeys; - - for (InfoMap::const_iterator it = map.begin(); it != map.end(); ++it) { - bibkeys.push_back(it->first); - } +using namespace biblio; + +char const * const citeCommands[] = { + "cite", "citet", "citep", "citealt", "citealp", "citeauthor", + "citeyear", "citeyearpar" }; - sort(bibkeys.begin(), bibkeys.end(), compareNoCase()); - return bibkeys; -} +unsigned int const nCiteCommands = + sizeof(citeCommands) / sizeof(char *); +CiteStyle const citeStyles[] = { + CITE, CITET, CITEP, CITEALT, CITEALP, + CITEAUTHOR, CITEYEAR, CITEYEARPAR }; -string const getInfo(InfoMap const & map, string const & key) -{ - lyx::Assert(!map.empty()); +unsigned int const nCiteStyles = + sizeof(citeStyles) / sizeof(CiteStyle); - string result; +CiteStyle const citeStylesFull[] = { + CITET, CITEP, CITEALT, CITEALP, CITEAUTHOR }; - InfoMap::const_iterator it = map.find(key); - if (it != map.end()) { - // Search for all possible "required" keys - string author = parseBibTeX(it->second, "author"); - if (author.empty()) - author = parseBibTeX(it->second, "editor"); +unsigned int const nCiteStylesFull = + sizeof(citeStylesFull) / sizeof(CiteStyle); - string year = parseBibTeX(it->second, "year"); - string title = parseBibTeX(it->second, "title"); - string booktitle = parseBibTeX(it->second, "booktitle"); - string chapter = parseBibTeX(it->second, "chapter"); - string pages = parseBibTeX(it->second, "pages"); - - string media = parseBibTeX(it->second, "journal"); - if (media.empty()) - media = parseBibTeX(it->second, "publisher"); - if (media.empty()) - media = parseBibTeX(it->second, "school"); - if (media.empty()) - media = parseBibTeX(it->second, "institution"); - - result = author; - if (!year.empty()) - result += ", " + year; - if (!title.empty()) - result += ", " + title; - if (!booktitle.empty()) - result += ", in " + booktitle; - if (!chapter.empty()) - result += ", Ch. " + chapter; - if (!media.empty()) - result += ", " + media; - if (!pages.empty()) - result += ", pp. " + pages; - - if (result.empty()) // not a BibTeX record - result = it->second; - } +CiteStyle const citeStylesUCase[] = { + CITET, CITEP, CITEALT, CITEALP, CITEAUTHOR }; - return result; -} +unsigned int const nCiteStylesUCase = + sizeof(citeStylesUCase) / sizeof(CiteStyle); -vector::const_iterator -searchKeys(InfoMap const & theMap, - vector const & keys, - string const & expr, - vector::const_iterator start, - Search type, - Direction dir, - bool caseSensitive) -{ - // Preliminary checks - if(start < keys.begin() || start >= keys.end()) - return keys.end(); - - string search_expr = frontStrip(strip(expr)); - if (search_expr.empty()) - return keys.end(); - - if (type == SIMPLE) - return simpleSearch(theMap, keys, search_expr, start, dir, - caseSensitive); - - return regexSearch(theMap, keys, search_expr, start, dir); -} - - +// The functions doing the dirty work for the search. vector::const_iterator simpleSearch(InfoMap const & theMap, vector const & keys, @@ -159,7 +90,7 @@ simpleSearch(InfoMap const & theMap, (dir == FORWARD) ? (++it) : (--it)) { string data = (*it); - biblio::InfoMap::const_iterator info = theMap.find(*it); + InfoMap::const_iterator info = theMap.find(*it); if (info != theMap.end()) data += " " + info->second; if (!caseSensitive) @@ -182,7 +113,7 @@ simpleSearch(InfoMap const & theMap, return keys.end(); } - + vector::const_iterator regexSearch(InfoMap const & theMap, vector const & keys, @@ -199,7 +130,7 @@ regexSearch(InfoMap const & theMap, (dir == FORWARD) ? (++it) : (--it)) { string data = (*it); - biblio::InfoMap::const_iterator info = theMap.find(*it); + InfoMap::const_iterator info = theMap.find(*it); if (info != theMap.end()) data += " " + info->second; @@ -210,6 +141,181 @@ regexSearch(InfoMap const & theMap, return keys.end(); } +string const familyName(string const & name) +{ + // Very simple parser + string fname = name; + + string::size_type idx = fname.rfind("."); + if (idx != string::npos) + fname = frontStrip(fname.substr(idx+1)); + + return fname; +} + + +string const getAbbreviatedAuthor(InfoMap const & map, string const & key) +{ + lyx::Assert(!map.empty()); + + InfoMap::const_iterator it = map.find(key); + + string author; + if (it != map.end()) { + author = parseBibTeX(it->second, "author"); + if (author.empty()) + author = parseBibTeX(it->second, "editor"); + + vector authors = getVectorFromString(author, "and"); + + if (!authors.empty()) { + author.erase(); + + for (vector::iterator it = authors.begin(); + it != authors.end(); ++it) { + *it = familyName(strip(*it)); + } + + author = authors[0]; + if (authors.size() == 2) + author += _(" and ") + authors[1]; + else if (authors.size() > 2) + author += _(" et al."); + } + } + + if (author.empty()) + author = _("Caesar et al."); + + return author; +} + + +string const getYear(InfoMap const & map, string const & key) +{ + lyx::Assert(!map.empty()); + + InfoMap::const_iterator it = map.find(key); + + string year; + + if (it != map.end()) + year = parseBibTeX(it->second, "year"); + + if (year.empty()) + year = "50BC"; + + return year; +} + +} // namespace anon + + + + + + + +// A functor for use with std::sort, leading to case insensitive sorting +struct compareNoCase: public std::binary_function +{ + bool operator()(string const & s1, string const & s2) const { + return compare_no_case(s1, s2) < 0; + } +}; + +vector const getKeys(InfoMap const & map) +{ + vector bibkeys; + + for (InfoMap::const_iterator it = map.begin(); it != map.end(); ++it) { + bibkeys.push_back(it->first); + } + + sort(bibkeys.begin(), bibkeys.end(), compareNoCase()); + return bibkeys; +} + + +string const getInfo(InfoMap const & map, string const & key) +{ + lyx::Assert(!map.empty()); + + InfoMap::const_iterator it = map.find(key); + if (it == map.end()) return string(); + + // Search for all possible "required" keys + string author = parseBibTeX(it->second, "author"); + if (author.empty()) + author = parseBibTeX(it->second, "editor"); + + string year = parseBibTeX(it->second, "year"); + string title = parseBibTeX(it->second, "title"); + string booktitle = parseBibTeX(it->second, "booktitle"); + string chapter = parseBibTeX(it->second, "chapter"); + string number = parseBibTeX(it->second, "number"); + string volume = parseBibTeX(it->second, "volume"); + string pages = parseBibTeX(it->second, "pages"); + + string media = parseBibTeX(it->second, "journal"); + if (media.empty()) + media = parseBibTeX(it->second, "publisher"); + if (media.empty()) + media = parseBibTeX(it->second, "school"); + if (media.empty()) + media = parseBibTeX(it->second, "institution"); + + ostringstream result; + result << author; + if (!title.empty()) + result << ", " << title; + if (!booktitle.empty()) + result << ", in " << booktitle; + if (!chapter.empty()) + result << ", Ch. " << chapter; + if (!media.empty()) + result << ", " << media; + if (!volume.empty()) + result << ", vol. " << volume; + if (!number.empty()) + result << ", no. " << number; + if (!pages.empty()) + result << ", pp. " << pages; + if (!year.empty()) + result << ", " << year; + + if (result.str().empty()) // not a BibTeX record + result << it->second; + + return result.str().c_str(); +} + + +vector::const_iterator +searchKeys(InfoMap const & theMap, + vector const & keys, + string const & expr, + vector::const_iterator start, + Search type, + Direction dir, + bool caseSensitive) +{ + // Preliminary checks + if(start < keys.begin() || start >= keys.end()) + return keys.end(); + + string search_expr = frontStrip(strip(expr)); + if (search_expr.empty()) + return keys.end(); + + if (type == SIMPLE) + return simpleSearch(theMap, keys, search_expr, start, dir, + caseSensitive); + + return regexSearch(theMap, keys, search_expr, start, dir); +} + + string const parseBibTeX(string data, string const & findkey) { string keyvalue; @@ -311,5 +417,185 @@ string const parseBibTeX(string data, string const & findkey) } -} // namespace biblio +CitationStyle const getCitationStyle(string const & command) +{ + if (command.empty()) return CitationStyle(); + + CitationStyle cs; + string cmd = command; + + if (cmd[0] == 'C') { + cs.forceUCase = true; + cmd[0] = 'c'; + } + + size_t n = cmd.size()-1; + if (cmd[n] == '*') { + cs.full = true; + cmd = cmd.substr(0,n); + } + + char const * const * const last = citeCommands + nCiteCommands; + char const * const * const ptr = std::find(citeCommands, last, cmd); + + if (ptr != last) { + size_t idx = ptr - citeCommands; + cs.style = citeStyles[idx]; + } + + return cs; +} + + +string const getCiteCommand(CiteStyle command, bool full, bool forceUCase) +{ + string cite = citeCommands[command]; + if (full) { + CiteStyle const * last = citeStylesFull + nCiteStylesFull; + if (std::find(citeStylesFull, last, command) != last) + cite += "*"; + } + + if (forceUCase) { + CiteStyle const * last = citeStylesUCase + nCiteStylesUCase; + if (std::find(citeStylesUCase, last, command) != last) + cite[0] = 'C'; + } + + return cite; +} + + +vector const getCiteStyles(bool usingNatbib) +{ + unsigned int nStyles = 1; + unsigned int start = 0; + if (usingNatbib) { + nStyles = nCiteStyles - 1; + start = 1; + } + + vector styles(nStyles); + + vector::size_type i = 0; + int j = start; + for (; i != styles.size(); ++i, ++j) { + styles[i] = citeStyles[j]; + } + + return styles; +} + +vector const +getNumericalStrings(string const & key, + InfoMap const & map, vector const & styles) +{ + if (map.empty()) { + vector vec(1); + vec[0] = _("No database"); + return vec; + } + + vector vec(styles.size()); + + string const author = getAbbreviatedAuthor(map, key); + string const year = getYear(map, key); + + for (vector::size_type i = 0; i != vec.size(); ++i) { + string str; + + switch (styles[i]) { + case CITE: + case CITEP: + str = "[#ID]"; + break; + + case CITET: + str = author + " [#ID]"; + break; + + case CITEALT: + str = author + " #ID"; + break; + + case CITEALP: + str = "#ID"; + break; + + case CITEAUTHOR: + str = author; + break; + + case CITEYEAR: + str = year; + break; + + case CITEYEARPAR: + str = "(" + year + ")"; + break; + } + + vec[i] = str; + } + + return vec; +} + + +vector const +getAuthorYearStrings(string const & key, + InfoMap const & map, vector const & styles) +{ + if (map.empty()) { + vector vec(1); + vec[0] = _("No database"); + return vec; + } + + vector vec(styles.size()); + + string const author = getAbbreviatedAuthor(map, key); + string const year = getYear(map, key); + + for (vector::size_type i = 0; i != vec.size(); ++i) { + string str; + + switch (styles[i]) { + case CITET: + str = author + " (" + year + ")"; + break; + + case CITE: + case CITEP: + str = "(" + author + ", " + year + ")"; + break; + + case CITEALT: + str = author + " " + year ; + break; + + case CITEALP: + str = author + ", " + year ; + break; + + case CITEAUTHOR: + str = author; + break; + + case CITEYEAR: + str = year; + break; + + case CITEYEARPAR: + str = "(" + year + ")"; + break; + } + + vec[i] = str; + } + + return vec; +} + +} // namespace biblio