summaryrefslogtreecommitdiff
path: root/doc/tools
diff options
context:
space:
mode:
Diffstat (limited to 'doc/tools')
-rwxr-xr-xdoc/tools/doc_merge.py114
-rwxr-xr-xdoc/tools/doc_status.py351
-rwxr-xr-xdoc/tools/makerst.py319
3 files changed, 426 insertions, 358 deletions
diff --git a/doc/tools/doc_merge.py b/doc/tools/doc_merge.py
index 496d5dcb74..f6f52f5d66 100755
--- a/doc/tools/doc_merge.py
+++ b/doc/tools/doc_merge.py
@@ -21,7 +21,7 @@ def write_string(_f, text, newline=True):
for t in range(tab):
_f.write("\t")
_f.write(text)
- if (newline):
+ if newline:
_f.write("\n")
@@ -30,7 +30,7 @@ def escape(ret):
ret = ret.replace("<", "&gt;")
ret = ret.replace(">", "&lt;")
ret = ret.replace("'", "&apos;")
- ret = ret.replace("\"", "&quot;")
+ ret = ret.replace('"', "&quot;")
return ret
@@ -43,25 +43,26 @@ def dec_tab():
global tab
tab -= 1
+
write_string(f, '<?xml version="1.0" encoding="UTF-8" ?>')
write_string(f, '<doc version="' + new_doc.attrib["version"] + '">')
def get_tag(node, name):
tag = ""
- if (name in node.attrib):
- tag = ' ' + name + '="' + escape(node.attrib[name]) + '" '
+ if name in node.attrib:
+ tag = " " + name + '="' + escape(node.attrib[name]) + '" '
return tag
def find_method_descr(old_class, name):
methods = old_class.find("methods")
- if(methods != None and len(list(methods)) > 0):
+ if methods != None and len(list(methods)) > 0:
for m in list(methods):
- if (m.attrib["name"] == name):
+ if m.attrib["name"] == name:
description = m.find("description")
- if (description != None and description.text.strip() != ""):
+ if description != None and description.text.strip() != "":
return description.text
return None
@@ -70,11 +71,11 @@ def find_method_descr(old_class, name):
def find_signal_descr(old_class, name):
signals = old_class.find("signals")
- if(signals != None and len(list(signals)) > 0):
+ if signals != None and len(list(signals)) > 0:
for m in list(signals):
- if (m.attrib["name"] == name):
+ if m.attrib["name"] == name:
description = m.find("description")
- if (description != None and description.text.strip() != ""):
+ if description != None and description.text.strip() != "":
return description.text
return None
@@ -82,13 +83,13 @@ def find_signal_descr(old_class, name):
def find_constant_descr(old_class, name):
- if (old_class is None):
+ if old_class is None:
return None
constants = old_class.find("constants")
- if(constants != None and len(list(constants)) > 0):
+ if constants != None and len(list(constants)) > 0:
for m in list(constants):
- if (m.attrib["name"] == name):
- if (m.text.strip() != ""):
+ if m.attrib["name"] == name:
+ if m.text.strip() != "":
return m.text
return None
@@ -96,35 +97,35 @@ def find_constant_descr(old_class, name):
def write_class(c):
class_name = c.attrib["name"]
print("Parsing Class: " + class_name)
- if (class_name in old_classes):
+ if class_name in old_classes:
old_class = old_classes[class_name]
else:
old_class = None
category = get_tag(c, "category")
inherits = get_tag(c, "inherits")
- write_string(f, '<class name="' + class_name + '" ' + category + inherits + '>')
+ write_string(f, '<class name="' + class_name + '" ' + category + inherits + ">")
inc_tab()
write_string(f, "<brief_description>")
- if (old_class != None):
+ if old_class != None:
old_brief_descr = old_class.find("brief_description")
- if (old_brief_descr != None):
+ if old_brief_descr != None:
write_string(f, escape(old_brief_descr.text.strip()))
write_string(f, "</brief_description>")
write_string(f, "<description>")
- if (old_class != None):
+ if old_class != None:
old_descr = old_class.find("description")
- if (old_descr != None):
+ if old_descr != None:
write_string(f, escape(old_descr.text.strip()))
write_string(f, "</description>")
methods = c.find("methods")
- if(methods != None and len(list(methods)) > 0):
+ if methods != None and len(list(methods)) > 0:
write_string(f, "<methods>")
inc_tab()
@@ -132,35 +133,46 @@ def write_class(c):
for m in list(methods):
qualifiers = get_tag(m, "qualifiers")
- write_string(f, '<method name="' + escape(m.attrib["name"]) + '" ' + qualifiers + '>')
+ write_string(f, '<method name="' + escape(m.attrib["name"]) + '" ' + qualifiers + ">")
inc_tab()
for a in list(m):
- if (a.tag == "return"):
+ if a.tag == "return":
typ = get_tag(a, "type")
- write_string(f, '<return' + typ + '>')
- write_string(f, '</return>')
- elif (a.tag == "argument"):
+ write_string(f, "<return" + typ + ">")
+ write_string(f, "</return>")
+ elif a.tag == "argument":
default = get_tag(a, "default")
- write_string(f, '<argument index="' + a.attrib["index"] + '" name="' + escape(a.attrib["name"]) + '" type="' + a.attrib["type"] + '"' + default + '>')
- write_string(f, '</argument>')
-
- write_string(f, '<description>')
- if (old_class != None):
+ write_string(
+ f,
+ '<argument index="'
+ + a.attrib["index"]
+ + '" name="'
+ + escape(a.attrib["name"])
+ + '" type="'
+ + a.attrib["type"]
+ + '"'
+ + default
+ + ">",
+ )
+ write_string(f, "</argument>")
+
+ write_string(f, "<description>")
+ if old_class != None:
old_method_descr = find_method_descr(old_class, m.attrib["name"])
- if (old_method_descr):
+ if old_method_descr:
write_string(f, escape(escape(old_method_descr.strip())))
- write_string(f, '</description>')
+ write_string(f, "</description>")
dec_tab()
write_string(f, "</method>")
dec_tab()
write_string(f, "</methods>")
signals = c.find("signals")
- if(signals != None and len(list(signals)) > 0):
+ if signals != None and len(list(signals)) > 0:
write_string(f, "<signals>")
inc_tab()
@@ -171,24 +183,33 @@ def write_class(c):
inc_tab()
for a in list(m):
- if (a.tag == "argument"):
-
- write_string(f, '<argument index="' + a.attrib["index"] + '" name="' + escape(a.attrib["name"]) + '" type="' + a.attrib["type"] + '">')
- write_string(f, '</argument>')
-
- write_string(f, '<description>')
- if (old_class != None):
+ if a.tag == "argument":
+
+ write_string(
+ f,
+ '<argument index="'
+ + a.attrib["index"]
+ + '" name="'
+ + escape(a.attrib["name"])
+ + '" type="'
+ + a.attrib["type"]
+ + '">',
+ )
+ write_string(f, "</argument>")
+
+ write_string(f, "<description>")
+ if old_class != None:
old_signal_descr = find_signal_descr(old_class, m.attrib["name"])
- if (old_signal_descr):
+ if old_signal_descr:
write_string(f, escape(old_signal_descr.strip()))
- write_string(f, '</description>')
+ write_string(f, "</description>")
dec_tab()
write_string(f, "</signal>")
dec_tab()
write_string(f, "</signals>")
constants = c.find("constants")
- if(constants != None and len(list(constants)) > 0):
+ if constants != None and len(list(constants)) > 0:
write_string(f, "<constants>")
inc_tab()
@@ -197,7 +218,7 @@ def write_class(c):
write_string(f, '<constant name="' + escape(m.attrib["name"]) + '" value="' + m.attrib["value"] + '">')
old_constant_descr = find_constant_descr(old_class, m.attrib["name"])
- if (old_constant_descr):
+ if old_constant_descr:
write_string(f, escape(old_constant_descr.strip()))
write_string(f, "</constant>")
@@ -207,9 +228,10 @@ def write_class(c):
dec_tab()
write_string(f, "</class>")
+
for c in list(old_doc):
old_classes[c.attrib["name"]] = c
for c in list(new_doc):
write_class(c)
-write_string(f, '</doc>\n')
+write_string(f, "</doc>\n")
diff --git a/doc/tools/doc_status.py b/doc/tools/doc_status.py
index e6e6d5f606..629b5a032b 100755
--- a/doc/tools/doc_status.py
+++ b/doc/tools/doc_status.py
@@ -13,75 +13,74 @@ import xml.etree.ElementTree as ET
################################################################################
flags = {
- 'c': platform.platform() != 'Windows', # Disable by default on windows, since we use ANSI escape codes
- 'b': False,
- 'g': False,
- 's': False,
- 'u': False,
- 'h': False,
- 'p': False,
- 'o': True,
- 'i': False,
- 'a': True,
- 'e': False,
+ "c": platform.platform() != "Windows", # Disable by default on windows, since we use ANSI escape codes
+ "b": False,
+ "g": False,
+ "s": False,
+ "u": False,
+ "h": False,
+ "p": False,
+ "o": True,
+ "i": False,
+ "a": True,
+ "e": False,
}
flag_descriptions = {
- 'c': 'Toggle colors when outputting.',
- 'b': 'Toggle showing only not fully described classes.',
- 'g': 'Toggle showing only completed classes.',
- 's': 'Toggle showing comments about the status.',
- 'u': 'Toggle URLs to docs.',
- 'h': 'Show help and exit.',
- 'p': 'Toggle showing percentage as well as counts.',
- 'o': 'Toggle overall column.',
- 'i': 'Toggle collapse of class items columns.',
- 'a': 'Toggle showing all items.',
- 'e': 'Toggle hiding empty items.',
+ "c": "Toggle colors when outputting.",
+ "b": "Toggle showing only not fully described classes.",
+ "g": "Toggle showing only completed classes.",
+ "s": "Toggle showing comments about the status.",
+ "u": "Toggle URLs to docs.",
+ "h": "Show help and exit.",
+ "p": "Toggle showing percentage as well as counts.",
+ "o": "Toggle overall column.",
+ "i": "Toggle collapse of class items columns.",
+ "a": "Toggle showing all items.",
+ "e": "Toggle hiding empty items.",
}
long_flags = {
- 'colors': 'c',
- 'use-colors': 'c',
-
- 'bad': 'b',
- 'only-bad': 'b',
-
- 'good': 'g',
- 'only-good': 'g',
-
- 'comments': 's',
- 'status': 's',
-
- 'urls': 'u',
- 'gen-url': 'u',
-
- 'help': 'h',
-
- 'percent': 'p',
- 'use-percentages': 'p',
-
- 'overall': 'o',
- 'use-overall': 'o',
-
- 'items': 'i',
- 'collapse': 'i',
-
- 'all': 'a',
-
- 'empty': 'e',
+ "colors": "c",
+ "use-colors": "c",
+ "bad": "b",
+ "only-bad": "b",
+ "good": "g",
+ "only-good": "g",
+ "comments": "s",
+ "status": "s",
+ "urls": "u",
+ "gen-url": "u",
+ "help": "h",
+ "percent": "p",
+ "use-percentages": "p",
+ "overall": "o",
+ "use-overall": "o",
+ "items": "i",
+ "collapse": "i",
+ "all": "a",
+ "empty": "e",
}
-table_columns = ['name', 'brief_description', 'description', 'methods', 'constants', 'members', 'signals', 'theme_items']
-table_column_names = ['Name', 'Brief Desc.', 'Desc.', 'Methods', 'Constants', 'Members', 'Signals', 'Theme Items']
+table_columns = [
+ "name",
+ "brief_description",
+ "description",
+ "methods",
+ "constants",
+ "members",
+ "signals",
+ "theme_items",
+]
+table_column_names = ["Name", "Brief Desc.", "Desc.", "Methods", "Constants", "Members", "Signals", "Theme Items"]
colors = {
- 'name': [36], # cyan
- 'part_big_problem': [4, 31], # underline, red
- 'part_problem': [31], # red
- 'part_mostly_good': [33], # yellow
- 'part_good': [32], # green
- 'url': [4, 34], # underline, blue
- 'section': [1, 4], # bold, underline
- 'state_off': [36], # cyan
- 'state_on': [1, 35], # bold, magenta/plum
- 'bold': [1], # bold
+ "name": [36], # cyan
+ "part_big_problem": [4, 31], # underline, red
+ "part_problem": [31], # red
+ "part_mostly_good": [33], # yellow
+ "part_good": [32], # green
+ "url": [4, 34], # underline, blue
+ "section": [1, 4], # bold, underline
+ "state_off": [36], # cyan
+ "state_on": [1, 35], # bold, magenta/plum
+ "bold": [1], # bold
}
overall_progress_description_weigth = 10
@@ -90,6 +89,7 @@ overall_progress_description_weigth = 10
# Utils #
################################################################################
+
def validate_tag(elem, tag):
if elem.tag != tag:
print('Tag mismatch, expected "' + tag + '", got ' + elem.tag)
@@ -97,36 +97,38 @@ def validate_tag(elem, tag):
def color(color, string):
- if flags['c'] and terminal_supports_color():
- color_format = ''
+ if flags["c"] and terminal_supports_color():
+ color_format = ""
for code in colors[color]:
- color_format += '\033[' + str(code) + 'm'
- return color_format + string + '\033[0m'
+ color_format += "\033[" + str(code) + "m"
+ return color_format + string + "\033[0m"
else:
return string
-ansi_escape = re.compile(r'\x1b[^m]*m')
+
+ansi_escape = re.compile(r"\x1b[^m]*m")
def nonescape_len(s):
- return len(ansi_escape.sub('', s))
+ return len(ansi_escape.sub("", s))
+
def terminal_supports_color():
p = sys.platform
- supported_platform = p != 'Pocket PC' and (p != 'win32' or
- 'ANSICON' in os.environ)
+ supported_platform = p != "Pocket PC" and (p != "win32" or "ANSICON" in os.environ)
- is_a_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
+ is_a_tty = hasattr(sys.stdout, "isatty") and sys.stdout.isatty()
if not supported_platform or not is_a_tty:
return False
return True
+
################################################################################
# Classes #
################################################################################
-class ClassStatusProgress:
+class ClassStatusProgress:
def __init__(self, described=0, total=0):
self.described = described
self.total = total
@@ -143,42 +145,41 @@ class ClassStatusProgress:
return self.described >= self.total
def to_configured_colored_string(self):
- if flags['p']:
- return self.to_colored_string('{percent}% ({has}/{total})', '{pad_percent}{pad_described}{s}{pad_total}')
+ if flags["p"]:
+ return self.to_colored_string("{percent}% ({has}/{total})", "{pad_percent}{pad_described}{s}{pad_total}")
else:
return self.to_colored_string()
- def to_colored_string(self, format='{has}/{total}', pad_format='{pad_described}{s}{pad_total}'):
+ def to_colored_string(self, format="{has}/{total}", pad_format="{pad_described}{s}{pad_total}"):
ratio = float(self.described) / float(self.total) if self.total != 0 else 1
percent = int(round(100 * ratio))
s = format.format(has=str(self.described), total=str(self.total), percent=str(percent))
if self.described >= self.total:
- s = color('part_good', s)
+ s = color("part_good", s)
elif self.described >= self.total / 4 * 3:
- s = color('part_mostly_good', s)
+ s = color("part_mostly_good", s)
elif self.described > 0:
- s = color('part_problem', s)
+ s = color("part_problem", s)
else:
- s = color('part_big_problem', s)
+ s = color("part_big_problem", s)
pad_size = max(len(str(self.described)), len(str(self.total)))
- pad_described = ''.ljust(pad_size - len(str(self.described)))
- pad_percent = ''.ljust(3 - len(str(percent)))
- pad_total = ''.ljust(pad_size - len(str(self.total)))
+ pad_described = "".ljust(pad_size - len(str(self.described)))
+ pad_percent = "".ljust(3 - len(str(percent)))
+ pad_total = "".ljust(pad_size - len(str(self.total)))
return pad_format.format(pad_described=pad_described, pad_total=pad_total, pad_percent=pad_percent, s=s)
class ClassStatus:
-
- def __init__(self, name=''):
+ def __init__(self, name=""):
self.name = name
self.has_brief_description = True
self.has_description = True
self.progresses = {
- 'methods': ClassStatusProgress(),
- 'constants': ClassStatusProgress(),
- 'members': ClassStatusProgress(),
- 'theme_items': ClassStatusProgress(),
- 'signals': ClassStatusProgress()
+ "methods": ClassStatusProgress(),
+ "constants": ClassStatusProgress(),
+ "members": ClassStatusProgress(),
+ "theme_items": ClassStatusProgress(),
+ "signals": ClassStatusProgress(),
}
def __add__(self, other):
@@ -208,66 +209,70 @@ class ClassStatus:
def make_output(self):
output = {}
- output['name'] = color('name', self.name)
+ output["name"] = color("name", self.name)
- ok_string = color('part_good', 'OK')
- missing_string = color('part_big_problem', 'MISSING')
+ ok_string = color("part_good", "OK")
+ missing_string = color("part_big_problem", "MISSING")
- output['brief_description'] = ok_string if self.has_brief_description else missing_string
- output['description'] = ok_string if self.has_description else missing_string
+ output["brief_description"] = ok_string if self.has_brief_description else missing_string
+ output["description"] = ok_string if self.has_description else missing_string
description_progress = ClassStatusProgress(
(self.has_brief_description + self.has_description) * overall_progress_description_weigth,
- 2 * overall_progress_description_weigth
+ 2 * overall_progress_description_weigth,
)
items_progress = ClassStatusProgress()
- for k in ['methods', 'constants', 'members', 'signals', 'theme_items']:
+ for k in ["methods", "constants", "members", "signals", "theme_items"]:
items_progress += self.progresses[k]
output[k] = self.progresses[k].to_configured_colored_string()
- output['items'] = items_progress.to_configured_colored_string()
+ output["items"] = items_progress.to_configured_colored_string()
- output['overall'] = (description_progress + items_progress).to_colored_string(color('bold', '{percent}%'), '{pad_percent}{s}')
+ output["overall"] = (description_progress + items_progress).to_colored_string(
+ color("bold", "{percent}%"), "{pad_percent}{s}"
+ )
- if self.name.startswith('Total'):
- output['url'] = color('url', 'https://docs.godotengine.org/en/latest/classes/')
- if flags['s']:
- output['comment'] = color('part_good', 'ALL OK')
+ if self.name.startswith("Total"):
+ output["url"] = color("url", "https://docs.godotengine.org/en/latest/classes/")
+ if flags["s"]:
+ output["comment"] = color("part_good", "ALL OK")
else:
- output['url'] = color('url', 'https://docs.godotengine.org/en/latest/classes/class_{name}.html'.format(name=self.name.lower()))
+ output["url"] = color(
+ "url", "https://docs.godotengine.org/en/latest/classes/class_{name}.html".format(name=self.name.lower())
+ )
- if flags['s'] and not flags['g'] and self.is_ok():
- output['comment'] = color('part_good', 'ALL OK')
+ if flags["s"] and not flags["g"] and self.is_ok():
+ output["comment"] = color("part_good", "ALL OK")
return output
@staticmethod
def generate_for_class(c):
status = ClassStatus()
- status.name = c.attrib['name']
+ status.name = c.attrib["name"]
for tag in list(c):
- if tag.tag == 'brief_description':
+ if tag.tag == "brief_description":
status.has_brief_description = len(tag.text.strip()) > 0
- elif tag.tag == 'description':
+ elif tag.tag == "description":
status.has_description = len(tag.text.strip()) > 0
- elif tag.tag in ['methods', 'signals']:
+ elif tag.tag in ["methods", "signals"]:
for sub_tag in list(tag):
- descr = sub_tag.find('description')
+ descr = sub_tag.find("description")
status.progresses[tag.tag].increment(len(descr.text.strip()) > 0)
- elif tag.tag in ['constants', 'members', 'theme_items']:
+ elif tag.tag in ["constants", "members", "theme_items"]:
for sub_tag in list(tag):
if not sub_tag.text is None:
status.progresses[tag.tag].increment(len(sub_tag.text.strip()) > 0)
- elif tag.tag in ['tutorials']:
+ elif tag.tag in ["tutorials"]:
pass # Ignore those tags for now
- elif tag.tag in ['theme_items']:
+ elif tag.tag in ["theme_items"]:
pass # Ignore those tags, since they seem to lack description at all
else:
@@ -286,63 +291,69 @@ merged_file = ""
for arg in sys.argv[1:]:
try:
- if arg.startswith('--'):
+ if arg.startswith("--"):
flags[long_flags[arg[2:]]] = not flags[long_flags[arg[2:]]]
- elif arg.startswith('-'):
+ elif arg.startswith("-"):
for f in arg[1:]:
flags[f] = not flags[f]
elif os.path.isdir(arg):
for f in os.listdir(arg):
- if f.endswith('.xml'):
- input_file_list.append(os.path.join(arg, f));
+ if f.endswith(".xml"):
+ input_file_list.append(os.path.join(arg, f))
else:
input_class_list.append(arg)
except KeyError:
print("Unknown command line flag: " + arg)
sys.exit(1)
-if flags['i']:
- for r in ['methods', 'constants', 'members', 'signals', 'theme_items']:
+if flags["i"]:
+ for r in ["methods", "constants", "members", "signals", "theme_items"]:
index = table_columns.index(r)
del table_column_names[index]
del table_columns[index]
- table_column_names.append('Items')
- table_columns.append('items')
+ table_column_names.append("Items")
+ table_columns.append("items")
-if flags['o'] == (not flags['i']):
- table_column_names.append(color('bold', 'Overall'))
- table_columns.append('overall')
+if flags["o"] == (not flags["i"]):
+ table_column_names.append(color("bold", "Overall"))
+ table_columns.append("overall")
-if flags['u']:
- table_column_names.append('Docs URL')
- table_columns.append('url')
+if flags["u"]:
+ table_column_names.append("Docs URL")
+ table_columns.append("url")
################################################################################
# Help #
################################################################################
-if len(input_file_list) < 1 or flags['h']:
- if not flags['h']:
- print(color('section', 'Invalid usage') + ': Please specify a classes directory')
- print(color('section', 'Usage') + ': doc_status.py [flags] <classes_dir> [class names]')
- print('\t< and > signify required parameters, while [ and ] signify optional parameters.')
- print(color('section', 'Available flags') + ':')
+if len(input_file_list) < 1 or flags["h"]:
+ if not flags["h"]:
+ print(color("section", "Invalid usage") + ": Please specify a classes directory")
+ print(color("section", "Usage") + ": doc_status.py [flags] <classes_dir> [class names]")
+ print("\t< and > signify required parameters, while [ and ] signify optional parameters.")
+ print(color("section", "Available flags") + ":")
possible_synonym_list = list(long_flags)
possible_synonym_list.sort()
flag_list = list(flags)
flag_list.sort()
for flag in flag_list:
- synonyms = [color('name', '-' + flag)]
+ synonyms = [color("name", "-" + flag)]
for synonym in possible_synonym_list:
if long_flags[synonym] == flag:
- synonyms.append(color('name', '--' + synonym))
-
- print(('{synonyms} (Currently ' + color('state_' + ('on' if flags[flag] else 'off'), '{value}') + ')\n\t{description}').format(
- synonyms=', '.join(synonyms),
- value=('on' if flags[flag] else 'off'),
- description=flag_descriptions[flag]
- ))
+ synonyms.append(color("name", "--" + synonym))
+
+ print(
+ (
+ "{synonyms} (Currently "
+ + color("state_" + ("on" if flags[flag] else "off"), "{value}")
+ + ")\n\t{description}"
+ ).format(
+ synonyms=", ".join(synonyms),
+ value=("on" if flags[flag] else "off"),
+ description=flag_descriptions[flag],
+ )
+ )
sys.exit(0)
@@ -357,21 +368,21 @@ for file in input_file_list:
tree = ET.parse(file)
doc = tree.getroot()
- if 'version' not in doc.attrib:
+ if "version" not in doc.attrib:
print('Version missing from "doc"')
sys.exit(255)
- version = doc.attrib['version']
+ version = doc.attrib["version"]
- if doc.attrib['name'] in class_names:
+ if doc.attrib["name"] in class_names:
continue
- class_names.append(doc.attrib['name'])
- classes[doc.attrib['name']] = doc
+ class_names.append(doc.attrib["name"])
+ classes[doc.attrib["name"]] = doc
class_names.sort()
if len(input_class_list) < 1:
- input_class_list = ['*']
+ input_class_list = ["*"]
filtered_classes = set()
for pattern in input_class_list:
@@ -384,23 +395,23 @@ filtered_classes.sort()
################################################################################
table = [table_column_names]
-table_row_chars = '| - '
-table_column_chars = '|'
+table_row_chars = "| - "
+table_column_chars = "|"
-total_status = ClassStatus('Total')
+total_status = ClassStatus("Total")
for cn in filtered_classes:
c = classes[cn]
- validate_tag(c, 'class')
+ validate_tag(c, "class")
status = ClassStatus.generate_for_class(c)
total_status = total_status + status
- if (flags['b'] and status.is_ok()) or (flags['g'] and not status.is_ok()) or (not flags['a']):
+ if (flags["b"] and status.is_ok()) or (flags["g"] and not status.is_ok()) or (not flags["a"]):
continue
- if flags['e'] and status.is_empty():
+ if flags["e"] and status.is_empty():
continue
out = status.make_output()
@@ -409,10 +420,10 @@ for cn in filtered_classes:
if column in out:
row.append(out[column])
else:
- row.append('')
+ row.append("")
- if 'comment' in out and out['comment'] != '':
- row.append(out['comment'])
+ if "comment" in out and out["comment"] != "":
+ row.append(out["comment"])
table.append(row)
@@ -421,22 +432,22 @@ for cn in filtered_classes:
# Print output table #
################################################################################
-if len(table) == 1 and flags['a']:
- print(color('part_big_problem', 'No classes suitable for printing!'))
+if len(table) == 1 and flags["a"]:
+ print(color("part_big_problem", "No classes suitable for printing!"))
sys.exit(0)
-if len(table) > 2 or not flags['a']:
- total_status.name = 'Total = {0}'.format(len(table) - 1)
+if len(table) > 2 or not flags["a"]:
+ total_status.name = "Total = {0}".format(len(table) - 1)
out = total_status.make_output()
row = []
for column in table_columns:
if column in out:
row.append(out[column])
else:
- row.append('')
+ row.append("")
table.append(row)
-if flags['a']:
+if flags["a"]:
# Duplicate the headers at the bottom of the table so they can be viewed
# without having to scroll back to the top.
table.append(table_column_names)
@@ -451,7 +462,9 @@ for row in table:
divider_string = table_row_chars[0]
for cell_i in range(len(table[0])):
- divider_string += table_row_chars[1] + table_row_chars[2] * (table_column_sizes[cell_i]) + table_row_chars[1] + table_row_chars[0]
+ divider_string += (
+ table_row_chars[1] + table_row_chars[2] * (table_column_sizes[cell_i]) + table_row_chars[1] + table_row_chars[0]
+ )
print(divider_string)
for row_i, row in enumerate(table):
@@ -461,7 +474,11 @@ for row_i, row in enumerate(table):
if cell_i == 0:
row_string += table_row_chars[3] + cell + table_row_chars[3] * (padding_needed - 1)
else:
- row_string += table_row_chars[3] * int(math.floor(float(padding_needed) / 2)) + cell + table_row_chars[3] * int(math.ceil(float(padding_needed) / 2))
+ row_string += (
+ table_row_chars[3] * int(math.floor(float(padding_needed) / 2))
+ + cell
+ + table_row_chars[3] * int(math.ceil(float(padding_needed) / 2))
+ )
row_string += table_column_chars
print(row_string)
@@ -474,5 +491,5 @@ for row_i, row in enumerate(table):
print(divider_string)
-if total_status.is_ok() and not flags['g']:
- print('All listed classes are ' + color('part_good', 'OK') + '!')
+if total_status.is_ok() and not flags["g"]:
+ print("All listed classes are " + color("part_good", "OK") + "!")
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 9012de03b3..c6c6cae6c0 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -7,10 +7,12 @@ import xml.etree.ElementTree as ET
from collections import OrderedDict
# Uncomment to do type checks. I have it commented out so it works below Python 3.5
-#from typing import List, Dict, TextIO, Tuple, Iterable, Optional, DefaultDict, Any, Union
+# from typing import List, Dict, TextIO, Tuple, Iterable, Optional, DefaultDict, Any, Union
# http(s)://docs.godotengine.org/<langcode>/<tag>/path/to/page.html(#fragment-tag)
-GODOT_DOCS_PATTERN = re.compile(r'^http(?:s)?://docs\.godotengine\.org/(?:[a-zA-Z0-9.\-_]*)/(?:[a-zA-Z0-9.\-_]*)/(.*)\.html(#.*)?$')
+GODOT_DOCS_PATTERN = re.compile(
+ r"^http(?:s)?://docs\.godotengine\.org/(?:[a-zA-Z0-9.\-_]*)/(?:[a-zA-Z0-9.\-_]*)/(.*)\.html(#.*)?$"
+)
def print_error(error, state): # type: (str, State) -> None
@@ -37,7 +39,9 @@ class TypeName:
class PropertyDef:
- def __init__(self, name, type_name, setter, getter, text, default_value, overridden): # type: (str, TypeName, Optional[str], Optional[str], Optional[str], Optional[str], Optional[bool]) -> None
+ def __init__(
+ self, name, type_name, setter, getter, text, default_value, overridden
+ ): # type: (str, TypeName, Optional[str], Optional[str], Optional[str], Optional[str], Optional[bool]) -> None
self.name = name
self.type_name = type_name
self.setter = setter
@@ -46,6 +50,7 @@ class PropertyDef:
self.default_value = default_value
self.overridden = overridden
+
class ParameterDef:
def __init__(self, name, type_name, default_value): # type: (str, TypeName, Optional[str]) -> None
self.name = name
@@ -61,7 +66,9 @@ class SignalDef:
class MethodDef:
- def __init__(self, name, return_type, parameters, description, qualifiers): # type: (str, TypeName, List[ParameterDef], Optional[str], Optional[str]) -> None
+ def __init__(
+ self, name, return_type, parameters, description, qualifiers
+ ): # type: (str, TypeName, List[ParameterDef], Optional[str], Optional[str]) -> None
self.name = name
self.return_type = return_type
self.parameters = parameters
@@ -144,10 +151,12 @@ class State:
getter = property.get("getter") or None
default_value = property.get("default") or None
if default_value is not None:
- default_value = '``{}``'.format(default_value)
+ default_value = "``{}``".format(default_value)
overridden = property.get("override") or False
- property_def = PropertyDef(property_name, type_name, setter, getter, property.text, default_value, overridden)
+ property_def = PropertyDef(
+ property_name, type_name, setter, getter, property.text, default_value, overridden
+ )
class_def.properties[property_name] = property_def
methods = class_root.find("methods")
@@ -246,8 +255,6 @@ class State:
if link.text is not None:
class_def.tutorials.append(link.text)
-
-
def sort_classes(self): # type: () -> None
self.classes = OrderedDict(sorted(self.classes.items(), key=lambda t: t[0]))
@@ -273,7 +280,11 @@ def main(): # type: () -> None
parser.add_argument("path", nargs="+", help="A path to an XML file or a directory containing XML files to parse.")
group = parser.add_mutually_exclusive_group()
group.add_argument("--output", "-o", default=".", help="The directory to save output .rst files in.")
- group.add_argument("--dry-run", action="store_true", help="If passed, no output will be generated and XML files are only checked for errors.")
+ group.add_argument(
+ "--dry-run",
+ action="store_true",
+ help="If passed, no output will be generated and XML files are only checked for errors.",
+ )
args = parser.parse_args()
file_list = [] # type: List[str]
@@ -283,15 +294,15 @@ def main(): # type: () -> None
if path.endswith(os.sep):
path = path[:-1]
- if os.path.basename(path) == 'modules':
+ if os.path.basename(path) == "modules":
for subdir, dirs, _ in os.walk(path):
- if 'doc_classes' in dirs:
- doc_dir = os.path.join(subdir, 'doc_classes')
- class_file_names = (f for f in os.listdir(doc_dir) if f.endswith('.xml'))
+ if "doc_classes" in dirs:
+ doc_dir = os.path.join(subdir, "doc_classes")
+ class_file_names = (f for f in os.listdir(doc_dir) if f.endswith(".xml"))
file_list += (os.path.join(doc_dir, f) for f in class_file_names)
elif os.path.isdir(path):
- file_list += (os.path.join(path, f) for f in os.listdir(path) if f.endswith('.xml'))
+ file_list += (os.path.join(path, f) for f in os.listdir(path) if f.endswith(".xml"))
elif os.path.isfile(path):
if not path.endswith(".xml"):
@@ -311,7 +322,7 @@ def main(): # type: () -> None
continue
doc = tree.getroot()
- if 'version' not in doc.attrib:
+ if "version" not in doc.attrib:
print_error("Version missing from 'doc', file: {}".format(cur_file), state)
continue
@@ -337,13 +348,14 @@ def main(): # type: () -> None
if state.errored:
exit(1)
+
def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, State, bool, str) -> None
class_name = class_def.name
if dry_run:
- f = open(os.devnull, "w")
+ f = open(os.devnull, "w", encoding="utf-8")
else:
- f = open(os.path.join(output_dir, "class_" + class_name.lower() + '.rst'), 'w', encoding='utf-8')
+ f = open(os.path.join(output_dir, "class_" + class_name.lower() + ".rst"), "w", encoding="utf-8")
# Warn contributors not to edit this file directly
f.write(":github_url: hide\n\n")
@@ -352,13 +364,13 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
f.write(".. The source is found in doc/classes or modules/<name>/doc_classes.\n\n")
f.write(".. _class_" + class_name + ":\n\n")
- f.write(make_heading(class_name, '='))
+ f.write(make_heading(class_name, "="))
# Inheritance tree
# Ascendants
if class_def.inherits:
inh = class_def.inherits.strip()
- f.write('**Inherits:** ')
+ f.write("**Inherits:** ")
first = True
while inh in state.classes:
if not first:
@@ -381,7 +393,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
inherited.append(c.name)
if len(inherited):
- f.write('**Inherited By:** ')
+ f.write("**Inherited By:** ")
for i, child in enumerate(inherited):
if i > 0:
f.write(", ")
@@ -393,26 +405,26 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
f.write(rstize_text(class_def.brief_description.strip(), state) + "\n\n")
# Class description
- if class_def.description is not None and class_def.description.strip() != '':
- f.write(make_heading('Description', '-'))
+ if class_def.description is not None and class_def.description.strip() != "":
+ f.write(make_heading("Description", "-"))
f.write(rstize_text(class_def.description.strip(), state) + "\n\n")
# Online tutorials
if len(class_def.tutorials) > 0:
- f.write(make_heading('Tutorials', '-'))
+ f.write(make_heading("Tutorials", "-"))
for t in class_def.tutorials:
link = t.strip()
f.write("- " + make_url(link) + "\n\n")
# Properties overview
if len(class_def.properties) > 0:
- f.write(make_heading('Properties', '-'))
+ f.write(make_heading("Properties", "-"))
ml = [] # type: List[Tuple[str, str, str]]
for property_def in class_def.properties.values():
type_rst = property_def.type_name.to_rst(state)
default = property_def.default_value
if property_def.overridden:
- ml.append((type_rst, property_def.name, "**O:** " + default))
+ ml.append((type_rst, property_def.name, default + " *(parent override)*"))
else:
ref = ":ref:`{0}<class_{1}_property_{0}>`".format(property_def.name, class_name)
ml.append((type_rst, ref, default))
@@ -420,7 +432,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
# Methods overview
if len(class_def.methods) > 0:
- f.write(make_heading('Methods', '-'))
+ f.write(make_heading("Methods", "-"))
ml = []
for method_list in class_def.methods.values():
for m in method_list:
@@ -429,7 +441,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
# Theme properties
if class_def.theme_items is not None and len(class_def.theme_items) > 0:
- f.write(make_heading('Theme Properties', '-'))
+ f.write(make_heading("Theme Properties", "-"))
pl = []
for theme_item_list in class_def.theme_items.values():
for theme_item in theme_item_list:
@@ -438,30 +450,30 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
# Signals
if len(class_def.signals) > 0:
- f.write(make_heading('Signals', '-'))
+ f.write(make_heading("Signals", "-"))
index = 0
for signal in class_def.signals.values():
if index != 0:
- f.write('----\n\n')
+ f.write("----\n\n")
f.write(".. _class_{}_signal_{}:\n\n".format(class_name, signal.name))
_, signature = make_method_signature(class_def, signal, False, state)
f.write("- {}\n\n".format(signature))
- if signal.description is not None and signal.description.strip() != '':
- f.write(rstize_text(signal.description.strip(), state) + '\n\n')
+ if signal.description is not None and signal.description.strip() != "":
+ f.write(rstize_text(signal.description.strip(), state) + "\n\n")
index += 1
# Enums
if len(class_def.enums) > 0:
- f.write(make_heading('Enumerations', '-'))
+ f.write(make_heading("Enumerations", "-"))
index = 0
for e in class_def.enums.values():
if index != 0:
- f.write('----\n\n')
+ f.write("----\n\n")
f.write(".. _enum_{}_{}:\n\n".format(class_name, e.name))
# Sphinx seems to divide the bullet list into individual <ul> tags if we weave the labels into it.
@@ -474,16 +486,16 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
f.write("enum **{}**:\n\n".format(e.name))
for value in e.values.values():
f.write("- **{}** = **{}**".format(value.name, value.value))
- if value.text is not None and value.text.strip() != '':
- f.write(' --- ' + rstize_text(value.text.strip(), state))
+ if value.text is not None and value.text.strip() != "":
+ f.write(" --- " + rstize_text(value.text.strip(), state))
- f.write('\n\n')
+ f.write("\n\n")
index += 1
# Constants
if len(class_def.constants) > 0:
- f.write(make_heading('Constants', '-'))
+ f.write(make_heading("Constants", "-"))
# Sphinx seems to divide the bullet list into individual <ul> tags if we weave the labels into it.
# As such I'll put them all above the list. Won't be perfect but better than making the list visually broken.
for constant in class_def.constants.values():
@@ -491,14 +503,14 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
for constant in class_def.constants.values():
f.write("- **{}** = **{}**".format(constant.name, constant.value))
- if constant.text is not None and constant.text.strip() != '':
- f.write(' --- ' + rstize_text(constant.text.strip(), state))
+ if constant.text is not None and constant.text.strip() != "":
+ f.write(" --- " + rstize_text(constant.text.strip(), state))
- f.write('\n\n')
+ f.write("\n\n")
# Property descriptions
if any(not p.overridden for p in class_def.properties.values()) > 0:
- f.write(make_heading('Property Descriptions', '-'))
+ f.write(make_heading("Property Descriptions", "-"))
index = 0
for property_def in class_def.properties.values():
@@ -506,36 +518,36 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
continue
if index != 0:
- f.write('----\n\n')
+ f.write("----\n\n")
f.write(".. _class_{}_property_{}:\n\n".format(class_name, property_def.name))
- f.write('- {} **{}**\n\n'.format(property_def.type_name.to_rst(state), property_def.name))
+ f.write("- {} **{}**\n\n".format(property_def.type_name.to_rst(state), property_def.name))
info = []
if property_def.default_value is not None:
info.append(("*Default*", property_def.default_value))
if property_def.setter is not None and not property_def.setter.startswith("_"):
- info.append(("*Setter*", property_def.setter + '(value)'))
+ info.append(("*Setter*", property_def.setter + "(value)"))
if property_def.getter is not None and not property_def.getter.startswith("_"):
- info.append(('*Getter*', property_def.getter + '()'))
+ info.append(("*Getter*", property_def.getter + "()"))
if len(info) > 0:
format_table(f, info)
- if property_def.text is not None and property_def.text.strip() != '':
- f.write(rstize_text(property_def.text.strip(), state) + '\n\n')
+ if property_def.text is not None and property_def.text.strip() != "":
+ f.write(rstize_text(property_def.text.strip(), state) + "\n\n")
index += 1
# Method descriptions
if len(class_def.methods) > 0:
- f.write(make_heading('Method Descriptions', '-'))
+ f.write(make_heading("Method Descriptions", "-"))
index = 0
for method_list in class_def.methods.values():
for i, m in enumerate(method_list):
if index != 0:
- f.write('----\n\n')
+ f.write("----\n\n")
if i == 0:
f.write(".. _class_{}_method_{}:\n\n".format(class_name, m.name))
@@ -543,24 +555,24 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
ret_type, signature = make_method_signature(class_def, m, False, state)
f.write("- {} {}\n\n".format(ret_type, signature))
- if m.description is not None and m.description.strip() != '':
- f.write(rstize_text(m.description.strip(), state) + '\n\n')
+ if m.description is not None and m.description.strip() != "":
+ f.write(rstize_text(m.description.strip(), state) + "\n\n")
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')
+ f = open("class_list.rst", "w", encoding="utf-8")
col_max = len(class_list) // columns + 1
- print(('col max is ', col_max))
+ 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 = ''
+ last_initial = ""
for idx, name in enumerate(class_list):
col = idx // col_max
@@ -590,7 +602,7 @@ def make_class_list(class_list, columns): # type: (List[str], int) -> None
f.write("\n")
for r in range(0, row_max):
- s = '+ '
+ s = "+ "
for c in range(0, columns):
if r >= len(fit_columns[c]):
continue
@@ -598,13 +610,13 @@ def make_class_list(class_list, columns): # type: (List[str], int) -> None
classname = fit_columns[c][r]
initial = classname[0]
if classname in indexers:
- s += '**' + initial + '** | '
+ s += "**" + initial + "** | "
else:
- s += ' | '
+ s += " | "
- s += '[' + classname + '](class_' + classname.lower() + ') | '
+ s += "[" + classname + "](class_" + classname.lower() + ") | "
- s += '\n'
+ s += "\n"
f.write(s)
for n in range(0, columns):
@@ -618,29 +630,29 @@ def escape_rst(text, until_pos=-1): # type: (str) -> str
# Escape \ character, otherwise it ends up as an escape character in rst
pos = 0
while True:
- pos = text.find('\\', pos, until_pos)
+ pos = text.find("\\", pos, until_pos)
if pos == -1:
break
- text = text[:pos] + "\\\\" + text[pos + 1:]
+ text = text[:pos] + "\\\\" + text[pos + 1 :]
pos += 2
# Escape * character to avoid interpreting it as emphasis
pos = 0
while True:
- pos = text.find('*', pos, until_pos)
+ pos = text.find("*", pos, until_pos)
if pos == -1:
break
- text = text[:pos] + "\*" + text[pos + 1:]
+ text = text[:pos] + "\*" + text[pos + 1 :]
pos += 2
# Escape _ character at the end of a word to avoid interpreting it as an inline hyperlink
pos = 0
while True:
- pos = text.find('_', pos, until_pos)
+ pos = text.find("_", pos, until_pos)
if pos == -1:
break
if not text[pos + 1].isalnum(): # don't escape within a snake_case word
- text = text[:pos] + "\_" + text[pos + 1:]
+ text = text[:pos] + "\_" + text[pos + 1 :]
pos += 2
else:
pos += 1
@@ -652,16 +664,16 @@ 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
while True:
- pos = text.find('\n', pos)
+ pos = text.find("\n", pos)
if pos == -1:
break
pre_text = text[:pos]
indent_level = 0
- while text[pos + 1] == '\t':
+ while text[pos + 1] == "\t":
pos += 1
indent_level += 1
- post_text = text[pos + 1:]
+ post_text = text[pos + 1 :]
# Handle codeblocks
if post_text.startswith("[codeblock]"):
@@ -670,28 +682,33 @@ def rstize_text(text, state): # type: (str, State) -> str
print_error("[codeblock] without a closing tag, file: {}".format(state.current_class), state)
return ""
- code_text = post_text[len("[codeblock]"):end_pos]
+ 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)
+ 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':
+ 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:
+ 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_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
@@ -702,7 +719,7 @@ def rstize_text(text, state): # type: (str, State) -> str
text = pre_text + "\n\n" + post_text
pos += 2
- next_brac_pos = text.find('[')
+ next_brac_pos = text.find("[")
text = escape_rst(text, next_brac_pos)
# Handle [tags]
@@ -714,54 +731,59 @@ def rstize_text(text, state): # type: (str, State) -> str
tag_depth = 0
previous_pos = 0
while True:
- pos = text.find('[', pos)
+ pos = text.find("[", pos)
if inside_url and (pos > previous_pos):
url_has_name = True
if pos == -1:
break
- endq_pos = text.find(']', pos + 1)
+ endq_pos = text.find("]", pos + 1)
if endq_pos == -1:
break
pre_text = text[:pos]
- post_text = text[endq_pos + 1:]
- tag_text = text[pos + 1:endq_pos]
+ post_text = text[endq_pos + 1 :]
+ tag_text = text[pos + 1 : endq_pos]
escape_post = False
if tag_text in state.classes:
if tag_text == state.current_class:
# We don't want references to the same class
- tag_text = '``{}``'.format(tag_text)
+ tag_text = "``{}``".format(tag_text)
else:
tag_text = make_type(tag_text, state)
escape_post = True
else: # command
cmd = tag_text
- space_pos = tag_text.find(' ')
- if cmd == '/codeblock':
- tag_text = ''
+ space_pos = tag_text.find(" ")
+ if cmd == "/codeblock":
+ tag_text = ""
tag_depth -= 1
inside_code = False
# Strip newline if the tag was alone on one
- if pre_text[-1] == '\n':
+ if pre_text[-1] == "\n":
pre_text = pre_text[:-1]
- elif cmd == '/code':
- tag_text = '``'
+ elif cmd == "/code":
+ tag_text = "``"
tag_depth -= 1
inside_code = False
escape_post = True
elif inside_code:
- tag_text = '[' + tag_text + ']'
- elif cmd.find('html') == 0:
- param = tag_text[space_pos + 1:]
+ tag_text = "[" + tag_text + "]"
+ elif cmd.find("html") == 0:
+ param = tag_text[space_pos + 1 :]
tag_text = param
- elif cmd.startswith('method') or cmd.startswith('member') or cmd.startswith('signal') or cmd.startswith('constant'):
- param = tag_text[space_pos + 1:]
-
- if param.find('.') != -1:
- ss = param.split('.')
+ elif (
+ cmd.startswith("method")
+ or cmd.startswith("member")
+ or cmd.startswith("signal")
+ or cmd.startswith("constant")
+ ):
+ param = tag_text[space_pos + 1 :]
+
+ if param.find(".") != -1:
+ ss = param.split(".")
if len(ss) > 2:
print_error("Bad reference: '{}', file: {}".format(param, state.current_class), state)
class_param, method_param = ss
@@ -794,7 +816,7 @@ def rstize_text(text, state): # type: (str, State) -> str
# Search in the current class
search_class_defs = [class_def]
- if param.find('.') == -1:
+ if param.find(".") == -1:
# Also search in @GlobalScope as a last resort if no class was specified
search_class_defs.append(state.classes["@GlobalScope"])
@@ -815,66 +837,71 @@ def rstize_text(text, state): # type: (str, State) -> str
ref_type = "_constant"
else:
- print_error("Unresolved type reference '{}' in method reference '{}', file: {}".format(class_param, param, state.current_class), state)
+ print_error(
+ "Unresolved type reference '{}' in method reference '{}', file: {}".format(
+ class_param, param, state.current_class
+ ),
+ state,
+ )
repl_text = method_param
if class_param != state.current_class:
repl_text = "{}.{}".format(class_param, method_param)
- tag_text = ':ref:`{}<class_{}{}_{}>`'.format(repl_text, class_param, ref_type, method_param)
+ tag_text = ":ref:`{}<class_{}{}_{}>`".format(repl_text, class_param, ref_type, method_param)
escape_post = True
- elif cmd.find('image=') == 0:
+ elif cmd.find("image=") == 0:
tag_text = "" # '![](' + cmd[6:] + ')'
- elif cmd.find('url=') == 0:
+ elif cmd.find("url=") == 0:
url_link = cmd[4:]
- tag_text = '`'
+ tag_text = "`"
tag_depth += 1
inside_url = True
url_has_name = False
- elif cmd == '/url':
- tag_text = ('' if url_has_name else url_link) + " <" + url_link + ">`_"
+ elif cmd == "/url":
+ tag_text = ("" if url_has_name else url_link) + " <" + url_link + ">`_"
tag_depth -= 1
escape_post = True
inside_url = False
url_has_name = False
- elif cmd == 'center':
+ elif cmd == "center":
tag_depth += 1
- tag_text = ''
- elif cmd == '/center':
+ tag_text = ""
+ elif cmd == "/center":
tag_depth -= 1
- tag_text = ''
- elif cmd == 'codeblock':
+ tag_text = ""
+ elif cmd == "codeblock":
tag_depth += 1
- tag_text = '\n::\n'
+ tag_text = "\n::\n"
inside_code = True
- elif cmd == 'br':
+ elif cmd == "br":
# Make a new paragraph instead of a linebreak, rst is not so linebreak friendly
- tag_text = '\n\n'
+ tag_text = "\n\n"
# Strip potential leading spaces
- while post_text[0] == ' ':
+ while post_text[0] == " ":
post_text = post_text[1:]
- elif cmd == 'i' or cmd == '/i':
+ elif cmd == "i" or cmd == "/i":
if cmd == "/i":
tag_depth -= 1
else:
tag_depth += 1
- tag_text = '*'
- elif cmd == 'b' or cmd == '/b':
+ tag_text = "*"
+ elif cmd == "b" or cmd == "/b":
if cmd == "/b":
tag_depth -= 1
else:
tag_depth += 1
- tag_text = '**'
- elif cmd == 'u' or cmd == '/u':
+ tag_text = "**"
+ elif cmd == "u" or cmd == "/u":
if cmd == "/u":
tag_depth -= 1
else:
tag_depth += 1
- tag_text = ''
- elif cmd == 'code':
- tag_text = '``'
+ tag_text = ""
+ elif cmd == "code":
+ tag_text = "``"
tag_depth += 1
inside_code = True
- elif cmd.startswith('enum '):
+ elif cmd.startswith("enum "):
tag_text = make_enum(cmd[5:], state)
escape_post = True
else:
@@ -883,24 +910,24 @@ def rstize_text(text, state): # type: (str, State) -> str
# Properly escape things like `[Node]s`
if escape_post and post_text and (post_text[0].isalnum() or post_text[0] == "("): # not punctuation, escape
- post_text = '\ ' + post_text
+ post_text = "\ " + post_text
- next_brac_pos = post_text.find('[', 0)
+ next_brac_pos = post_text.find("[", 0)
iter_pos = 0
while not inside_code:
- iter_pos = post_text.find('*', iter_pos, next_brac_pos)
+ iter_pos = post_text.find("*", iter_pos, next_brac_pos)
if iter_pos == -1:
break
- post_text = post_text[:iter_pos] + "\*" + post_text[iter_pos + 1:]
+ post_text = post_text[:iter_pos] + "\*" + post_text[iter_pos + 1 :]
iter_pos += 2
iter_pos = 0
while not inside_code:
- iter_pos = post_text.find('_', iter_pos, next_brac_pos)
+ iter_pos = post_text.find("_", iter_pos, next_brac_pos)
if iter_pos == -1:
break
if not post_text[iter_pos + 1].isalnum(): # don't escape within a snake_case word
- post_text = post_text[:iter_pos] + "\_" + post_text[iter_pos + 1:]
+ post_text = post_text[:iter_pos] + "\_" + post_text[iter_pos + 1 :]
iter_pos += 2
else:
iter_pos += 1
@@ -922,7 +949,7 @@ def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterabl
column_sizes = [0] * len(data[0])
for row in data:
for i, text in enumerate(row):
- text_length = len(text or '')
+ text_length = len(text or "")
if text_length > column_sizes[i]:
column_sizes[i] = text_length
@@ -939,16 +966,16 @@ def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterabl
for i, text in enumerate(row):
if column_sizes[i] == 0 and remove_empty_columns:
continue
- row_text += " " + (text or '').ljust(column_sizes[i]) + " |"
+ row_text += " " + (text or "").ljust(column_sizes[i]) + " |"
row_text += "\n"
f.write(row_text)
f.write(sep)
- f.write('\n')
+ f.write("\n")
def make_type(t, state): # type: (str, State) -> str
if t in state.classes:
- return ':ref:`{0}<class_{0}>`'.format(t)
+ return ":ref:`{0}<class_{0}>`".format(t)
print_error("Unresolved type '{}', file: {}".format(t, state.current_class), state)
return t
@@ -957,7 +984,7 @@ def make_enum(t, state): # type: (str, State) -> str
p = t.find(".")
if p >= 0:
c = t[0:p]
- e = t[p + 1:]
+ e = t[p + 1 :]
# Variant enums live in GlobalScope but still use periods.
if c == "Variant":
c = "@GlobalScope"
@@ -969,7 +996,7 @@ def make_enum(t, state): # type: (str, State) -> str
c = "@GlobalScope"
if not c in state.classes and c.startswith("_"):
- c = c[1:] # Remove the underscore prefix
+ c = c[1:] # Remove the underscore prefix
if c in state.classes and e in state.classes[c].enums:
return ":ref:`{0}<enum_{1}_{0}>`".format(e, c)
@@ -981,7 +1008,9 @@ def make_enum(t, state): # type: (str, State) -> str
return t
-def make_method_signature(class_def, method_def, make_ref, state): # type: (ClassDef, Union[MethodDef, SignalDef], bool, State) -> Tuple[str, str]
+def make_method_signature(
+ class_def, method_def, make_ref, state
+): # type: (ClassDef, Union[MethodDef, SignalDef], bool, State) -> Tuple[str, str]
ret_type = " "
ref_type = "signal"
@@ -996,34 +1025,34 @@ def make_method_signature(class_def, method_def, make_ref, state): # type: (Cla
else:
out += "**{}** ".format(method_def.name)
- out += '**(**'
+ out += "**(**"
for i, arg in enumerate(method_def.parameters):
if i > 0:
- out += ', '
+ out += ", "
else:
- out += ' '
+ out += " "
out += "{} {}".format(arg.type_name.to_rst(state), arg.name)
if arg.default_value is not None:
- out += '=' + arg.default_value
+ out += "=" + arg.default_value
- if isinstance(method_def, MethodDef) and method_def.qualifiers is not None and 'vararg' in method_def.qualifiers:
+ if isinstance(method_def, MethodDef) and method_def.qualifiers is not None and "vararg" in method_def.qualifiers:
if len(method_def.parameters) > 0:
- out += ', ...'
+ out += ", ..."
else:
- out += ' ...'
+ out += " ..."
- out += ' **)**'
+ out += " **)**"
if isinstance(method_def, MethodDef) and method_def.qualifiers is not None:
- out += ' ' + method_def.qualifiers
+ out += " " + method_def.qualifiers
return ret_type, out
def make_heading(title, underline): # type: (str, str) -> str
- return title + '\n' + (underline * len(title)) + "\n\n"
+ return title + "\n" + (underline * len(title)) + "\n\n"
def make_url(link): # type: (str) -> str
@@ -1047,5 +1076,5 @@ def make_url(link): # type: (str) -> str
return "`" + link + " <" + link + ">`_"
-if __name__ == '__main__':
+if __name__ == "__main__":
main()