mirror of
https://github.com/godotengine/godot.git
synced 2024-11-13 23:52:41 +00:00
Merge pull request #69444 from YuriSizov/classref-makerst-does-heavylifting
Improve layout of generated class references RST pages
This commit is contained in:
commit
d34fab98d1
@ -240,7 +240,7 @@ class State:
|
||||
enum_def = class_def.enums[enum]
|
||||
|
||||
else:
|
||||
enum_def = EnumDef(enum, is_bitfield)
|
||||
enum_def = EnumDef(enum, TypeName("int", enum), is_bitfield)
|
||||
class_def.enums[enum] = enum_def
|
||||
|
||||
enum_def.values[constant_name] = constant_def
|
||||
@ -458,9 +458,10 @@ class ConstantDef(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)
|
||||
|
||||
self.type_name = type_name
|
||||
self.values: OrderedDict[str, ConstantDef] = OrderedDict()
|
||||
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(make_heading(class_name, "=", False))
|
||||
|
||||
# Inheritance tree
|
||||
### INHERITANCE TREE ###
|
||||
|
||||
# Ascendants
|
||||
if class_def.inherits:
|
||||
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("\n\n")
|
||||
|
||||
### INTRODUCTION ###
|
||||
|
||||
has_description = False
|
||||
|
||||
# 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() != "":
|
||||
has_description = True
|
||||
|
||||
f.write(".. rst-class:: classref-introduction-group\n\n")
|
||||
f.write(make_heading("Description", "-"))
|
||||
|
||||
f.write(f"{format_text_block(class_def.description.strip(), class_def, state)}\n\n")
|
||||
|
||||
if not has_description:
|
||||
@ -814,14 +820,22 @@ def make_rst_class(class_def: ClassDef, state: State, dry_run: bool, output_dir:
|
||||
|
||||
# Online tutorials
|
||||
if len(class_def.tutorials) > 0:
|
||||
f.write(".. rst-class:: classref-introduction-group\n\n")
|
||||
f.write(make_heading("Tutorials", "-"))
|
||||
|
||||
for url, title in class_def.tutorials:
|
||||
f.write(f"- {make_link(url, title)}\n\n")
|
||||
|
||||
# Properties overview
|
||||
### REFERENCE TABLES ###
|
||||
|
||||
# Reused container for reference tables.
|
||||
ml: List[Tuple[Optional[str], ...]] = []
|
||||
|
||||
# Properties reference table
|
||||
if len(class_def.properties) > 0:
|
||||
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||
f.write(make_heading("Properties", "-"))
|
||||
|
||||
ml = []
|
||||
for property_def in class_def.properties.values():
|
||||
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:
|
||||
ref = f":ref:`{property_def.name}<class_{class_name}_property_{property_def.name}>`"
|
||||
ml.append((type_rst, ref, default))
|
||||
|
||||
format_table(f, ml, True)
|
||||
|
||||
# Constructors, Methods, Operators overview
|
||||
# Constructors, Methods, Operators reference tables
|
||||
if len(class_def.constructors) > 0:
|
||||
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||
f.write(make_heading("Constructors", "-"))
|
||||
|
||||
ml = []
|
||||
for method_list in class_def.constructors.values():
|
||||
for m in method_list:
|
||||
ml.append(make_method_signature(class_def, m, "constructor", state))
|
||||
|
||||
format_table(f, ml)
|
||||
|
||||
if len(class_def.methods) > 0:
|
||||
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||
f.write(make_heading("Methods", "-"))
|
||||
|
||||
ml = []
|
||||
for method_list in class_def.methods.values():
|
||||
for m in method_list:
|
||||
ml.append(make_method_signature(class_def, m, "method", state))
|
||||
|
||||
format_table(f, ml)
|
||||
|
||||
if len(class_def.operators) > 0:
|
||||
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||
f.write(make_heading("Operators", "-"))
|
||||
|
||||
ml = []
|
||||
for method_list in class_def.operators.values():
|
||||
for m in method_list:
|
||||
ml.append(make_method_signature(class_def, m, "operator", state))
|
||||
|
||||
format_table(f, ml)
|
||||
|
||||
# Theme properties
|
||||
# Theme properties reference table
|
||||
if len(class_def.theme_items) > 0:
|
||||
f.write(".. rst-class:: classref-reftable-group\n\n")
|
||||
f.write(make_heading("Theme Properties", "-"))
|
||||
pl: List[Tuple[Optional[str], ...]] = []
|
||||
|
||||
ml = []
|
||||
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}>`"
|
||||
pl.append((theme_item_def.type_name.to_rst(state), ref, theme_item_def.default_value))
|
||||
format_table(f, pl, True)
|
||||
ml.append((theme_item_def.type_name.to_rst(state), ref, theme_item_def.default_value))
|
||||
|
||||
# Signals
|
||||
format_table(f, ml, True)
|
||||
|
||||
### DETAILED DESCRIPTIONS ###
|
||||
|
||||
# Signal descriptions
|
||||
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", "-"))
|
||||
|
||||
index = 0
|
||||
|
||||
for signal in class_def.signals.values():
|
||||
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(".. rst-class:: classref-signal\n\n")
|
||||
|
||||
_, 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() != "":
|
||||
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
|
||||
|
||||
# Enums
|
||||
# Enumeration descriptions
|
||||
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", "-"))
|
||||
|
||||
index = 0
|
||||
|
||||
for e in class_def.enums.values():
|
||||
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")
|
||||
# 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.
|
||||
# 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")
|
||||
f.write(".. rst-class:: classref-enumeration\n\n")
|
||||
|
||||
if e.is_bitfield:
|
||||
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")
|
||||
|
||||
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 contains a bullet point list, each entry needs additional indentation
|
||||
f.write(f" --- {indent_bullets(format_text_block(value.text.strip(), value, state))}")
|
||||
f.write(f"{format_text_block(value.text.strip(), value, state)}")
|
||||
|
||||
f.write("\n\n")
|
||||
|
||||
index += 1
|
||||
|
||||
# Constants
|
||||
# Constant descriptions
|
||||
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", "-"))
|
||||
# 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():
|
||||
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() != "":
|
||||
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")
|
||||
|
||||
# Annotations
|
||||
# Annotation descriptions
|
||||
if len(class_def.annotations) > 0:
|
||||
f.write(make_separator(True))
|
||||
f.write(make_heading("Annotations", "-"))
|
||||
|
||||
index = 0
|
||||
|
||||
for method_list in class_def.annotations.values(): # type: ignore
|
||||
for i, m in enumerate(method_list):
|
||||
if index != 0:
|
||||
f.write("----\n\n")
|
||||
f.write(make_separator())
|
||||
|
||||
# Create annotation signature and anchor point.
|
||||
|
||||
if i == 0:
|
||||
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)
|
||||
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() != "":
|
||||
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
|
||||
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", "-"))
|
||||
|
||||
index = 0
|
||||
|
||||
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
|
||||
|
||||
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"- {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], ...]] = []
|
||||
# Not using translate() for now as it breaks table formatting.
|
||||
property_default = ""
|
||||
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*", 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}()"))
|
||||
property_default = f" = {property_def.default_value}"
|
||||
f.write(f"{property_def.type_name.to_rst(state)} **{property_def.name}**{property_default}\n\n")
|
||||
|
||||
if len(info) > 0:
|
||||
format_table(f, info)
|
||||
# Create property setter and getter records.
|
||||
|
||||
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() != "":
|
||||
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
|
||||
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", "-"))
|
||||
|
||||
index = 0
|
||||
|
||||
for method_list in class_def.constructors.values():
|
||||
for i, m in enumerate(method_list):
|
||||
if index != 0:
|
||||
f.write("----\n\n")
|
||||
f.write(make_separator())
|
||||
|
||||
# Create constructor signature and anchor point.
|
||||
|
||||
if i == 0:
|
||||
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)
|
||||
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() != "":
|
||||
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
|
||||
|
||||
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", "-"))
|
||||
|
||||
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(make_separator())
|
||||
|
||||
# Create method signature and anchor point.
|
||||
|
||||
if i == 0:
|
||||
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)
|
||||
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() != "":
|
||||
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
|
||||
|
||||
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", "-"))
|
||||
|
||||
index = 0
|
||||
|
||||
for method_list in class_def.operators.values():
|
||||
for i, m in enumerate(method_list):
|
||||
if index != 0:
|
||||
f.write("----\n\n")
|
||||
out = f".. _class_{class_name}_operator_{sanitize_operator_name(m.name, state)}"
|
||||
f.write(make_separator())
|
||||
|
||||
# Create operator signature and anchor point.
|
||||
|
||||
operator_anchor = f".. _class_{class_name}_operator_{sanitize_operator_name(m.name, state)}"
|
||||
for parameter in m.parameters:
|
||||
out += f"_{parameter.type_name.type_name}"
|
||||
out += f":\n\n"
|
||||
f.write(out)
|
||||
operator_anchor += f"_{parameter.type_name.type_name}"
|
||||
operator_anchor += f":\n\n"
|
||||
f.write(operator_anchor)
|
||||
|
||||
f.write(".. rst-class:: classref-operator\n\n")
|
||||
|
||||
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() != "":
|
||||
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
|
||||
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", "-"))
|
||||
|
||||
index = 0
|
||||
|
||||
for theme_item_def in class_def.theme_items.values():
|
||||
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"- {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:
|
||||
# Not using translate() for now as it breaks table formatting.
|
||||
info.append(("*Default*", theme_item_def.default_value))
|
||||
theme_item_default = f" = {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:
|
||||
format_table(f, info)
|
||||
# Add theme property description, or a call to action if it's missing.
|
||||
|
||||
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")
|
||||
@ -1216,6 +1333,39 @@ def make_method_signature(
|
||||
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:
|
||||
if l10n:
|
||||
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:
|
||||
match = GODOT_DOCS_PATTERN.search(url)
|
||||
if match:
|
||||
@ -1409,8 +1567,8 @@ def format_text_block(
|
||||
# Tag is a reference to a class.
|
||||
if tag_text in state.classes:
|
||||
if tag_text == state.current_class:
|
||||
# Don't create a link to the same class, format it as inline code.
|
||||
tag_text = f"``{tag_text}``"
|
||||
# Don't create a link to the same class, format it as strong emphasis.
|
||||
tag_text = f"**{tag_text}**"
|
||||
else:
|
||||
tag_text = make_type(tag_text, state)
|
||||
escape_pre = True
|
||||
@ -1872,6 +2030,11 @@ def format_table(f: TextIO, data: List[Tuple[Optional[str], ...]], remove_empty_
|
||||
if len(data) == 0:
|
||||
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])
|
||||
for row in data:
|
||||
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]:
|
||||
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 = ""
|
||||
for size in column_sizes:
|
||||
if size == 0 and remove_empty_columns:
|
||||
continue
|
||||
sep += "+" + "-" * (size + 2)
|
||||
sep += "+" + "-" * (size + 2) # Content of each cell is padded by 1 on each side.
|
||||
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:
|
||||
row_text = "|"
|
||||
for i, text in enumerate(row):
|
||||
@ -1894,8 +2064,10 @@ def format_table(f: TextIO, data: List[Tuple[Optional[str], ...]], remove_empty_
|
||||
continue
|
||||
row_text += f' {(text or "").ljust(column_sizes[i])} |'
|
||||
row_text += "\n"
|
||||
f.write(row_text)
|
||||
f.write(sep)
|
||||
|
||||
f.write(f" {row_text}")
|
||||
f.write(f" {sep}")
|
||||
|
||||
f.write("\n")
|
||||
|
||||
|
||||
@ -1957,24 +2129,5 @@ def sanitize_operator_name(dirty_name: str, state: State) -> str:
|
||||
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__":
|
||||
main()
|
||||
|
Loading…
Reference in New Issue
Block a user