Optimized sphinx

This commit is contained in:
Kevin Veen-Birkenbach 2025-03-15 16:10:02 +01:00
parent cc458753b3
commit 12e0367c66
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
9 changed files with 47 additions and 28 deletions

View File

View File

@ -7,7 +7,4 @@ Cyber Master Infrastructure Solution documentation
:glob:
*
roles/index.rst
.. roles-overview::
roles/index.rst

View File

@ -1,3 +1,2 @@
test
# h1
# Hello World
test

3
roles/categories.rst Normal file
View File

@ -0,0 +1,3 @@
# Applications by Category
.. roles-overview::

8
roles/glosar.rst Normal file
View File

@ -0,0 +1,8 @@
# Application Glosar
.. toctree::
:maxdepth: 1
:caption: Included Applications:
:glob:
*/README

View File

@ -6,8 +6,6 @@ Applications and Roles
.. toctree::
:maxdepth: 1
:caption: Included Applications:
:caption: Overview
:glob:
*/README
./*.rst

View File

@ -14,7 +14,7 @@
</ul>
{% endfor %}
{% endif %}
<li><a href="{{ pathto(item.link) }}">{{ item.text }}</a></li>
<li><a href="{{ pathto(item.link).replace("#","") + "#" + item.anchor}}">{{ item.text }}</a></li>
{% set ns.current_level = item.level %}
{% endfor %}
{# Close any remaining open <ul> tags #}

View File

@ -68,12 +68,13 @@ def add_local_md_headings(app, pagename, templatename, context, doctree):
filepath = os.path.join(abs_dir, file)
headings = extract_headings_from_file(filepath)
for heading in headings:
file_link = os.path.join(directory, file) if directory else file
full_link = file_link + '#' + heading['anchor']
# Build file link: zunächst Pfad + Dateiname, dann Ersetzen der .md-Endung durch .html
file_link = os.path.join(directory, file).replace(".md","") if directory else file
local_md_headings.append({
'level': heading['level'],
'text': heading['text'],
'link': full_link
'link': file_link,
'anchor': heading['anchor']
})
# Sort headings in natural ascending order using natural_sort_key.
local_md_headings.sort(key=lambda x: natural_sort_key(x['text']))

View File

@ -13,8 +13,9 @@ class RolesOverviewDirective(Directive):
A directive to embed a roles overview as reStructuredText.
It scans the roles directory (i.e. every folder under "roles") for a
"meta/main.yml" file, reads the category (if provided) and the roles description
(from galaxy_info.description), and outputs a listing grouped by category.
"meta/main.yml" file, reads the roles galaxy tags (from galaxy_info.galaxy_tags)
and description (from galaxy_info.description), and outputs a listing grouped
by each tag. Roles without galaxy tags are grouped under "uncategorized".
"""
has_content = False
@ -28,7 +29,7 @@ class RolesOverviewDirective(Directive):
"Roles directory not found.", line=self.lineno)
return [error_node]
# Dictionary mapping categories to role entries.
# Dictionary mapping tags to role entries.
categories = {}
for role_path in glob.glob(os.path.join(roles_dir, '*')):
if os.path.isdir(role_path):
@ -42,38 +43,50 @@ class RolesOverviewDirective(Directive):
continue
role_name = os.path.basename(role_path)
category = data.get('category', 'uncategorized')
role_description = data.get('galaxy_info', {}).get('description', '')
# Try to get galaxy_tags from galaxy_info. If none, use "uncategorized".
galaxy_info = data.get('galaxy_info', {})
tags = galaxy_info.get('galaxy_tags', [])
if not tags:
tags = ['uncategorized']
role_description = galaxy_info.get('description', '')
role_entry = {
'name': role_name,
'description': role_description,
'link': f'roles/{role_name}/README.md'
'link': f'roles/{role_name}/README.md',
'tags': tags,
}
categories.setdefault(category, []).append(role_entry)
# Add this role to every tag it belongs to.
for tag in tags:
categories.setdefault(tag, []).append(role_entry)
else:
logger.warning(f"meta/main.yml not found for role {role_path}")
logger.info("For role %s, galaxy_info: %s", role_name, galaxy_info)
# Sort categories and roles alphabetically.
sorted_categories = sorted(categories.items(), key=lambda x: x[0].lower())
for category, roles in sorted_categories:
for tag, roles in sorted_categories:
roles.sort(key=lambda r: r['name'].lower())
# Build reStructuredText content.
lines = []
for category, roles in sorted_categories:
lines.append(f".. rubric:: {category}")
for tag, roles in sorted_categories:
lines.append(f".. rubric:: {tag}")
lines.append("")
for role in roles:
lines.append(f"* **[`{role['name']}`]({role['link']})**")
# Render the role name as a hyperlink in reStructuredText.
lines.append(f"* `{role['name']} <{role['link']}>`_")
# Insert a line break before the description.
if role['description']:
lines.append(f" - {role['description']}")
lines.append("")
lines.append(f" {role['description']}")
lines.append("")
lines.append("")
rst_content = "\n".join(lines)
# Use a ViewList for nested_parse.
rst_lines = ViewList()
for i, line in enumerate(rst_content.splitlines()):
for line in rst_content.splitlines():
rst_lines.append(line, '<roles-overview>')
container = nodes.container()