X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2Finsetcite.C;h=a8bf9a068e5a87daedc172ce1e9636476a567b06;hb=e28331ed63062dea10d0a21b9ec12034b4b17b9a;hp=bcc8e1cd7dacd10f607f69775d2bc1ff1df4186e;hpb=4758d556c9d91f83d40585d2f87885aa32e94e23;p=lyx.git diff --git a/src/insets/insetcite.C b/src/insets/insetcite.C index bcc8e1cd7d..a8bf9a068e 100644 --- a/src/insets/insetcite.C +++ b/src/insets/insetcite.C @@ -15,7 +15,6 @@ #include "buffer.h" #include "bufferparams.h" -#include "BufferView.h" #include "debug.h" #include "dispatchresult.h" #include "funcrequest.h" @@ -26,63 +25,79 @@ #include "support/fs_extras.h" #include "support/lstrings.h" +#include + #include +#include + + +namespace lyx { -using lyx::support::ascii_lowercase; -using lyx::support::contains; -using lyx::support::getVectorFromString; -using lyx::support::ltrim; -using lyx::support::rtrim; -using lyx::support::split; +using support::ascii_lowercase; +using support::contains; +using support::FileName; +using support::getStringFromVector; +using support::getVectorFromString; +using support::ltrim; +using support::rtrim; +using support::split; +using support::tokenPos; using std::endl; +using std::replace; using std::string; using std::ostream; using std::vector; using std::map; -namespace biblio = lyx::biblio; namespace fs = boost::filesystem; namespace { -string const getNatbibLabel(Buffer const & buffer, +docstring const getNatbibLabel(Buffer const & buffer, string const & citeType, string const & keyList, - string const & before, string const & after, + docstring const & before, docstring const & after, biblio::CiteEngine engine) { // Only start the process off after the buffer is loaded from file. if (!buffer.fully_loaded()) - return string(); + return docstring(); // Cache the labels typedef std::map CachedMap; static CachedMap cached_keys; // and cache the timestamp of the bibliography files. - static std::map bibfileStatus; + static std::map bibfileStatus; biblio::InfoMap infomap; - vector const & bibfilesCache = buffer.getBibfilesCache(); + vector const & bibfilesCache = buffer.getBibfilesCache(); // compare the cached timestamps with the actual ones. bool changed = false; - for (vector::const_iterator it = bibfilesCache.begin(); + for (vector::const_iterator it = bibfilesCache.begin(); it != bibfilesCache.end(); ++ it) { - string const f = *it; - if (!fs::exists(f) || !fs::is_readable(fs::path(f).branch_path())) { - lyxerr << "Couldn't find or read bibtex file " << f << endl; - changed = true; - } else if (bibfileStatus[f] != fs::last_write_time(f)) { + FileName const f = *it; + try { + std::time_t lastw = fs::last_write_time(f.toFilesystemEncoding()); + if (lastw != bibfileStatus[f]) { + changed = true; + bibfileStatus[f] = lastw; + } + } + catch (fs::filesystem_error & fserr) { changed = true; - bibfileStatus[f] = fs::last_write_time(f); + lyxerr << "Couldn't find or read bibtex file " + << f << endl; + lyxerr[Debug::DEBUG] << "Fs error: " + << fserr.what() << endl; } } // build the keylist only if the bibfiles have been changed - if (cached_keys.empty() || bibfileStatus.empty() || changed) { - typedef vector > InfoType; + if (cached_keys[&buffer].empty() || bibfileStatus.empty() || changed) { + typedef vector > InfoType; InfoType bibkeys; buffer.fillWithBibKeys(bibkeys); @@ -98,7 +113,7 @@ string const getNatbibLabel(Buffer const & buffer, infomap = cached_keys[&buffer]; if (infomap.empty()) - return string(); + return docstring(); // the natbib citation-styles // CITET: author (year) @@ -118,7 +133,7 @@ string const getNatbibLabel(Buffer const & buffer, if (cite_type[cite_type.size() - 1] == '*') cite_type = cite_type.substr(0, cite_type.size() - 1); - string before_str; + docstring before_str; if (!before.empty()) { // In CITET and CITEALT mode, the "before" string is // attached to the label associated with each and every key. @@ -138,7 +153,7 @@ string const getNatbibLabel(Buffer const & buffer, before_str = '/' + before; } - string after_str; + docstring after_str; if (!after.empty()) { // The "after" key is appended only to the end of the whole. after_str = ", " + after; @@ -150,22 +165,22 @@ string const getNatbibLabel(Buffer const & buffer, // puctuation mark separating citation entries. char const * const sep = ";"; - string const op_str(' ' + string(1, op)); - string const cp_str(string(1, cp) + ' '); - string const sep_str(string(sep) + ' '); + docstring const op_str(' ' + docstring(1, op)); + docstring const cp_str(docstring(1, cp) + ' '); + docstring const sep_str(from_ascii(sep) + ' '); - string label; + docstring label; vector keys = getVectorFromString(keyList); vector::const_iterator it = keys.begin(); vector::const_iterator end = keys.end(); for (; it != end; ++it) { // get the bibdata corresponding to the key - string const author(biblio::getAbbreviatedAuthor(infomap, *it)); - string const year(biblio::getYear(infomap, *it)); + docstring const author(biblio::getAbbreviatedAuthor(infomap, *it)); + docstring const year(biblio::getYear(infomap, *it)); // Something isn't right. Fail safely. if (author.empty() || year.empty()) - return string(); + return docstring(); // authors1/; ... ; // authors_last, @@ -184,8 +199,9 @@ string const getNatbibLabel(Buffer const & buffer, year + cp + sep_str; break; case biblio::ENGINE_NATBIB_NUMERICAL: + // FIXME UNICODE label += author + op_str + before_str + - '#' + *it + cp + sep_str; + '#' + from_utf8(*it) + cp + sep_str; break; case biblio::ENGINE_JURABIB: label += before_str + author + op_str + @@ -199,7 +215,8 @@ string const getNatbibLabel(Buffer const & buffer, } else if (cite_type == "citep" || cite_type == "citealp") { if (engine == biblio::ENGINE_NATBIB_NUMERICAL) { - label += *it + sep_str; + // FIXME UNICODE + label += from_utf8(*it) + sep_str; } else { label += author + ", " + year + sep_str; } @@ -213,8 +230,9 @@ string const getNatbibLabel(Buffer const & buffer, year + sep_str; break; case biblio::ENGINE_NATBIB_NUMERICAL: + // FIXME UNICODE label += author + ' ' + before_str + - '#' + *it + sep_str; + '#' + from_utf8(*it) + sep_str; break; case biblio::ENGINE_JURABIB: label += before_str + author + ' ' + @@ -257,22 +275,22 @@ string const getNatbibLabel(Buffer const & buffer, } if (cite_type == "citep" || cite_type == "citeyearpar") - label = string(1, op) + label + string(1, cp); + label = op + label + cp; return label; } -string const getBasicLabel(string const & keyList, string const & after) +docstring const getBasicLabel(docstring const & keyList, docstring const & after) { - string keys(keyList); - string label; + docstring keys(keyList); + docstring label; if (contains(keys, ',')) { // Final comma allows while loop to cover all keys keys = ltrim(split(keys, label, ',')) + ','; while (contains(keys, ',')) { - string key; + docstring key; keys = ltrim(split(keys, key, ',')); label += ", " + key; } @@ -293,28 +311,29 @@ InsetCitation::InsetCitation(InsetCommandParams const & p) {} -string const InsetCitation::generateLabel(Buffer const & buffer) const +docstring const InsetCitation::generateLabel(Buffer const & buffer) const { - string const before = getSecOptions(); - string const after = getOptions(); + docstring const before = getParam("before"); + docstring const after = getParam("after"); - string label; + docstring label; biblio::CiteEngine const engine = buffer.params().cite_engine; if (engine != biblio::ENGINE_BASIC) { - label = getNatbibLabel(buffer, getCmdName(), getContents(), + // FIXME UNICODE + label = getNatbibLabel(buffer, getCmdName(), to_utf8(getParam("key")), before, after, engine); } // Fallback to fail-safe if (label.empty()) { - label = getBasicLabel(getContents(), after); + label = getBasicLabel(getParam("key"), after); } return label; } -string const InsetCitation::getScreenLabel(Buffer const & buffer) const +docstring const InsetCitation::getScreenLabel(Buffer const & buffer) const { biblio::CiteEngine const engine = biblio::getEngine(buffer); if (cache.params == params() && cache.engine == engine) @@ -324,11 +343,11 @@ string const InsetCitation::getScreenLabel(Buffer const & buffer) const string const before = getSecOptions(); string const after = getOptions(); - string const glabel = generateLabel(buffer); + docstring const glabel = generateLabel(buffer); unsigned int const maxLabelChars = 45; - string label = glabel; + docstring label = glabel; if (label.size() > maxLabelChars) { label.erase(maxLabelChars-3); label += "..."; @@ -343,7 +362,8 @@ string const InsetCitation::getScreenLabel(Buffer const & buffer) const } -int InsetCitation::plaintext(Buffer const & buffer, ostream & os, OutputParams const &) const +int InsetCitation::plaintext(Buffer const & buffer, odocstream & os, + OutputParams const &) const { if (cache.params == params() && cache.engine == biblio::getEngine(buffer)) @@ -356,14 +376,14 @@ int InsetCitation::plaintext(Buffer const & buffer, ostream & os, OutputParams c namespace { -string const cleanupWhitespace(string const & citelist) +docstring const cleanupWhitespace(docstring const & citelist) { - string::const_iterator it = citelist.begin(); - string::const_iterator end = citelist.end(); + docstring::const_iterator it = citelist.begin(); + docstring::const_iterator end = citelist.end(); // Paranoia check: make sure that there is no whitespace in here // -- at least not behind commas or at the beginning - string result; - char last = ','; + docstring result; + char_type last = ','; for (; it != end; ++it) { if (*it != ' ') last = *it; @@ -376,14 +396,16 @@ string const cleanupWhitespace(string const & citelist) // end anon namyspace } -int InsetCitation::docbook(Buffer const &, ostream & os, OutputParams const &) const +int InsetCitation::docbook(Buffer const &, odocstream & os, OutputParams const &) const { - os << "" << cleanupWhitespace(getContents()) << ""; + os << "" + << cleanupWhitespace(getParam("key")) + << ""; return 0; } -int InsetCitation::textString(Buffer const & buf, ostream & os, +int InsetCitation::textString(Buffer const & buf, odocstream & os, OutputParams const & op) const { return plaintext(buf, os, op); @@ -394,23 +416,24 @@ int InsetCitation::textString(Buffer const & buf, ostream & os, // 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(Buffer const & buffer, ostream & os, +int InsetCitation::latex(Buffer const & buffer, odocstream & os, OutputParams const &) const { biblio::CiteEngine const cite_engine = buffer.params().cite_engine; - string const cite_str = - biblio::asValidLatexCommand(getCmdName(), cite_engine); + // FIXME UNICODE + docstring const cite_str = from_utf8( + biblio::asValidLatexCommand(getCmdName(), cite_engine)); os << "\\" << cite_str; - string const before = getSecOptions(); - string const after = getOptions(); + docstring const & before = getParam("before"); + docstring const & after = getParam("after"); if (!before.empty() && cite_engine != biblio::ENGINE_BASIC) os << '[' << before << "][" << after << ']'; else if (!after.empty()) os << '[' << after << ']'; - os << '{' << cleanupWhitespace(getContents()) << '}'; + os << '{' << cleanupWhitespace(getParam("key")) << '}'; return 0; } @@ -430,3 +453,16 @@ void InsetCitation::validate(LaTeXFeatures & features) const break; } } + + +void InsetCitation::replaceContents(string const & from, string const & to) +{ + if (tokenPos(getContents(), ',', from) != -1) { + vector items = getVectorFromString(getContents()); + replace(items.begin(), items.end(), from, to); + setContents(getStringFromVector(items)); + } +} + + +} // namespace lyx