diff options
Diffstat (limited to 'servers/text_server.cpp')
-rw-r--r-- | servers/text_server.cpp | 116 |
1 files changed, 98 insertions, 18 deletions
diff --git a/servers/text_server.cpp b/servers/text_server.cpp index d339533688..027109b67d 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -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; |