diff --git a/src/config.rs b/src/config.rs index fa5319f..0999b10 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,6 +13,7 @@ pub struct Config { pub struct Folders { pub content: Option, pub templates: Option, + pub stylesheets: Option, pub output: Option, } diff --git a/src/context.rs b/src/context.rs new file mode 100644 index 0000000..13d16bc --- /dev/null +++ b/src/context.rs @@ -0,0 +1,8 @@ +use std::path::PathBuf; + +pub struct Context { + pub content_dir: PathBuf, + pub template_dir: PathBuf, + pub stylesheet_dir: PathBuf, + pub output_dir: PathBuf, +} diff --git a/src/main.rs b/src/main.rs index 4f62e0a..8d8a674 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,12 @@ +use std::{ + path::{Path, PathBuf}, + sync::Arc, +}; + use args::BuildArgs; use clap::Parser; use config::{read_config, Config}; +use context::Context; use data::DirLoader; use miette::Result; use rendering::ContentRenderer; @@ -11,6 +17,7 @@ use crate::args::Args; mod args; mod config; +mod context; pub mod data; mod processors; mod rendering; @@ -29,24 +36,33 @@ async fn main() -> Result<()> { } async fn build(args: &Args, _build_args: &BuildArgs, cfg: Config) -> Result<()> { - let folders = cfg.folders; let base_path = &args.directory; - let content_dir = base_path.join(folders.content.unwrap_or("content".into())); - let template_dir = base_path.join(folders.templates.unwrap_or("templates".into())); - let out_dir = base_path.join(folders.output.unwrap_or("dist".into())); + let ctx = Arc::new(build_context(&base_path, &cfg)); - let dirs = DirLoader::new(content_dir.to_owned()) + let dirs = DirLoader::new(ctx.content_dir.to_owned()) .read_content() .await?; - let template_glob = format!("{}/**/*", template_dir.to_string_lossy()); - ContentRenderer::new(template_glob, content_dir, out_dir) - .render_all(dirs) - .await?; + ContentRenderer::new(ctx).render_all(dirs).await?; Ok(()) } +fn build_context(base_path: &Path, config: &Config) -> Context { + let folders = config.folders.clone(); + let content_dir = base_path.join(folders.content.unwrap_or("content".into())); + let template_dir = base_path.join(folders.templates.unwrap_or("templates".into())); + let output_dir = base_path.join(folders.output.unwrap_or("dist".into())); + let stylesheet_dir = base_path.join(folders.stylesheets.unwrap_or("style".into())); + + Context { + content_dir, + template_dir, + stylesheet_dir, + output_dir, + } +} + fn init_tracing() { tracing_subscriber::fmt::SubscriberBuilder::default() .with_max_level(LevelFilter::TRACE) diff --git a/src/rendering/mod.rs b/src/rendering/mod.rs index 8537679..d73d29c 100644 --- a/src/rendering/mod.rs +++ b/src/rendering/mod.rs @@ -1,32 +1,33 @@ -use std::path::PathBuf; +use std::{path::PathBuf, sync::Arc}; use futures::future; use miette::{IntoDiagnostic, Result}; -use tera::{Context, Tera}; +use tera::{Context as TeraContext, Tera}; use tokio::fs; -use crate::data::{load_page, FolderData}; +use crate::{ + context::Context, + data::{load_page, FolderData}, +}; // renders content using the given template folder pub struct ContentRenderer { template_glob: String, - out_dir: PathBuf, - content_dir: PathBuf, + ctx: Arc, } impl ContentRenderer { - pub fn new(template_glob: String, content_dir: PathBuf, out_dir: PathBuf) -> Self { - Self { - template_glob, - content_dir, - out_dir, - } + pub fn new(ctx: Arc) -> Self { + let template_glob = format!("{}/**/*", ctx.template_dir.to_string_lossy()); + Self { template_glob, ctx } } #[tracing::instrument(level = "trace", skip_all)] pub async fn render_all(&self, dirs: Vec) -> Result<()> { - if self.out_dir.exists() { - fs::remove_dir_all(&self.out_dir).await.into_diagnostic()?; + if self.ctx.output_dir.exists() { + fs::remove_dir_all(&self.ctx.output_dir) + .await + .into_diagnostic()?; } let mut tera = Tera::new(&self.template_glob).into_diagnostic()?; super::processors::register_all(&mut tera); @@ -70,7 +71,7 @@ impl ContentRenderer { tracing::debug!("Rendering {page_path:?}"); let page = load_page(&page_path).await?; - let mut context = Context::new(); + let mut context = TeraContext::new(); let mut template_name = default_template; match page { @@ -87,9 +88,9 @@ impl ContentRenderer { let html = tera.render(&template_name, &context).into_diagnostic()?; let rel_path = page_path - .strip_prefix(&self.content_dir) + .strip_prefix(&self.ctx.content_dir) .into_diagnostic()?; - let mut out_path = self.out_dir.join(rel_path); + let mut out_path = self.ctx.output_dir.join(rel_path); out_path.set_extension("html"); let parent = out_path.parent().unwrap();