use crate::ast::LatexNode;
pub fn generate_html(node: &LatexNode) -> String {
match node {
LatexNode::Document { preamble: _, body } => {
let content = body.iter().map(generate_html).collect::<Vec<_>>().join("\n");
format!("<html><body>{}</body></html>", content)
}
LatexNode::Section(title) => format!("<h1>{}</h1>", title),
LatexNode::Subsection(title) => format!("<h2>{}</h2>", title),
LatexNode::Subsubsection(title) => format!("<h3>{}</h3>", title),
LatexNode::Paragraph(title) => format!("<h4>{}</h4>" , title),
LatexNode::Subparagraph(title) => format!("<h5>{}</h5>", title),
LatexNode::Text(text) => text.clone(),
LatexNode::Bold(text) => format!("<b>{}</b>", text),
LatexNode::Italic(text) => format!("<i>{}</i>", text),
LatexNode::Underline(text) => format!("<u>{}</u>", text),
LatexNode::Emphasized(text) => format!("<em>{}</em>", text),
LatexNode::Colored { color, content } => format!("<span style=\"color:{}\">{}</span>", color, content),
LatexNode::FontSize { size, content } => format!("<span style=\"font-size:{}\">{}</span>", size, content),
LatexNode::InlineMath(expr) => format!("<span class=\"math-inline\">{}</span>", expr),
LatexNode::DisplayMath(expr) => format!("<div class=\"math-display\">{}</div>", expr),
LatexNode::MathEnvironment { name, content } => format!("<div class=\"math-env\" data-env=\"{}\">{}</div>", name, content),
LatexNode::Itemize(items) => {
let content = items.iter().map(generate_html).collect::<Vec<_>>().join("");
format!("<ul>{}</ul>", content)
}
LatexNode::Enumerate(items) => {
let content = items.iter().map(generate_html).collect::<Vec<_>>().join("");
format!("<ol>{}</ol>", content)
}
LatexNode::Description(pairs) => {
let items = pairs.iter().map(|(k, v)| format!("<dt>{}</dt><dd>{}</dd>", k, v)).collect::<Vec<_>>().join("");
format!("<dl>{}</dl>", items)
}
LatexNode::ListItem(item) => format!("<li>{}</li>", item),
LatexNode::Table { alignment: _, rows, caption } => {
let body = rows.iter().map(|row| {
let cols = row.iter().map(|c| format!("<td>{}</td>", c)).collect::<Vec<_>>().join("");
format!("<tr>{}</tr>", cols)
}).collect::<Vec<_>>().join("");
let caption_html = caption.as_ref().map(|c| format!("<caption>{}</caption>", c)).unwrap_or_default();
format!("<table>{}{}</table>", caption_html, body)
}
LatexNode::Image { path, width, height, caption } => {
let mut attrs = format!("src=\"{}\"", path);
if let Some(w) = width { attrs += &format!(" width=\"{}\"", w); }
if let Some(h) = height { attrs += &format!(" height=\"{}\"", h); }
let img_tag = format!("<img {} />", attrs);
if let Some(c) = caption {
format!("<figure>{}<figcaption>{}</figcaption></figure>", img_tag, c)
} else {
img_tag
}
}
LatexNode::Figure { content, caption } => {
let inner = content.iter().map(generate_html).collect::<Vec<_>>().join("");
let cap = caption.as_ref().map(|c| format!("<figcaption>{}</figcaption>", c)).unwrap_or_default();
format!("<figure>{}{}</figure>", inner, cap)
}
LatexNode::Hyperlink { url, text } => format!("<a href=\"{}\">{}</a>", url, text),
LatexNode::Footnote(text) => format!("<sup class=\"footnote\">{}</sup>", text),
LatexNode::Label(label) => format!("<span id=\"{}\"></span>", label),
LatexNode::Ref(reference) => format!("<a href=\"#{}\">[ref]</a>", reference),
LatexNode::Cite(key) => format!("<span class=\"citation\">[{}]</span>", key),
LatexNode::Bibliography { style: _, items } => {
let list = items.iter().map(generate_html).collect::<Vec<_>>().join("");
format!("<div class=\"bibliography\">{}</div>", list)
}
LatexNode::BibItem { key, content } => {
let inner = content.iter().map(generate_html).collect::<Vec<_>>().join("");
format!("<div id=\"bib-{}\">{}</div>", key, inner)
}
LatexNode::NewCommand { name, args, definition } => format!("<!-- newcommand: {}({}) = {} -->", name, args, definition),
LatexNode::RenewCommand { name, args, definition } => format!("<!-- renewcommand: {}({}) = {} -->", name, args, definition),
LatexNode::Environment { name, content } => {
let inner = content.iter().map(generate_html).collect::<Vec<_>>().join("");
format!("<div class=\"env-{}\">{}</div>", name, inner)
}
LatexNode::HorizontalRule => "<hr />".to_string(),
LatexNode::PageBreak => "<div style=\"page-break-after: always;\"></div>".to_string(),
LatexNode::TableOfContents => "<!-- Table of contents would be generated here -->".to_string(),
LatexNode::RawLatex(raw) => format!("<!-- Raw LaTeX: {} -->", raw),
}
}