from pathlib import Path from typing import List, Dict, Any from docforge.nav.resolver import ResolvedNav class MkDocsNavEmitter: """Emit MkDocs-compatible nav structures.""" def emit(self, nav: ResolvedNav) -> List[Dict[str, Any]]: 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 to a docs-relative path. """ 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]