|
@@ -483,6 +483,7 @@ void TextServer::_bind_methods() {
|
|
|
BIND_ENUM_CONSTANT(DIRECTION_AUTO);
|
|
|
BIND_ENUM_CONSTANT(DIRECTION_LTR);
|
|
|
BIND_ENUM_CONSTANT(DIRECTION_RTL);
|
|
|
+ BIND_ENUM_CONSTANT(DIRECTION_INHERITED);
|
|
|
|
|
|
/* Orientation */
|
|
|
BIND_ENUM_CONSTANT(ORIENTATION_HORIZONTAL);
|
|
@@ -599,7 +600,7 @@ void TextServer::_bind_methods() {
|
|
|
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_FILE);
|
|
|
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_EMAIL);
|
|
|
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_LIST);
|
|
|
- BIND_ENUM_CONSTANT(STRUCTURED_TEXT_NONE);
|
|
|
+ BIND_ENUM_CONSTANT(STRUCTURED_TEXT_GDSCRIPT);
|
|
|
BIND_ENUM_CONSTANT(STRUCTURED_TEXT_CUSTOM);
|
|
|
}
|
|
|
|
|
@@ -1692,22 +1693,22 @@ String TextServer::strip_diacritics(const String &p_string) const {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-TypedArray<Vector2i> TextServer::parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const {
|
|
|
- TypedArray<Vector2i> ret;
|
|
|
+TypedArray<Vector3i> TextServer::parse_structured_text(StructuredTextParser p_parser_type, const Array &p_args, const String &p_text) const {
|
|
|
+ TypedArray<Vector3i> ret;
|
|
|
switch (p_parser_type) {
|
|
|
case STRUCTURED_TEXT_URI: {
|
|
|
int prev = 0;
|
|
|
for (int i = 0; i < p_text.length(); i++) {
|
|
|
if ((p_text[i] == '\\') || (p_text[i] == '/') || (p_text[i] == '.') || (p_text[i] == ':') || (p_text[i] == '&') || (p_text[i] == '=') || (p_text[i] == '@') || (p_text[i] == '?') || (p_text[i] == '#')) {
|
|
|
if (prev != i) {
|
|
|
- ret.push_back(Vector2i(prev, i));
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
}
|
|
|
- ret.push_back(Vector2i(i, i + 1));
|
|
|
+ ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
|
|
prev = i + 1;
|
|
|
}
|
|
|
}
|
|
|
if (prev != p_text.length()) {
|
|
|
- ret.push_back(Vector2i(prev, p_text.length()));
|
|
|
+ ret.push_back(Vector3i(prev, p_text.length(), TextServer::DIRECTION_AUTO));
|
|
|
}
|
|
|
} break;
|
|
|
case STRUCTURED_TEXT_FILE: {
|
|
@@ -1715,14 +1716,14 @@ TypedArray<Vector2i> TextServer::parse_structured_text(StructuredTextParser p_pa
|
|
|
for (int i = 0; i < p_text.length(); i++) {
|
|
|
if ((p_text[i] == '\\') || (p_text[i] == '/') || (p_text[i] == ':')) {
|
|
|
if (prev != i) {
|
|
|
- ret.push_back(Vector2i(prev, i));
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
}
|
|
|
- ret.push_back(Vector2i(i, i + 1));
|
|
|
+ ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
|
|
prev = i + 1;
|
|
|
}
|
|
|
}
|
|
|
if (prev != p_text.length()) {
|
|
|
- ret.push_back(Vector2i(prev, p_text.length()));
|
|
|
+ ret.push_back(Vector3i(prev, p_text.length(), TextServer::DIRECTION_AUTO));
|
|
|
}
|
|
|
} break;
|
|
|
case STRUCTURED_TEXT_EMAIL: {
|
|
@@ -1731,19 +1732,19 @@ TypedArray<Vector2i> TextServer::parse_structured_text(StructuredTextParser p_pa
|
|
|
for (int i = 0; i < p_text.length(); i++) {
|
|
|
if ((p_text[i] == '@') && local) { // Add full "local" as single context.
|
|
|
local = false;
|
|
|
- ret.push_back(Vector2i(prev, i));
|
|
|
- ret.push_back(Vector2i(i, i + 1));
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
+ ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
|
|
prev = i + 1;
|
|
|
} else if (!local && (p_text[i] == '.')) { // Add each dot separated "domain" part as context.
|
|
|
if (prev != i) {
|
|
|
- ret.push_back(Vector2i(prev, i));
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
}
|
|
|
- ret.push_back(Vector2i(i, i + 1));
|
|
|
+ ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
|
|
prev = i + 1;
|
|
|
}
|
|
|
}
|
|
|
if (prev != p_text.length()) {
|
|
|
- ret.push_back(Vector2i(prev, p_text.length()));
|
|
|
+ ret.push_back(Vector3i(prev, p_text.length(), TextServer::DIRECTION_AUTO));
|
|
|
}
|
|
|
} break;
|
|
|
case STRUCTURED_TEXT_LIST: {
|
|
@@ -1752,18 +1753,97 @@ TypedArray<Vector2i> TextServer::parse_structured_text(StructuredTextParser p_pa
|
|
|
int prev = 0;
|
|
|
for (int i = 0; i < tags.size(); i++) {
|
|
|
if (prev != i) {
|
|
|
- ret.push_back(Vector2i(prev, prev + tags[i].length()));
|
|
|
+ ret.push_back(Vector3i(prev, prev + tags[i].length(), TextServer::DIRECTION_INHERITED));
|
|
|
}
|
|
|
- ret.push_back(Vector2i(prev + tags[i].length(), prev + tags[i].length() + 1));
|
|
|
+ ret.push_back(Vector3i(prev + tags[i].length(), prev + tags[i].length() + 1, TextServer::DIRECTION_INHERITED));
|
|
|
prev = prev + tags[i].length() + 1;
|
|
|
}
|
|
|
}
|
|
|
} break;
|
|
|
+ case STRUCTURED_TEXT_GDSCRIPT: {
|
|
|
+ bool in_string_literal = false;
|
|
|
+ bool in_string_literal_single = false;
|
|
|
+ bool in_id = false;
|
|
|
+
|
|
|
+ int prev = 0;
|
|
|
+ for (int i = 0; i < p_text.length(); i++) {
|
|
|
+ char32_t c = p_text[i];
|
|
|
+ if (in_string_literal) {
|
|
|
+ if (c == '\\') {
|
|
|
+ i++;
|
|
|
+ continue; // Skip escaped chars.
|
|
|
+ } else if (c == '\"') {
|
|
|
+ // String literal end, push string and ".
|
|
|
+ if (prev != i) {
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
+ }
|
|
|
+ prev = i + 1;
|
|
|
+ ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
|
|
+ in_string_literal = false;
|
|
|
+ }
|
|
|
+ } else if (in_string_literal_single) {
|
|
|
+ if (c == '\\') {
|
|
|
+ i++;
|
|
|
+ continue; // Skip escaped chars.
|
|
|
+ } else if (c == '\'') {
|
|
|
+ // String literal end, push string and '.
|
|
|
+ if (prev != i) {
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
+ }
|
|
|
+ prev = i + 1;
|
|
|
+ ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
|
|
+ in_string_literal_single = false;
|
|
|
+ }
|
|
|
+ } else if (in_id) {
|
|
|
+ if (!is_unicode_identifier_continue(c)) {
|
|
|
+ // End of id, push id.
|
|
|
+ if (prev != i) {
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
+ }
|
|
|
+ prev = i;
|
|
|
+ in_id = false;
|
|
|
+ }
|
|
|
+ } else if (is_unicode_identifier_start(c)) {
|
|
|
+ // Start of new id, push prev element.
|
|
|
+ if (prev != i) {
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
+ }
|
|
|
+ prev = i;
|
|
|
+ in_id = true;
|
|
|
+ } else if (c == '\"') {
|
|
|
+ // String literal start, push prev element and ".
|
|
|
+ if (prev != i) {
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
+ }
|
|
|
+ prev = i + 1;
|
|
|
+ ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
|
|
+ in_string_literal = true;
|
|
|
+ } else if (c == '\'') {
|
|
|
+ // String literal start, push prev element and '.
|
|
|
+ if (prev != i) {
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
+ }
|
|
|
+ prev = i + 1;
|
|
|
+ ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
|
|
+ in_string_literal_single = true;
|
|
|
+ } else if (c == '#') {
|
|
|
+ // Start of comment, push prev element and #, skip the rest of the text.
|
|
|
+ if (prev != i) {
|
|
|
+ ret.push_back(Vector3i(prev, i, TextServer::DIRECTION_AUTO));
|
|
|
+ }
|
|
|
+ prev = i + 1;
|
|
|
+ ret.push_back(Vector3i(i, i + 1, TextServer::DIRECTION_LTR));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (prev < p_text.length()) {
|
|
|
+ ret.push_back(Vector3i(prev, p_text.length(), TextServer::DIRECTION_AUTO));
|
|
|
+ }
|
|
|
+ } break;
|
|
|
case STRUCTURED_TEXT_CUSTOM:
|
|
|
- case STRUCTURED_TEXT_NONE:
|
|
|
case STRUCTURED_TEXT_DEFAULT:
|
|
|
default: {
|
|
|
- ret.push_back(Vector2i(0, p_text.length()));
|
|
|
+ ret.push_back(Vector3i(0, p_text.length(), TextServer::DIRECTION_INHERITED));
|
|
|
}
|
|
|
}
|
|
|
return ret;
|