]> git.lyx.org Git - features.git/blobdiff - src/lyxfind.cpp
FindAdv:
[features.git] / src / lyxfind.cpp
index fddf398377d10cd11ca068f97c2229d63bb8b6b1..609f38c7815fce43eed133435c94a27cde1ee14b 100644 (file)
@@ -892,6 +892,7 @@ string correctRegex(string t, bool withformat)
                buildAccentsMap();
 
        //LYXERR0("correctRegex input '" << t << "'");
+       int skip = 0;
        for (sregex_iterator it(t.begin(), t.end(), wordre), end; it != end; ++it) {
                sub = *it;
                string replace;
@@ -908,6 +909,10 @@ string correctRegex(string t, bool withformat)
                                                replace = "";
                                                backslashed = true;
                                        }
+                                       else if (withformat && next[0] == '$') {
+                                               replace = accents["lyxdollar"];
+                                               skip = 1;       // Skip following '$'
+                                       }
                                }
                        }
                        else if (sub.str(4) == "mathcircumflex")
@@ -960,7 +965,8 @@ string correctRegex(string t, bool withformat)
                if (lastpos < (size_t) sub.position(2))
                        s += std::regex_replace(t.substr(lastpos, sub.position(2) - lastpos), protectedSpace, R"( )");
                s += replace;
-               lastpos = sub.position(2) + sub.length(2);
+               lastpos = sub.position(2) + sub.length(2) + skip;
+               skip = 0;
        }
        if (lastpos == 0)
                s = std::regex_replace(t, protectedSpace, R"( )");
@@ -1422,8 +1428,8 @@ public:
        string par;
        int ignoreidx;
        static vector<Border> borders;
-       int depts[MAXOPENED];
-       int closes[MAXOPENED];
+       static vector<int> depts;
+       static vector<int> closes;
        int actualdeptindex;
        int previousNotIgnored(int) const;
        int nextNotIgnored(int) const;
@@ -1448,6 +1454,8 @@ public:
 };
 
 vector<Border> Intervall::borders = vector<Border>(30);
+vector<int> Intervall::depts = vector<int>(30);
+vector<int> Intervall::closes = vector<int>(30);
 
 int Intervall::isOpeningPar(int pos) const
 {
@@ -1481,6 +1489,8 @@ void Intervall::setForDefaultLang(KeyInfo const & defLang) const
        }
 }
 
+#if 0
+// Not needed, because dpts and closes are now dynamically expanded
 static void checkDepthIndex(int val)
 {
        static int maxdepthidx = MAXOPENED-2;
@@ -1494,6 +1504,7 @@ static void checkDepthIndex(int val)
                LYXERR(Debug::INFO, "maxdepthidx now " << val);
        }
 }
+#endif
 
 #if 0
 // Not needed, because borders are now dynamically expanded
@@ -2043,7 +2054,8 @@ void Intervall::removeAccents()
        if (accents.empty())
                buildAccentsMap();
        static regex const accre("\\\\("
-                                "([\\S]|[A-Za-z]+)\\{[^\\{\\}]+\\}"
+                                "([\\S]|[A-Za-z]+)\\{[^\\\\\\{\\}]+\\}"
+                                "|([\\S]|[A-Za-z]+)\\{\\\\[ij](math)?\\}"
                                 "|("
                                 "(backslash ([lL]y[xX]|[tT]e[xX]|[lL]a[tT]e[xX]e?|lyxarrow))"
                                 "|[A-Za-z]+"
@@ -2079,9 +2091,13 @@ void Intervall::removeAccents()
 void Intervall::handleOpenP(int i)
 {
        actualdeptindex++;
+       if ((size_t) actualdeptindex >= depts.size()) {
+               depts.resize(actualdeptindex + 30);
+               closes.resize(actualdeptindex + 30);
+       }
        depts[actualdeptindex] = i+1;
        closes[actualdeptindex] = -1;
-       checkDepthIndex(actualdeptindex);
+       // checkDepthIndex(actualdeptindex);
 }
 
 void Intervall::handleCloseP(int i, bool closingAllowed)
@@ -2757,7 +2773,8 @@ void LatexInfo::buildKeys(bool isPatternString)
        if (keysBuilt && !isPatternString) return;
 
        // Keys to ignore in any case
-       makeKey("text|textcyrillic|lyxmathsym|ensuremath", KeyInfo(KeyInfo::headRemove, 1, true), true);
+       makeKey("text|lyxmathsym|ensuremath", KeyInfo(KeyInfo::headRemove, 1, true), true);
+       makeKey("nonumber|notag", KeyInfo(KeyInfo::headRemove, 0, true), true);
        // Known standard keys with 1 parameter.
        // Split is done, if not at start of region
        makeKey("textsf|textss|texttt", KeyInfo(KeyInfo::isStandard, 1, ignoreFormats.getFamily()), isPatternString);
@@ -3635,7 +3652,7 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions & opt)
                CreateRegexp(opt, "", "", "");
                return;
        }
-       use_regexp = lyx::to_utf8(ds).find("\\regexp{") != std::string::npos;
+       use_regexp = ds.find(from_utf8("\\regexp{")) != std::string::npos;
        if (opt.replace_all && previous_single_replace) {
                previous_single_replace = false;
                num_replaced = 0;
@@ -3724,7 +3741,7 @@ MatchStringAdv::MatchStringAdv(lyx::Buffer & buf, FindAndReplaceOptions & opt)
                                        break;
                        }
                        if (lng < par_as_string.size())
-                               par_as_string = par_as_string.substr(0,lng);
+                               par_as_string.resize(lng);
                }
                LYXERR(Debug::FINDVERBOSE, "par_as_string after correctRegex is '" << par_as_string << "'");
                if ((lng > 0) && (par_as_string[0] == '^')) {
@@ -3767,9 +3784,6 @@ MatchResult MatchStringAdv::findAux(DocIterator const & cur, int len, bool at_be
        MatchResult mres;
 
        mres.searched_size = len;
-       if (at_begin &&
-                       (opt.restr == FindAndReplaceOptions::R_ONLY_MATHS && !cur.inMathed()) )
-               return mres;
 
        docstring docstr = stringifyFromForSearch(opt, cur, len);
        string str;
@@ -3980,12 +3994,14 @@ static string convertLF2Space(docstring const &s, bool ignore_format)
        size_t pos;
        size_t start = 0;
        size_t end = s.size() - 1;
-       while (s[start] == '\n' && start <= end)
-               start++;
-       while (end >= start && s[end] == '\n')
-               end--;
-       if (start >= end + 1)
-               return "";
+       if (!ignore_format) {
+               while (s[start] == '\n' && start <= end)
+                       start++;
+               while (end >= start && s[end] == '\n')
+                       end--;
+               if (start >= end + 1)
+                       return "";
+       }
        do {
                bool dospace = true;
                int skip = -1;
@@ -3994,31 +4010,34 @@ static string convertLF2Space(docstring const &s, bool ignore_format)
                        t << lyx::to_utf8(s.substr(start, end + 1 - start));
                        break;
                }
-               if ((pos > start+2) &&
-                    s[pos-1] == '\\' &&
-                    s[pos-2] == '\\') {
-                       if (s[pos-1] == '\\' && s[pos-2] == '\\') {
+               if (!ignore_format) {
+                       if ((pos > start + 1) &&
+                            s[pos-1] == '\\' &&
+                            s[pos-2] == '\\') {
                                skip = 2;
-                               if ((pos > start+3) &&
+                               if ((pos > start + 2) &&
                                    (s[pos+1] == '~' || isSpace(s[pos+1]) ||
                                     s[pos-3] == '~' || isSpace(s[pos-3]))) {
-                                       // discard '\n'
+                                       // discard "\\\\\n", do not replace with space
                                        dospace = false;
                                }
                        }
-                       else if (s[pos-1] == '\\' && s[pos-2] == '\\')
-                               skip = 2;
-               }
-               else if (!ignore_format && (pos > start) &&
-                    s[pos-1] == '%') {
-                       skip = 1;
-                       while ((pos > start+skip) && (s[pos-1-skip] == '%'))
-                               skip++;
-                       if ((pos > start+skip) &&
-                           (s[pos+1] == '~' || isSpace(s[pos+1]) ||
-                            s[pos-1-skip] == '~' || isSpace(s[pos-1-skip]))) {
-                               // discard '%%%%%\n'
-                               dospace = false;
+                       else if (pos > start) {
+                               if (s[pos-1] == '%') {
+                                       skip = 1;
+                                       while ((pos > start+skip) && (s[pos-1-skip] == '%'))
+                                               skip++;
+                                       if ((pos > start+skip) &&
+                                           (s[pos+1] == '~' || isSpace(s[pos+1]) ||
+                                            s[pos-1-skip] == '~' || isSpace(s[pos-1-skip]))) {
+                                               // discard '%%%%%\n'
+                                               dospace = false;
+                                       }
+                               }
+                               else if (!isAlnumASCII(s[pos+1]) || !isAlnumASCII(s[pos-1])) {
+                                       dospace = false;
+                                       skip = 0;       // remove the '\n' only
+                               }
                        }
                }
                else {
@@ -4069,14 +4088,14 @@ static string convertLF2Space(docstring const & s, bool ignore_format)
                                // Replace all other \n with spaces
                                t.replace(pos, 1, " ");
                        }
-               }
-               if (!ignore_format) {
-                       size_t count = 0;
-                       while ((pos > count + 1) && (t[pos - 1 -count] == '%')) {
-                               count++;
-                       }
-                       if (count > 0) {
-                               t.replace(pos - count, count, "");
+                       if (!ignore_format) {
+                               size_t count = 0;
+                               while ((pos > count + 1) && (t[pos - 1 -count] == '%')) {
+                                       count++;
+                               }
+                               if (count > 0) {
+                                       t.replace(pos - count, count, "");
+                               }
                        }
                }
        }
@@ -4089,16 +4108,18 @@ string MatchStringAdv::normalize(docstring const & s, bool ignore_format) const
 {
        string t = convertLF2Space(s, ignore_format);
 
-       // Remove stale empty \emph{}, \textbf{} and similar blocks from latexify
-       // Kornel: Added textsl, textsf, textit, texttt and noun
-       // + allow to seach for colored text too
-       LYXERR(Debug::FINDVERBOSE, "Removing stale empty macros from: " << t);
-       while (regex_replace(t, t, "\\\\(emph|noun|text(bf|sl|sf|it|tt)|(u|uu)line|(s|x)out|uwave)(\\{(\\{\\})?\\})+", ""))
-               LYXERR(Debug::FINDVERBOSE, "  further removing stale empty \\emph{}, \\textbf{} macros from: " << t);
-       while (regex_replace(t, t, "\\\\((sub)?(((sub)?section)|paragraph)|part)\\*?(\\{(\\{\\})?\\})+", ""))
-               LYXERR(Debug::FINDVERBOSE, "  further removing stale empty \\section{}, \\part{}, \\paragraph{} macros from: " << t);
-       while (regex_replace(t, t, "\\\\(foreignlanguage|textcolor|item)\\{[a-z]+\\}(\\{(\\{\\})?\\})+", ""));
-
+       // The following replaces are not appropriate in non-format-search mode
+       if (!ignore_format) {
+               // Remove stale empty \emph{}, \textbf{} and similar blocks from latexify
+               // Kornel: Added textsl, textsf, textit, texttt and noun
+               // + allow to seach for colored text too
+               LYXERR(Debug::FINDVERBOSE, "Removing stale empty macros from: " << t);
+               while (regex_replace(t, t, "\\\\(emph|noun|text(bf|sl|sf|it|tt)|(u|uu)line|(s|x)out|uwave)(\\{(\\{\\})?\\})+", ""))
+                       LYXERR(Debug::FINDVERBOSE, "  further removing stale empty \\emph{}, \\textbf{} macros from: " << t);
+               while (regex_replace(t, t, "\\\\((sub)?(((sub)?section)|paragraph)|part)\\*?(\\{(\\{\\})?\\})+", ""))
+                       LYXERR(Debug::FINDVERBOSE, "  further removing stale empty \\section{}, \\part{}, \\paragraph{} macros from: " << t);
+               while (regex_replace(t, t, "\\\\(foreignlanguage|textcolor|item)\\{[a-z]+\\}(\\{(\\{\\})?\\})+", ""));
+       }
        return t;
 }
 
@@ -4324,7 +4345,10 @@ MatchResult findAdvFinalize(DocIterator & cur, MatchStringAdv const & match, Mat
                displayMres(mres, "Start with negative match", cur);
                max_match = mres;
        }
-       if (max_match.match_len <= 0) return fail;
+       // Only now we are really at_begin
+       if ((max_match.match_len <= 0) ||
+           (match.opt.restr == FindAndReplaceOptions::R_ONLY_MATHS && !cur.inMathed()))
+               return fail;
        LYXERR(Debug::FINDVERBOSE, "Ok");
 
        // Compute the match length