Skip to content

Commit

Permalink
Merge pull request #167 from nyalldawson/nicer
Browse files Browse the repository at this point in the history
Fix appearance of class docstrings, constructor methods, ...
  • Loading branch information
3nids authored Aug 27, 2024
2 parents 2dca357 + fbffe0d commit 22be803
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 38 deletions.
5 changes: 5 additions & 0 deletions _static/css/custom.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.graphviz {
margin-top: 10px;
margin-bottom: 10px;
}

/* adds scrollbar to sidenav */
.wy-side-scroll {
width: auto;
Expand Down
30 changes: 29 additions & 1 deletion process_links.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,35 @@ def create_links(doc: str) -> str:


def process_docstring(app, what, name, obj, options, lines):
# print('d', what, name, obj, options)
if what == "class":
# hacky approach to detect nested classes, eg QgsCallout.QgsCalloutContext
is_nested = len(name.split(".")) > 3
if not is_nested:
# remove docstring part, we've already included it in the page header
# only leave the __init__ methods
init_idx = 0
class_name = name.split(".")[-1]
for init_idx, line in enumerate(lines):
if re.match(rf"^{class_name}\(", line):
break

lines[:] = lines[init_idx:]
lines_out = []
# loop through remaining lines, which are the constructors. Format
# these up so they look like proper __init__ method documentation
for i, line in enumerate(lines):
if re.match(rf"^{class_name}\(", line):
lines_out.append(
re.sub(rf"\b{class_name}\(", ".. py:method:: __init__(", line)
)
lines_out.append(" :noindex:")
lines_out.append("")
else:
lines_out.append(" " + line)

lines[:] = lines_out[:]
return

for i in range(len(lines)):

# fix seealso
Expand Down
4 changes: 2 additions & 2 deletions rst/qgis_pydoc_template.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ Class: $CLASS

$HEADER_CONTENT

$TABLE_OF_CONTENTS

.. autoclass:: qgis.$PACKAGE.$CLASS
:special-members: __init__
:members:
:undoc-members:
:exclude-members: $EXCLUDE_METHODS

$TABLE_OF_CONTENTS
94 changes: 59 additions & 35 deletions scripts/make_api_rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ def _recursive_substitute(self, **kws):
raise ValueError("Max recursion depth exceeded")

self.depth += 1
result = super().safe_substitute(**kws)
try:
result = super().safe_substitute(**kws)
except RecursionError:
return self.template

if "$" in result:
return self.__class__(result)._recursive_substitute(**kws)
Expand Down Expand Up @@ -178,35 +181,35 @@ def _recursive_substitute(self, **kws):
"""

class_header = """
inheritance_diagram = """
.. inheritance-diagram:: qgis.$PACKAGE.$CLASS
:parts: 1
"""

class_toc = """
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:enums:
:nosignatures:
:exclude-members: $EXCLUDE_METHODS
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:methods:
:nosignatures:
:exclude-members: $EXCLUDE_METHODS
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:static_methods:
:nosignatures:
:exclude-members: $EXCLUDE_METHODS
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:signals:
:nosignatures:
:exclude-members: $EXCLUDE_METHODS
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:attributes:
:exclude-members: $EXCLUDE_METHODS
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:enums:
:nosignatures:
:exclude-members: $EXCLUDE_METHODS
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:methods:
:nosignatures:
:exclude-members: $EXCLUDE_METHODS
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:static_methods:
:nosignatures:
:exclude-members: $EXCLUDE_METHODS
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:signals:
:nosignatures:
:exclude-members: $EXCLUDE_METHODS
.. autoautosummary:: qgis.$PACKAGE.$CLASS
:attributes:
:exclude-members: $EXCLUDE_METHODS
"""

MODULE_TOC_MAX_COLUMN_SIZES = [300, 500]
Expand Down Expand Up @@ -318,10 +321,7 @@ def generate_docs():
header = ""
toc = ""

if inspect.isclass(_class):
header = class_header
toc = class_toc

bases_and_subclass_header = ""
if hasattr(_class, "__bases__") and _class.__bases__:

def export_bases(_b):
Expand All @@ -342,22 +342,46 @@ def export_bases(_b):

base_header = export_bases(_class)
if base_header:
header += "\n" + write_header("Base classes")
header += f"\n+{'-' * MODULE_TOC_MAX_COLUMN_SIZES[0]}+{'-' * MODULE_TOC_MAX_COLUMN_SIZES[1]}+\n"
header += base_header
bases_and_subclass_header += "\n" + write_header("Base classes", 2)
bases_and_subclass_header += f"\n+{'-' * MODULE_TOC_MAX_COLUMN_SIZES[0]}+{'-' * MODULE_TOC_MAX_COLUMN_SIZES[1]}+\n"
bases_and_subclass_header += base_header

if hasattr(_class, "__subclasses__") and _class.__subclasses__():
header += "\n" + write_header("Subclasses")
header += f"\n+{'-' * MODULE_TOC_MAX_COLUMN_SIZES[0]}+{'-' * MODULE_TOC_MAX_COLUMN_SIZES[1]}+\n"
bases_and_subclass_header += "\n" + write_header("Subclasses", 2)
bases_and_subclass_header += f"\n+{'-' * MODULE_TOC_MAX_COLUMN_SIZES[0]}+{'-' * MODULE_TOC_MAX_COLUMN_SIZES[1]}+\n"

for subclass in _class.__subclasses__():
header += make_table_row(
bases_and_subclass_header += make_table_row(
[
f"`{subclass.__name__} <{subclass.__name__}.html>`_",
extract_summary(subclass.__doc__),
]
)

if inspect.isclass(_class):
class_doc = _class.__doc__
# only keep the actual class doc string part. SIP will
# append the constructor signatures and docs at the end
# of the class doc, so let's trim those off.
# They'll get included later in the actual listing of
# class methods
if class_doc:
lines = class_doc.split("\n")
init_idx = 0
for init_idx, line in enumerate(lines):
if re.match(rf"^{_class.__name__}\(", line):
break

header = "\n".join(lines[:init_idx])

if bases_and_subclass_header:
if header:
header += "\n\n"
header += write_header("Class Hierarchy")
header += inheritance_diagram
header += bases_and_subclass_header
toc = class_toc

for method in dir(_class):
if not hasattr(_class, method):
continue
Expand Down

0 comments on commit 22be803

Please sign in to comment.