#include "Paragraph.h"
#include "Text.h"
#include "Encoding.h"
+#include "Language.h"
#include "frontends/Application.h"
#include "frontends/alert.h"
#include "support/lstrings.h"
#include "support/textutils.h"
-#include <map>
+#include <unordered_map>
#include <regex>
//#define ResultsDebug
namespace lyx {
-typedef map<string, string> AccentsMap;
-static AccentsMap accents = map<string, string>();
+typedef unordered_map<string, string> AccentsMap;
+typedef unordered_map<string,string>::const_iterator AccentsIterator;
+static AccentsMap accents = unordered_map<string, string>();
// Helper class for deciding what should be ignored
class IgnoreFormats {
///
bool getLanguage() const { return ignoreLanguage_; }
///
+ bool getDeleted() const { return ignoreDeleted_; }
+ ///
+ void setIgnoreDeleted(bool value);
+ ///
void setIgnoreFormat(string const & type, bool value);
private:
bool ignoreColor_ = false;
///
bool ignoreLanguage_ = false;
+ ///
+ bool ignoreDeleted_ = true;
};
-
void IgnoreFormats::setIgnoreFormat(string const & type, bool value)
{
if (type == "color") {
else if (type == "strike") {
ignoreStrikeOut_ = value;
}
+ else if (type == "deleted") {
+ ignoreDeleted_ = value;
+ }
}
// The global variable that can be changed from outside
runparams.linelen = 10000; //lyxrc.plaintext_linelen;
// No side effect of file copying and image conversion
runparams.dryrun = true;
- runparams.for_search = true;
+ if (ignoreFormats.getDeleted())
+ runparams.for_searchAdv = OutputParams::SearchWithoutDeleted;
+ else
+ runparams.for_searchAdv = OutputParams::SearchWithDeleted;
pit_type const endpit = buffer.paragraphs().size();
for (pit_type pit = 0; pit != endpit; ++pit) {
TeXOnePar(buffer, buffer.text(), pit, os, runparams);
runparams.flavor = Flavor::XeTeX;
runparams.linelen = 10000; //lyxrc.plaintext_linelen;
runparams.dryrun = true;
- runparams.for_search = true;
+ int option = AS_STR_INSETS |AS_STR_PLAINTEXT;
+ if (ignoreFormats.getDeleted()) {
+ option |= AS_STR_SKIPDELETE;
+ runparams.for_searchAdv = OutputParams::SearchWithoutDeleted;
+ }
+ else {
+ runparams.for_searchAdv = OutputParams::SearchWithDeleted;
+ }
for (pos_type pit = pos_type(0); pit < (pos_type)buffer.paragraphs().size(); ++pit) {
Paragraph const & par = buffer.paragraphs().at(pit);
LYXERR(Debug::FIND, "Adding to search string: '"
<< par.asString(pos_type(0), par.size(),
- AS_STR_INSETS | AS_STR_SKIPDELETE | AS_STR_PLAINTEXT,
+ option,
&runparams)
<< "'");
str += par.asString(pos_type(0), par.size(),
- AS_STR_INSETS | AS_STR_SKIPDELETE | AS_STR_PLAINTEXT,
+ option,
&runparams);
}
// Even in ignore-format we have to remove "\text{}, \lyxmathsym{}" parts
for (sregex_iterator itacc(par.begin(), par.end(), accre), end; itacc != end; ++itacc) {
sub = *itacc;
string key = sub.str(1);
- if (accents.find(key) != accents.end()) {
- string val = accents[key];
+ AccentsIterator it_ac = accents.find(key);
+ if (it_ac != accents.end()) {
+ string val = it_ac->second;
size_t pos = sub.position(size_t(0));
for (size_t i = 0; i < val.size(); i++) {
par[pos+i] = val[i];
return start;
}
-typedef map<string, KeyInfo> KeysMap;
+typedef unordered_map<string, KeyInfo> KeysMap;
+typedef unordered_map<string, KeyInfo>::const_iterator KeysIterator;
typedef vector< KeyInfo> Entries;
-static KeysMap keys = map<string, KeyInfo>();
+static KeysMap keys = unordered_map<string, KeyInfo>();
class LatexInfo {
private:
key = sub.str(2);
}
}
- if (keys.find(key) != keys.end()) {
- if (keys[key].keytype == KeyInfo::headRemove) {
- KeyInfo found1 = keys[key];
+ KeysIterator it_key = keys.find(key);
+ if (it_key != keys.end()) {
+ if (it_key->second.keytype == KeyInfo::headRemove) {
+ KeyInfo found1 = it_key->second;
found1.disabled = true;
found1.head = "\\" + key + "{";
found1._tokenstart = sub.position(size_t(2));
mi.incrEntry();
math_pos = mi.getStartPos();
}
- if (keys.find(key) == keys.end()) {
+ if (it_key == keys.end()) {
found = KeyInfo(KeyInfo::isStandard, 0, true);
LYXERR(Debug::INFO, "Undefined key " << key << " ==> will be used as text");
found = KeyInfo(KeyInfo::isText, 0, false);
* Resulting modified string is set to "", if
* the searched tex does not contain all the features in the search pattern
*/
-static string correctlanguagesetting(string par, bool isPatternString, bool withformat)
+static string correctlanguagesetting(string par, bool isPatternString, bool withformat, lyx::Buffer *pbuf = nullptr)
{
static Features regex_f;
static int missed = 0;
// Split the latex input into pieces which
// can be digested by our search engine
LYXERR(Debug::FIND, "input: \"" << par << "\"");
+ if (isPatternString && (pbuf != nullptr)) { // Check if we should disable/enable test for language
+ // We check for polyglossia, because in runparams.flavor we use Flavor::XeTeX
+ string doclang = pbuf->params().language->polyglossia();
+ static regex langre("\\\\(foreignlanguage)\\{([^\\}]+)\\}");
+ smatch sub;
+ bool toIgnoreLang = true;
+ for (sregex_iterator it(par.begin(), par.end(), langre), end; it != end; ++it) {
+ sub = *it;
+ if (sub.str(2) != doclang) {
+ toIgnoreLang = false;
+ break;
+ }
+ }
+ setIgnoreFormat("language", toIgnoreLang);
+
+ }
result = splitOnKnownMacros(par.substr(0,parlen), isPatternString);
LYXERR(Debug::FIND, "After splitOnKnownMacros:\n\"" << result << "\"");
}
size_t lead_size = 0;
// correct the language settings
- par_as_string = correctlanguagesetting(par_as_string, true, !opt.ignoreformat);
- opt.matchstart = false;
+ par_as_string = correctlanguagesetting(par_as_string, true, !opt.ignoreformat, &buf);
+ opt.matchAtStart = false;
if (!use_regexp) {
identifyClosing(par_as_string); // Removes math closings ($, ], ...) at end of string
if (opt.ignoreformat) {
if ((lng > 0) && (par_as_string[0] == '^')) {
par_as_string = par_as_string.substr(1);
--lng;
- opt.matchstart = true;
+ opt.matchAtStart = true;
}
// LYXERR(Debug::FIND, "par_as_string now is '" << par_as_string << "'");
// LYXERR(Debug::FIND, "Open braces: " << open_braces);
int res = mres.match_len;
LYXERR(Debug::FIND,
"res=" << res << ", at_begin=" << at_begin
- << ", matchstart=" << opt.matchstart
+ << ", matchAtStart=" << opt.matchAtStart
<< ", inTexted=" << cur.inTexted());
- if (opt.matchstart) {
+ if (opt.matchAtStart) {
if (cur.pos() != 0)
mres.match_len = 0;
else if (mres.match_prefix > 0)
runparams.linelen = 10000; //lyxrc.plaintext_linelen;
// No side effect of file copying and image conversion
runparams.dryrun = true;
- runparams.for_search = true;
+ int option = AS_STR_INSETS | AS_STR_PLAINTEXT;
+ if (ignoreFormats.getDeleted()) {
+ option |= AS_STR_SKIPDELETE;
+ runparams.for_searchAdv = OutputParams::SearchWithoutDeleted;
+ }
+ else {
+ runparams.for_searchAdv = OutputParams::SearchWithDeleted;
+ }
LYXERR(Debug::FIND, "Stringifying with cur: "
<< cur << ", from pos: " << cur.pos() << ", end: " << end);
return par.asString(cur.pos(), end,
- AS_STR_INSETS | AS_STR_SKIPDELETE | AS_STR_PLAINTEXT,
+ option,
&runparams);
} else if (cur.inMathed()) {
CursorSlice cs = cur.top();
runparams.linelen = 8000; //lyxrc.plaintext_linelen;
// No side effect of file copying and image conversion
runparams.dryrun = true;
- runparams.for_search = true;
+ if (ignoreFormats.getDeleted()) {
+ runparams.for_searchAdv = OutputParams::SearchWithoutDeleted;
+ }
+ else {
+ runparams.for_searchAdv = OutputParams::SearchWithDeleted;
+ }
if (cur.inTexted()) {
// @TODO what about searching beyond/across paragraph breaks ?
else { // match_len > 0
// Try to find the begin of searched string
int increment;
- int firstInvalid = 100000;
+ int firstInvalid = cur.lastpos() - cur.pos();
{
int incrmatch = (mres.match_prefix + mres.pos - mres.leadsize + 1)*3/4;
- int incrcur = (cur.lastpos() - cur.pos() + 1 )*3/4;
+ int incrcur = (firstInvalid + 1 )*3/4;
if (incrcur < incrmatch)
increment = incrcur;
else
LYXERR(Debug::FIND, "Set increment to " << increment);
while (increment > 0) {
DocIterator old_cur = cur;
- size_t skipping = cur.depth();
- for (int i = 0; i < increment && cur; i++) {
- cur.forwardPos();
- while (cur && cur.depth() > skipping) {
- cur.pos() = cur.lastpos();
- cur.forwardPos();
- }
- }
- if (! cur || (cur.pit() > old_cur.pit())) {
- // Are we outside of the paragraph?
- // This can happen if moving past some UTF8-encoded chars
- cur = old_cur;
+ if (cur.pos() + increment >= cur.lastpos()) {
increment /= 2;
+ continue;
}
- else {
- MatchResult mres2 = match(cur, -1, false);
- displayMres(mres2, "findForwardAdv loop", cur)
- switch (interpretMatch(mres, mres2)) {
+ cur.pos() = cur.pos() + increment;
+ MatchResult mres2 = match(cur, -1, false);
+ displayMres(mres2, "findForwardAdv loop", cur)
+ switch (interpretMatch(mres, mres2)) {
case MatchResult::newIsTooFar:
- // behind the expected match
- firstInvalid = increment;
- cur = old_cur;
- increment /= 2;
- break;
+ // behind the expected match
+ firstInvalid = increment;
+ cur = old_cur;
+ increment /= 2;
+ break;
case MatchResult::newIsBetter:
- // not reached yet, but cur.pos()+increment is bettert
- mres = mres2;
- firstInvalid -= increment;
- if (increment > firstInvalid*3/4)
- increment = firstInvalid*3/4;
- if ((mres2.pos == mres2.leadsize) && (increment >= mres2.match_prefix)) {
- if (increment >= mres2.match_prefix)
- increment = (mres2.match_prefix+1)*3/4;
- }
- break;
+ // not reached yet, but cur.pos()+increment is bettert
+ mres = mres2;
+ firstInvalid -= increment;
+ if (increment > firstInvalid*3/4)
+ increment = firstInvalid*3/4;
+ if ((mres2.pos == mres2.leadsize) && (increment >= mres2.match_prefix)) {
+ if (increment >= mres2.match_prefix)
+ increment = (mres2.match_prefix+1)*3/4;
+ }
+ break;
default:
- // Todo@
- // Handle not like MatchResult::newIsTooFar
- LYXERR0( "Probably too far: Increment = " << increment << " match_prefix = " << mres.match_prefix);
- firstInvalid--;
- increment = increment*3/4;
- cur = old_cur;
- break;
- }
+ // Todo@
+ // Handle not like MatchResult::newIsTooFar
+ LYXERR0( "Probably too far: Increment = " << increment << " match_prefix = " << mres.match_prefix);
+ firstInvalid--;
+ increment = increment*3/4;
+ cur = old_cur;
+ break;
}
}
if (mres.match_len > 0) {
if (mres.match_prefix + mres.pos - mres.leadsize > 0) {
+ // The match seems to indicate some deeper level
repeat = true;
orig_cur = cur;
orig_mres = mres;
}
}
else if (repeat) {
- // seems to never be reached.
+ // should never be reached.
cur = orig_cur;
mres = orig_mres;
}
LYXERR(Debug::FIND, "Finalizing 1");
MatchResult found_match = findAdvFinalize(cur, match, mres);
if (found_match.match_len > 0) {
- LASSERT(found_match.pos_len > 0, /**/);
- match.FillResults(found_match);
- return found_match.pos_len;
+ LASSERT(found_match.pos_len > 0, /**/);
+ match.FillResults(found_match);
+ return found_match.pos_len;
}
else {
- // try next possible match
- cur.forwardPos();
- repeat = false;
- continue;
+ // try next possible match
+ cur.forwardPos();
+ repeat = false;
+ continue;
}
}
}