use pochoir_template_engine::TemplateBlock;
use crate::{Node, Tree, TreeRefId, EMPTY_HTML_ELEMENTS};
use std::fmt::Write;
pub fn render(tree: &Tree) -> String {
fn recursive(result: &mut String, tree: &Tree, node_id: TreeRefId) {
let node = tree.get(node_id);
match node.data() {
Node::Element(name, attrs) => {
write!(result, "<{name}").expect("writing to a String can't fail");
for (key, val) in attrs {
if val.is_empty() {
write!(result, " {}", **key).expect("writing to a String can't fail");
} else {
write!(
result,
" {}=\"{}\"",
**key,
val.iter()
.map(|b| {
match &**b {
TemplateBlock::RawText(t) => t.to_string(),
TemplateBlock::Expr(t, is_escaped) => format!(
"{{{}{t}{}}}",
if *is_escaped { "{" } else { "!" },
if *is_escaped { "}" } else { "!" }
),
TemplateBlock::Stmt(t) => format!("{{%{t}%}}"),
}
})
.collect::<String>()
)
.expect("writing to a String can't fail");
}
}
write!(result, ">").expect("writing to a String can't fail");
for node_id in node.children_id() {
recursive(result, tree, node_id);
}
if !EMPTY_HTML_ELEMENTS.contains(&&**name) {
write!(result, "</{name}>").expect("writing to a String can't fail");
}
}
Node::Doctype(doctype) => {
write!(result, "<!DOCTYPE {doctype}>").expect("writing to a String can't fail");
}
Node::TemplateBlock(TemplateBlock::RawText(text)) => {
write!(result, "{text}").expect("writing to a String can't fail");
}
Node::TemplateBlock(TemplateBlock::Expr(text, is_escaped)) => write!(
result,
"{{{}{text}{}}}",
if *is_escaped { "{" } else { "!" },
if *is_escaped { "}" } else { "!" }
)
.expect("writing to a String can't fail"),
Node::TemplateBlock(TemplateBlock::Stmt(text)) => {
write!(result, "{{%{text}%}}",).expect("writing to a String can't fail");
}
_ => (),
}
}
let mut result = String::new();
for node_id in tree.root_nodes() {
recursive(&mut result, tree, node_id);
}
result
}