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: :glob:
* *
roles/index.rst roles/index.rst
.. roles-overview::

View File

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

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:: .. toctree::
:maxdepth: 1 :maxdepth: 1
:caption: Included Applications: :caption: Overview
:glob: :glob:
./*.rst
*/README

View File

@ -14,7 +14,7 @@
</ul> </ul>
{% endfor %} {% endfor %}
{% endif %} {% 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 %} {% set ns.current_level = item.level %}
{% endfor %} {% endfor %}
{# Close any remaining open <ul> tags #} {# 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) filepath = os.path.join(abs_dir, file)
headings = extract_headings_from_file(filepath) headings = extract_headings_from_file(filepath)
for heading in headings: for heading in headings:
file_link = os.path.join(directory, file) if directory else file # Build file link: zunächst Pfad + Dateiname, dann Ersetzen der .md-Endung durch .html
full_link = file_link + '#' + heading['anchor'] file_link = os.path.join(directory, file).replace(".md","") if directory else file
local_md_headings.append({ local_md_headings.append({
'level': heading['level'], 'level': heading['level'],
'text': heading['text'], 'text': heading['text'],
'link': full_link 'link': file_link,
'anchor': heading['anchor']
}) })
# Sort headings in natural ascending order using natural_sort_key. # Sort headings in natural ascending order using natural_sort_key.
local_md_headings.sort(key=lambda x: natural_sort_key(x['text'])) 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. A directive to embed a roles overview as reStructuredText.
It scans the roles directory (i.e. every folder under "roles") for a 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 "meta/main.yml" file, reads the roles galaxy tags (from galaxy_info.galaxy_tags)
(from galaxy_info.description), and outputs a listing grouped by category. 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 has_content = False
@ -28,7 +29,7 @@ class RolesOverviewDirective(Directive):
"Roles directory not found.", line=self.lineno) "Roles directory not found.", line=self.lineno)
return [error_node] return [error_node]
# Dictionary mapping categories to role entries. # Dictionary mapping tags to role entries.
categories = {} categories = {}
for role_path in glob.glob(os.path.join(roles_dir, '*')): for role_path in glob.glob(os.path.join(roles_dir, '*')):
if os.path.isdir(role_path): if os.path.isdir(role_path):
@ -42,38 +43,50 @@ class RolesOverviewDirective(Directive):
continue continue
role_name = os.path.basename(role_path) role_name = os.path.basename(role_path)
category = data.get('category', 'uncategorized') # Try to get galaxy_tags from galaxy_info. If none, use "uncategorized".
role_description = data.get('galaxy_info', {}).get('description', '') 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 = { role_entry = {
'name': role_name, 'name': role_name,
'description': role_description, '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: else:
logger.warning(f"meta/main.yml not found for role {role_path}") 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. # Sort categories and roles alphabetically.
sorted_categories = sorted(categories.items(), key=lambda x: x[0].lower()) 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()) roles.sort(key=lambda r: r['name'].lower())
# Build reStructuredText content. # Build reStructuredText content.
lines = [] lines = []
for category, roles in sorted_categories: for tag, roles in sorted_categories:
lines.append(f".. rubric:: {category}") lines.append(f".. rubric:: {tag}")
lines.append("") lines.append("")
for role in roles: 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']: if role['description']:
lines.append(f" - {role['description']}") lines.append("")
lines.append(f" {role['description']}")
lines.append("")
lines.append("") lines.append("")
rst_content = "\n".join(lines) rst_content = "\n".join(lines)
# Use a ViewList for nested_parse. # Use a ViewList for nested_parse.
rst_lines = ViewList() rst_lines = ViewList()
for i, line in enumerate(rst_content.splitlines()): for line in rst_content.splitlines():
rst_lines.append(line, '<roles-overview>') rst_lines.append(line, '<roles-overview>')
container = nodes.container() container = nodes.container()