233 lines
7.7 KiB
Python
233 lines
7.7 KiB
Python
"""Markdown documentation generator."""
|
|
|
|
from typing import Optional
|
|
from datetime import datetime
|
|
from .templates import DocumentationTemplate, SyntaxHighlighter
|
|
from ..parsers.base import DocElement, ElementType
|
|
|
|
|
|
class MarkdownGenerator:
|
|
"""Generator for Markdown documentation."""
|
|
|
|
def __init__(
|
|
self,
|
|
template_style: str = "default",
|
|
theme: str = "default",
|
|
syntax_highlighting: bool = True,
|
|
):
|
|
self.template = DocumentationTemplate(style=template_style)
|
|
self.highlighter = SyntaxHighlighter(theme) if syntax_highlighting else None
|
|
|
|
def generate(
|
|
self,
|
|
elements: list[DocElement],
|
|
title: Optional[str] = None,
|
|
include_metadata: bool = True,
|
|
) -> str:
|
|
"""Generate Markdown documentation.
|
|
|
|
Args:
|
|
elements: List of documentation elements
|
|
title: Documentation title
|
|
include_metadata: Include generation metadata
|
|
|
|
Returns:
|
|
Markdown formatted documentation
|
|
"""
|
|
lines = []
|
|
|
|
if include_metadata:
|
|
if title:
|
|
lines.append(f"# {title}")
|
|
else:
|
|
lines.append("# API Documentation")
|
|
lines.append("")
|
|
lines.append(f"*Generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*")
|
|
lines.append("")
|
|
|
|
modules = [e for e in elements if e.element_type == ElementType.MODULE]
|
|
classes = [e for e in elements if e.element_type == ElementType.CLASS]
|
|
functions = [e for e in elements if e.element_type == ElementType.FUNCTION]
|
|
methods = [e for e in elements if e.element_type == ElementType.METHOD]
|
|
interfaces = [e for e in elements if e.element_type == ElementType.INTERFACE]
|
|
structs = [e for e in elements if e.element_type == ElementType.STRUCT]
|
|
constants = [e for e in elements if e.element_type == ElementType.CONSTANT]
|
|
variables = [e for e in elements if e.element_type == ElementType.VARIABLE]
|
|
|
|
if modules:
|
|
lines.append("## Modules")
|
|
lines.append("")
|
|
for module in modules:
|
|
lines.append(self._format_module(module))
|
|
lines.append("")
|
|
|
|
if classes or structs:
|
|
lines.append("## Classes & Structs")
|
|
lines.append("")
|
|
for elem in classes + structs:
|
|
lines.append(self._format_class(elem))
|
|
lines.append("")
|
|
|
|
if interfaces:
|
|
lines.append("## Interfaces")
|
|
lines.append("")
|
|
for interface in interfaces:
|
|
lines.append(self._format_interface(interface))
|
|
lines.append("")
|
|
|
|
if functions:
|
|
lines.append("## Functions")
|
|
lines.append("")
|
|
for func in functions:
|
|
lines.append(self._format_function(func))
|
|
lines.append("")
|
|
|
|
if methods:
|
|
lines.append("## Methods")
|
|
lines.append("")
|
|
for method in methods:
|
|
lines.append(self._format_function(method))
|
|
lines.append("")
|
|
|
|
if constants or variables:
|
|
lines.append("## Constants & Variables")
|
|
lines.append("")
|
|
for elem in constants + variables:
|
|
lines.append(f"### {elem.name}")
|
|
lines.append("")
|
|
if elem.description:
|
|
lines.append(f"{elem.description}")
|
|
lines.append("")
|
|
lines.append(f"*Source: {elem.source_file}:{elem.line_number}*")
|
|
lines.append("")
|
|
|
|
return "\n".join(lines)
|
|
|
|
def _format_module(self, element: DocElement) -> str:
|
|
"""Format module documentation."""
|
|
elements_count = {
|
|
"functions": sum(1 for e in element.imports if "function" in e.lower()),
|
|
"classes": sum(1 for e in element.imports if "class" in e.lower()),
|
|
"constants": 0,
|
|
}
|
|
|
|
return self.template.format_module(
|
|
name=element.name,
|
|
description=element.description,
|
|
imports=element.imports,
|
|
elements_count=elements_count,
|
|
)
|
|
|
|
def _format_class(self, element: DocElement) -> str:
|
|
"""Format class documentation."""
|
|
params = [(p.name, p.type_hint, p.description) for p in element.parameters]
|
|
method_names = []
|
|
for elem in element.imports:
|
|
if "." in elem:
|
|
method_names.append(elem.split(".", 1)[1])
|
|
|
|
return self.template.format_class(
|
|
name=element.name,
|
|
description=element.description,
|
|
attributes=element.attributes,
|
|
methods=method_names,
|
|
parameters=params,
|
|
decorators=element.decorators,
|
|
source_file=element.source_file,
|
|
line_number=element.line_number,
|
|
)
|
|
|
|
def _format_function(self, element: DocElement) -> str:
|
|
"""Format function documentation."""
|
|
params = [
|
|
(p.name, p.type_hint, p.default_value, p.description)
|
|
for p in element.parameters
|
|
]
|
|
|
|
raises = [(r[0], r[1]) for r in element.raises]
|
|
|
|
return self.template.format_function(
|
|
name=element.name,
|
|
description=element.description,
|
|
parameters=params,
|
|
return_type=element.return_type,
|
|
return_description=element.return_description,
|
|
raises=raises,
|
|
examples=element.examples,
|
|
source_file=element.source_file,
|
|
line_number=element.line_number,
|
|
decorators=element.decorators,
|
|
)
|
|
|
|
def _format_interface(self, element: DocElement) -> str:
|
|
"""Format interface documentation."""
|
|
return self.template.format_interface(
|
|
name=element.name,
|
|
description=element.description,
|
|
properties=element.attributes,
|
|
)
|
|
|
|
def generate_json(self, elements: list[DocElement]) -> str:
|
|
"""Generate JSON output for machine-readable format.
|
|
|
|
Args:
|
|
elements: List of documentation elements
|
|
|
|
Returns:
|
|
JSON formatted string
|
|
"""
|
|
import json
|
|
|
|
data = {
|
|
"generated_at": datetime.now().isoformat(),
|
|
"elements": [],
|
|
}
|
|
|
|
for elem in elements:
|
|
elem_data = {
|
|
"name": elem.name,
|
|
"type": elem.element_type.value,
|
|
"description": elem.description,
|
|
"source_file": elem.source_file,
|
|
"line_number": elem.line_number,
|
|
"visibility": elem.visibility,
|
|
}
|
|
|
|
if elem.parameters:
|
|
elem_data["parameters"] = [
|
|
{
|
|
"name": p.name,
|
|
"type": p.type_hint,
|
|
"default": p.default_value,
|
|
"description": p.description,
|
|
}
|
|
for p in elem.parameters
|
|
]
|
|
|
|
if elem.return_type:
|
|
elem_data["return"] = {
|
|
"type": elem.return_type,
|
|
"description": elem.return_description,
|
|
}
|
|
|
|
if elem.attributes:
|
|
elem_data["attributes"] = [
|
|
{"name": a[0], "type": a[1], "description": a[2]}
|
|
for a in elem.attributes
|
|
]
|
|
|
|
if elem.raises:
|
|
elem_data["raises"] = [
|
|
{"type": r[0], "description": r[1]} for r in elem.raises
|
|
]
|
|
|
|
if elem.examples:
|
|
elem_data["examples"] = elem.examples
|
|
|
|
if elem.decorators:
|
|
elem_data["decorators"] = elem.decorators
|
|
|
|
data["elements"].append(elem_data)
|
|
|
|
return json.dumps(data, indent=2)
|