diff --git a/default_environment/stylesheet/main.css b/default_environment/stylesheet/main.css new file mode 100644 index 0000000..e69de29 diff --git a/default_environment/stylesheet/reset.css b/default_environment/stylesheet/reset.css new file mode 100644 index 0000000..ed11813 --- /dev/null +++ b/default_environment/stylesheet/reset.css @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/src/command/build/mod.rs b/src/command/build/mod.rs index 8edcb15..b1b161e 100644 --- a/src/command/build/mod.rs +++ b/src/command/build/mod.rs @@ -1,4 +1,5 @@ mod render; mod runner; +mod stylesheet; pub(crate) use runner::build_site; diff --git a/src/command/build/render.rs b/src/command/build/render.rs index 853028a..4420ddc 100644 --- a/src/command/build/render.rs +++ b/src/command/build/render.rs @@ -11,23 +11,29 @@ use crate::intermediate::BlogPost; use crate::render::DusterRenderer; use crate::render::RendererIntegration; +use super::stylesheet::Stylesheet; + static MAIN_TEMPLATES: Dir = include_dir!("$CARGO_MANIFEST_DIR/default_environment/templates/html"); pub(crate) struct SiteRenderer { output_directory: PathBuf, blog_posts: Vec, + stylesheets: Vec, } impl SiteRenderer { pub(crate) fn new>( output_directory: P, blog_posts: Vec, + stylesheets: Vec, ) -> SiteRenderer { SiteRenderer { output_directory: output_directory.into(), blog_posts, + stylesheets, } } + pub(crate) async fn render_blog_posts(&self, config: &Config) -> Result<(), CustomError> { let mut renderer_integration = DusterRenderer::new(); @@ -82,6 +88,22 @@ impl SiteRenderer { Ok(()) } + + pub(crate) async fn render_stylesheets(&self) -> Result<(), CustomError> { + let stylesheet_output_directory = self.output_directory.join("stylesheet"); + if !stylesheet_output_directory.exists() { + tokio::fs::create_dir(&stylesheet_output_directory).await?; + } + for stylesheet in &self.stylesheets { + let file_output_path = stylesheet_output_directory.join(&stylesheet.path); + let parent_directory = file_output_path + .parent() + .ok_or("Output file should have a containing directory.")?; + tokio::fs::create_dir_all(parent_directory).await?; + tokio::fs::write(file_output_path, stylesheet.contents.as_bytes()).await?; + } + Ok(()) + } } fn build_name_contents_pairs<'a>( diff --git a/src/command/build/runner.rs b/src/command/build/runner.rs index 13dc846..f41cf74 100644 --- a/src/command/build/runner.rs +++ b/src/command/build/runner.rs @@ -1,16 +1,29 @@ +use std::ffi::OsStr; use std::path::PathBuf; +use super::stylesheet::Stylesheet; use crate::cli::parameters::BuildArgs; use crate::command::build::render::SiteRenderer; use crate::config::Config; use crate::error::CustomError; use crate::intermediate::BlogPost; +use include_dir::include_dir; +use include_dir::Dir; + +static DEFAULT_STYLESHEETS: Dir = + include_dir!("$CARGO_MANIFEST_DIR/default_environment/stylesheet"); pub(crate) async fn build_site(args: BuildArgs) -> Result<(), CustomError> { let config = Config::load_from_file(args.config).await?; let blog_posts = load_blog_posts(&config).await?; - let renderer = SiteRenderer::new(get_output_directory(&config).await?, blog_posts); + let stylesheets = load_stylesheets().await?; + let renderer = SiteRenderer::new( + get_output_directory(&config).await?, + blog_posts, + stylesheets, + ); renderer.render_blog_posts(&config).await?; + renderer.render_stylesheets().await?; Ok(()) } @@ -58,3 +71,18 @@ async fn load_blog_posts(config: &Config) -> Result, CustomError> } Ok(blog_posts) } + +async fn load_stylesheets() -> Result, CustomError> { + let sources: Vec<_> = DEFAULT_STYLESHEETS + .files() + .filter(|f| f.path().extension() == Some(OsStr::new("css"))) + .collect(); + let mut ret = Vec::with_capacity(sources.len()); + for entry in sources { + let path = entry.path().to_path_buf(); + let contents = String::from_utf8(entry.contents().to_vec())?; + let stylesheet = Stylesheet::new(path, contents).await?; + ret.push(stylesheet); + } + Ok(ret) +} diff --git a/src/command/build/stylesheet.rs b/src/command/build/stylesheet.rs new file mode 100644 index 0000000..1c2fab5 --- /dev/null +++ b/src/command/build/stylesheet.rs @@ -0,0 +1,15 @@ +use std::path::PathBuf; + +use crate::error::CustomError; + +#[derive(Debug)] +pub(crate) struct Stylesheet { + pub(crate) path: PathBuf, + pub(crate) contents: String, +} + +impl Stylesheet { + pub(crate) async fn new(path: PathBuf, contents: String) -> Result { + Ok(Stylesheet { path, contents }) + } +} diff --git a/src/intermediate/convert.rs b/src/intermediate/convert.rs index 6bdb654..747fce8 100644 --- a/src/intermediate/convert.rs +++ b/src/intermediate/convert.rs @@ -21,12 +21,15 @@ pub(crate) fn convert_blog_post_page_to_render_context, F: AsRef< ) -> Result { let output_directory = output_directory.as_ref(); let output_file = output_file.as_ref(); - let css_files = vec![get_web_path( - config, - output_directory, - output_file, - "main.css", - )?]; + let css_files = vec![ + get_web_path( + config, + output_directory, + output_file, + "stylesheet/reset.css", + )?, + get_web_path(config, output_directory, output_file, "stylesheet/main.css")?, + ]; let js_files = vec![get_web_path( config, output_directory,