From 5b51ae1c5d1b521030611398cf955055e0136669 Mon Sep 17 00:00:00 2001 From: HaSa1002 Date: Wed, 22 Jul 2020 22:41:10 +0200 Subject: [PATCH] Add multiple programming language support to class reference --- doc/tools/makerst.py | 99 ++++++++++++++++++++++++-------------- editor/editor_help.cpp | 49 +++++++++++++++++++ editor/editor_settings.cpp | 2 + 3 files changed, 113 insertions(+), 37 deletions(-) diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index c0bba38799..9c569fd240 100755 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -600,6 +600,43 @@ def escape_rst(text, until_pos=-1): # type: (str) -> str return text +def format_codeblock(code_type, post_text, indent_level, state): # types: str, str, int, state + end_pos = post_text.find("[/" + code_type + "]") + if end_pos == -1: + print_error("[" + code_type + "] without a closing tag, file: {}".format(state.current_class), state) + return None + + code_text = post_text[len("[" + code_type + "]") : end_pos] + post_text = post_text[end_pos:] + + # Remove extraneous tabs + code_pos = 0 + while True: + code_pos = code_text.find("\n", code_pos) + if code_pos == -1: + break + + to_skip = 0 + while code_pos + to_skip + 1 < len(code_text) and code_text[code_pos + to_skip + 1] == "\t": + to_skip += 1 + + if to_skip > indent_level: + print_error( + "Four spaces should be used for indentation within [" + + code_type + + "], file: {}".format(state.current_class), + state, + ) + + if len(code_text[code_pos + to_skip + 1 :]) == 0: + code_text = code_text[:code_pos] + "\n" + code_pos += 1 + else: + code_text = code_text[:code_pos] + "\n " + code_text[code_pos + to_skip + 1 :] + code_pos += 5 - to_skip + return ["\n[" + code_type + "]" + code_text + post_text, len("\n[" + code_type + "]" + code_text)] + + def rstize_text(text, state): # type: (str, State) -> str # Linebreak + tabs in the XML should become two line breaks unless in a "codeblock" pos = 0 @@ -616,43 +653,17 @@ def rstize_text(text, state): # type: (str, State) -> str post_text = text[pos + 1 :] # Handle codeblocks - if post_text.startswith("[codeblock]"): - end_pos = post_text.find("[/codeblock]") - if end_pos == -1: - print_error("[codeblock] without a closing tag, file: {}".format(state.current_class), state) + if ( + post_text.startswith("[codeblock]") + or post_text.startswith("[gdscript]") + or post_text.startswith("[csharp]") + ): + block_type = post_text[1:].split("]")[0] + result = format_codeblock(block_type, post_text, indent_level, state) + if result is None: return "" - - code_text = post_text[len("[codeblock]") : end_pos] - post_text = post_text[end_pos:] - - # Remove extraneous tabs - code_pos = 0 - while True: - code_pos = code_text.find("\n", code_pos) - if code_pos == -1: - break - - to_skip = 0 - while code_pos + to_skip + 1 < len(code_text) and code_text[code_pos + to_skip + 1] == "\t": - to_skip += 1 - - if to_skip > indent_level: - print_error( - "Four spaces should be used for indentation within [codeblock], file: {}".format( - state.current_class - ), - state, - ) - - if len(code_text[code_pos + to_skip + 1 :]) == 0: - code_text = code_text[:code_pos] + "\n" - code_pos += 1 - else: - code_text = code_text[:code_pos] + "\n " + code_text[code_pos + to_skip + 1 :] - code_pos += 5 - to_skip - - text = pre_text + "\n[codeblock]" + code_text + post_text - pos += len("\n[codeblock]" + code_text) + text = pre_text + result[0] + pos += result[1] # Handle normal text else: @@ -697,7 +708,7 @@ def rstize_text(text, state): # type: (str, State) -> str else: # command cmd = tag_text space_pos = tag_text.find(" ") - if cmd == "/codeblock": + if cmd == "/codeblock" or cmd == "/gdscript" or cmd == "/csharp": tag_text = "" tag_depth -= 1 inside_code = False @@ -813,6 +824,20 @@ def rstize_text(text, state): # type: (str, State) -> str tag_depth += 1 tag_text = "\n::\n" inside_code = True + elif cmd == "gdscript": + tag_depth += 1 + tag_text = "\n .. code-tab:: gdscript GDScript\n" + inside_code = True + elif cmd == "csharp": + tag_depth += 1 + tag_text = "\n .. code-tab:: csharp\n" + inside_code = True + elif cmd == "codeblocks": + tag_depth += 1 + tag_text = "\n.. tabs::" + elif cmd == "/codeblocks": + tag_depth -= 1 + tag_text = "" elif cmd == "br": # Make a new paragraph instead of a linebreak, rst is not so linebreak friendly tag_text = "\n\n" diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 2a59aadd61..bce34db740 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -1252,6 +1252,55 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { String bbcode = p_bbcode.dedent().replace("\t", "").replace("\r", "").strip_edges(); + // Select the correct code examples + switch ((int)EDITOR_GET("text_editor/help/class_reference_examples")) { + case 0: // GDScript + bbcode = bbcode.replace("[gdscript]", "[codeblock]"); + bbcode = bbcode.replace("[/gdscript]", "[/codeblock]"); + + for (int pos = bbcode.find("[csharp]"); pos != -1; pos = bbcode.find("[csharp]")) { + if (bbcode.find("[/csharp]") == -1) { + WARN_PRINT("Unclosed [csharp] block or parse fail in code (search for tag errors)"); + break; + } + + bbcode.erase(pos, bbcode.find("[/csharp]") + 9 - pos); + while (bbcode[pos] == '\n') { + bbcode.erase(pos, 1); + } + } + break; + case 1: // C# + bbcode = bbcode.replace("[csharp]", "[codeblock]"); + bbcode = bbcode.replace("[/csharp]", "[/codeblock]"); + + for (int pos = bbcode.find("[gdscript]"); pos != -1; pos = bbcode.find("[gdscript]")) { + if (bbcode.find("[/gdscript]") == -1) { + WARN_PRINT("Unclosed [gdscript] block or parse fail in code (search for tag errors)"); + break; + } + + bbcode.erase(pos, bbcode.find("[/gdscript]") + 11 - pos); + while (bbcode[pos] == '\n') { + bbcode.erase(pos, 1); + } + } + break; + case 2: // GDScript and C# + bbcode = bbcode.replace("[csharp]", "[b]C#:[/b]\n[codeblock]"); + bbcode = bbcode.replace("[gdscript]", "[b]GDScript:[/b]\n[codeblock]"); + + bbcode = bbcode.replace("[/csharp]", "[/codeblock]"); + bbcode = bbcode.replace("[/gdscript]", "[/codeblock]"); + break; + } + + // Remove codeblocks (they would be printed otherwise) + bbcode = bbcode.replace("[codeblocks]\n", ""); + bbcode = bbcode.replace("\n[/codeblocks]", ""); + bbcode = bbcode.replace("[codeblocks]", ""); + bbcode = bbcode.replace("[/codeblocks]", ""); + // remove extra new lines around code blocks bbcode = bbcode.replace("[codeblock]\n", "[codeblock]"); bbcode = bbcode.replace("\n[/codeblock]", "[/codeblock]"); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 3a1a0d5b01..a3438b3601 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -495,6 +495,8 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { hints["text_editor/help/help_source_font_size"] = PropertyInfo(Variant::INT, "text_editor/help/help_source_font_size", PROPERTY_HINT_RANGE, "8,48,1"); _initial_set("text_editor/help/help_title_font_size", 23); hints["text_editor/help/help_title_font_size"] = PropertyInfo(Variant::INT, "text_editor/help/help_title_font_size", PROPERTY_HINT_RANGE, "8,48,1"); + _initial_set("text_editor/help/class_reference_examples", 0); + hints["text_editor/help/class_reference_examples"] = PropertyInfo(Variant::INT, "text_editor/help/class_reference_examples", PROPERTY_HINT_ENUM, "GDScript,C#,GDScript and C#"); /* Editors */