string par_as_string;
// regular expression to use for searching
lyx::regex regexp;
- // same as regexp, but prefixed with a ".*"
+ // same as regexp, but prefixed with a ".*?"
lyx::regex regexp2;
// leading format material as string
string lead_as_string;
/* inputencoding, shortcut, ...
* Discard also content, because they do not help in search */
doRemove,
+ /* twocolumns, ...
+ * like remove, but also all arguments */
+ removeWithArg,
/* item */
isList,
/* tex, latex, ... like isChar */
isIgnored,
/* like \lettrine[lines=5]{}{} */
cleanToStart,
+ /* End of arguments marker for lettrine,
+ * so that they can be ignored */
endArguments
};
KeyInfo()
int closes[MAXOPENED];
int actualdeptindex;
Border borders[2*MAXOPENED];
- // int previousNotIgnored(int);
+ int previousNotIgnored(int);
int nextNotIgnored(int);
void handleOpenP(int i);
void handleCloseP(int i, bool closingAllowed);
closes[1] = -1;
}
-#if 0
int Intervall::previousNotIgnored(int start)
{
int idx = 0; /* int intervalls */
}
return start;
}
-#endif
int Intervall::nextNotIgnored(int start)
{
else
return false;
};
+ int find(int start, KeyInfo::KeyType keytype) {
+ if (start < 0)
+ return (-1);
+ int tmpIdx = start;
+ while (tmpIdx < int(entries.size())) {
+ if (entries[tmpIdx].keytype == keytype)
+ return tmpIdx;
+ tmpIdx++;
+ }
+ return(-1);
+ };
int process(ostringstream &os, KeyInfo &actual);
int dispatch(ostringstream &os, int previousStart, KeyInfo &actual);
// string show(int lastpos) { return interval.show(lastpos);};
bool evaluatingMath = false;
bool evaluatingCode = false;
size_t codeEnd = 0;
+ bool evaluatingOptional = false;
+ size_t optionalEnd = 0;
int codeStart = -1;
KeyInfo found;
bool math_end_waiting = false;
// First handle tables
// longtable|tabular
bool discardComment;
+ found = keys[key];
+ found.keytype = KeyInfo::doRemove;
if ((sub.str(5).compare("longtable") == 0) ||
(sub.str(5).compare("tabular") == 0)) {
discardComment = true; /* '%' */
}
- else
+ else {
discardComment = false;
- found = keys[key];
+ if (sub.str(5).compare("multicols") == 0)
+ found.keytype = KeyInfo::removeWithArg;
+ }
// discard spaces before pos(0)
int pos = sub.position(size_t(0));
int count;
else if (c != ' ')
break;
}
- found.keytype = KeyInfo::doRemove;
found._tokenstart = pos - count;
if (sub.str(1).compare(0, 5, "begin") == 0) {
size_t pos1 = pos + sub.str(0).length();
found._dataStart = found._dataEnd;
}
else {
+ int params = found._tokenstart + key.length() + 1;
+ if (evaluatingOptional) {
+ if (size_t(found._tokenstart) > optionalEnd) {
+ evaluatingOptional = false;
+ }
+ else {
+ found.disabled = true;
+ }
+ }
+ if (interval.par[params] == '[') {
+ // discard optional parameters
+ int optend = interval.findclosing(params+1, interval.par.length(), '[', ']') + 1;
+ key += interval.par.substr(params, optend-params);
+ evaluatingOptional = true;
+ optionalEnd = optend;
+ }
if (found.parenthesiscount == 1) {
found.head = "\\" + key + "{";
}
// No split
makeKey("backslash|textbackslash|slash", KeyInfo(KeyInfo::isChar, 0, false), isPatternString);
makeKey("textasciicircum|textasciitilde", KeyInfo(KeyInfo::isChar, 0, false), isPatternString);
- makeKey("textasciiacute", KeyInfo(KeyInfo::isChar, 0, false), isPatternString);
+ makeKey("textasciiacute|texemdash", KeyInfo(KeyInfo::isChar, 0, false), isPatternString);
makeKey("dots|ldots", KeyInfo(KeyInfo::isChar, 0, false), isPatternString);
// Spaces
makeKey("quad|qquad|hfill|dotfill", KeyInfo(KeyInfo::isChar, 0, false), isPatternString);
makeKey("menuitem|textmd|textrm", KeyInfo(KeyInfo::isStandard, 1, true), isPatternString);
// Remove language spec from content of these insets
- makeKey("code|footnote", KeyInfo(KeyInfo::noMain, 1, false), isPatternString);
+ makeKey("code", KeyInfo(KeyInfo::noMain, 1, false), isPatternString);
// Same effect as previous, parameter will survive (because there is no one anyway)
// No split
makeKey("trianglerightpar|hexagonpar|starpar", KeyInfo(KeyInfo::isStandard, 1, true), isPatternString);
makeKey("triangleuppar|triangledownpar|droppar", KeyInfo(KeyInfo::isStandard, 1, true), isPatternString);
makeKey("triangleleftpar|shapepar|dropuppar", KeyInfo(KeyInfo::isStandard, 1, true), isPatternString);
+ makeKey("hphantom|footnote", KeyInfo(KeyInfo::isStandard, 1, true), isPatternString);
// like ('tiny{}' or '\tiny ' ... )
makeKey("footnotesize|tiny|scriptsize|small|large|Large|LARGE|huge|Huge", KeyInfo(KeyInfo::isSize, 0, false), isPatternString);
makeKey("[|]", KeyInfo(KeyInfo::isMath, 1, false), isPatternString);
makeKey("$", KeyInfo(KeyInfo::isMath, 1, false), isPatternString);
- makeKey("par|uldepth|ULdepth|protect|nobreakdash", KeyInfo(KeyInfo::isStandard, 0, true), isPatternString);
+ makeKey("par|uldepth|ULdepth|protect|nobreakdash|medskip", KeyInfo(KeyInfo::isStandard, 0, true), isPatternString);
// Remove RTL/LTR marker
makeKey("l|r|textlr|textfr|textar|beginl|endl", KeyInfo(KeyInfo::isStandard, 0, true), isPatternString);
makeKey("lettrine", KeyInfo(KeyInfo::cleanToStart, 0, true), isPatternString);
+ makeKey("lyxslide", KeyInfo(KeyInfo::isSectioning, 1, true), isPatternString);
makeKey("endarguments", KeyInfo(KeyInfo::endArguments, 0, true), isPatternString);
+ makeKey("twocolumn", KeyInfo(KeyInfo::removeWithArg, 2, true), isPatternString);
+ makeKey("lyxend", KeyInfo(KeyInfo::isStandard, 0, true), isPatternString);
if (isPatternString) {
// Allow the first searched string to rebuild the keys too
keysBuilt = false;
}
else {
// Remove header hull, that is "\url{abcd}" ==> "abcd"
- interval.addIntervall(actual._tokenstart, actual._dataStart);
+ interval.addIntervall(actual._tokenstart - count, actual._dataStart);
interval.addIntervall(actual._dataEnd, actual._dataEnd+1);
}
}
switch (actual.keytype)
{
case KeyInfo::cleanToStart: {
- actual._dataEnd = actual._dataStart;
- if (interval.par[actual._dataStart] == '[') {
- // Discard optional params
- actual._dataStart = interval.findclosing(actual._dataStart+1, interval.par.length(), '[', ']') + 1;
- }
actual._dataEnd = actual._dataStart;
nextKeyIdx = getNextKey();
// Search for end of arguments
- int tmpIdx = nextKeyIdx;
- while (tmpIdx > 0) {
- KeyInfo &nextk = entries[tmpIdx];
- if (nextk.keytype == KeyInfo::endArguments) {
- actual._dataEnd = nextk._dataEnd;
- break;
+ int tmpIdx = find(nextKeyIdx, KeyInfo::endArguments);
+ if (tmpIdx > 0) {
+ for (int i = nextKeyIdx; i <= tmpIdx; i++) {
+ entries[i].disabled = true;
}
- nextk.disabled = true;
- tmpIdx++;
- if (tmpIdx >= int(entries.size()))
- break;
+ actual._dataEnd = entries[tmpIdx]._dataEnd;
}
while (interval.par[actual._dataEnd] == ' ')
actual._dataEnd++;
processRegion(actual._dataStart, actual._dataStart+1);
nextKeyIdx = getNextKey();
} else {
- // Split on this key if not at start
+ // Split on this key if not at datastart of calling entry
int start = interval.nextNotIgnored(previousStart);
if (start < actual._tokenstart) {
interval.output(os, actual._tokenstart);
}
break;
}
+ case KeyInfo::removeWithArg: {
+ nextKeyIdx = getNextKey();
+ // Search for end of arguments
+ int tmpIdx = find(nextKeyIdx, KeyInfo::endArguments);
+ if (tmpIdx > 0) {
+ for (int i = nextKeyIdx; i <= tmpIdx; i++) {
+ entries[i].disabled = true;
+ }
+ actual._dataEnd = entries[tmpIdx]._dataEnd;
+ }
+ interval.addIntervall(actual._tokenstart, actual._dataEnd+1);
+ break;
+ }
case KeyInfo::doRemove: {
// Remove the key with all parameters and following spaces
size_t pos;
case KeyInfo::isSectioning: {
// Discard spaces before _tokenstart
int count;
- for (count = 0; count < actual._tokenstart; count++) {
- if (interval.par[actual._tokenstart-count-1] != ' ')
+ int val = actual._tokenstart;
+ for (count = 0; count < actual._tokenstart;) {
+ val = interval.previousNotIgnored(val-1);
+ if (interval.par[val] != ' ')
break;
+ else {
+ count = actual._tokenstart - val;
+ }
}
if (actual.disabled) {
removeHead(actual, count);
// Discard also the space before math-equation
interval.addIntervall(actual._dataStart, actual._dataStart+1);
}
- interval.resetOpenedP(actual._dataStart-1);
+ nextKeyIdx = getNextKey();
+ // interval.resetOpenedP(actual._dataStart-1);
}
else {
if (actual._tokenstart == 0) {
}
KeyInfo &nextKey = getKeyInfo(nextKeyIdx);
- if (nextKey.keytype == KeyInfo::isMain) {
+ if ((nextKey.keytype == KeyInfo::isMain) && !nextKey.disabled) {
(void) dispatch(os, actual._dataStart, nextKey);
end = nextKey._tokenstart;
break;
return nextKeyIdx;
}
-string splitOnKnownMacros(string par, bool isPatternString) {
+string splitOnKnownMacros(string par, bool isPatternString)
+{
ostringstream os;
LatexInfo li(par, isPatternString);
+ // LYXERR0("Berfore split: " << par);
KeyInfo DummyKey = KeyInfo(KeyInfo::KeyType::isMain, 2, true);
DummyKey.head = "";
DummyKey._tokensize = 0;
}
else
s = par; /* no known macros found */
+ // LYXERR0("After split: " << s);
return s;
}
while (regex_replace(par_as_string, par_as_string, orig, dest));
}
regexp_str = "(" + lead_as_regexp + ")" + par_as_string;
- regexp2_str = "(" + lead_as_regexp + ").*" + par_as_string;
+ regexp2_str = "(" + lead_as_regexp + ").*?" + par_as_string;
}
LYXERR(Debug::FIND, "Setting regexp to : '" << regexp_str << "'");
regexp = lyx::regex(regexp_str);
while (!t.empty() && t[t.size() - 1] == '\n')
t = t.substr(0, t.size() - 1);
size_t pos;
- // Replace all other \n with spaces
- while ((pos = t.find("\n")) != string::npos)
- t.replace(pos, 1, " ");
+ // Handle all other '\n'
+ while ((pos = t.find("\n")) != string::npos) {
+ if (pos > 1 && t[pos-1] == '\\' && t[pos-2] == '\\' ) {
+ // Handle '\\\n'
+ if (std::isalnum(t[pos+1])) {
+ t.replace(pos-2, 3, " ");
+ }
+ else {
+ t.replace(pos-2, 3, "");
+ }
+ }
+ else if (!std::isalnum(t[pos+1]) || !std::isalnum(t[pos-1])) {
+ // '\n' adjacent to non-alpha-numerics, discard
+ t.replace(pos, 1, "");
+ }
+ else {
+ // Replace all other \n with spaces
+ t.replace(pos, 1, " ");
+ }
+ }
// 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