"""
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("")
# 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"| {header} | \n"
html += "
\n\n\n"
for row in rows:
html += "\n"
for cell in row:
html += f"| {cell} | \n"
html += "
\n"
html += "\n
"
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}
"""