Files
doc-forge/docforge/nav/mkdocs.py
Vishesh 'ironeagle' Bangotra 06ffd2febd chore(release): 0.0.7
Squash-merge lib-standardisation: adopt repo standards across packaging,
tooling, docs, and CI.

- standardize pyproject.toml (canonical packaging, lint config, extras, GSDFC pydoclint)
- add py.typed marker, modernize type hints and Google-style docstrings
- nest generated docs under docs/lib and docs/mcp; add hand-written wiki
- adopt standard Type A PyPI CI pipeline (tag==version guard + quality gate)
- promote generated CHANGELOG.md; bump version to 0.0.7
2026-10-17 02:16:44 +05:30

95 lines
3.0 KiB
Python

"""
MkDocs navigation emitter.
This module provides the ``MkDocsNavEmitter`` class, which converts a
``ResolvedNav`` instance into the navigation structure required by the
MkDocs ``nav`` configuration.
---
Notes:
- The emitted structure is a list of dictionaries, one per top-level nav
entry, matching the MkDocs ``nav`` YAML format.
---
"""
from pathlib import Path
from typing import Any
from docforge.nav.resolver import ResolvedNav
class MkDocsNavEmitter:
"""
Emit MkDocs navigation structures from resolved navigation data.
The emitter transforms a ``ResolvedNav`` object into the YAML-compatible
list structure expected by the MkDocs ``nav`` configuration field.
"""
def emit(self, nav: ResolvedNav) -> list[dict[str, Any]]:
"""
Generate a navigation structure for ``mkdocs.yml``.
Args:
nav (ResolvedNav):
Resolved navigation data describing documentation groups
and their associated Markdown files.
Returns:
list[dict[str, Any]]:
A list of dictionaries representing the MkDocs navigation layout.
Each dictionary maps a navigation label to a page or a list of
pages.
"""
result: list[dict[str, Any]] = []
# Home entry (semantic path)
if nav.home:
result.append({"Home": nav.home})
# Group entries
for group, paths in nav.groups.items():
entries: list[str] = []
for p in paths:
# Convert filesystem path back to docs-relative path
rel_path = self._to_relative(p, nav._docs_root)
entries.append(rel_path)
result.append({group: entries})
return result
def _to_relative(self, path: Path, docs_root: Path | None) -> str:
"""
Convert a filesystem path into a documentation-relative path.
This method normalizes paths so they can be used in MkDocs navigation.
It handles both absolute and relative filesystem paths and ensures the
resulting path is relative to the documentation root.
Args:
path (Path):
Filesystem path to convert.
docs_root (Path | None):
Root directory of the documentation sources.
Returns:
str:
POSIX-style path relative to the documentation root.
"""
if docs_root and path.is_absolute():
try:
path = path.relative_to(docs_root.resolve())
except ValueError:
pass
elif docs_root:
# Handle relative paths (e.g. starting with 'docs/')
path_str = path.as_posix()
docs_root_str = docs_root.as_posix()
if path_str.startswith(docs_root_str + "/"):
return path_str[len(docs_root_str) + 1 :]
# Fallback for other cases
return path.as_posix().split("/docs/", 1)[-1]