Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.

Commit e56c3a7

Browse files
authored
feat: add summary page for Classes and Modules (#361)
* feat: add summary page for Classes and Modules * fix: update toc yaml alias to just be yaml alias * feat: address review comments
1 parent 56223a8 commit e56c3a7

2 files changed

Lines changed: 127 additions & 10 deletions

File tree

docfx_yaml/extension.py

Lines changed: 126 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import logging
2929

3030
from collections import defaultdict
31-
from collections.abc import MutableSet
31+
from collections.abc import MutableSet, Mapping, Sequence
3232
from pathlib import Path
3333
from functools import partial
3434
from itertools import zip_longest
@@ -134,6 +134,21 @@ class Bcolors:
134134
DEPRECATED: 'deprecated',
135135
}
136136

137+
_SUMMARY_TYPE_BY_ITEM_TYPE = {
138+
# Modules and Classes are similar types.
139+
MODULE: CLASS,
140+
CLASS: CLASS,
141+
}
142+
# Construct a mapping of name and content for each unique summary type entry.
143+
_ENTRY_NAME_AND_ENTRY_CONTENT_BY_SUMMARY_TYPE = {
144+
summary_type: [[], []] # entry name then entry content
145+
for summary_type in set(_SUMMARY_TYPE_BY_ITEM_TYPE.values())
146+
}
147+
# Mapping for each summary page entry's file name and entry name.
148+
_FILE_NAME_AND_ENTRY_NAME_BY_SUMMARY_TYPE = {
149+
CLASS: ('summary_class.yml', "Classes"),
150+
}
151+
137152
# Disable blib2to3 output that clutters debugging log.
138153
logging.getLogger("blib2to3").setLevel(logging.ERROR)
139154

@@ -1348,6 +1363,61 @@ def pretty_package_name(package_group):
13481363
return " ".join(capitalized_name)
13491364

13501365

1366+
# Type alias used for yaml entries.
1367+
_yaml_type_alias = dict[str, any]
1368+
1369+
1370+
def _find_and_add_summary_details(
1371+
yaml_data: _yaml_type_alias,
1372+
summary_type: str,
1373+
cgc_url: str,
1374+
) -> None:
1375+
"""Finds the summary details to add for a given entry."""
1376+
uid = yaml_data.get("uid", "")
1377+
item_to_add = uid if summary_type == CLASS else f"{uid}-summary"
1378+
1379+
if item_to_add not in _ENTRY_NAME_AND_ENTRY_CONTENT_BY_SUMMARY_TYPE[summary_type][0]:
1380+
_ENTRY_NAME_AND_ENTRY_CONTENT_BY_SUMMARY_TYPE[summary_type][0].append(
1381+
item_to_add
1382+
)
1383+
1384+
if summary_type in [CLASS]:
1385+
name_to_use = f"[{uid}]({cgc_url}{uid})"
1386+
1387+
_ENTRY_NAME_AND_ENTRY_CONTENT_BY_SUMMARY_TYPE[summary_type][1].append({
1388+
"uid": uid,
1389+
"name": name_to_use,
1390+
"fullName": uid,
1391+
"isExternal": False,
1392+
})
1393+
1394+
1395+
def _render_summary_content(
1396+
children_name_and_summary_content: Sequence[Sequence[str | _yaml_type_alias]],
1397+
entry_name: str,
1398+
summary_type: str,
1399+
library_name: str,
1400+
) -> _yaml_type_alias:
1401+
"""Returns the summary content in appropriate YAML format to write."""
1402+
summary_content = {}
1403+
1404+
if summary_type in [CLASS]:
1405+
summary_content = {
1406+
"items": [{
1407+
'uid': f'{summary_type.lower()}-summary',
1408+
'name': entry_name,
1409+
'fullName': f'{entry_name} Summary',
1410+
'langs': ['python'],
1411+
'type': 'package',
1412+
'summary': f'Summary of entries of {entry_name} for {library_name}.',
1413+
'children': children_name_and_summary_content[0],
1414+
}],
1415+
'references': children_name_and_summary_content[1],
1416+
}
1417+
1418+
return summary_content
1419+
1420+
13511421
def find_uid_to_convert(
13521422
current_word: str,
13531423
words: List[str],
@@ -1575,14 +1645,11 @@ def search_cross_references(obj, current_object_name: str, known_uids: List[str]
15751645
markdown_utils.reformat_markdown_to_html(attribute_type))
15761646

15771647

1578-
# Type alias used for toc_yaml entries.
1579-
_toc_yaml_type_alias = dict[str, any]
1580-
15811648
def merge_markdown_and_package_toc(
1582-
pkg_toc_yaml: list[_toc_yaml_type_alias],
1583-
markdown_toc_yaml: _toc_yaml_type_alias,
1649+
pkg_toc_yaml: list[_yaml_type_alias],
1650+
markdown_toc_yaml: _yaml_type_alias,
15841651
known_uids: set[str],
1585-
) -> tuple[MutableSet[str], list[_toc_yaml_type_alias]]:
1652+
) -> tuple[MutableSet[str], list[_yaml_type_alias]]:
15861653
"""
15871654
Merges the markdown and package table of contents.
15881655
@@ -1595,8 +1662,8 @@ def merge_markdown_and_package_toc(
15951662
contents file, with files in the correct position.
15961663
"""
15971664
def _flatten_toc(
1598-
toc_yaml_entry: list[_toc_yaml_type_alias],
1599-
) -> list[_toc_yaml_type_alias]:
1665+
toc_yaml_entry: list[_yaml_type_alias],
1666+
) -> list[_yaml_type_alias]:
16001667
"""Flattens and retrieves all children within pkg_toc_yaml."""
16011668
entries = list(toc_yaml_entry)
16021669
for entry in toc_yaml_entry:
@@ -1897,6 +1964,17 @@ def convert_module_to_package_if_needed(obj):
18971964
markdown_utils.remove_unused_pages(
18981965
added_pages, app.env.moved_markdown_pages, normalized_outdir)
18991966

1967+
# Add summary pages as the second entry into the table of contents.
1968+
pkg_toc_yaml.insert(
1969+
1,
1970+
{
1971+
"name": f"{app.config.project} APIs",
1972+
"items": [
1973+
{"name": "Classes", "href": "summary_class.yml"},
1974+
],
1975+
}
1976+
)
1977+
19001978
toc_file = os.path.join(normalized_outdir, 'toc.yml')
19011979
with open(toc_file, 'w') as writable:
19021980
writable.write(
@@ -1909,6 +1987,11 @@ def convert_module_to_package_if_needed(obj):
19091987
)
19101988
)
19111989

1990+
cgc_url = (
1991+
"https://cloud.google.com/python/docs/reference/"
1992+
f"{app.config.project}/latest/"
1993+
)
1994+
yaml_entry_line = "### YamlMime:UniversalReference\n"
19121995
# Output files
19131996
for uid, data in iter(yaml_map.items()):
19141997

@@ -1935,7 +2018,7 @@ def convert_module_to_package_if_needed(obj):
19352018
app.info(bold('[docfx_yaml] ') + darkgreen('Outputting %s' % filename))
19362019

19372020
with open(out_file, 'w') as out_file_obj:
1938-
out_file_obj.write('### YamlMime:UniversalReference\n')
2021+
out_file_obj.write(yaml_entry_line)
19392022
try:
19402023
dump(
19412024
{
@@ -1951,6 +2034,39 @@ def convert_module_to_package_if_needed(obj):
19512034

19522035
file_name_set.add(filename)
19532036

2037+
for entry in yaml_data:
2038+
summary_type = _SUMMARY_TYPE_BY_ITEM_TYPE.get(entry.get("type"))
2039+
if not (summary_type):
2040+
continue
2041+
2042+
_find_and_add_summary_details(entry, summary_type, cgc_url)
2043+
2044+
for summary_type in _ENTRY_NAME_AND_ENTRY_CONTENT_BY_SUMMARY_TYPE:
2045+
children_names_and_content = (
2046+
_ENTRY_NAME_AND_ENTRY_CONTENT_BY_SUMMARY_TYPE[summary_type]
2047+
)
2048+
if not all(children_names_and_content):
2049+
continue
2050+
2051+
file_name, entry_name = _FILE_NAME_AND_ENTRY_NAME_BY_SUMMARY_TYPE[summary_type]
2052+
2053+
dump_content = _render_summary_content(
2054+
children_names_and_content,
2055+
entry_name,
2056+
summary_type,
2057+
app.config.project,
2058+
)
2059+
2060+
file_path_to_use = os.path.join(normalized_outdir, file_name)
2061+
with open(file_path_to_use, "w") as summary_file_obj:
2062+
summary_file_obj.write(yaml_entry_line)
2063+
dump(
2064+
dump_content,
2065+
summary_file_obj,
2066+
default_flow_style=False,
2067+
)
2068+
2069+
19542070
index_file = os.path.join(normalized_outdir, 'index.yml')
19552071
index_children = []
19562072
index_references = []

docfx_yaml/markdown_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ def move_markdown_pages(
280280

281281
"reference.md", # Reference docs overlap with Overview. Will try and incorporate this in later.
282282
# See https://github.com/googleapis/sphinx-docfx-yaml/issues/106.
283+
"summary_overview.md", # Already included in the TOC.
283284
]
284285

285286
files_to_rename = {

0 commit comments

Comments
 (0)