Improve layout of generated class references RST pages
- General improvements to the page layout - Improved formatting for all class (properties, signals, annotations, theme properties, methods, operators, constructors, enumerations, constants) - Added extra styling opportunities throughout the generated document - Made generated tables more flexible to their content - Changed highlighting for self-reference from code to strong
This commit is contained in:
parent
1db23e472b
commit
9e71cacd61
|
@ -240,7 +240,7 @@ class State:
|
||||||
enum_def = class_def.enums[enum]
|
enum_def = class_def.enums[enum]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
enum_def = EnumDef(enum, is_bitfield)
|
enum_def = EnumDef(enum, TypeName("int", enum), is_bitfield)
|
||||||
class_def.enums[enum] = enum_def
|
class_def.enums[enum] = enum_def
|
||||||
|
|
||||||
enum_def.values[constant_name] = constant_def
|
enum_def.values[constant_name] = constant_def
|
||||||
|
@ -458,9 +458,10 @@ class ConstantDef(DefinitionBase):
|
||||||
|
|
||||||
|
|
||||||
class EnumDef(DefinitionBase):
|
class EnumDef(DefinitionBase):
|
||||||
def __init__(self, name: str, bitfield: bool) -> None:
|
def __init__(self, name: str, type_name: TypeName, bitfield: bool) -> None:
|
||||||
super().__init__("enum", name)
|
super().__init__("enum", name)
|
||||||
|
|
||||||
|
self.type_name = type_name
|
||||||
self.values: OrderedDict[str, ConstantDef] = OrderedDict()
|
self.values: OrderedDict[str, ConstantDef] = OrderedDict()
|
||||||
self.is_bitfield = bitfield
|
self.is_bitfield = bitfield
|
||||||
|
|
||||||
|
@ -754,7 +755,8 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
f.write(f".. _class_{class_name}:\n\n")
|
f.write(f".. _class_{class_name}:\n\n")
|
||||||
f.write(make_heading(class_name, "=", False))
|
f.write(make_heading(class_name, "=", False))
|
||||||
|
|
||||||
# Inheritance tree
|
### INHERITANCE TREE ###
|
||||||
|
|
||||||
# Ascendants
|
# Ascendants
|
||||||
if class_def.inherits:
|
if class_def.inherits:
|
||||||
inherits = class_def.inherits.strip()
|
inherits = class_def.inherits.strip()
|
||||||
|
@ -788,6 +790,8 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
f.write(make_type(child, state))
|
f.write(make_type(child, state))
|
||||||
f.write("\n\n")
|
f.write("\n\n")
|
||||||
|
|
||||||
|
### INTRODUCTION ###
|
||||||
|
|
||||||
has_description = False
|
has_description = False
|
||||||
|
|
||||||
# Brief description
|
# Brief description
|
||||||
|
@ -800,7 +804,9 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
if class_def.description is not None and class_def.description.strip() != "":
|
if class_def.description is not None and class_def.description.strip() != "":
|
||||||
has_description = True
|
has_description = True
|
||||||
|
|
||||||
|
f.write(".. rst-class:: classref-introduction-group\n\n")
|
||||||
f.write(make_heading("Description", "-"))
|
f.write(make_heading("Description", "-"))
|
||||||
|
|
||||||
f.write(f"{format_text_block(class_def.description.strip(), class_def, state)}\n\n")
|
f.write(f"{format_text_block(class_def.description.strip(), class_def, state)}\n\n")
|
||||||
|
|
||||||
if not has_description:
|
if not has_description:
|
||||||
|
@ -814,14 +820,22 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
|
|
||||||
# Online tutorials
|
# Online tutorials
|
||||||
if len(class_def.tutorials) > 0:
|
if len(class_def.tutorials) > 0:
|
||||||
|
f.write(".. rst-class:: classref-introduction-group\n\n")
|
||||||
f.write(make_heading("Tutorials", "-"))
|
f.write(make_heading("Tutorials", "-"))
|
||||||
|
|
||||||
for url, title in class_def.tutorials:
|
for url, title in class_def.tutorials:
|
||||||
f.write(f"- {make_link(url, title)}\n\n")
|
f.write(f"- {make_link(url, title)}\n\n")
|
||||||
|
|
||||||
# Properties overview
|
### REFERENCE TABLES ###
|
||||||
|
|
||||||
|
# Reused container for reference tables.
|
||||||
ml: List[Tuple[Optional[str], ...]] = []
|
ml: List[Tuple[Optional[str], ...]] = []
|
||||||
|
|
||||||
|
# Properties reference table
|
||||||
if len(class_def.properties) > 0:
|
if len(class_def.properties) > 0:
|
||||||
|
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||||
f.write(make_heading("Properties", "-"))
|
f.write(make_heading("Properties", "-"))
|
||||||
|
|
||||||
ml = []
|
ml = []
|
||||||
for property_def in class_def.properties.values():
|
for property_def in class_def.properties.values():
|
||||||
type_rst = property_def.type_name.to_rst(state)
|
type_rst = property_def.type_name.to_rst(state)
|
||||||
|
@ -833,76 +847,108 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
else:
|
else:
|
||||||
ref = f":ref:`{property_def.name}<class_{class_name}_property_{property_def.name}>`"
|
ref = f":ref:`{property_def.name}<class_{class_name}_property_{property_def.name}>`"
|
||||||
ml.append((type_rst, ref, default))
|
ml.append((type_rst, ref, default))
|
||||||
|
|
||||||
format_table(f, ml, True)
|
format_table(f, ml, True)
|
||||||
|
|
||||||
# Constructors, Methods, Operators overview
|
# Constructors, Methods, Operators reference tables
|
||||||
if len(class_def.constructors) > 0:
|
if len(class_def.constructors) > 0:
|
||||||
|
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||||
f.write(make_heading("Constructors", "-"))
|
f.write(make_heading("Constructors", "-"))
|
||||||
|
|
||||||
ml = []
|
ml = []
|
||||||
for method_list in class_def.constructors.values():
|
for method_list in class_def.constructors.values():
|
||||||
for m in method_list:
|
for m in method_list:
|
||||||
ml.append(make_method_signature(class_def, m, "constructor", state))
|
ml.append(make_method_signature(class_def, m, "constructor", state))
|
||||||
|
|
||||||
format_table(f, ml)
|
format_table(f, ml)
|
||||||
|
|
||||||
if len(class_def.methods) > 0:
|
if len(class_def.methods) > 0:
|
||||||
|
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||||
f.write(make_heading("Methods", "-"))
|
f.write(make_heading("Methods", "-"))
|
||||||
|
|
||||||
ml = []
|
ml = []
|
||||||
for method_list in class_def.methods.values():
|
for method_list in class_def.methods.values():
|
||||||
for m in method_list:
|
for m in method_list:
|
||||||
ml.append(make_method_signature(class_def, m, "method", state))
|
ml.append(make_method_signature(class_def, m, "method", state))
|
||||||
|
|
||||||
format_table(f, ml)
|
format_table(f, ml)
|
||||||
|
|
||||||
if len(class_def.operators) > 0:
|
if len(class_def.operators) > 0:
|
||||||
|
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||||
f.write(make_heading("Operators", "-"))
|
f.write(make_heading("Operators", "-"))
|
||||||
|
|
||||||
ml = []
|
ml = []
|
||||||
for method_list in class_def.operators.values():
|
for method_list in class_def.operators.values():
|
||||||
for m in method_list:
|
for m in method_list:
|
||||||
ml.append(make_method_signature(class_def, m, "operator", state))
|
ml.append(make_method_signature(class_def, m, "operator", state))
|
||||||
|
|
||||||
format_table(f, ml)
|
format_table(f, ml)
|
||||||
|
|
||||||
# Theme properties
|
# Theme properties reference table
|
||||||
if len(class_def.theme_items) > 0:
|
if len(class_def.theme_items) > 0:
|
||||||
|
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||||
f.write(make_heading("Theme Properties", "-"))
|
f.write(make_heading("Theme Properties", "-"))
|
||||||
pl: List[Tuple[Optional[str], ...]] = []
|
|
||||||
|
ml = []
|
||||||
for theme_item_def in class_def.theme_items.values():
|
for theme_item_def in class_def.theme_items.values():
|
||||||
ref = f":ref:`{theme_item_def.name}<class_{class_name}_theme_{theme_item_def.data_name}_{theme_item_def.name}>`"
|
ref = f":ref:`{theme_item_def.name}<class_{class_name}_theme_{theme_item_def.data_name}_{theme_item_def.name}>`"
|
||||||
pl.append((theme_item_def.type_name.to_rst(state), ref, theme_item_def.default_value))
|
ml.append((theme_item_def.type_name.to_rst(state), ref, theme_item_def.default_value))
|
||||||
format_table(f, pl, True)
|
|
||||||
|
|
||||||
# Signals
|
format_table(f, ml, True)
|
||||||
|
|
||||||
|
### DETAILED DESCRIPTIONS ###
|
||||||
|
|
||||||
|
# Signal descriptions
|
||||||
if len(class_def.signals) > 0:
|
if len(class_def.signals) > 0:
|
||||||
|
f.write(make_separator(True))
|
||||||
|
f.write(".. rst-class:: classref-descriptions-group\n\n")
|
||||||
f.write(make_heading("Signals", "-"))
|
f.write(make_heading("Signals", "-"))
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for signal in class_def.signals.values():
|
for signal in class_def.signals.values():
|
||||||
if index != 0:
|
if index != 0:
|
||||||
f.write("----\n\n")
|
f.write(make_separator())
|
||||||
|
|
||||||
|
# Create signal signature and anchor point.
|
||||||
|
|
||||||
f.write(f".. _class_{class_name}_signal_{signal.name}:\n\n")
|
f.write(f".. _class_{class_name}_signal_{signal.name}:\n\n")
|
||||||
|
f.write(".. rst-class:: classref-signal\n\n")
|
||||||
|
|
||||||
_, signature = make_method_signature(class_def, signal, "", state)
|
_, signature = make_method_signature(class_def, signal, "", state)
|
||||||
f.write(f"- {signature}\n\n")
|
f.write(f"{signature}\n\n")
|
||||||
|
|
||||||
|
# Add signal description, or a call to action if it's missing.
|
||||||
|
|
||||||
if signal.description is not None and signal.description.strip() != "":
|
if signal.description is not None and signal.description.strip() != "":
|
||||||
f.write(f"{format_text_block(signal.description.strip(), signal, state)}\n\n")
|
f.write(f"{format_text_block(signal.description.strip(), signal, state)}\n\n")
|
||||||
|
else:
|
||||||
|
f.write(".. container:: contribute\n\n\t")
|
||||||
|
f.write(
|
||||||
|
translate(
|
||||||
|
"There is currently no description for this signal. Please help us by :ref:`contributing one <doc_updating_the_class_reference>`!"
|
||||||
|
)
|
||||||
|
+ "\n\n"
|
||||||
|
)
|
||||||
|
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
# Enums
|
# Enumeration descriptions
|
||||||
if len(class_def.enums) > 0:
|
if len(class_def.enums) > 0:
|
||||||
|
f.write(make_separator(True))
|
||||||
|
f.write(".. rst-class:: classref-descriptions-group\n\n")
|
||||||
f.write(make_heading("Enumerations", "-"))
|
f.write(make_heading("Enumerations", "-"))
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for e in class_def.enums.values():
|
for e in class_def.enums.values():
|
||||||
if index != 0:
|
if index != 0:
|
||||||
f.write("----\n\n")
|
f.write(make_separator())
|
||||||
|
|
||||||
|
# Create enumeration signature and anchor point.
|
||||||
|
|
||||||
f.write(f".. _enum_{class_name}_{e.name}:\n\n")
|
f.write(f".. _enum_{class_name}_{e.name}:\n\n")
|
||||||
# Sphinx seems to divide the bullet list into individual <ul> tags if we weave the labels into it.
|
f.write(".. rst-class:: classref-enumeration\n\n")
|
||||||
# As such I'll put them all above the list. Won't be perfect but better than making the list visually broken.
|
|
||||||
# As to why I'm not modifying the reference parser to directly link to the _enum label:
|
|
||||||
# If somebody gets annoyed enough to fix it, all existing references will magically improve.
|
|
||||||
for value in e.values.values():
|
|
||||||
f.write(f".. _class_{class_name}_constant_{value.name}:\n\n")
|
|
||||||
|
|
||||||
if e.is_bitfield:
|
if e.is_bitfield:
|
||||||
f.write(f"flags **{e.name}**:\n\n")
|
f.write(f"flags **{e.name}**:\n\n")
|
||||||
|
@ -910,45 +956,66 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
f.write(f"enum **{e.name}**:\n\n")
|
f.write(f"enum **{e.name}**:\n\n")
|
||||||
|
|
||||||
for value in e.values.values():
|
for value in e.values.values():
|
||||||
f.write(f"- **{value.name}** = **{value.value}**")
|
# Also create signature and anchor point for each enum constant.
|
||||||
|
|
||||||
|
f.write(f".. _class_{class_name}_constant_{value.name}:\n\n")
|
||||||
|
f.write(".. rst-class:: classref-enumeration-constant\n\n")
|
||||||
|
|
||||||
|
f.write(f"{e.type_name.to_rst(state)} **{value.name}** = ``{value.value}``\n\n")
|
||||||
|
|
||||||
|
# Add enum constant description.
|
||||||
|
|
||||||
if value.text is not None and value.text.strip() != "":
|
if value.text is not None and value.text.strip() != "":
|
||||||
# If value.text contains a bullet point list, each entry needs additional indentation
|
f.write(f"{format_text_block(value.text.strip(), value, state)}")
|
||||||
f.write(f" --- {indent_bullets(format_text_block(value.text.strip(), value, state))}")
|
|
||||||
|
|
||||||
f.write("\n\n")
|
f.write("\n\n")
|
||||||
|
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
# Constants
|
# Constant descriptions
|
||||||
if len(class_def.constants) > 0:
|
if len(class_def.constants) > 0:
|
||||||
|
f.write(make_separator(True))
|
||||||
|
f.write(".. rst-class:: classref-descriptions-group\n\n")
|
||||||
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():
|
|
||||||
f.write(f".. _class_{class_name}_constant_{constant.name}:\n\n")
|
|
||||||
|
|
||||||
for constant in class_def.constants.values():
|
for constant in class_def.constants.values():
|
||||||
f.write(f"- **{constant.name}** = **{constant.value}**")
|
# Create constant signature and anchor point.
|
||||||
|
|
||||||
|
f.write(f".. _class_{class_name}_constant_{constant.name}:\n\n")
|
||||||
|
f.write(".. rst-class:: classref-constant\n\n")
|
||||||
|
|
||||||
|
f.write(f"**{constant.name}** = ``{constant.value}``\n\n")
|
||||||
|
|
||||||
|
# Add enum constant description.
|
||||||
|
|
||||||
if constant.text is not None and constant.text.strip() != "":
|
if constant.text is not None and constant.text.strip() != "":
|
||||||
f.write(f" --- {format_text_block(constant.text.strip(), constant, state)}")
|
f.write(f"{format_text_block(constant.text.strip(), constant, state)}")
|
||||||
|
|
||||||
f.write("\n\n")
|
f.write("\n\n")
|
||||||
|
|
||||||
# Annotations
|
# Annotation descriptions
|
||||||
if len(class_def.annotations) > 0:
|
if len(class_def.annotations) > 0:
|
||||||
|
f.write(make_separator(True))
|
||||||
f.write(make_heading("Annotations", "-"))
|
f.write(make_heading("Annotations", "-"))
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for method_list in class_def.annotations.values(): # type: ignore
|
for method_list in class_def.annotations.values(): # type: ignore
|
||||||
for i, m in enumerate(method_list):
|
for i, m in enumerate(method_list):
|
||||||
if index != 0:
|
if index != 0:
|
||||||
f.write("----\n\n")
|
f.write(make_separator())
|
||||||
|
|
||||||
|
# Create annotation signature and anchor point.
|
||||||
|
|
||||||
if i == 0:
|
if i == 0:
|
||||||
f.write(f".. _class_{class_name}_annotation_{m.name}:\n\n")
|
f.write(f".. _class_{class_name}_annotation_{m.name}:\n\n")
|
||||||
|
|
||||||
|
f.write(".. rst-class:: classref-annotation\n\n")
|
||||||
|
|
||||||
_, signature = make_method_signature(class_def, m, "", state)
|
_, signature = make_method_signature(class_def, m, "", state)
|
||||||
f.write(f"- {signature}\n\n")
|
f.write(f"{signature}\n\n")
|
||||||
|
|
||||||
|
# Add annotation description, or a call to action if it's missing.
|
||||||
|
|
||||||
if m.description is not None and m.description.strip() != "":
|
if m.description is not None and m.description.strip() != "":
|
||||||
f.write(f"{format_text_block(m.description.strip(), m, state)}\n\n")
|
f.write(f"{format_text_block(m.description.strip(), m, state)}\n\n")
|
||||||
|
@ -965,7 +1032,10 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
|
|
||||||
# Property descriptions
|
# Property descriptions
|
||||||
if any(not p.overrides for p in class_def.properties.values()) > 0:
|
if any(not p.overrides for p in class_def.properties.values()) > 0:
|
||||||
|
f.write(make_separator(True))
|
||||||
|
f.write(".. rst-class:: classref-descriptions-group\n\n")
|
||||||
f.write(make_heading("Property Descriptions", "-"))
|
f.write(make_heading("Property Descriptions", "-"))
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for property_def in class_def.properties.values():
|
for property_def in class_def.properties.values():
|
||||||
|
@ -973,22 +1043,36 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if index != 0:
|
if index != 0:
|
||||||
f.write("----\n\n")
|
f.write(make_separator())
|
||||||
|
|
||||||
|
# Create property signature and anchor point.
|
||||||
|
|
||||||
f.write(f".. _class_{class_name}_property_{property_def.name}:\n\n")
|
f.write(f".. _class_{class_name}_property_{property_def.name}:\n\n")
|
||||||
f.write(f"- {property_def.type_name.to_rst(state)} **{property_def.name}**\n\n")
|
f.write(".. rst-class:: classref-property\n\n")
|
||||||
|
|
||||||
info: List[Tuple[Optional[str], ...]] = []
|
property_default = ""
|
||||||
# Not using translate() for now as it breaks table formatting.
|
|
||||||
if property_def.default_value is not None:
|
if property_def.default_value is not None:
|
||||||
info.append(("*Default*", property_def.default_value))
|
property_default = f" = {property_def.default_value}"
|
||||||
if property_def.setter is not None and not property_def.setter.startswith("_"):
|
f.write(f"{property_def.type_name.to_rst(state)} **{property_def.name}**{property_default}\n\n")
|
||||||
info.append(("*Setter*", f"{property_def.setter}(value)"))
|
|
||||||
if property_def.getter is not None and not property_def.getter.startswith("_"):
|
|
||||||
info.append(("*Getter*", f"{property_def.getter}()"))
|
|
||||||
|
|
||||||
if len(info) > 0:
|
# Create property setter and getter records.
|
||||||
format_table(f, info)
|
|
||||||
|
property_setget = ""
|
||||||
|
|
||||||
|
if property_def.setter is not None and not property_def.setter.startswith("_"):
|
||||||
|
property_setter = make_setter_signature(class_def, property_def, state)
|
||||||
|
property_setget += f"- {property_setter}\n"
|
||||||
|
|
||||||
|
if property_def.getter is not None and not property_def.getter.startswith("_"):
|
||||||
|
property_getter = make_getter_signature(class_def, property_def, state)
|
||||||
|
property_setget += f"- {property_getter}\n"
|
||||||
|
|
||||||
|
if property_setget != "":
|
||||||
|
f.write(".. rst-class:: classref-property-setget\n\n")
|
||||||
|
f.write(property_setget)
|
||||||
|
f.write("\n")
|
||||||
|
|
||||||
|
# Add property description, or a call to action if it's missing.
|
||||||
|
|
||||||
if property_def.text is not None and property_def.text.strip() != "":
|
if property_def.text is not None and property_def.text.strip() != "":
|
||||||
f.write(f"{format_text_block(property_def.text.strip(), property_def, state)}\n\n")
|
f.write(f"{format_text_block(property_def.text.strip(), property_def, state)}\n\n")
|
||||||
|
@ -1005,19 +1089,28 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
|
|
||||||
# Constructor, Method, Operator descriptions
|
# Constructor, Method, Operator descriptions
|
||||||
if len(class_def.constructors) > 0:
|
if len(class_def.constructors) > 0:
|
||||||
|
f.write(make_separator(True))
|
||||||
|
f.write(".. rst-class:: classref-descriptions-group\n\n")
|
||||||
f.write(make_heading("Constructor Descriptions", "-"))
|
f.write(make_heading("Constructor Descriptions", "-"))
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for method_list in class_def.constructors.values():
|
for method_list in class_def.constructors.values():
|
||||||
for i, m in enumerate(method_list):
|
for i, m in enumerate(method_list):
|
||||||
if index != 0:
|
if index != 0:
|
||||||
f.write("----\n\n")
|
f.write(make_separator())
|
||||||
|
|
||||||
|
# Create constructor signature and anchor point.
|
||||||
|
|
||||||
if i == 0:
|
if i == 0:
|
||||||
f.write(f".. _class_{class_name}_constructor_{m.name}:\n\n")
|
f.write(f".. _class_{class_name}_constructor_{m.name}:\n\n")
|
||||||
|
|
||||||
|
f.write(".. rst-class:: classref-constructor\n\n")
|
||||||
|
|
||||||
ret_type, signature = make_method_signature(class_def, m, "", state)
|
ret_type, signature = make_method_signature(class_def, m, "", state)
|
||||||
f.write(f"- {ret_type} {signature}\n\n")
|
f.write(f"{ret_type} {signature}\n\n")
|
||||||
|
|
||||||
|
# Add constructor description, or a call to action if it's missing.
|
||||||
|
|
||||||
if m.description is not None and m.description.strip() != "":
|
if m.description is not None and m.description.strip() != "":
|
||||||
f.write(f"{format_text_block(m.description.strip(), m, state)}\n\n")
|
f.write(f"{format_text_block(m.description.strip(), m, state)}\n\n")
|
||||||
|
@ -1033,19 +1126,28 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
if len(class_def.methods) > 0:
|
if len(class_def.methods) > 0:
|
||||||
|
f.write(make_separator(True))
|
||||||
|
f.write(".. rst-class:: classref-descriptions-group\n\n")
|
||||||
f.write(make_heading("Method Descriptions", "-"))
|
f.write(make_heading("Method Descriptions", "-"))
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for method_list in class_def.methods.values():
|
for method_list in class_def.methods.values():
|
||||||
for i, m in enumerate(method_list):
|
for i, m in enumerate(method_list):
|
||||||
if index != 0:
|
if index != 0:
|
||||||
f.write("----\n\n")
|
f.write(make_separator())
|
||||||
|
|
||||||
|
# Create method signature and anchor point.
|
||||||
|
|
||||||
if i == 0:
|
if i == 0:
|
||||||
f.write(f".. _class_{class_name}_method_{m.name}:\n\n")
|
f.write(f".. _class_{class_name}_method_{m.name}:\n\n")
|
||||||
|
|
||||||
|
f.write(".. rst-class:: classref-method\n\n")
|
||||||
|
|
||||||
ret_type, signature = make_method_signature(class_def, m, "", state)
|
ret_type, signature = make_method_signature(class_def, m, "", state)
|
||||||
f.write(f"- {ret_type} {signature}\n\n")
|
f.write(f"{ret_type} {signature}\n\n")
|
||||||
|
|
||||||
|
# Add method description, or a call to action if it's missing.
|
||||||
|
|
||||||
if m.description is not None and m.description.strip() != "":
|
if m.description is not None and m.description.strip() != "":
|
||||||
f.write(f"{format_text_block(m.description.strip(), m, state)}\n\n")
|
f.write(f"{format_text_block(m.description.strip(), m, state)}\n\n")
|
||||||
|
@ -1061,20 +1163,31 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
if len(class_def.operators) > 0:
|
if len(class_def.operators) > 0:
|
||||||
|
f.write(make_separator(True))
|
||||||
|
f.write(".. rst-class:: classref-descriptions-group\n\n")
|
||||||
f.write(make_heading("Operator Descriptions", "-"))
|
f.write(make_heading("Operator Descriptions", "-"))
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for method_list in class_def.operators.values():
|
for method_list in class_def.operators.values():
|
||||||
for i, m in enumerate(method_list):
|
for i, m in enumerate(method_list):
|
||||||
if index != 0:
|
if index != 0:
|
||||||
f.write("----\n\n")
|
f.write(make_separator())
|
||||||
out = f".. _class_{class_name}_operator_{sanitize_operator_name(m.name, state)}"
|
|
||||||
|
# Create operator signature and anchor point.
|
||||||
|
|
||||||
|
operator_anchor = f".. _class_{class_name}_operator_{sanitize_operator_name(m.name, state)}"
|
||||||
for parameter in m.parameters:
|
for parameter in m.parameters:
|
||||||
out += f"_{parameter.type_name.type_name}"
|
operator_anchor += f"_{parameter.type_name.type_name}"
|
||||||
out += f":\n\n"
|
operator_anchor += f":\n\n"
|
||||||
f.write(out)
|
f.write(operator_anchor)
|
||||||
|
|
||||||
|
f.write(".. rst-class:: classref-operator\n\n")
|
||||||
|
|
||||||
ret_type, signature = make_method_signature(class_def, m, "", state)
|
ret_type, signature = make_method_signature(class_def, m, "", state)
|
||||||
f.write(f"- {ret_type} {signature}\n\n")
|
f.write(f"{ret_type} {signature}\n\n")
|
||||||
|
|
||||||
|
# Add operator description, or a call to action if it's missing.
|
||||||
|
|
||||||
if m.description is not None and m.description.strip() != "":
|
if m.description is not None and m.description.strip() != "":
|
||||||
f.write(f"{format_text_block(m.description.strip(), m, state)}\n\n")
|
f.write(f"{format_text_block(m.description.strip(), m, state)}\n\n")
|
||||||
|
@ -1091,23 +1204,27 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||||
|
|
||||||
# Theme property descriptions
|
# Theme property descriptions
|
||||||
if len(class_def.theme_items) > 0:
|
if len(class_def.theme_items) > 0:
|
||||||
|
f.write(make_separator(True))
|
||||||
|
f.write(".. rst-class:: classref-descriptions-group\n\n")
|
||||||
f.write(make_heading("Theme Property Descriptions", "-"))
|
f.write(make_heading("Theme Property Descriptions", "-"))
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
for theme_item_def in class_def.theme_items.values():
|
for theme_item_def in class_def.theme_items.values():
|
||||||
if index != 0:
|
if index != 0:
|
||||||
f.write("----\n\n")
|
f.write(make_separator())
|
||||||
|
|
||||||
|
# Create theme property signature and anchor point.
|
||||||
|
|
||||||
f.write(f".. _class_{class_name}_theme_{theme_item_def.data_name}_{theme_item_def.name}:\n\n")
|
f.write(f".. _class_{class_name}_theme_{theme_item_def.data_name}_{theme_item_def.name}:\n\n")
|
||||||
f.write(f"- {theme_item_def.type_name.to_rst(state)} **{theme_item_def.name}**\n\n")
|
f.write(".. rst-class:: classref-themeproperty\n\n")
|
||||||
|
|
||||||
info = []
|
theme_item_default = ""
|
||||||
if theme_item_def.default_value is not None:
|
if theme_item_def.default_value is not None:
|
||||||
# Not using translate() for now as it breaks table formatting.
|
theme_item_default = f" = {theme_item_def.default_value}"
|
||||||
info.append(("*Default*", theme_item_def.default_value))
|
f.write(f"{theme_item_def.type_name.to_rst(state)} **{theme_item_def.name}**{theme_item_default}\n\n")
|
||||||
|
|
||||||
if len(info) > 0:
|
# Add theme property description, or a call to action if it's missing.
|
||||||
format_table(f, info)
|
|
||||||
|
|
||||||
if theme_item_def.text is not None and theme_item_def.text.strip() != "":
|
if theme_item_def.text is not None and theme_item_def.text.strip() != "":
|
||||||
f.write(f"{format_text_block(theme_item_def.text.strip(), theme_item_def, state)}\n\n")
|
f.write(f"{format_text_block(theme_item_def.text.strip(), theme_item_def, state)}\n\n")
|
||||||
|
@ -1216,6 +1333,39 @@ def make_method_signature(
|
||||||
return ret_type, out
|
return ret_type, out
|
||||||
|
|
||||||
|
|
||||||
|
def make_setter_signature(class_def: ClassDef, property_def: PropertyDef, state: State) -> str:
|
||||||
|
if property_def.setter is None:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# If setter is a method available as a method definition, we use that.
|
||||||
|
if property_def.setter in class_def.methods:
|
||||||
|
setter = class_def.methods[property_def.setter][0]
|
||||||
|
# Otherwise we fake it with the information we have available.
|
||||||
|
else:
|
||||||
|
setter_params: List[ParameterDef] = []
|
||||||
|
setter_params.append(ParameterDef("value", property_def.type_name, None))
|
||||||
|
setter = MethodDef(property_def.setter, TypeName("void"), setter_params, None, None)
|
||||||
|
|
||||||
|
ret_type, signature = make_method_signature(class_def, setter, "", state)
|
||||||
|
return f"{ret_type} {signature}"
|
||||||
|
|
||||||
|
|
||||||
|
def make_getter_signature(class_def: ClassDef, property_def: PropertyDef, state: State) -> str:
|
||||||
|
if property_def.getter is None:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# If getter is a method available as a method definition, we use that.
|
||||||
|
if property_def.getter in class_def.methods:
|
||||||
|
getter = class_def.methods[property_def.getter][0]
|
||||||
|
# Otherwise we fake it with the information we have available.
|
||||||
|
else:
|
||||||
|
getter_params: List[ParameterDef] = []
|
||||||
|
getter = MethodDef(property_def.getter, property_def.type_name, getter_params, None, None)
|
||||||
|
|
||||||
|
ret_type, signature = make_method_signature(class_def, getter, "", state)
|
||||||
|
return f"{ret_type} {signature}"
|
||||||
|
|
||||||
|
|
||||||
def make_heading(title: str, underline: str, l10n: bool = True) -> str:
|
def make_heading(title: str, underline: str, l10n: bool = True) -> str:
|
||||||
if l10n:
|
if l10n:
|
||||||
new_title = translate(title)
|
new_title = translate(title)
|
||||||
|
@ -1247,6 +1397,14 @@ def make_footer() -> str:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def make_separator(section_level: bool = False) -> str:
|
||||||
|
separator_class = "item"
|
||||||
|
if section_level:
|
||||||
|
separator_class = "section"
|
||||||
|
|
||||||
|
return f".. rst-class:: classref-{separator_class}-separator\n\n----\n\n"
|
||||||
|
|
||||||
|
|
||||||
def make_link(url: str, title: str) -> str:
|
def make_link(url: str, title: str) -> str:
|
||||||
match = GODOT_DOCS_PATTERN.search(url)
|
match = GODOT_DOCS_PATTERN.search(url)
|
||||||
if match:
|
if match:
|
||||||
|
@ -1409,8 +1567,8 @@ def format_text_block(
|
||||||
# Tag is a reference to a class.
|
# Tag is a reference to a class.
|
||||||
if tag_text in state.classes:
|
if tag_text in state.classes:
|
||||||
if tag_text == state.current_class:
|
if tag_text == state.current_class:
|
||||||
# Don't create a link to the same class, format it as inline code.
|
# Don't create a link to the same class, format it as strong emphasis.
|
||||||
tag_text = f"``{tag_text}``"
|
tag_text = f"**{tag_text}**"
|
||||||
else:
|
else:
|
||||||
tag_text = make_type(tag_text, state)
|
tag_text = make_type(tag_text, state)
|
||||||
escape_pre = True
|
escape_pre = True
|
||||||
|
@ -1872,6 +2030,11 @@ def format_table(f: TextIO, data: List[Tuple[Optional[str], ...]], remove_empty_
|
||||||
if len(data) == 0:
|
if len(data) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
f.write(".. table::\n")
|
||||||
|
f.write(" :widths: auto\n\n")
|
||||||
|
|
||||||
|
# Calculate the width of each column first, we will use this information
|
||||||
|
# to properly format RST-style tables.
|
||||||
column_sizes = [0] * len(data[0])
|
column_sizes = [0] * len(data[0])
|
||||||
for row in data:
|
for row in data:
|
||||||
for i, text in enumerate(row):
|
for i, text in enumerate(row):
|
||||||
|
@ -1879,14 +2042,21 @@ def format_table(f: TextIO, data: List[Tuple[Optional[str], ...]], remove_empty_
|
||||||
if text_length > column_sizes[i]:
|
if text_length > column_sizes[i]:
|
||||||
column_sizes[i] = text_length
|
column_sizes[i] = text_length
|
||||||
|
|
||||||
|
# Each table row is wrapped in two separators, consecutive rows share the same separator.
|
||||||
|
# All separators, or rather borders, have the same shape and content. We compose it once,
|
||||||
|
# then reuse it.
|
||||||
|
|
||||||
sep = ""
|
sep = ""
|
||||||
for size in column_sizes:
|
for size in column_sizes:
|
||||||
if size == 0 and remove_empty_columns:
|
if size == 0 and remove_empty_columns:
|
||||||
continue
|
continue
|
||||||
sep += "+" + "-" * (size + 2)
|
sep += "+" + "-" * (size + 2) # Content of each cell is padded by 1 on each side.
|
||||||
sep += "+\n"
|
sep += "+\n"
|
||||||
f.write(sep)
|
|
||||||
|
|
||||||
|
# Draw the first separator.
|
||||||
|
f.write(f" {sep}")
|
||||||
|
|
||||||
|
# Draw each row and close it with a separator.
|
||||||
for row in data:
|
for row in data:
|
||||||
row_text = "|"
|
row_text = "|"
|
||||||
for i, text in enumerate(row):
|
for i, text in enumerate(row):
|
||||||
|
@ -1894,8 +2064,10 @@ def format_table(f: TextIO, data: List[Tuple[Optional[str], ...]], remove_empty_
|
||||||
continue
|
continue
|
||||||
row_text += f' {(text or "").ljust(column_sizes[i])} |'
|
row_text += f' {(text or "").ljust(column_sizes[i])} |'
|
||||||
row_text += "\n"
|
row_text += "\n"
|
||||||
f.write(row_text)
|
|
||||||
f.write(sep)
|
f.write(f" {row_text}")
|
||||||
|
f.write(f" {sep}")
|
||||||
|
|
||||||
f.write("\n")
|
f.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
@ -1957,24 +2129,5 @@ def sanitize_operator_name(dirty_name: str, state: State) -> str:
|
||||||
return clear_name
|
return clear_name
|
||||||
|
|
||||||
|
|
||||||
def indent_bullets(text: str) -> str:
|
|
||||||
# Take the text and check each line for a bullet point represented by "-".
|
|
||||||
# Where found, indent the given line by a further "\t".
|
|
||||||
# Used to properly indent bullet points contained in the description for enum values.
|
|
||||||
# Ignore the first line - text will be prepended to it so bullet points wouldn't work anyway.
|
|
||||||
bullet_points = "-"
|
|
||||||
|
|
||||||
lines = text.splitlines(keepends=True)
|
|
||||||
for line_index, line in enumerate(lines[1:], start=1):
|
|
||||||
pos = 0
|
|
||||||
while pos < len(line) and line[pos] == "\t":
|
|
||||||
pos += 1
|
|
||||||
|
|
||||||
if pos < len(line) and line[pos] in bullet_points:
|
|
||||||
lines[line_index] = f"{line[:pos]}\t{line[pos:]}"
|
|
||||||
|
|
||||||
return "".join(lines)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue