diff options
Diffstat (limited to 'doc/tools/makerst.py')
-rwxr-xr-x | doc/tools/makerst.py | 190 |
1 files changed, 87 insertions, 103 deletions
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index a14ef7c665..5335116c8a 100755 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -287,6 +287,8 @@ def main(): # type: () -> None ) args = parser.parse_args() + print("Checking for errors in the XML class reference...") + file_list = [] # type: List[str] for path in args.path: @@ -345,7 +347,10 @@ def main(): # type: () -> None state.current_class = class_name make_rst_class(class_def, state, args.dry_run, args.output) - if state.errored: + if not state.errored: + print("No errors found.") + else: + print("Errors were found in the class reference XML. Please check the messages above.") exit(1) @@ -560,70 +565,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S index += 1 - -def make_class_list(class_list, columns): # type: (List[str], int) -> None - # This function is no longer used. - f = open("class_list.rst", "w", encoding="utf-8") - col_max = len(class_list) // columns + 1 - print(("col max is ", col_max)) - fit_columns = [] # type: List[List[str]] - - for _ in range(0, columns): - fit_columns.append([]) - - indexers = [] # type List[str] - last_initial = "" - - for idx, name in enumerate(class_list): - col = idx // col_max - if col >= columns: - col = columns - 1 - fit_columns[col].append(name) - idx += 1 - if name[:1] != last_initial: - indexers.append(name) - last_initial = name[:1] - - row_max = 0 - f.write("\n") - - for n in range(0, columns): - if len(fit_columns[n]) > row_max: - row_max = len(fit_columns[n]) - - f.write("| ") - for n in range(0, columns): - f.write(" | |") - - f.write("\n") - f.write("+") - for n in range(0, columns): - f.write("--+-------+") - f.write("\n") - - for r in range(0, row_max): - s = "+ " - for c in range(0, columns): - if r >= len(fit_columns[c]): - continue - - classname = fit_columns[c][r] - initial = classname[0] - if classname in indexers: - s += "**" + initial + "** | " - else: - s += " | " - - s += "[" + classname + "](class_" + classname.lower() + ") | " - - s += "\n" - f.write(s) - - for n in range(0, columns): - f.write("--+-------+") - f.write("\n") - - f.close() + f.write(make_footer()) def escape_rst(text, until_pos=-1): # type: (str) -> str @@ -660,6 +602,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 @@ -676,43 +655,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: @@ -757,7 +710,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 @@ -873,6 +826,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" @@ -1055,7 +1022,10 @@ def make_method_signature( out += " **)**" if isinstance(method_def, MethodDef) and method_def.qualifiers is not None: - out += " " + method_def.qualifiers + # Use substitutions for abbreviations. This is used to display tooltips on hover. + # See `make_footer()` for descriptions. + for qualifier in method_def.qualifiers.split(): + out += " |" + qualifier + "|" return ret_type, out @@ -1064,6 +1034,20 @@ def make_heading(title, underline): # type: (str, str) -> str return title + "\n" + (underline * len(title)) + "\n\n" +def make_footer(): # type: () -> str + # Generate reusable abbreviation substitutions. + # This way, we avoid bloating the generated rST with duplicate abbreviations. + # fmt: off + return ( + ".. |virtual| replace:: :abbr:`virtual (This method should typically be overridden by the user to have any effect.)`\n" + ".. |const| replace:: :abbr:`const (This method has no side effects. It doesn't modify any of the instance's member variables.)`\n" + ".. |vararg| replace:: :abbr:`vararg (This method accepts any number of arguments after the ones described here.)`\n" + ".. |constructor| replace:: :abbr:`constructor (This method is used to construct a type.)`\n" + ".. |operator| replace:: :abbr:`operator (This method describes a valid operator to use with this type as left-hand operand.)`\n" + ) + # fmt: on + + def make_url(link): # type: (str) -> str match = GODOT_DOCS_PATTERN.search(link) if match: |