From 0cf1329e95fde8cd3259cb435d2de798d8d5c83e Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Thu, 29 Jan 2026 16:51:52 +0000 Subject: [PATCH] Add generators and parsers modules --- .../generators/markdown_generator.py | 232 ++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 .code_doc_cli/generators/markdown_generator.py diff --git a/.code_doc_cli/generators/markdown_generator.py b/.code_doc_cli/generators/markdown_generator.py new file mode 100644 index 0000000..8228210 --- /dev/null +++ b/.code_doc_cli/generators/markdown_generator.py @@ -0,0 +1,232 @@ +"""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)