X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FBiblioInfo.cpp;h=420eaa2177c87f9d1d05f92d939565fd60313136;hb=12c7e7dde3851ad894380fd42ba741dd3d0cbcc7;hp=8a38e18fada71ee4e93434e0592db80281009496;hpb=8c115c7185b04ad27d6e057d96427deb4e63c3df;p=lyx.git diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp index 8a38e18fad..420eaa2177 100644 --- a/src/BiblioInfo.cpp +++ b/src/BiblioInfo.cpp @@ -18,7 +18,9 @@ #include "buffer_funcs.h" #include "Encoding.h" #include "InsetIterator.h" +#include "Language.h" #include "Paragraph.h" +#include "TextClass.h" #include "TocBackend.h" #include "insets/Inset.h" @@ -34,7 +36,7 @@ #include "support/lstrings.h" #include "support/textutils.h" -#include "boost/regex.hpp" +#include "support/regex.h" #include @@ -173,8 +175,8 @@ docstring convertLaTeXCommands(docstring const & str) // unicodesymbols has things in the form: \"{u}, // whereas we may see things like: \"u. So we'll // look for that and change it, if necessary. - static boost::regex const reg("^\\\\\\W\\w"); - if (boost::regex_search(to_utf8(val), reg)) { + static lyx::regex const reg("^\\\\\\W\\w"); + if (lyx::regex_search(to_utf8(val), reg)) { val.insert(3, from_ascii("}")); val.insert(2, from_ascii("{")); } @@ -195,12 +197,6 @@ docstring convertLaTeXCommands(docstring const & str) return ret; } -// these are used in the expandFormat() routine, etc. - -static string const pp_text = N_("pp."); -static string const ed_text = N_("ed."); -static string const edby_text = N_("ed. by"); - } // anon namespace @@ -400,8 +396,11 @@ namespace { docstring BibTeXInfo::expandFormat(string const & format, - BibTeXInfo const * const xref, bool richtext) const + BibTeXInfo const * const xref, int & counter, Buffer const & buf, + bool richtext) const { + // incorrect use of macros could put us in an infinite loop + static int max_passes = 5000; docstring ret; // return value string key; bool scanning_key = false; @@ -411,6 +410,12 @@ docstring BibTeXInfo::expandFormat(string const & format, // we'll remove characters from the front of fmt as we // deal with them while (fmt.size()) { + if (counter++ > max_passes) { + LYXERR0("Recursion limit reached while parsing `" + << format << "'."); + return _("ERROR!"); + } + char_type thischar = fmt[0]; if (thischar == '%') { // beginning or end of key @@ -418,22 +423,29 @@ docstring BibTeXInfo::expandFormat(string const & format, // end of key scanning_key = false; // so we replace the key with its value, which may be empty - if (key == "pp_text") - ret += _(pp_text); - else if (key == "ed_text") - ret += _(ed_text); - else if(key == "edby_text") - ret += _(edby_text); - else { + if (key[0] == '!') { + // macro + string const val = + buf.params().documentClass().getCiteMacro(key); + fmt = val + fmt.substr(1); + continue; + } else if (key[0] == '_') { + // a translatable bit + string const val = + buf.params().documentClass().getCiteMacro(key); + docstring const trans = + translateIfPossible(from_utf8(val), buf.params().language->code()); + ret += trans; + } else { docstring const val = getValueForKey(key, xref); ret += val; } - key.clear(); } else { // beginning of key + key.clear(); scanning_key = true; } - } + } else if (thischar == '{') { // beginning of option? if (scanning_key) { @@ -453,9 +465,9 @@ docstring BibTeXInfo::expandFormat(string const & format, fmt = newfmt; docstring const val = getValueForKey(optkey, xref); if (!val.empty()) - ret += expandFormat(ifpart, xref, richtext); + ret += expandFormat(ifpart, xref, counter, buf, richtext); else if (!elsepart.empty()) - ret += expandFormat(elsepart, xref, richtext); + ret += expandFormat(elsepart, xref, counter, buf, richtext); // fmt will have been shortened for us already continue; } @@ -466,7 +478,8 @@ docstring BibTeXInfo::expandFormat(string const & format, continue; } } - // we are here if the '{' was at the end of the format. hmm. + // we are here if '{' was not followed by % or !. + // So it's just a character. ret += thischar; } else if (scanning_rich && thischar == '!' @@ -477,8 +490,20 @@ docstring BibTeXInfo::expandFormat(string const & format, continue; } else if (scanning_key) - key += thischar; - else if (richtext || !scanning_rich) + key += char(thischar); + else if (richtext) { + if (scanning_rich) + ret += thischar; + else { + // we need to escape '<' and '>' + if (thischar == '<') + ret += "<"; + else if (thischar == '>') + ret += ">"; + else + ret += thischar; + } + } else if (!scanning_rich /* && !richtext */) ret += thischar; // else the character is discarded, which will happen only if // richtext == false and we are scanning rich text @@ -496,25 +521,8 @@ docstring BibTeXInfo::expandFormat(string const & format, } -namespace { - -// FIXME These would be better read from a file, so that they -// could be customized. - - static string articleFormat = "%author%, \"%title%\", {!!}%journal%{!!} {%volume%[[ %volume%{%number%[[, %number%]]}]]} (%year%){%pages%[[, %pp_text% %pages%]]}.{%note%[[ %note%]]}"; - - static string bookFormat = "{%author%[[%author%]][[%editor%, %ed_text%]]}, {!!}%title%{!!}{%volume%[[ vol. %volume%]][[{%number%[[no. %number%]]}]]}{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%).{%note%[[ %note%]]}"; - - static string inSomething = "%author%, \"%title%\", in{%editor%[[ %editor%, %ed_text%,]]} {!!}%booktitle%{!!}{%volume%[[ vol. %volume%]][[{%number%[[no. %number%]]}]]}{%edition%[[%edition%]]} ({%address%[[%address%: ]]}%publisher%, %year%){%pages%[[, %pp_text% %pages%]]}.{%note%[[ %note%]]}"; - - static string thesis = "%author%, %title% ({%address%[[%address%: ]]}%school%, %year%).{%note%[[ %note%]]}"; - - static string defaultFormat = "{%author%[[%author%, ]][[{%editor%[[%editor%, %ed_text%, ]]}]]}\"%title%\"{%journal%[[, {!!}%journal%{!!}]][[{%publisher%[[, %publisher%]][[{%institution%[[, %institution%]]}]]}]]}{%year%[[ (%year%)]]}{%pages%[[, %pages%]]}."; - -} - docstring const & BibTeXInfo::getInfo(BibTeXInfo const * const xref, - bool richtext) const + Buffer const & buf, bool richtext) const { if (!info_.empty()) return info_; @@ -525,16 +533,10 @@ docstring const & BibTeXInfo::getInfo(BibTeXInfo const * const xref, return info_; } - if (entry_type_ == "article") - info_ = expandFormat(articleFormat, xref, richtext); - else if (entry_type_ == "book") - info_ = expandFormat(bookFormat, xref, richtext); - else if (entry_type_.substr(0,2) == "in") - info_ = expandFormat(inSomething, xref, richtext); - else if (entry_type_ == "phdthesis" || entry_type_ == "mastersthesis") - info_ = expandFormat(thesis, xref, richtext); - else - info_ = expandFormat(defaultFormat, xref, richtext); + DocumentClass const & dc = buf.params().documentClass(); + string const & format = dc.getCiteFormat(to_utf8(entry_type_)); + int counter = 0; + info_ = expandFormat(format, xref, counter, buf, richtext); if (!info_.empty()) info_ = convertLaTeXCommands(info_); @@ -665,7 +667,8 @@ docstring const BiblioInfo::getYear(docstring const & key, bool use_modifier) co } -docstring const BiblioInfo::getInfo(docstring const & key, bool richtext) const +docstring const BiblioInfo::getInfo(docstring const & key, + Buffer const & buf, bool richtext) const { BiblioInfo::const_iterator it = find(key); if (it == end()) @@ -678,7 +681,7 @@ docstring const BiblioInfo::getInfo(docstring const & key, bool richtext) const if (xrefit != end()) xrefptr = &(xrefit->second); } - return data.getInfo(xrefptr, richtext); + return data.getInfo(xrefptr, buf, richtext); }