Initial implementation of customisable single page output

pull/394/merge
Jorge Martinez Garrido 9 months ago committed by Ashley Whetter
parent 0d69974c19
commit ecd47ea456

@ -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)

@ -4,6 +4,7 @@ from collections import OrderedDict, namedtuple
import re
import anyascii
from docutils.parsers.rst import convert_directive_function
from jinja2 import Environment, FileSystemLoader, TemplateNotFound
import sphinx
import sphinx.util
@ -12,7 +13,7 @@ from sphinx.util.display import status_iterator
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__)
@ -306,7 +307,42 @@ class SphinxMapperBase:
"""
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... ",
@ -314,15 +350,24 @@ class SphinxMapperBase:
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)

@ -10,3 +10,15 @@ SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
TEMPLATE_DIR = os.path.join(SITE_ROOT, "templates")
API_ROOT = "autoapi"
SINGLE_PAGE_LEVELS = [
"package",
"module",
"exception",
"class",
"function",
"method",
"property",
"attribute",
"data",
]

@ -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 %}

@ -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 %}

@ -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 %}

@ -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 %}
@ -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
~~~~~~~~~~
@ -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 %}

@ -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 }}

@ -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
~~~~~~

Loading…
Cancel
Save