X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfind.cpp;h=73f6469754fe43b3ca2e903e6c893fac52491622;hb=837869452ad8d917615aa4bca77402dc49ba094e;hp=16527c02902435d236255a778125de41bcc8216c;hpb=bc9e5607fb1eaea451cba623aa7ce0ec8e3bb5b0;p=lyx.git diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp index 16527c0290..73f6469754 100644 --- a/src/lyxfind.cpp +++ b/src/lyxfind.cpp @@ -271,7 +271,7 @@ pair replaceOne(BufferView * bv, docstring searchstr, if (bv->buffer().isReadonly()) return pair(false, 0); - cap::replaceSelectionWithString(cur, replacestr, forward); + cap::replaceSelectionWithString(cur, replacestr); if (forward) { cur.pos() += replacestr.length(); LASSERT(cur.pos() <= cur.lastpos(), /* */); @@ -507,7 +507,7 @@ Escapes const & get_regexp_escapes() escape_map.push_back(pair(".", "\\.")); escape_map.push_back(pair("\\", "(?:\\\\|\\\\backslash)")); escape_map.push_back(pair("~", "(?:\\\\textasciitilde|\\\\sim)")); - escape_map.push_back(pair("^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex")); + escape_map.push_back(pair("^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex)")); } return escape_map; } @@ -517,12 +517,12 @@ Escapes const & get_lyx_unescapes() { static Escapes escape_map; if (escape_map.empty()) { escape_map.push_back(pair("\\%", "%")); - escape_map.push_back(pair("\\{", "{")); - escape_map.push_back(pair("\\}", "}")); escape_map.push_back(pair("\\mathcircumflex ", "^")); escape_map.push_back(pair("\\mathcircumflex", "^")); escape_map.push_back(pair("\\backslash ", "\\")); escape_map.push_back(pair("\\backslash", "\\")); + escape_map.push_back(pair("\\\\{", "_x_<")); + escape_map.push_back(pair("\\\\}", "_x_>")); escape_map.push_back(pair("\\sim ", "~")); escape_map.push_back(pair("\\sim", "~")); } @@ -565,26 +565,6 @@ string apply_escapes(string s, Escapes const & escape_map) return s; } -/** Return the position of the closing brace matching the open one at s[pos], - ** or s.size() if not found. - **/ -static size_t find_matching_brace(string const & s, size_t pos) -{ - LASSERT(s[pos] == '{', /* */); - int open_braces = 1; - for (++pos; pos < s.size(); ++pos) { - if (s[pos] == '\\') - ++pos; - else if (s[pos] == '{') - ++open_braces; - else if (s[pos] == '}') { - --open_braces; - if (open_braces == 0) - return pos; - } - } - return s.size(); -} /// Within \regexp{} apply get_lyx_unescapes() only (i.e., preserve regexp semantics of the string), /// while outside apply get_lyx_unescapes()+get_regexp_escapes(). @@ -593,7 +573,7 @@ string escape_for_regex(string s, bool match_latex) { size_t pos = 0; while (pos < s.size()) { - size_t new_pos = s.find("\\regexp{{{", pos); + size_t new_pos = s.find("\\regexp{", pos); if (new_pos == string::npos) new_pos = s.size(); LYXERR(Debug::FIND, "new_pos: " << new_pos); @@ -607,20 +587,25 @@ string escape_for_regex(string s, bool match_latex) LYXERR(Debug::FIND, "new_pos: " << new_pos); if (new_pos == s.size()) break; - size_t end_pos = s.find("}}}", new_pos + 10); // find_matching_brace(s, new_pos + 7); + // Might fail if \\endregexp{} is preceeded by unexpected stuff (weird escapes) + size_t end_pos = s.find("\\endregexp{}}", new_pos + 8); LYXERR(Debug::FIND, "end_pos: " << end_pos); - t = apply_escapes(s.substr(new_pos + 10, end_pos - (new_pos + 10)), get_lyx_unescapes()); - if (match_latex) + t = s.substr(new_pos + 8, end_pos - (new_pos + 8)); + LYXERR(Debug::FIND, "t in regexp : " << t); + t = apply_escapes(t, get_lyx_unescapes()); + LYXERR(Debug::FIND, "t in regexp [lyx]: " << t); + if (match_latex) { t = apply_escapes(t, get_regexp_latex_escapes()); - LYXERR(Debug::FIND, "t : " << t); + LYXERR(Debug::FIND, "t in regexp [ltx]: " << t); + } if (end_pos == s.size()) { s.replace(new_pos, end_pos - new_pos, t); pos = s.size(); LYXERR(Debug::FIND, "Regexp after \\regexp{} removal: " << s); break; } - s.replace(new_pos, end_pos + 3 - new_pos, t); - LYXERR(Debug::FIND, "Regexp after \\regexp{} removal: " << s); + s.replace(new_pos, end_pos + 13 - new_pos, t); + LYXERR(Debug::FIND, "Regexp after \\regexp{...\\endregexp{}} removal: " << s); pos = new_pos + t.size(); LYXERR(Debug::FIND, "pos: " << pos); } @@ -725,7 +710,7 @@ private: ** @todo Normalization should also expand macros, if the corresponding ** search option was checked. **/ - string normalize(docstring const & s) const; + string normalize(docstring const & s, bool hack_braces) const; // normalized string to search string par_as_string; // regular expression to use for searching @@ -829,12 +814,13 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions const & : p_buf(&buf), p_first_buf(&buf), opt(opt) { Buffer & find_buf = *theBufferList().getBuffer(FileName(to_utf8(opt.find_buf_name)), true); - par_as_string = normalize(stringifySearchBuffer(find_buf, opt)); + docstring const & ds = stringifySearchBuffer(find_buf, opt); + use_regexp = lyx::to_utf8(ds).find("\\regexp{") != std::string::npos; + // When using regexp, braces are hacked already by escape_for_regex() + par_as_string = normalize(ds, !use_regexp); open_braces = 0; close_wildcards = 0; - use_regexp = par_as_string.find("\\regexp") != std::string::npos; - size_t lead_size = 0; if (!opt.ignoreformat) { lead_size = identifyLeading(par_as_string); @@ -893,7 +879,7 @@ int MatchStringAdv::findAux(DocIterator const & cur, int len, bool at_begin) con { docstring docstr = stringifyFromForSearch(opt, cur, len); LYXERR(Debug::FIND, "Matching against '" << lyx::to_utf8(docstr) << "'"); - string str = normalize(docstr); + string str = normalize(docstr, true); LYXERR(Debug::FIND, "After normalization: '" << str << "'"); if (! use_regexp) { LYXERR(Debug::FIND, "Searching in normal mode: par_as_string='" << par_as_string << "', str='" << str << "'"); @@ -959,7 +945,7 @@ int MatchStringAdv::operator()(DocIterator const & cur, int len, bool at_begin) } -string MatchStringAdv::normalize(docstring const & s) const +string MatchStringAdv::normalize(docstring const & s, bool hack_braces) const { string t; if (! opt.casesensitive) @@ -980,6 +966,19 @@ string MatchStringAdv::normalize(docstring const & s) const LYXERR(Debug::FIND, "Removing stale empty \\emph{}, \\textbf{}, \\*section{} macros from: " << t); while (regex_replace(t, t, "\\\\(emph|textbf|subsubsection|subsection|section|subparagraph|paragraph|part)(\\{\\})+", "")) LYXERR(Debug::FIND, " further removing stale empty \\emph{}, \\textbf{} macros from: " << t); + + // FIXME - check what preceeds the brace + if (hack_braces) { + if (opt.ignoreformat) + while (regex_replace(t, t, "\\{", "_x_<") + || regex_replace(t, t, "\\}", "_x_>")) + LYXERR(Debug::FIND, "After {} replacement: '" << t << "'"); + else + while (regex_replace(t, t, "\\\\\\{", "_x_<") + || regex_replace(t, t, "\\\\\\}", "_x_>")) + LYXERR(Debug::FIND, "After {} replacement: '" << t << "'"); + } + return t; } @@ -1134,12 +1133,12 @@ int findForwardAdv(DocIterator & cur, MatchStringAdv & match) { if (!cur) return 0; - while (cur) { + while (!theApp()->longOperationCancelled() && cur) { LYXERR(Debug::FIND, "findForwardAdv() cur: " << cur); int match_len = match(cur, -1, false); LYXERR(Debug::FIND, "match_len: " << match_len); if (match_len) { - for (; cur; cur.forwardPos()) { + for (; !theApp()->longOperationCancelled() && cur; cur.forwardPos()) { LYXERR(Debug::FIND, "Advancing cur: " << cur); int match_len = match(cur); LYXERR(Debug::FIND, "match_len: " << match_len); @@ -1236,7 +1235,7 @@ int findBackwardsAdv(DocIterator & cur, MatchStringAdv & match) { else cur.backwardPos(); pit_changed = true; - } while (true); + } while (!theApp()->longOperationCancelled()); return 0; } @@ -1349,7 +1348,7 @@ static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, M } } cap::cutSelection(cur, false, false); - if (!cur.inMathed()) { + if (cur.inTexted()) { repl_buffer.changeLanguage( repl_buffer.language(), cur.getFont().language()); @@ -1360,7 +1359,7 @@ static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, M bv->buffer().errorList("Paste")); LYXERR(Debug::FIND, "After pasteParagraphList() cur=" << cur << endl); sel_len = repl_buffer.paragraphs().begin()->size(); - } else { + } else if (cur.inMathed()) { TexRow texrow; odocstringstream ods; otexstream os(ods, texrow);