rearrange things a bit

This commit is contained in:
liquidex 2023-08-18 21:19:31 +02:00
parent 63dd2fa5ab
commit 27414d4254
6 changed files with 251 additions and 1153 deletions

1182
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -6,15 +6,15 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.75" anyhow = "1.0.75"
axum = "0.6.20" axum = "0.6.20"
clap = { version = "4.3.22", features = ["derive"] }
codespan-reporting = "0.11.1" codespan-reporting = "0.11.1"
copy_dir = "0.1.3" copy_dir = "0.1.3"
handlebars = "4.3.7" handlebars = "4.3.7"
pulldown-cmark = { version = "0.9.3", default-features = false } pulldown-cmark = { version = "0.9.3", default-features = false }
serde = { version = "1.0.183", features = ["derive"] } serde = { version = "1.0.183", features = ["derive"] }
thiserror = "1.0.47" tokio = { version = "1.32.0", features = ["full"] }
tokio = "1.32.0"
tower-http = { version = "0.4.3", features = ["fs"] } tower-http = { version = "0.4.3", features = ["fs"] }
tower-livereload = "0.8.0" tower-livereload = "0.8.0"
treehouse-format = { workspace = true }
watchexec = "2.3.0" treehouse-format = { workspace = true }

View file

@ -0,0 +1,22 @@
pub mod regenerate;
use clap::{Args, Parser, Subcommand};
#[derive(Parser)]
pub struct ProgramArgs {
#[clap(subcommand)]
pub command: Command,
}
#[derive(Subcommand)]
pub enum Command {
/// Regenerate the website.
Regenerate(#[clap(flatten)] RegenerateArgs),
}
#[derive(Args)]
pub struct RegenerateArgs {
/// Start a web server serving the static files. Useful with `cargo watch`.
#[clap(short, long)]
pub serve: bool,
}

View file

@ -0,0 +1,87 @@
use axum::Router;
use codespan_reporting::{
diagnostic::{Diagnostic, Label, LabelStyle, Severity},
files::SimpleFile,
term::termcolor::{ColorChoice, StandardStream},
};
use copy_dir::copy_dir;
use handlebars::Handlebars;
use serde::Serialize;
use tower_http::services::ServeDir;
use tower_livereload::LiveReloadLayer;
use treehouse_format::ast::Roots;
use crate::html::tree::branches_to_html;
#[derive(Serialize)]
pub struct TemplateData {
pub tree: String,
}
pub fn regenerate() -> anyhow::Result<()> {
let _ = std::fs::remove_dir_all("target/site");
std::fs::create_dir_all("target/site")?;
copy_dir("static", "target/site/static")?;
let mut handlebars = Handlebars::new();
handlebars.register_template_file("template/index.hbs", "template/index.hbs")?;
let root_file = std::fs::read_to_string("content/tree/index.tree")?;
let parse_result = Roots::parse(&mut treehouse_format::pull::Parser {
input: &root_file,
position: 0,
});
match parse_result {
Ok(roots) => {
let mut tree = String::new();
branches_to_html(&mut tree, &roots.branches, &root_file);
let index_html = handlebars.render("template/index.hbs", &TemplateData { tree })?;
std::fs::write("target/site/index.html", index_html)?;
}
Err(error) => {
let writer = StandardStream::stderr(ColorChoice::Auto);
let config = codespan_reporting::term::Config::default();
let files = SimpleFile::new("index.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)?;
}
}
Ok(())
}
pub fn regenerate_or_report_error() {
eprintln!("regenerating");
match regenerate() {
Ok(_) => (),
Err(error) => eprintln!("error: {error:?}"),
}
}
pub async fn web_server() -> anyhow::Result<()> {
let app = Router::new().nest_service("/", ServeDir::new("target/site"));
#[cfg(debug_assertions)]
let app = app.layer(LiveReloadLayer::new());
eprintln!("serving on port 8080");
Ok(axum::Server::bind(&([0, 0, 0, 0], 8080).into())
.serve(app.into_make_service())
.await?)
}

View file

@ -1,95 +1,24 @@
use clap::Parser;
use cli::{
regenerate::{self, regenerate_or_report_error},
Command, ProgramArgs,
};
mod cli;
mod html; mod html;
use axum::Router;
use codespan_reporting::{
diagnostic::{Diagnostic, Label, LabelStyle, Severity},
files::SimpleFile,
term::termcolor::{ColorChoice, StandardStream},
};
use copy_dir::copy_dir;
use handlebars::Handlebars;
use html::tree::branches_to_html;
use serde::Serialize;
use tower_http::services::ServeDir;
use tower_livereload::LiveReloadLayer;
use treehouse_format::{ast::Roots, pull::Parser};
#[derive(Serialize)]
pub struct TemplateData {
pub tree: String,
}
fn regenerate() -> anyhow::Result<()> {
let _ = std::fs::remove_dir_all("target/site");
std::fs::create_dir_all("target/site")?;
copy_dir("static", "target/site/static")?;
let mut handlebars = Handlebars::new();
handlebars.register_template_file("template/index.hbs", "template/index.hbs")?;
let root_file = std::fs::read_to_string("content/tree/root.tree")?;
let parse_result = Roots::parse(&mut Parser {
input: &root_file,
position: 0,
});
match parse_result {
Ok(roots) => {
let mut tree = String::new();
branches_to_html(&mut tree, &roots.branches, &root_file);
let index_html = handlebars.render("template/index.hbs", &TemplateData { tree })?;
std::fs::write("target/site/index.html", index_html)?;
}
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)?;
}
}
Ok(())
}
fn regenerate_or_report_error() {
eprintln!("regenerating");
match regenerate() {
Ok(_) => (),
Err(error) => eprintln!("error: {error:?}"),
}
}
async fn web_server() -> anyhow::Result<()> {
let app = Router::new().nest_service("/", ServeDir::new("target/site"));
#[cfg(debug_assertions)]
let app = app.layer(LiveReloadLayer::new());
Ok(axum::Server::bind(&([0, 0, 0, 0], 8080).into())
.serve(app.into_make_service())
.await?)
}
async fn fallible_main() -> anyhow::Result<()> { async fn fallible_main() -> anyhow::Result<()> {
let args = ProgramArgs::parse();
match args.command {
Command::Regenerate(regenerate_args) => {
regenerate_or_report_error(); regenerate_or_report_error();
web_server().await?; if regenerate_args.serve {
regenerate::web_server().await?;
}
}
}
Ok(()) Ok(())
} }