Skip to content

Commit

Permalink
Initial implementation of customisable single page output
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgepiloto authored and AWhetter committed Mar 26, 2024
1 parent 0d69974 commit ecd47ea
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 7 deletions.
1 change: 1 addition & 0 deletions autoapi/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ def setup(app):
app.add_config_value("autoapi_python_class_content", "class", "html")
app.add_config_value("autoapi_generate_api_docs", True, "html")
app.add_config_value("autoapi_prepare_jinja_env", None, "html")
app.add_config_value("autoapi_single_page_level", "module", "html")
app.add_autodocumenter(documenters.AutoapiFunctionDocumenter)
app.add_autodocumenter(documenters.AutoapiPropertyDocumenter)
app.add_autodocumenter(documenters.AutoapiDecoratorDocumenter)
Expand Down
49 changes: 47 additions & 2 deletions autoapi/mappers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import re

import anyascii
from docutils.parsers.rst import convert_directive_function
from jinja2 import Environment, FileSystemLoader, TemplateNotFound
import sphinx
import sphinx.util
Expand All @@ -12,7 +13,7 @@
from sphinx.util.osutil import ensuredir
import sphinx.util.logging

from ..settings import API_ROOT, TEMPLATE_DIR
from ..settings import API_ROOT, TEMPLATE_DIR, SINGLE_PAGE_LEVELS

LOGGER = sphinx.util.logging.getLogger(__name__)

Expand Down Expand Up @@ -306,23 +307,67 @@ def create_class(self, data, options=None, **kwargs):
"""
raise NotImplementedError

def output_child_rst(self, obj, obj_parent, detail_dir, single_page_level, source_suffix):

if not obj.display:
return

obj_child_page_level = SINGLE_PAGE_LEVELS.index(obj.type)
desired_page_level = SINGLE_PAGE_LEVELS.index(single_page_level)
needs_single_page = obj_child_page_level <= desired_page_level
if not needs_single_page:
return

obj_child_rst = obj.render(
needs_single_page=needs_single_page,
)
if not obj_child_rst:
return

ensuredir(os.path.join(detail_dir, obj.short_name))
path = os.path.join(
detail_dir, obj.short_name, f"index{source_suffix}"
)

with open(path, "wb+") as obj_child_detail_file:
obj_child_detail_file.write(obj_child_rst.encode("utf-8"))

for obj_child in obj.children:
child_detail_dir = os.path.join(detail_dir, obj.name)
self.output_child_rst(obj_child, obj, child_detail_dir, single_page_level, source_suffix)


def output_rst(self, root, source_suffix):
# Evaluate which object types should render in a single page
single_page_level = self.app.config.autoapi_single_page_level
desired_page_level = SINGLE_PAGE_LEVELS.index(single_page_level)
single_page_objects = SINGLE_PAGE_LEVELS[:desired_page_level+1]

for _, obj in status_iterator(
self.objects.items(),
colorize("bold", "[AutoAPI] ") + "Rendering Data... ",
length=len(self.objects),
verbosity=1,
stringify_func=(lambda x: x[0]),
):
rst = obj.render()
if not obj.display:
continue

rst = obj.render(single_page_objects=single_page_objects)
if not rst:
continue

detail_dir = obj.include_dir(root=root)
ensuredir(detail_dir)
path = os.path.join(detail_dir, f"index{source_suffix}")

with open(path, "wb+") as detail_file:
detail_file.write(rst.encode("utf-8"))

for obj_child in obj.children:
self.output_child_rst(obj_child, obj, detail_dir=detail_dir,
single_page_level=single_page_level,
source_suffix=source_suffix)

if self.app.config.autoapi_add_toctree_entry:
self._output_top_rst(root)
Expand Down
12 changes: 12 additions & 0 deletions autoapi/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,15 @@
TEMPLATE_DIR = os.path.join(SITE_ROOT, "templates")

API_ROOT = "autoapi"

SINGLE_PAGE_LEVELS = [
"package",
"module",
"exception",
"class",
"function",
"method",
"property",
"attribute",
"data",
]
5 changes: 5 additions & 0 deletions autoapi/templates/python/class.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{% if obj.display %}
{% if needs_single_page %}
{{ obj.short_name }}
{{ "=" * obj.short_name | length }}
{% endif %}

.. py:{{ obj.type }}:: {{ obj.short_name }}{% if obj.args %}({{ obj.args }}){% endif %}
{% for (args, return_annotation) in obj.overloads %}
Expand Down
5 changes: 5 additions & 0 deletions autoapi/templates/python/function.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{% if obj.display %}
{% if needs_single_page %}
{{ obj.short_name }}
{{ "=" * obj.short_name | length }}
{% endif %}

.. py:function:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %}
{% for (args, return_annotation) in obj.overloads %}
Expand Down
5 changes: 5 additions & 0 deletions autoapi/templates/python/method.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{%- if obj.display %}
{% if needs_single_page %}
{{ obj.short_name }}
{{ "=" * obj.short_name | length }}
{% endif %}

.. py:method:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %}
{% for (args, return_annotation) in obj.overloads %}
Expand Down
43 changes: 38 additions & 5 deletions autoapi/templates/python/module.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,18 @@ Classes
{{ klass.id }}
{% endfor %}

{% if "class" in single_page_objects %}
{% for klass in visible_classes %}
.. toctree::
:titlesonly:
:maxdepth: 1
:hidden:

{% endif %}
{{ klass.name }}

{% endfor %}
{%- endif -%}
{%- endif -%}
{% endblock %}

{% block functions scoped %}
Expand All @@ -88,12 +98,21 @@ Functions
{{ function.id }}
{% endfor %}

{% if "function" in single_page_objects %}
.. toctree::
:titlesonly:
:maxdepth: 1
:hidden:

{% endif %}
{% endblock %}
{% for function in visible_functions %}
{{ function.name }}
{% endfor %}

{%- endif -%}
{%- endif -%}
{% endblock %}
{% block attributes scoped %}
{% if visible_attributes %}
{%- if visible_attributes -%}
Attributes
~~~~~~~~~~

Expand All @@ -103,12 +122,26 @@ Attributes
{{ attribute.id }}
{% endfor %}

{% if "attribute" in single_page_objects %}
.. toctree::
:titlesonly:
:maxdepth: 1
:hidden:

{% for attr in visible_attributes %}
{{ attr.name }}
{% endfor %}

{% endif %}
{%- endif -%}
{%- endif -%}
{% endblock %}
{% endif %}

{% for obj_item in visible_children %}
{% if obj_item.type not in single_page_objects %}
{{ obj_item.render()|indent(0) }}
{% endif %}
{% endfor %}

{% endif %}
{% endblock %}
4 changes: 4 additions & 0 deletions autoapi/templates/python/property.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{%- if obj.display %}
{% if needs_single_page %}
{{ obj.short_name }}
{{ "=" * obj.short_name | length }}
{% endif %}
.. py:property:: {{ obj.short_name }}
{% if obj.annotation %}
:type: {{ obj.annotation }}
Expand Down
23 changes: 23 additions & 0 deletions docs/reference/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,29 @@ Customisation Options
:noindex:


.. confval:: autoapi_single_page_level

Default: ``'module'``

This configuration value specifies the level at which objects are rendered on
a single page. Valid levels, in descending order of hierarchy, are as
follows:

* Package

* Module

* Class

* Function

* Method

* Attribute

* Data


Events
~~~~~~

Expand Down

0 comments on commit ecd47ea

Please sign in to comment.