use anyhow::{Context, Result};
use tree_sitter::Parser;
use tree_sitter_askama::LANGUAGE as ASKAMA_LANGUAGE;
use tree_sitter_html::LANGUAGE as HTML_LANGUAGE;
use crate::{askama, config::Config, html, sakura_tree::SakuraTree, wire, woodcut};
pub struct AskamaFormatter {
askama_parser: Parser,
html_parser: Parser,
config: Config,
}
impl Default for AskamaFormatter {
fn default() -> Self {
Self::new().expect("Failed to initialize kirei")
}
}
impl AskamaFormatter {
pub fn new() -> Result<Self> {
let mut askama_parser = Parser::new();
askama_parser
.set_language(&ASKAMA_LANGUAGE.into())
.context("Failed to set Askama language")?;
let mut html_parser = Parser::new();
html_parser
.set_language(&HTML_LANGUAGE.into())
.context("Failed to set HTML language")?;
Ok(Self {
askama_parser,
html_parser,
config: Config::default(),
})
}
pub fn format(&mut self, source: &str) -> Result<String> {
let ast_tree = self
.askama_parser
.parse(source, None)
.context("Failed to parse Askama")?;
let (html, askama_nodes) = askama::extract_nodes(source, &ast_tree.root_node())
.context("Failed to extract Askama nodes")?;
let html_tree = self
.html_parser
.parse(&html, None)
.context("Failed to parse HTML")?;
let html_nodes = html::parse_html_tree(&html_tree.root_node(), html.as_bytes())
.context("Failed to extract HTML nodes")?;
let mut sakura_tree = SakuraTree::grow(&askama_nodes, &html_nodes, self.config.clone());
wire::wire(&mut sakura_tree);
Ok(woodcut::print(&sakura_tree))
}
}