rewrite the parser to produce an AST

This commit is contained in:
りき萌 2023-08-18 13:25:20 +02:00
parent e69dcdc197
commit 0a185250da
13 changed files with 344 additions and 162 deletions

View file

@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
codespan-reporting = "0.11.1"
handlebars = "4.3.7"
pulldown-cmark = { version = "0.9.3", default-features = false }
thiserror = "1.0.47"

View file

@ -1,6 +1,12 @@
use tree_html::HtmlGenerator;
mod tree_html;
use codespan_reporting::{
diagnostic::{Diagnostic, Label, LabelStyle, Severity},
files::SimpleFile,
term::termcolor::{ColorChoice, StandardStream},
};
use treehouse_format::{
ast::{Branch, Roots},
pull::Parser,
};
#[derive(Debug, thiserror::Error)]
enum Error {
@ -11,35 +17,82 @@ enum Error {
Parse(#[from] treehouse_format::ParseError),
}
fn print_branch(branch: &Branch, source: &str) {
fn inner(branch: &Branch, source: &str, indent_level: usize) {
for _ in 0..indent_level {
print!(" ");
}
println!(
"{} {:?}",
branch.kind.char(),
&source[branch.content.clone()]
);
for child in &branch.children {
inner(child, source, indent_level + 1);
}
}
inner(branch, source, 0);
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let _ = std::fs::remove_dir_all("target/site");
std::fs::create_dir_all("target/site")?;
let root_file = std::fs::read_to_string("content/tree/root.tree")?;
let mut parser = treehouse_format::Parser {
let parse_result = Roots::parse(&mut Parser {
input: &root_file,
position: 0,
};
let mut generator = HtmlGenerator::default();
while let Some(branch) = parser.next_branch()? {
for _ in 0..branch.indent_level {
print!(" ");
});
match parse_result {
Ok(roots) => {
for root in &roots.branches {
print_branch(root, &root_file);
}
}
Err(error) => {
let writer = StandardStream::stderr(ColorChoice::Auto);
let config = codespan_reporting::term::Config::default();
let files = SimpleFile::new("root.tree", &root_file);
let diagnostic = Diagnostic {
severity: Severity::Error,
code: None,
message: error.kind.to_string(),
labels: vec![Label {
style: LabelStyle::Primary,
file_id: (),
range: error.range,
message: String::new(),
}],
notes: vec![],
};
codespan_reporting::term::emit(&mut writer.lock(), &config, &files, &diagnostic)?;
}
println!(
"{} {:?}",
branch.kind.char(),
&root_file[branch.content.clone()]
);
generator.add(&root_file, &branch);
}
std::fs::write(
"target/site/index.html",
format!(
"<!DOCTYPE html><html><head></head><body>{}</body></html>",
generator.finish()
),
)?;
// let mut parser = treehouse_format::Parser {
// input: &root_file,
// position: 0,
// };
// let mut generator = HtmlGenerator::default();
// while let Some(branch) = parser.next_branch()? {
// for _ in 0..branch.indent_level {
// print!(" ");
// }
// println!(
// "{} {:?}",
// branch.kind.char(),
// &root_file[branch.content.clone()]
// );
// generator.add(&root_file, &branch);
// }
// std::fs::write(
// "target/site/index.html",
// format!(
// "<!DOCTYPE html><html><head></head><body>{}</body></html>",
// generator.finish()
// ),
// )?;
Ok(())
}

View file

@ -1,30 +0,0 @@
use treehouse_format::Branch;
#[derive(Debug, Clone, Default)]
pub struct HtmlGenerator {
buffer: String,
indent_level_stack: Vec<usize>,
}
impl HtmlGenerator {
pub fn add(&mut self, source: &str, branch: &Branch) {
if Some(&branch.indent_level) > self.indent_level_stack.last() {
self.indent_level_stack.push(branch.indent_level);
self.buffer.push_str("<ul>");
}
while Some(&branch.indent_level) < self.indent_level_stack.last() {
self.indent_level_stack.pop();
self.buffer.push_str("</ul>");
}
self.buffer.push_str("<li>");
self.buffer.push_str(&source[branch.content.clone()]);
self.buffer.push_str("</li>");
}
pub fn finish(mut self) -> String {
for _ in self.indent_level_stack.drain(..) {
self.buffer.push_str("</ul>");
}
self.buffer
}
}