]> git.lyx.org Git - lyx.git/blobdiff - src/lyxfind.cpp
tex2lyx/text.cpp: whitespace fix
[lyx.git] / src / lyxfind.cpp
index 486d10fe9ea950bc66237223f189caf884ea5df9..73f6469754fe43b3ca2e903e6c893fac52491622 100644 (file)
@@ -271,7 +271,7 @@ pair<bool, int> replaceOne(BufferView * bv, docstring searchstr,
        if (bv->buffer().isReadonly())
                return pair<bool, int>(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<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", "~"));
        }
@@ -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);
@@ -1377,14 +1376,18 @@ static void findAdvReplace(BufferView * bv, FindAndReplaceOptions const & opt, M
                regex_replace(to_utf8(repl_latex), s, "\\$(.*)\\$", "$1");
                regex_replace(s, s, "\\\\\\[(.*)\\\\\\]", "$1");
                repl_latex = from_utf8(s);
-               LYXERR(Debug::FIND, "Replacing by niceInsert()ing latex: '" << repl_latex << "'");
-               sel_len = cur.niceInsert(repl_latex);
+               LYXERR(Debug::FIND, "Replacing by insert()ing latex: '" << repl_latex << "' cur=" << cur << " with depth=" << cur.depth());
+               MathData ar(cur.buffer());
+               asArray(repl_latex, ar, Parse::NORMAL);
+               cur.insert(ar);
+               sel_len = ar.size();
+               LYXERR(Debug::FIND, "After insert() cur=" << cur << " with depth: " << cur.depth() << " and len: " << sel_len);
        }
        if (cur.pos() >= sel_len)
                cur.pos() -= sel_len;
        else
                cur.pos() = 0;
-       LYXERR(Debug::FIND, "Putting selection at cur=" << cur << " with len: " << sel_len);
+       LYXERR(Debug::FIND, "After pos adj cur=" << cur << " with depth: " << cur.depth() << " and len: " << sel_len);
        bv->putSelectionAt(DocIterator(cur), sel_len, !opt.forward);
        bv->processUpdateFlags(Update::Force);
        bv->buffer().updatePreviews();