mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
fix bug with adding multiple tags at once
This commit is contained in:
@@ -120,13 +120,19 @@ unique_ptr<TextValueAction> toggle_format_action(const TextValueP& value, vector
|
|||||||
compute_new_simple_value (new_value, tag, start_i, end_i);
|
compute_new_simple_value (new_value, tag, start_i, end_i);
|
||||||
// Erase redundant tags
|
// Erase redundant tags
|
||||||
if (start != end) {
|
if (start != end) {
|
||||||
// don't simplify if start == end, this way we insert <b></b>, allowing the
|
// Simplify
|
||||||
// user to press Ctrl+B and start typing bold text
|
|
||||||
new_value = simplify_tagged(new_value);
|
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
|
// Build action
|
||||||
if (value->value() == new_value) {
|
if (value->value() == new_value) {
|
||||||
|
|||||||
@@ -129,10 +129,12 @@ String fix_old_tags(const String& str) {
|
|||||||
return it;
|
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
|
// move after first possible position corresponding
|
||||||
while (it != end && *it == '<') {
|
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) {
|
if (skip_close) {
|
||||||
it = skip_tag(it, end);
|
it = skip_tag(it, end);
|
||||||
} else {
|
} else {
|
||||||
@@ -149,7 +151,7 @@ String fix_old_tags(const String& str) {
|
|||||||
return it;
|
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) {
|
while (n > 0) {
|
||||||
it = skip_all_tags(it, end);
|
it = skip_all_tags(it, end);
|
||||||
if (it != end) {
|
if (it != end) {
|
||||||
@@ -159,7 +161,7 @@ String fix_old_tags(const String& str) {
|
|||||||
return it;
|
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) {
|
[[nodiscard]] bool is_tag(String::const_iterator it, String::const_iterator end, const char* tag, bool strict) {
|
||||||
@@ -285,6 +287,63 @@ bool is_formatting_tag(const String& str, size_t pos) {
|
|||||||
is_substr(str, pos, _("color")) || is_substr(str, pos, _("/color"));
|
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) {
|
[[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;
|
size_t last_start = String::npos;
|
||||||
size_t size = str.size();
|
size_t size = str.size();
|
||||||
@@ -343,10 +402,10 @@ size_t to_untagged_pos(const String& str, size_t pos) {
|
|||||||
return untag(str.substr(0, pos)).size();
|
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();
|
String::const_iterator it = str.begin();
|
||||||
const String::const_iterator end = str.end();
|
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);
|
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?
|
/// Does a string contain a tag at the given location?
|
||||||
/** Matches <b <i <u <strike <font <size <color <sym or their anti tags */
|
/** 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(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?
|
/// 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
|
||||||
@@ -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);
|
[[nodiscard]] String::const_iterator skip_all_tags(String::const_iterator it, String::const_iterator end);
|
||||||
|
|
||||||
// Skip past all open/close tags
|
// 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
|
// Advance an iterator by n positions, not counting tags
|
||||||
// For example: advance_untagged("<b>abc</b>",_,2) = "c</b>"
|
// 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
|
// Find the position of the closing tag matching the tag at it
|
||||||
// If not found, returns end
|
// 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,
|
/// Take a tagged string and a position inside the untagged version,
|
||||||
/// return the position in the tagged 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
|
/// Directions of cursor movement
|
||||||
enum Movement
|
enum Movement
|
||||||
|
|||||||
Reference in New Issue
Block a user