campus-Me / src /document_engine /latex_generator.py
Mithun-999's picture
Complete AI Academic Document Suite
342973b
"""
LaTeX Generator - Generate LaTeX documents
"""
from typing import Dict, List, Optional
from datetime import datetime
class LaTeXGenerator:
"""
Generate LaTeX documents for advanced academic formatting.
"""
def __init__(self):
"""Initialize LaTeX generator."""
pass
def generate_latex(
self,
title: str,
content: Dict[str, str],
author: str = "AI Academic Suite",
include_toc: bool = True,
include_citations: bool = False,
citations: List[str] = None,
document_class: str = "article",
) -> str:
"""
Generate LaTeX 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
document_class: LaTeX document class (article, report, book)
Returns:
LaTeX string
"""
latex_parts = []
# Document header
latex_parts.append(f"\\documentclass{{{document_class}}}")
latex_parts.append("\\usepackage[utf-8]{inputenc}")
latex_parts.append("\\usepackage{babel}")
latex_parts.append("\\usepackage{graphicx}")
latex_parts.append("\\usepackage{hyperref}")
latex_parts.append("\\usepackage{amsmath}")
latex_parts.append("\\usepackage{cite}")
# Document metadata
latex_parts.append(f"\\title{{{title}}}")
latex_parts.append(f"\\author{{{author}}}")
latex_parts.append(f"\\date{{{datetime.now().strftime('%B %d, %Y')}}}")
# Begin document
latex_parts.append("\\begin{document}")
latex_parts.append("\\maketitle")
# Table of contents
if include_toc:
latex_parts.append("\\tableofcontents")
latex_parts.append("\\newpage")
# Sections
for section_title, section_content in content.items():
latex_parts.append(f"\\section{{{section_title}}}")
latex_parts.append(self._sanitize_latex(section_content))
latex_parts.append("")
# Bibliography
if include_citations and citations:
latex_parts.append("\\begin{thebibliography}{99}")
for citation in citations:
latex_parts.append(f"\\bibitem{{ref}} {self._sanitize_latex(citation)}")
latex_parts.append("\\end{thebibliography}")
# End document
latex_parts.append("\\end{document}")
return "\n".join(latex_parts)
def generate_latex_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,
document_class: str = "article",
) -> bytes:
"""
Generate LaTeX 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
document_class: LaTeX document class
Returns:
LaTeX bytes
"""
latex = self.generate_latex(
title, content, author, include_toc, include_citations, citations, document_class
)
return latex.encode("utf-8")
def _sanitize_latex(self, text: str) -> str:
"""
Sanitize text for LaTeX special characters.
Args:
text: Text to sanitize
Returns:
Sanitized text
"""
# Escape special LaTeX characters
special_chars = {
"\\": "\\textbackslash{}",
"&": "\\&",
"%": "\\%",
"$": "\\$",
"#": "\\#",
"_": "\\_",
"{": "\\{",
"}": "\\}",
"~": "\\textasciitilde{}",
"^": "\\textasciicircum{}",
}
for char, escape in special_chars.items():
text = text.replace(char, escape)
return text
def create_latex_table(self, headers: List[str], rows: List[List[str]]) -> str:
"""
Create LaTeX table.
Args:
headers: Table headers
rows: Table rows
Returns:
LaTeX table string
"""
num_cols = len(headers)
col_spec = "c" * num_cols
latex_table = f"\\begin{{tabular}}{{{col_spec}}}\n"
latex_table += " & ".join(headers) + " \\\\\n"
latex_table += "\\hline\n"
for row in rows:
latex_table += " & ".join(self._sanitize_latex(str(cell)) for cell in row) + " \\\\\n"
latex_table += "\\end{tabular}"
return latex_table
def create_latex_figure(
self, image_path: str, caption: str = "", label: str = "fig:1", width: str = "0.8"
) -> str:
"""
Create LaTeX figure environment.
Args:
image_path: Path to image file
caption: Figure caption
label: Figure label for referencing
width: Figure width (as fraction of textwidth)
Returns:
LaTeX figure string
"""
latex_fig = f"""
\\begin{{figure}}[h]
\\centering
\\includegraphics[width={width}\\textwidth]{{{image_path}}}
\\caption{{{caption}}}
\\label{{{label}}}
\\end{{figure}}
"""
return latex_fig
def create_latex_equation(self, equation: str, label: str = "eq:1") -> str:
"""
Create LaTeX equation.
Args:
equation: Mathematical equation
label: Equation label for referencing
Returns:
LaTeX equation string
"""
return f"""
\\begin{{equation}}
{equation}
\\label{{{label}}}
\\end{{equation}}
"""
def create_latex_section(self, title: str, content: str, subsections: Optional[Dict] = None) -> str:
"""
Create LaTeX section with optional subsections.
Args:
title: Section title
content: Section content
subsections: Dictionary of subsection titles and content
Returns:
LaTeX section string
"""
latex = f"\\section{{{title}}}\n{content}\n"
if subsections:
for sub_title, sub_content in subsections.items():
latex += f"\\subsection{{{sub_title}}}\n{sub_content}\n"
return latex
def compile_to_pdf(self, latex_content: str, output_path: str) -> bool:
"""
Compile LaTeX to PDF (requires pdflatex installed).
Args:
latex_content: LaTeX document content
output_path: Output PDF file path
Returns:
Success status
"""
try:
import subprocess
import tempfile
import os
# Create temporary tex file
with tempfile.NamedTemporaryFile(mode="w", suffix=".tex", delete=False) as f:
f.write(latex_content)
tex_file = f.name
try:
# Compile LaTeX to PDF
subprocess.run(
["pdflatex", "-interaction=nonstopmode", "-output-directory", os.path.dirname(output_path), tex_file],
check=True,
capture_output=True,
)
return True
finally:
# Clean up temporary file
os.unlink(tex_file)
except:
return False