diff --git a/core/ustring.cpp b/core/ustring.cpp index 80881f1adb..415494ddc8 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -2757,6 +2757,48 @@ CharType String::ord_at(int p_idx) const { return operator[](p_idx); } +String String::dedent() const { + + String new_string; + String indent; + bool has_indent = false; + bool has_text = false; + int line_start = 0; + int indent_stop = -1; + + for (int i = 0; i < length(); i++) { + + CharType c = operator[](i); + if (c == '\n') { + if (has_text) + new_string += substr(indent_stop, i - indent_stop); + new_string += "\n"; + has_text = false; + line_start = i + 1; + indent_stop = -1; + } else if (!has_text) { + if (c > 32) { + has_text = true; + if (!has_indent) { + has_indent = true; + indent = substr(line_start, i - line_start); + indent_stop = i; + } + } + if (has_indent && indent_stop < 0) { + int j = i - line_start; + if (j >= indent.length() || c != indent[j]) + indent_stop = i; + } + } + } + + if (has_text) + new_string += substr(indent_stop, length() - indent_stop); + + return new_string; +} + String String::strip_edges(bool left, bool right) const { int len = length(); diff --git a/core/ustring.h b/core/ustring.h index aa4a5c910d..353c8e6c1d 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -176,6 +176,7 @@ public: String left(int p_pos) const; String right(int p_pos) const; + String dedent() const; String strip_edges(bool left = true, bool right = true) const; String strip_escapes() const; String get_extension() const; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index cdf1ea46a3..1a29b92810 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -260,6 +260,7 @@ struct _VariantCall { VCALL_LOCALMEM0R(String, to_lower); VCALL_LOCALMEM1R(String, left); VCALL_LOCALMEM1R(String, right); + VCALL_LOCALMEM0R(String, dedent); VCALL_LOCALMEM2R(String, strip_edges); VCALL_LOCALMEM0R(String, get_extension); VCALL_LOCALMEM0R(String, get_basename); @@ -1457,6 +1458,7 @@ void register_variant_methods() { ADDFUNC0R(STRING, STRING, String, get_basename, varray()); ADDFUNC1R(STRING, STRING, String, plus_file, STRING, "file", varray()); ADDFUNC1R(STRING, INT, String, ord_at, INT, "at", varray()); + ADDFUNC0(STRING, STRING, String, dedent, varray()); ADDFUNC2(STRING, NIL, String, erase, INT, "position", INT, "chars", varray()); ADDFUNC0R(STRING, INT, String, hash, varray()); ADDFUNC0R(STRING, STRING, String, md5_text, varray()); diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index d35dc53ae1..057b2d827d 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -615,6 +615,11 @@ void DocData::generate(bool p_basic_types) { } } +static String _format_description(const String &string) { + + return string.dedent().strip_edges().replace("\n", "\n\n"); +} + static Error _parse_methods(Ref &parser, Vector &methods) { String section = parser->get_node_name(); @@ -661,7 +666,7 @@ static Error _parse_methods(Ref &parser, Vector & parser->read(); if (parser->get_node_type() == XMLParser::NODE_TEXT) - method.description = parser->get_node_data().strip_edges(); + method.description = _format_description(parser->get_node_data()); } } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == element) @@ -776,12 +781,12 @@ Error DocData::_load(Ref parser) { parser->read(); if (parser->get_node_type() == XMLParser::NODE_TEXT) - c.brief_description = parser->get_node_data().strip_edges(); + c.brief_description = _format_description(parser->get_node_data()); } else if (name == "description") { parser->read(); if (parser->get_node_type() == XMLParser::NODE_TEXT) - c.description = parser->get_node_data().strip_edges(); + c.description = _format_description(parser->get_node_data()); } else if (name == "tutorials") { parser->read(); if (parser->get_node_type() == XMLParser::NODE_TEXT) @@ -823,7 +828,7 @@ Error DocData::_load(Ref parser) { prop.enumeration = parser->get_attribute_value("enum"); parser->read(); if (parser->get_node_type() == XMLParser::NODE_TEXT) - prop.description = parser->get_node_data().strip_edges(); + prop.description = _format_description(parser->get_node_data()); c.properties.push_back(prop); } else { ERR_EXPLAIN("Invalid tag in doc file: " + name);