mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-09 20:47:00 -04:00
fix bug with adding multiple tags at once
This commit is contained in:
@@ -119,14 +119,20 @@ unique_ptr<TextValueAction> toggle_format_action(const TextValueP& value, vector
|
||||
tag == _("li") ? compute_new_bullet_value (new_value, offset, start_i, end_i):
|
||||
compute_new_simple_value (new_value, tag, start_i, end_i);
|
||||
// Erase redundant tags
|
||||
if (start != end) {
|
||||
// don't simplify if start == end, this way we insert <b></b>, allowing the
|
||||
// user to press Ctrl+B and start typing bold text
|
||||
new_value = simplify_tagged(new_value);
|
||||
if (start != end) {
|
||||
// Simplify
|
||||
new_value = simplify_tagged(new_value);
|
||||
// Adjust selection
|
||||
start_i = to_tagged_pos(new_value, untagged_start_i, true, true, true);
|
||||
end_i = to_tagged_pos(new_value, untagged_end_i, false, false, false);
|
||||
}
|
||||
else {
|
||||
// Don't simplify if start == end, this way we insert <b></b>,
|
||||
// allowing the user to press Ctrl+B and start typing bold text
|
||||
// Adjust selection
|
||||
start_i = to_tagged_pos(new_value, untagged_start_i, true, false, true);
|
||||
end_i = to_tagged_pos(new_value, untagged_end_i, true, false, true);
|
||||
}
|
||||
// Adjust selection
|
||||
start_i = to_tagged_pos(new_value, untagged_start_i, true, false);
|
||||
end_i = to_tagged_pos(new_value, untagged_end_i, true, false);
|
||||
}
|
||||
// Build action
|
||||
if (value->value() == new_value) {
|
||||
|
||||
@@ -129,10 +129,12 @@ String fix_old_tags(const String& str) {
|
||||
return it;
|
||||
}
|
||||
|
||||
[[nodiscard]] String::const_iterator skip_all_tags(String::const_iterator it, String::const_iterator end, bool skip_open, bool skip_close) {
|
||||
[[nodiscard]] String::const_iterator skip_all_tags(String::const_iterator it, String::const_iterator end, bool skip_open, bool skip_close, bool skip_nonformat) {
|
||||
// move after first possible position corresponding
|
||||
while (it != end && *it == '<') {
|
||||
if (it + 1 != end && *(it + 1) == '/') {
|
||||
if (skip_nonformat && !is_formatting_tag(it, end)) {
|
||||
it = skip_tag(it, end);
|
||||
} else if (it + 1 != end && *(it + 1) == '/') {
|
||||
if (skip_close) {
|
||||
it = skip_tag(it, end);
|
||||
} else {
|
||||
@@ -149,7 +151,7 @@ String fix_old_tags(const String& str) {
|
||||
return it;
|
||||
}
|
||||
|
||||
[[nodiscard]] String::const_iterator advance_untagged(String::const_iterator it, String::const_iterator end, size_t n, bool after_open, bool after_close) {
|
||||
[[nodiscard]] String::const_iterator advance_untagged(String::const_iterator it, String::const_iterator end, size_t n, bool after_open, bool after_close, bool after_nonformat) {
|
||||
while (n > 0) {
|
||||
it = skip_all_tags(it, end);
|
||||
if (it != end) {
|
||||
@@ -159,7 +161,7 @@ String fix_old_tags(const String& str) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return skip_all_tags(it, end, after_open, after_close);
|
||||
return skip_all_tags(it, end, after_open, after_close, after_nonformat);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_tag(String::const_iterator it, String::const_iterator end, const char* tag, bool strict) {
|
||||
@@ -284,6 +286,63 @@ bool is_formatting_tag(const String& str, size_t pos) {
|
||||
is_substr(str, pos, _("size")) || is_substr(str, pos, _("/size")) ||
|
||||
is_substr(str, pos, _("color")) || is_substr(str, pos, _("/color"));
|
||||
}
|
||||
|
||||
bool is_formatting_tag(String::const_iterator it, String::const_iterator end) {
|
||||
// so ugly but so fast!
|
||||
if (it == end) return false;
|
||||
if (*it != '<') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it == '/') {++it; if (it == end) return false;}
|
||||
if (*it == 'b' || *it == 'i' || *it == 'u') return true;
|
||||
if (*it == 's') {
|
||||
++it; if (it == end) return false;
|
||||
if (*it == 'y') {
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'm') return false;
|
||||
return true;
|
||||
}
|
||||
if (*it == 't') {
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'r') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'i') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'k') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'e') return false;
|
||||
return true;
|
||||
}
|
||||
if (*it == 'i') {
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'z') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'e') return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (*it == 'f') {
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'o') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'n') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 't') return false;
|
||||
return true;
|
||||
}
|
||||
if (*it == 'c') {
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'o') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'l') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'o') return false;
|
||||
++it; if (it == end) return false;
|
||||
if (*it != 'r') return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t in_tag(const String& str, const String& tag, size_t start, size_t end, bool strict) {
|
||||
size_t last_start = String::npos;
|
||||
@@ -343,10 +402,10 @@ size_t to_untagged_pos(const String& str, size_t pos) {
|
||||
return untag(str.substr(0, pos)).size();
|
||||
}
|
||||
|
||||
size_t to_tagged_pos(const String& str, size_t pos, bool after_open, bool after_close) {
|
||||
size_t to_tagged_pos(const String& str, size_t pos, bool after_open, bool after_close, bool after_nonformat) {
|
||||
String::const_iterator it = str.begin();
|
||||
const String::const_iterator end = str.end();
|
||||
it = advance_untagged(it, end, pos, after_open, after_close);
|
||||
it = advance_untagged(it, end, pos, after_open, after_close, after_nonformat);
|
||||
return std::distance(str.begin(), it);
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ String fix_old_tags(const String&);
|
||||
/// Does a string contain a tag at the given location?
|
||||
/** Matches <b <i <u <strike <font <size <color <sym or their anti tags */
|
||||
[[nodiscard]] bool is_formatting_tag(const String& str, size_t pos);
|
||||
[[nodiscard]] bool is_formatting_tag(String::const_iterator it, String::const_iterator end);
|
||||
|
||||
/// Is the given range entirely contained in a given tagged block?
|
||||
/** If so: return the start position of that tag, otherwise returns String::npos
|
||||
@@ -113,11 +114,11 @@ String anti_tag(const String& tag);
|
||||
[[nodiscard]] String::const_iterator skip_all_tags(String::const_iterator it, String::const_iterator end);
|
||||
|
||||
// Skip past all open/close tags
|
||||
[[nodiscard]] String::const_iterator skip_all_tags(String::const_iterator it, String::const_iterator end, bool skip_open, bool skip_close);
|
||||
[[nodiscard]] String::const_iterator skip_all_tags(String::const_iterator it, String::const_iterator end, bool skip_open, bool skip_close, bool skip_nonformat=false);
|
||||
|
||||
// Advance an iterator by n positions, not counting tags
|
||||
// For example: advance_untagged("<b>abc</b>",_,2) = "c</b>"
|
||||
[[nodiscard]] String::const_iterator advance_untagged(String::const_iterator it, String::const_iterator end, size_t n, bool after_open=false, bool after_close=false);
|
||||
[[nodiscard]] String::const_iterator advance_untagged(String::const_iterator it, String::const_iterator end, size_t n, bool after_open=false, bool after_close=false, bool after_nonformat=false);
|
||||
|
||||
// Find the position of the closing tag matching the tag at it
|
||||
// If not found, returns end
|
||||
@@ -142,7 +143,7 @@ size_t to_untagged_pos(const String& str, size_t pos);
|
||||
|
||||
/// Take a tagged string and a position inside the untagged version,
|
||||
/// return the position in the tagged version.
|
||||
size_t to_tagged_pos(const String& str, size_t pos, bool after_open=false, bool after_close=false);
|
||||
size_t to_tagged_pos(const String& str, size_t pos, bool after_open=false, bool after_close=false, bool after_nonformat=false);
|
||||
|
||||
/// Directions of cursor movement
|
||||
enum Movement
|
||||
|
||||
Reference in New Issue
Block a user