Commit 8c9a524d authored by twanvl's avatar twanvl

in_tag function now looks for a positive number of tag occurrences.

In particular: in "<tag><tag></tag>x</tag>" the x is now in_tag.
This fixes the rest of #20.

Also added is_in_tag function that returns a bool instead of the tag position.
parent d5893fad
...@@ -140,8 +140,7 @@ TextValueAction* toggle_format_action(const TextValueP& value, const String& tag ...@@ -140,8 +140,7 @@ TextValueAction* toggle_format_action(const TextValueP& value, const String& tag
String new_value; String new_value;
const String& str = value->value(); const String& str = value->value();
// Are we inside the tag we are toggling? // Are we inside the tag we are toggling?
size_t tagpos = in_tag(str, _("<") + tag, start_i, end_i); if (!is_in_tag(str, _("<") + tag, start_i, end_i)) {
if (tagpos == String::npos) {
// we are not inside this tag, add it // we are not inside this tag, add it
new_value = str.substr(0, start_i); new_value = str.substr(0, start_i);
new_value += _("<") + tag + _(">"); new_value += _("<") + tag + _(">");
......
...@@ -809,7 +809,7 @@ bool TextValueEditor::canFormat(int type) const { ...@@ -809,7 +809,7 @@ bool TextValueEditor::canFormat(int type) const {
return !style().always_symbol && style().allow_formating && style().symbol_font.valid(); return !style().always_symbol && style().allow_formating && style().symbol_font.valid();
case ID_FORMAT_REMINDER: case ID_FORMAT_REMINDER:
return !style().always_symbol && style().allow_formating && return !style().always_symbol && style().allow_formating &&
in_tag(value().value(), _("<kw"), selection_start_i, selection_start_i) != String::npos; is_in_tag(value().value(), _("<kw"), selection_start_i, selection_start_i);
default: default:
return false; return false;
} }
...@@ -818,11 +818,11 @@ bool TextValueEditor::canFormat(int type) const { ...@@ -818,11 +818,11 @@ bool TextValueEditor::canFormat(int type) const {
bool TextValueEditor::hasFormat(int type) const { bool TextValueEditor::hasFormat(int type) const {
switch (type) { switch (type) {
case ID_FORMAT_BOLD: case ID_FORMAT_BOLD:
return in_tag(value().value(), _("<b"), selection_start_i, selection_end_i) != String::npos; return is_in_tag(value().value(), _("<b"), selection_start_i, selection_end_i);
case ID_FORMAT_ITALIC: case ID_FORMAT_ITALIC:
return in_tag(value().value(), _("<i"), selection_start_i, selection_end_i) != String::npos; return is_in_tag(value().value(), _("<i"), selection_start_i, selection_end_i);
case ID_FORMAT_SYMBOL: case ID_FORMAT_SYMBOL:
return in_tag(value().value(), _("<sym"), selection_start_i, selection_end_i) != String::npos; return is_in_tag(value().value(), _("<sym"), selection_start_i, selection_end_i);
case ID_FORMAT_REMINDER: { case ID_FORMAT_REMINDER: {
const String& v = value().value(); const String& v = value().value();
size_t tag = in_tag(v, _("<kw"), selection_start_i, selection_start_i); size_t tag = in_tag(v, _("<kw"), selection_start_i, selection_start_i);
......
...@@ -21,8 +21,8 @@ inline size_t spelled_correctly(const String& input, size_t start, size_t end, S ...@@ -21,8 +21,8 @@ inline size_t spelled_correctly(const String& input, size_t start, size_t end, S
String word = untag(input.substr(start,end-start)); String word = untag(input.substr(start,end-start));
if (word.empty()) return true; if (word.empty()) return true;
// symbol? // symbol?
if (in_tag(input,_("<sym"),start,end) != String::npos || if (is_in_tag(input,_("<sym"),start,end) ||
in_tag(input,_("<nospellcheck"),start,end) != String::npos) { is_in_tag(input,_("<nospellcheck"),start,end)) {
// symbols are always spelled correctly // symbols are always spelled correctly
// and <nospellcheck> tags should prevent spellcheck // and <nospellcheck> tags should prevent spellcheck
return true; return true;
......
...@@ -148,12 +148,32 @@ size_t last_start_tag_before(const String& str, const String& tag, size_t start) ...@@ -148,12 +148,32 @@ size_t last_start_tag_before(const String& str, const String& tag, size_t start)
} }
size_t in_tag(const String& str, const String& tag, size_t start, size_t end) { size_t in_tag(const String& str, const String& tag, size_t start, size_t end) {
if (start > end) swap(start, end); size_t last_start = String::npos;
size_t pos = last_start_tag_before(str, tag, start); size_t size = str.size();
if (pos == String::npos) return String::npos; // no tag found before start int taglevel = 0;
size_t posE = match_close_tag(str, pos); end = min(end,size);
if (posE < end) return String::npos; // the tag ends before end for (size_t pos = 0 ; pos < end ; ) {
return pos; Char c = str.GetChar(pos);
if (c == _('<')) {
if (is_substr(str, pos + 1, tag.c_str()+1)) {
if (pos < start) last_start = pos;
++taglevel;
} else if (pos + 2 < size && str.GetChar(pos+1) == _('/') && is_substr(str, pos + 2, tag.c_str()+1)) {
--taglevel; // close tag
}
pos = skip_tag(str,pos);
} else {
pos++;
}
if (pos >= start && taglevel < 1) {
// not inside tag anymore
return String::npos;
}
}
return taglevel < 1 ? String::npos : last_start;
}
bool is_in_tag(const String& str, const String& tag, size_t start, size_t end) {
return in_tag(str,tag,start,end) != String::npos;
} }
......
...@@ -73,8 +73,13 @@ size_t last_start_tag_before(const String& str, const String& tag, size_t start) ...@@ -73,8 +73,13 @@ size_t last_start_tag_before(const String& str, const String& tag, size_t start)
/// Is the given range entirely contained in a given tagged block? /// Is the given range entirely contained in a given tagged block?
/** If so: return the start position of that tag, otherwise returns String::npos /** If so: return the start position of that tag, otherwise returns String::npos
* A tagged block is everything between <tag>...</tag> * A tagged block is everything between <tag>...</tag>
* Note: this function looks for a positive number of tags, so in for example
* <tag><tag></tag>x</tag>
* the x is in_tag
*/ */
size_t in_tag(const String& str, const String& tag, size_t start, size_t end); size_t in_tag(const String& str, const String& tag, size_t start, size_t end);
/// Boolean returning version of the above
bool is_in_tag(const String& str, const String& tag, size_t start, size_t end);
/// Return the tag at the given position (without the <>) /// Return the tag at the given position (without the <>)
String tag_at(const String& str, size_t pos); String tag_at(const String& str, size_t pos);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment