Browse Source

Add multiple programming language support to class reference

HaSa1002 5 years ago
parent
commit
5b51ae1c5d
3 changed files with 113 additions and 37 deletions
  1. 62 37
      doc/tools/makerst.py
  2. 49 0
      editor/editor_help.cpp
  3. 2 0
      editor/editor_settings.cpp

+ 62 - 37
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"

+ 49 - 0
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]");

+ 2 - 0
editor/editor_settings.cpp

@@ -495,6 +495,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> 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 */