summaryrefslogtreecommitdiff
path: root/doc/tools/makerst.py
diff options
context:
space:
mode:
Diffstat (limited to 'doc/tools/makerst.py')
-rwxr-xr-xdoc/tools/makerst.py141
1 files changed, 82 insertions, 59 deletions
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index e81b4db13e..763c29ab4e 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -37,12 +37,13 @@ class TypeName:
class PropertyDef:
- def __init__(self, name, type_name, setter, getter, text): # type: (str, TypeName, Optional[str], Optional[str], Optional[str]) -> None
+ def __init__(self, name, type_name, setter, getter, text, default_value): # type: (str, TypeName, Optional[str], Optional[str], Optional[str], Optional[str]) -> None
self.name = name
self.type_name = type_name
self.setter = setter
self.getter = getter
self.text = text
+ self.default_value = default_value
class ParameterDef:
def __init__(self, name, type_name, default_value): # type: (str, TypeName, Optional[str]) -> None
@@ -81,9 +82,10 @@ class EnumDef:
class ThemeItemDef:
- def __init__(self, name, type_name): # type: (str, TypeName) -> None
+ def __init__(self, name, type_name, default_value): # type: (str, TypeName, Optional[str]) -> None
self.name = name
self.type_name = type_name
+ self.default_value = default_value
class ClassDef:
@@ -144,8 +146,9 @@ class State:
type_name = TypeName.from_element(property)
setter = property.get("setter") or None # Use or None so '' gets turned into None.
getter = property.get("getter") or None
+ default_value = property.get("default") or None
- property_def = PropertyDef(property_name, type_name, setter, getter, property.text)
+ property_def = PropertyDef(property_name, type_name, setter, getter, property.text, default_value)
class_def.properties[property_name] = property_def
methods = class_root.find("methods")
@@ -230,7 +233,8 @@ class State:
assert theme_item.tag == "theme_item"
theme_item_name = theme_item.attrib["name"]
- theme_item_def = ThemeItemDef(theme_item_name, TypeName.from_element(theme_item))
+ default_value = theme_item.get("default") or None
+ theme_item_def = ThemeItemDef(theme_item_name, TypeName.from_element(theme_item), default_value)
if theme_item_name not in class_def.theme_items:
class_def.theme_items[theme_item_name] = []
class_def.theme_items[theme_item_name].append(theme_item_def)
@@ -400,8 +404,9 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
for property_def in class_def.properties.values():
type_rst = property_def.type_name.to_rst(state)
ref = ":ref:`{0}<class_{1}_property_{0}>`".format(property_def.name, class_name)
- ml.append((type_rst, ref))
- format_table(f, ml)
+ default = property_def.default_value
+ ml.append((type_rst, ref, default))
+ format_table(f, ml, True)
# Methods overview
if len(class_def.methods) > 0:
@@ -415,11 +420,11 @@ 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', '-'))
- ml = []
+ pl = []
for theme_item_list in class_def.theme_items.values():
for theme_item in theme_item_list:
- ml.append((theme_item.type_name.to_rst(state), theme_item.name))
- format_table(f, ml)
+ pl.append((theme_item.type_name.to_rst(state), theme_item.name, theme_item.default_value))
+ format_table(f, pl, True)
# Signals
if len(class_def.signals) > 0:
@@ -478,24 +483,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
f.write(make_heading('Tutorials', '-'))
for t in class_def.tutorials:
link = t.strip()
- match = GODOT_DOCS_PATTERN.search(link)
- if match:
- groups = match.groups()
- if match.lastindex == 2:
- # Doc reference with fragment identifier: emit direct link to section with reference to page, for example:
- # `#calling-javascript-from-script in Exporting For Web`
- f.write("- `" + groups[1] + " <../" + groups[0] + ".html" + groups[1] + ">`_ in :doc:`../" + groups[0] + "`\n\n")
- # Commented out alternative: Instead just emit:
- # `Subsection in Exporting For Web`
- # f.write("- `Subsection <../" + groups[0] + ".html" + groups[1] + ">`_ in :doc:`../" + groups[0] + "`\n\n")
- elif match.lastindex == 1:
- # Doc reference, for example:
- # `Math`
- f.write("- :doc:`../" + groups[0] + "`\n\n")
- else:
- # External link, for example:
- # `http://enet.bespin.org/usergroup0.html`
- f.write("- `" + link + " <" + link + ">`_\n\n")
+ f.write("- " + make_url(link) + "\n\n")
# Property descriptions
if len(class_def.properties) > 0:
@@ -505,14 +493,16 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
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))
- setget = []
+ 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("_"):
- setget.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("_"):
- setget.append(('*Getter*', property_def.getter + '()'))
+ info.append(('*Getter*', property_def.getter + '()'))
- if len(setget) > 0:
- format_table(f, setget)
+ 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))
@@ -683,10 +673,16 @@ def rstize_text(text, state): # type: (str, State) -> str
# Handle [tags]
inside_code = False
+ inside_url = False
+ url_has_name = False
+ url_link = ""
pos = 0
tag_depth = 0
+ previous_pos = 0
while True:
pos = text.find('[', pos)
+ if inside_url and (pos > previous_pos):
+ url_has_name = True
if pos == -1:
break
@@ -795,12 +791,17 @@ def rstize_text(text, state): # type: (str, State) -> str
elif cmd.find('image=') == 0:
tag_text = "" # '![](' + cmd[6:] + ')'
elif cmd.find('url=') == 0:
- tag_text = ':ref:`' + cmd[4:] + '<' + cmd[4:] + ">`"
+ url_link = cmd[4:]
+ tag_text = '`'
tag_depth += 1
+ inside_url = True
+ url_has_name = False
elif cmd == '/url':
- tag_text = ''
+ 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':
tag_depth += 1
tag_text = ''
@@ -871,6 +872,7 @@ def rstize_text(text, state): # type: (str, State) -> str
text = pre_text + tag_text + post_text
pos = len(pre_text) + len(tag_text)
+ previous_pos = pos
if tag_depth > 0:
print_error("Tag depth mismatch: too many/little open/close tags, file: {}".format(state.current_class), state)
@@ -878,33 +880,33 @@ def rstize_text(text, state): # type: (str, State) -> str
return text
-def format_table(f, pp): # type: (TextIO, Iterable[Tuple[str, ...]]) -> None
- longest_t = 0
- longest_s = 0
- for s in pp:
- sl = len(s[0])
- if sl > longest_s:
- longest_s = sl
- tl = len(s[1])
- if tl > longest_t:
- longest_t = tl
-
- sep = "+"
- for i in range(longest_s + 2):
- sep += "-"
- sep += "+"
- for i in range(longest_t + 2):
- sep += "-"
+def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterable[Tuple[str, ...]]) -> None
+ if len(data) == 0:
+ return
+
+ column_sizes = [0] * len(data[0])
+ for row in data:
+ for i, text in enumerate(row):
+ text_length = len(text or '')
+ if text_length > column_sizes[i]:
+ column_sizes[i] = text_length
+
+ sep = ""
+ for size in column_sizes:
+ if size == 0 and remove_empty_columns:
+ continue
+ sep += "+" + "-" * (size + 2)
sep += "+\n"
f.write(sep)
- for s in pp:
- rt = s[0]
- while len(rt) < longest_s:
- rt += " "
- st = s[1]
- while len(st) < longest_t:
- st += " "
- f.write("| " + rt + " | " + st + " |\n")
+
+ for row in data:
+ row_text = "|"
+ 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 += "\n"
+ f.write(row_text)
f.write(sep)
f.write('\n')
@@ -985,5 +987,26 @@ def make_heading(title, underline): # type: (str, str) -> str
return title + '\n' + (underline * len(title)) + "\n\n"
+def make_url(link): # type: (str) -> str
+ match = GODOT_DOCS_PATTERN.search(link)
+ if match:
+ groups = match.groups()
+ if match.lastindex == 2:
+ # Doc reference with fragment identifier: emit direct link to section with reference to page, for example:
+ # `#calling-javascript-from-script in Exporting For Web`
+ return "`" + groups[1] + " <../" + groups[0] + ".html" + groups[1] + ">`_ in :doc:`../" + groups[0] + "`"
+ # Commented out alternative: Instead just emit:
+ # `Subsection in Exporting For Web`
+ # return "`Subsection <../" + groups[0] + ".html" + groups[1] + ">`__ in :doc:`../" + groups[0] + "`"
+ elif match.lastindex == 1:
+ # Doc reference, for example:
+ # `Math`
+ return ":doc:`../" + groups[0] + "`"
+ else:
+ # External link, for example:
+ # `http://enet.bespin.org/usergroup0.html`
+ return "`" + link + " <" + link + ">`_"
+
+
if __name__ == '__main__':
main()