""" HTML Generator - Generate HTML documents """ from typing import Dict, List, Optional from datetime import datetime class HTMLGenerator: """ Generate HTML documents with CSS styling. """ def __init__(self): """Initialize HTML generator.""" self.default_css = self._get_default_css() def generate_html( self, title: str, content: Dict[str, str], author: str = "AI Academic Suite", include_toc: bool = True, include_citations: bool = False, citations: List[str] = None, custom_css: Optional[str] = None, ) -> str: """ Generate HTML document. Args: title: Document title content: Dictionary of section titles and content author: Document author include_toc: Include table of contents include_citations: Include bibliography citations: List of citations custom_css: Custom CSS styles Returns: HTML string """ html_parts = [] # HTML header html_parts.append("") html_parts.append("") html_parts.append("") html_parts.append("") html_parts.append("") html_parts.append(f"{title}") # Add CSS css = custom_css if custom_css else self.default_css html_parts.append(f"") html_parts.append("") html_parts.append("") # Title page html_parts.append("
") html_parts.append(f"

{title}

") html_parts.append(f"

By {author}

") html_parts.append(f"

{datetime.now().strftime('%B %d, %Y')}

") html_parts.append("
") # Table of contents if include_toc: html_parts.append("") html_parts.append("
") # Main content html_parts.append("
") for section_title, section_content in content.items(): anchor = section_title.lower().replace(" ", "-") html_parts.append(f"
") html_parts.append(f"

{section_title}

") # Convert paragraph breaks for para in section_content.split("\n\n"): if para.strip(): html_parts.append(f"

{para}

") html_parts.append("
") html_parts.append("
") # Bibliography if include_citations and citations: html_parts.append("") html_parts.append("") html_parts.append("") return "\n".join(html_parts) def generate_html_bytes( self, title: str, content: Dict[str, str], author: str = "AI Academic Suite", include_toc: bool = True, include_citations: bool = False, citations: List[str] = None, custom_css: Optional[str] = None, ) -> bytes: """ Generate HTML as bytes. Args: title: Document title content: Dictionary of section titles and content author: Document author include_toc: Include table of contents include_citations: Include bibliography citations: List of citations custom_css: Custom CSS styles Returns: HTML bytes """ html = self.generate_html( title, content, author, include_toc, include_citations, citations, custom_css ) return html.encode("utf-8") def _get_default_css(self) -> str: """Get default CSS styling.""" return """ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Calibri', 'Arial', sans-serif; line-height: 1.6; color: #333; background-color: #fff; max-width: 900px; margin: 0 auto; padding: 40px; } header { text-align: center; margin-bottom: 40px; border-bottom: 2px solid #333; padding-bottom: 20px; } header h1 { font-size: 2.5em; margin-bottom: 10px; } .author { font-size: 1.1em; font-weight: bold; } .date { color: #666; font-style: italic; } nav.toc { background-color: #f5f5f5; padding: 20px; margin: 20px 0; border-left: 4px solid #007bff; } nav.toc h2 { margin-bottom: 15px; } nav.toc ul { list-style-position: inside; } nav.toc a { color: #007bff; text-decoration: none; } nav.toc a:hover { text-decoration: underline; } main { margin: 40px 0; } section { margin-bottom: 30px; } h2 { font-size: 1.8em; margin-top: 30px; margin-bottom: 15px; color: #222; border-bottom: 1px solid #ddd; padding-bottom: 10px; } h3 { font-size: 1.3em; margin-top: 20px; margin-bottom: 10px; } p { margin-bottom: 15px; text-align: justify; } hr { margin: 30px 0; border: none; border-top: 1px solid #ddd; } footer { margin-top: 40px; border-top: 2px solid #333; padding-top: 20px; } footer h2 { font-size: 1.5em; } .references { margin-left: 30px; line-height: 1.8; } .references li { margin-bottom: 10px; } code { background-color: #f4f4f4; padding: 2px 6px; border-radius: 3px; font-family: 'Courier New', monospace; } pre { background-color: #f4f4f4; padding: 15px; border-radius: 5px; overflow-x: auto; margin: 15px 0; } pre code { background-color: transparent; padding: 0; } blockquote { border-left: 4px solid #007bff; padding-left: 15px; margin: 15px 0; font-style: italic; color: #555; } table { width: 100%; border-collapse: collapse; margin: 20px 0; } table th, table td { border: 1px solid #ddd; padding: 12px; text-align: left; } table th { background-color: #f4f4f4; font-weight: bold; } table tr:nth-child(even) { background-color: #f9f9f9; } @media print { body { padding: 0; } nav.toc { page-break-after: always; } } """ def create_html_table(self, headers: List[str], rows: List[List[str]]) -> str: """ Create HTML table. Args: headers: Table headers rows: Table rows Returns: HTML table string """ html = "\n\n\n" for header in headers: html += f"\n" html += "\n\n\n" for row in rows: html += "\n" for cell in row: html += f"\n" html += "\n" html += "\n
{header}
{cell}
" return html def create_responsive_layout(self, left_content: str, right_content: str) -> str: """ Create responsive two-column layout. Args: left_content: Left column HTML right_content: Right column HTML Returns: HTML with two-column layout """ layout_css = """ """ return f""" {layout_css}
{left_content}
{right_content}
"""