# Improve documentation look & feel via MkDocs Material template enhancements ## Summary This MR improves the overall **documentation experience and visual presentation** of the doc-forge docs by enhancing the MkDocs Material template configuration. The changes focus on **navigation usability, code readability, and richer Markdown rendering**, resulting in a cleaner and more professional documentation site. Docstring changes were made across the codebase for consistency, but this MR description focuses on the **template and presentation improvements**. --- ## Navigation Improvements The navigation system has been enhanced to provide a clearer structure and better discoverability. Key improvements include: * Section-aware navigation in the sidebar * Automatic expansion of module/package hierarchy * Scroll tracking within the sidebar * Clickable package index pages Material navigation features added: * `navigation.sections` * `navigation.expand` * `navigation.tracking` * `navigation.indexes` This results in a **single cohesive navigation tree** that exposes the entire documentation hierarchy from the sidebar. --- ## Code Block Improvements Code blocks previously appeared relatively plain. The template now enables richer syntax highlighting and improved readability. Enhancements include: * Syntax highlighting using `pymdownx.highlight` * Line numbers for code blocks * Anchored line numbers for deep linking * Improved fenced code block rendering Additional Material features: * `content.code.copy` — copy button for code blocks * `content.code.annotate` — support for code annotations These changes significantly improve the readability of examples and API snippets throughout the documentation. --- ## Markdown Rendering Enhancements Additional Markdown extensions were enabled to support richer documentation features: * `pymdownx.superfences` for advanced fenced blocks * `pymdownx.inlinehilite` for inline code highlighting * `pymdownx.snippets` for reusable snippets * `admonition` and `pymdownx.details` for callouts and collapsible sections * `pymdownx.tabbed` for tabbed content blocks * `pymdownx.tasklist` for checklist-style items * `tables`, `footnotes`, and advanced formatting extensions These extensions make it easier to write expressive and structured documentation. --- ## Search Experience The documentation search experience has been improved using Material search features: * `search.highlight` * `search.share` * `search.suggest` These enhancements provide: * highlighted search matches * sharable search URLs * auto-suggestions while typing --- ## mkdocstrings Improvements The mkdocstrings configuration has been expanded to produce clearer API documentation. Notable improvements include: * grouping objects by category * explicit category headings * improved symbol headings * cleaner object path display This results in more structured API documentation pages. --- ## Result Overall, these changes provide: * cleaner and more intuitive navigation * significantly improved code presentation * richer Markdown capabilities * better search usability The documentation now has a **more polished, modern appearance** and improved usability for both readers and contributors. Reviewed-on: #5 Co-authored-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com> Co-committed-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com>
139 lines
3.8 KiB
Python
139 lines
3.8 KiB
Python
import json
|
|
from pathlib import Path
|
|
from typing import Dict, List
|
|
|
|
from docforge.models import Project, Module, DocObject
|
|
|
|
|
|
class MCPRenderer:
|
|
"""
|
|
Renderer that generates MCP-compatible documentation resources.
|
|
|
|
This renderer converts doc-forge project models into structured JSON
|
|
resources suitable for consumption by systems implementing the Model
|
|
Context Protocol (MCP).
|
|
"""
|
|
|
|
name = "mcp"
|
|
|
|
def generate_sources(self, project: Project, out_dir: Path) -> None:
|
|
"""
|
|
Generate MCP documentation resources for a project.
|
|
|
|
The renderer serializes each module into a JSON resource and produces
|
|
supporting metadata files such as ``nav.json`` and ``index.json``.
|
|
|
|
Args:
|
|
project: Documentation project model to render.
|
|
out_dir: Directory where MCP resources will be written.
|
|
"""
|
|
modules_dir = out_dir / "modules"
|
|
modules_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
nav: List[Dict[str, str]] = []
|
|
|
|
for module in project.get_all_modules():
|
|
self._write_module(module, modules_dir)
|
|
|
|
nav.append({
|
|
"module": module.path,
|
|
"resource": f"doc://modules/{module.path}",
|
|
})
|
|
|
|
# Write nav.json
|
|
(out_dir / "nav.json").write_text(
|
|
self._json(nav),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
# Write index.json
|
|
index = {
|
|
"project": project.name,
|
|
"type": "docforge-model",
|
|
"modules_count": len(nav),
|
|
"source": "docforge",
|
|
}
|
|
|
|
(out_dir / "index.json").write_text(
|
|
self._json(index),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
def _write_module(self, module: Module, modules_dir: Path) -> None:
|
|
"""
|
|
Serialize a module into an MCP resource file.
|
|
|
|
Args:
|
|
module: Module instance to serialize.
|
|
modules_dir: Directory where module JSON files are stored.
|
|
"""
|
|
payload = {
|
|
"module": module.path,
|
|
"content": self._render_module(module),
|
|
}
|
|
|
|
out = modules_dir / f"{module.path}.json"
|
|
out.parent.mkdir(parents=True, exist_ok=True)
|
|
out.write_text(self._json(payload), encoding="utf-8")
|
|
|
|
def _render_module(self, module: Module) -> Dict:
|
|
"""
|
|
Convert a Module model into MCP-compatible structured data.
|
|
|
|
Args:
|
|
module: Module instance to convert.
|
|
|
|
Returns:
|
|
Dictionary representing the module and its documented objects.
|
|
"""
|
|
data: Dict = {
|
|
"path": module.path,
|
|
"docstring": module.docstring,
|
|
"objects": {},
|
|
}
|
|
|
|
for obj in module.get_all_objects():
|
|
data["objects"][obj.name] = self._render_object(obj)
|
|
|
|
return data
|
|
|
|
def _render_object(self, obj: DocObject) -> Dict:
|
|
"""
|
|
Recursively convert a DocObject into structured MCP data.
|
|
|
|
Args:
|
|
obj: Documentation object to convert.
|
|
|
|
Returns:
|
|
Dictionary describing the object and any nested members.
|
|
"""
|
|
data: Dict = {
|
|
"name": obj.name,
|
|
"kind": obj.kind,
|
|
"path": obj.path,
|
|
"signature": obj.signature,
|
|
"docstring": obj.docstring,
|
|
}
|
|
|
|
members = list(obj.get_all_members())
|
|
if members:
|
|
data["members"] = {
|
|
member.name: self._render_object(member)
|
|
for member in members
|
|
}
|
|
|
|
return data
|
|
|
|
@staticmethod
|
|
def _json(data: Dict) -> str:
|
|
"""
|
|
Serialize data to formatted JSON.
|
|
|
|
Args:
|
|
data: Dictionary to serialize.
|
|
|
|
Returns:
|
|
JSON string formatted with indentation and UTF-8 compatibility.
|
|
"""
|
|
return json.dumps(data, indent=2, ensure_ascii=False)
|