"""Markdown formatter for code structure output."""
from typing import List
from ..models import AnalysisResult, CodeElement, CodeStructure, ParseError
class MarkdownFormatter:
"""Formats code structure as markdown for LLM consumption."""
SCHEMA = "Format: ### `Name` (Start-End, Nesting, [Parent]) | - Type | - [Parameters] | - [Return Type] | - [Docstring]"
def format_structure(self, structure: CodeStructure, include_schema: bool = True) -> str:
"""Format code structure as markdown."""
lines: List[str] = []
if include_schema:
lines.append(self.SCHEMA)
lines.append("")
# Minimal header: just the file path
lines.append(f"# `{structure.file_path}`")
# Classes
for cls in structure.classes:
lines.extend(self._format_element(cls))
# Functions (top-level)
for func in structure.functions:
lines.extend(self._format_element(func))
# Errors
if structure.errors:
lines.append("\n## Errors")
for error in structure.errors:
lines.append(f"⚠️ L{error.line}: {error.message}")
return "\n".join(lines).strip()
def _format_element(self, element: CodeElement, indent: int = 0) -> List[str]:
"""Format a class or function element."""
lines: List[str] = []
prefix = " " * indent
# Header: ### `Name` (Start-End, N:Nesting [, P:Parent])
parent_info = ""
if element.parent:
parent_info = f", P: `{element.parent.name}`"
lines.append(
f"\n{prefix}### `{element.name}` ({element.start_line}-{element.end_line}, N:{element.nesting_level}{parent_info})"
)
# Details with dashes
lines.append(f"{prefix}- {element.element_type.capitalize()}")
if element.parameters:
params = ", ".join(str(p) for p in element.parameters)
lines.append(f"{prefix}- ({params})")
if element.return_type:
lines.append(f"{prefix}- -> {element.return_type}")
if element.docstring:
# Keep docstring on one line for efficiency
doc = element.docstring.replace("\n", " ").strip()
lines.append(f"{prefix}- {doc}")
# Recurse children
for child in element.children:
lines.extend(self._format_element(child, indent + 1))
return lines
def format_multi_file_structure(self, results: List[AnalysisResult]) -> str:
"""Format multiple code structure results as markdown."""
lines: List[str] = []
lines.append(self.SCHEMA)
# Failures
failed = [r.file_path for r in results if not r.success]
if failed:
lines.append("\nFailed: " + ", ".join(failed))
# Successes
for i, result in enumerate(results):
if result.success:
lines.append("\n---")
lines.append(self.format_structure(result.structure, include_schema=False))
return "\n".join(lines).strip()