X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBiblioInfo.cpp;h=420eaa2177c87f9d1d05f92d939565fd60313136;hb=0fd75fefc4aa1816f8d5a72ed0e30f8accdd0bfc;hp=e7ff51e6d9aa977ab8bfefcf2135c9cb21962d0a;hpb=f1912e1c33cebbd41fdaf76fb7307fa464d030b8;p=lyx.git diff --git a/src/BiblioInfo.cpp b/src/BiblioInfo.cpp index e7ff51e6d9..420eaa2177 100644 --- a/src/BiblioInfo.cpp +++ b/src/BiblioInfo.cpp @@ -18,6 +18,7 @@ #include "buffer_funcs.h" #include "Encoding.h" #include "InsetIterator.h" +#include "Language.h" #include "Paragraph.h" #include "TextClass.h" #include "TocBackend.h" @@ -35,7 +36,7 @@ #include "support/lstrings.h" #include "support/textutils.h" -#include "boost/regex.hpp" +#include "support/regex.h" #include @@ -174,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("{")); } @@ -395,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; @@ -406,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 @@ -413,14 +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 - docstring const val = getValueForKey(key, xref); - ret += val; - key.clear(); + 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; + } } else { // beginning of key + key.clear(); scanning_key = true; } - } + } else if (thischar == '{') { // beginning of option? if (scanning_key) { @@ -440,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; } @@ -453,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 == '!' @@ -465,7 +491,19 @@ docstring BibTeXInfo::expandFormat(string const & format, } else if (scanning_key) key += char(thischar); - else if (richtext || !scanning_rich) + 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 @@ -497,7 +535,8 @@ docstring const & BibTeXInfo::getInfo(BibTeXInfo const * const xref, DocumentClass const & dc = buf.params().documentClass(); string const & format = dc.getCiteFormat(to_utf8(entry_type_)); - info_ = expandFormat(format, xref, richtext); + int counter = 0; + info_ = expandFormat(format, xref, counter, buf, richtext); if (!info_.empty()) info_ = convertLaTeXCommands(info_);