]> git.lyx.org Git - features.git/commitdiff
Fixed longstanding bug in Advanced Find&Replace, when dealing with documents containi...
authorTommaso Cucinotta <tommaso@lyx.org>
Thu, 25 Aug 2011 19:16:14 +0000 (19:16 +0000)
committerTommaso Cucinotta <tommaso@lyx.org>
Thu, 25 Aug 2011 19:16:14 +0000 (19:16 +0000)
Corresponding test-case needed a fix as well and now it is passed.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@39518 a592a061-630c-0410-9148-cb99ea01b6c8

development/autotests/findadv-re-03-in.txt
src/lyxfind.cpp
src/mathed/InsetMathHull.cpp

index c86ac718d9ae19f67841607777a88840132e97cc..44564588666eaa41d203adca64ec74776024eaed 100644 (file)
@@ -24,7 +24,7 @@ TestBegin test.lyx -dbg find > lyx-log.txt 2>&1
 KK: \CF
 KK: \Axregexp-mode\[Return]\\}\[Return]
 TestEnd
-Assert pcregrep -M 'Putting selection at .*idx: 0 par: 0 pos: 5\n with len: 1' lyx-log.txt
+Assert pcregrep -M 'Putting selection at .*idx: 0 par: 0 pos: 6\n with len: 1' lyx-log.txt
 #
 TestBegin test.lyx -dbg find > lyx-log.txt 2>&1
 KK: \CF
@@ -32,4 +32,4 @@ KK: \CF
 KK: \Az\Ag\Ae
 KK: \Axregexp-mode\[Return]\\}\[Return]
 TestEnd
-Assert pcregrep -M 'Putting selection at .*idx: 0 par: 0 pos: 5\n with len: 1' lyx-log.txt
+Assert pcregrep -M 'Putting selection at .*idx: 0 par: 0 pos: 6\n with len: 1' lyx-log.txt
index 16527c02902435d236255a778125de41bcc8216c..af27be2b91861d4a953ad410999a150d5b58c79a 100644 (file)
@@ -507,7 +507,7 @@ Escapes const & get_regexp_escapes()
                escape_map.push_back(pair<string, string>(".", "\\."));
                escape_map.push_back(pair<string, string>("\\", "(?:\\\\|\\\\backslash)"));
                escape_map.push_back(pair<string, string>("~", "(?:\\\\textasciitilde|\\\\sim)"));
-               escape_map.push_back(pair<string, string>("^", "(?:\\^|\\\\textasciicircum\\{\\}|\\\\mathcircumflex"));
+               escape_map.push_back(pair<string, string>("^", "(?:\\^|\\\\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<string, string>("\\%", "%"));
-               escape_map.push_back(pair<string, string>("\\{", "{"));
-               escape_map.push_back(pair<string, string>("\\}", "}"));
                escape_map.push_back(pair<string, string>("\\mathcircumflex ", "^"));
                escape_map.push_back(pair<string, string>("\\mathcircumflex", "^"));
                escape_map.push_back(pair<string, string>("\\backslash ", "\\"));
                escape_map.push_back(pair<string, string>("\\backslash", "\\"));
+               escape_map.push_back(pair<string, string>("\\\\{", "_x_<"));
+               escape_map.push_back(pair<string, string>("\\\\}", "_x_>"));
                escape_map.push_back(pair<string, string>("\\sim ", "~"));
                escape_map.push_back(pair<string, string>("\\sim", "~"));
        }
@@ -593,7 +593,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 +607,24 @@ 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);
+               size_t end_pos = s.find("\\endregexp{}}", new_pos + 8); // find_matching_brace(s, new_pos + 7);
                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 +729,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 +833,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 +898,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 +964,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 +985,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;
 }
 
index d92c33c75a141c221f7596f219342f529c38776e..50fb014dc4acbb85da72f72d483a2d7dc17098d8 100644 (file)
@@ -743,6 +743,8 @@ void InsetMathHull::validate(LaTeXFeatures & features) const
                                string("\\newcommand{\\regexp}[1]{\\fcolorbox{")
                                + frcol + string("}{")
                                + bgcol + string("}{\\ensuremath{\\mathtt{#1}}}}"));
+                       features.addPreambleSnippet(
+                               string("\\newcommand{\\endregexp}{}"));
                }
        
                // Validation is necessary only if not using AMS math.
@@ -807,7 +809,7 @@ void InsetMathHull::header_write(WriteStream & os) const
                break;
 
        case hullRegexp:
-               os << "\\regexp{{{";
+               os << "\\regexp{";
                break;
 
        default:
@@ -852,7 +854,8 @@ void InsetMathHull::footer_write(WriteStream & os) const
                break;
 
        case hullRegexp:
-               os << "}}}";
+               // Only used as a heuristic to find the regexp termination, when searching in ignore-format mode
+               os << "\\endregexp{}}";
                break;
 
        default: