Skip to content

Commit ecd47ea

Browse files
jorgepilotoAWhetter
authored andcommitted
Initial implementation of customisable single page output
1 parent 0d69974 commit ecd47ea

File tree

9 files changed

+140
-7
lines changed

9 files changed

+140
-7
lines changed

autoapi/extension.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ def setup(app):
271271
app.add_config_value("autoapi_python_class_content", "class", "html")
272272
app.add_config_value("autoapi_generate_api_docs", True, "html")
273273
app.add_config_value("autoapi_prepare_jinja_env", None, "html")
274+
app.add_config_value("autoapi_single_page_level", "module", "html")
274275
app.add_autodocumenter(documenters.AutoapiFunctionDocumenter)
275276
app.add_autodocumenter(documenters.AutoapiPropertyDocumenter)
276277
app.add_autodocumenter(documenters.AutoapiDecoratorDocumenter)

autoapi/mappers/base.py

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import re
55

66
import anyascii
7+
from docutils.parsers.rst import convert_directive_function
78
from jinja2 import Environment, FileSystemLoader, TemplateNotFound
89
import sphinx
910
import sphinx.util
@@ -12,7 +13,7 @@
1213
from sphinx.util.osutil import ensuredir
1314
import sphinx.util.logging
1415

15-
from ..settings import API_ROOT, TEMPLATE_DIR
16+
from ..settings import API_ROOT, TEMPLATE_DIR, SINGLE_PAGE_LEVELS
1617

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

@@ -306,23 +307,67 @@ def create_class(self, data, options=None, **kwargs):
306307
"""
307308
raise NotImplementedError
308309

310+
def output_child_rst(self, obj, obj_parent, detail_dir, single_page_level, source_suffix):
311+
312+
if not obj.display:
313+
return
314+
315+
obj_child_page_level = SINGLE_PAGE_LEVELS.index(obj.type)
316+
desired_page_level = SINGLE_PAGE_LEVELS.index(single_page_level)
317+
needs_single_page = obj_child_page_level <= desired_page_level
318+
if not needs_single_page:
319+
return
320+
321+
obj_child_rst = obj.render(
322+
needs_single_page=needs_single_page,
323+
)
324+
if not obj_child_rst:
325+
return
326+
327+
ensuredir(os.path.join(detail_dir, obj.short_name))
328+
path = os.path.join(
329+
detail_dir, obj.short_name, f"index{source_suffix}"
330+
)
331+
332+
with open(path, "wb+") as obj_child_detail_file:
333+
obj_child_detail_file.write(obj_child_rst.encode("utf-8"))
334+
335+
for obj_child in obj.children:
336+
child_detail_dir = os.path.join(detail_dir, obj.name)
337+
self.output_child_rst(obj_child, obj, child_detail_dir, single_page_level, source_suffix)
338+
339+
309340
def output_rst(self, root, source_suffix):
341+
# Evaluate which object types should render in a single page
342+
single_page_level = self.app.config.autoapi_single_page_level
343+
desired_page_level = SINGLE_PAGE_LEVELS.index(single_page_level)
344+
single_page_objects = SINGLE_PAGE_LEVELS[:desired_page_level+1]
345+
310346
for _, obj in status_iterator(
311347
self.objects.items(),
312348
colorize("bold", "[AutoAPI] ") + "Rendering Data... ",
313349
length=len(self.objects),
314350
verbosity=1,
315351
stringify_func=(lambda x: x[0]),
316352
):
317-
rst = obj.render()
353+
if not obj.display:
354+
continue
355+
356+
rst = obj.render(single_page_objects=single_page_objects)
318357
if not rst:
319358
continue
320359

321360
detail_dir = obj.include_dir(root=root)
322361
ensuredir(detail_dir)
323362
path = os.path.join(detail_dir, f"index{source_suffix}")
363+
324364
with open(path, "wb+") as detail_file:
325365
detail_file.write(rst.encode("utf-8"))
366+
367+
for obj_child in obj.children:
368+
self.output_child_rst(obj_child, obj, detail_dir=detail_dir,
369+
single_page_level=single_page_level,
370+
source_suffix=source_suffix)
326371

327372
if self.app.config.autoapi_add_toctree_entry:
328373
self._output_top_rst(root)

autoapi/settings.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,15 @@
1010
TEMPLATE_DIR = os.path.join(SITE_ROOT, "templates")
1111

1212
API_ROOT = "autoapi"
13+
14+
SINGLE_PAGE_LEVELS = [
15+
"package",
16+
"module",
17+
"exception",
18+
"class",
19+
"function",
20+
"method",
21+
"property",
22+
"attribute",
23+
"data",
24+
]

autoapi/templates/python/class.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
{% if obj.display %}
2+
{% if needs_single_page %}
3+
{{ obj.short_name }}
4+
{{ "=" * obj.short_name | length }}
5+
{% endif %}
6+
27
.. py:{{ obj.type }}:: {{ obj.short_name }}{% if obj.args %}({{ obj.args }}){% endif %}
38
49
{% for (args, return_annotation) in obj.overloads %}

autoapi/templates/python/function.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
{% if obj.display %}
2+
{% if needs_single_page %}
3+
{{ obj.short_name }}
4+
{{ "=" * obj.short_name | length }}
5+
{% endif %}
6+
27
.. py:function:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %}
38
49
{% for (args, return_annotation) in obj.overloads %}

autoapi/templates/python/method.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
{%- if obj.display %}
2+
{% if needs_single_page %}
3+
{{ obj.short_name }}
4+
{{ "=" * obj.short_name | length }}
5+
{% endif %}
6+
27
.. py:method:: {{ obj.short_name }}({{ obj.args }}){% if obj.return_annotation is not none %} -> {{ obj.return_annotation }}{% endif %}
38
49
{% for (args, return_annotation) in obj.overloads %}

autoapi/templates/python/module.rst

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,18 @@ Classes
7373
{{ klass.id }}
7474
{% endfor %}
7575

76+
{% if "class" in single_page_objects %}
77+
{% for klass in visible_classes %}
78+
.. toctree::
79+
:titlesonly:
80+
:maxdepth: 1
81+
:hidden:
7682

77-
{% endif %}
83+
{{ klass.name }}
84+
85+
{% endfor %}
86+
{%- endif -%}
87+
{%- endif -%}
7888
{% endblock %}
7989

8090
{% block functions scoped %}
@@ -88,12 +98,21 @@ Functions
8898
{{ function.id }}
8999
{% endfor %}
90100

101+
{% if "function" in single_page_objects %}
102+
.. toctree::
103+
:titlesonly:
104+
:maxdepth: 1
105+
:hidden:
91106

92-
{% endif %}
93-
{% endblock %}
107+
{% for function in visible_functions %}
108+
{{ function.name }}
109+
{% endfor %}
94110

111+
{%- endif -%}
112+
{%- endif -%}
113+
{% endblock %}
95114
{% block attributes scoped %}
96-
{% if visible_attributes %}
115+
{%- if visible_attributes -%}
97116
Attributes
98117
~~~~~~~~~~
99118

@@ -103,12 +122,26 @@ Attributes
103122
{{ attribute.id }}
104123
{% endfor %}
105124

125+
{% if "attribute" in single_page_objects %}
126+
.. toctree::
127+
:titlesonly:
128+
:maxdepth: 1
129+
:hidden:
130+
131+
{% for attr in visible_attributes %}
132+
{{ attr.name }}
133+
{% endfor %}
106134

107-
{% endif %}
135+
{%- endif -%}
136+
{%- endif -%}
108137
{% endblock %}
109138
{% endif %}
139+
110140
{% for obj_item in visible_children %}
141+
{% if obj_item.type not in single_page_objects %}
111142
{{ obj_item.render()|indent(0) }}
143+
{% endif %}
112144
{% endfor %}
145+
113146
{% endif %}
114147
{% endblock %}

autoapi/templates/python/property.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
{%- if obj.display %}
2+
{% if needs_single_page %}
3+
{{ obj.short_name }}
4+
{{ "=" * obj.short_name | length }}
5+
{% endif %}
26
.. py:property:: {{ obj.short_name }}
37
{% if obj.annotation %}
48
:type: {{ obj.annotation }}

docs/reference/config.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,29 @@ Customisation Options
181181
:noindex:
182182

183183

184+
.. confval:: autoapi_single_page_level
185+
186+
Default: ``'module'``
187+
188+
This configuration value specifies the level at which objects are rendered on
189+
a single page. Valid levels, in descending order of hierarchy, are as
190+
follows:
191+
192+
* Package
193+
194+
* Module
195+
196+
* Class
197+
198+
* Function
199+
200+
* Method
201+
202+
* Attribute
203+
204+
* Data
205+
206+
184207
Events
185208
~~~~~~
186209

0 commit comments

Comments
 (0)