diff --git a/config.toml b/config.toml index acceb88..11df64b 100644 --- a/config.toml +++ b/config.toml @@ -4,13 +4,13 @@ built_pages = ["test_page.toml"] use_default_css = true javascript = [] css = [] -#favicon = "path.png" +#favicon = "favicon.png" #twitter_author = "@teascade" #google_robots = "all" #google_site_verification = "" [navbar] -items = ["home", "potato", "games"] +items = ["home", "games"] [navbar.item.home] title = "Home" diff --git a/public/css/default.css b/public/css/default.css deleted file mode 100644 index ce5581f..0000000 --- a/public/css/default.css +++ /dev/null @@ -1,141 +0,0 @@ -:root { - --color-main-bg: rgb(38, 40, 43); - - --color-navbar-bg: rgb(52, 52, 56); - --color-navbar-button: rgb(50, 50, 53); - --color-navbar-button-hover: rgb(43, 43, 46); - --color-navbar-button-focus: rgb(44, 44, 48); - --color-navbar-border-bottom: rgb(41, 41, 44); - - --color-content-bg: rgb(44, 44, 48); - --color-content-fg: rgb(164, 161, 172); - - --navbar-height: 3.5vw; - --navbar-width: 60%; - --navbar-padding-size: 0.5em; - --navbar-text-size: 24px; - - --content-width: 50%; - --content-text-size: 1.2em; - --content-top-padding: 2em; - --content-side-padding: 2em; - - --highlight-color: rgb(230, 134, 217); -} - -body, html { - width: 100%; - height: 100%; - padding: 0; - margin: 0; - font-family: Roboto, Helvetica, sans-serif; - background-color: var(--color-main-bg); -} - -#text { - width: 100%; - margin: 0; - padding: 0; -} - -/* Navbar styles */ - -nav { - width: 100%; - height: var(--navbar-height); - background-color: var(--color-navbar-bg); - border-bottom: solid 4px var(--color-navbar-border-bottom); -} - -nav ul { - height: 100%; - font-size: 0; - margin: 0; - padding: 0; - list-style-type: none; - width: var(--navbar-width); - margin-left: auto; - margin-right: auto; -} - -nav li { - height: 100%; - font-size: var(--navbar-text-size); - display: inline-block; - margin: 0; -} - -nav li a { - display: block; - height: 100%; - background-color: var(--color-navbar-button); - color: var(--highlight-color); - text-decoration: none; - padding-left: var(--navbar-padding-size); - padding-right: var(--navbar-padding-size); - transition: 0.15s; - border-left: solid 3px var(--color-navbar-button-hover); - position: relative; -} -nav li:not(.image) a { - display: flex; - justify-content: center; - flex-direction: column; -} - -nav li:first-child a { - border-left: solid 5px var(--color-navbar-button-hover); -} - -nav li:last-child a { - border-right: solid 5px var(--color-navbar-button-hover); -} - -nav ul a:hover { - background-color: var(--color-navbar-button-hover); -} - -nav ul a:focus { - outline: none; - background-color: var(--color-navbar-button-focus); -} - -/* Navbar images */ - -nav img { - height: var(--navbar-height); - vertical-align: top; - border: 50%; -} - -nav li.image { - position: relative; - bottom: calc(var(--navbar-height) / 4); - padding: 0; -} - -nav li.image a { - height: auto; -} - -/* Article styles */ - -article { - width: var(--content-width); - min-height: calc(100% - var(--navbar-height) - var(--content-top-padding) - 4px); - margin: auto; - padding-top: var(--content-top-padding); - padding-left: var(--content-side-padding); - padding-right: var(--content-side-padding); - background-color: var(--color-content-bg); - color: var(--color-content-fg); - font-size: var(--content-text-size); -} - -article > * { - margin: 0; -} - -article a { - color: var(--highlight-color); -} \ No newline at end of file diff --git a/public/img/teascade.png b/public/img/teascade.png deleted file mode 100644 index e263d2b..0000000 Binary files a/public/img/teascade.png and /dev/null differ diff --git a/public/test.html b/public/test.html deleted file mode 100644 index b07c191..0000000 --- a/public/test.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Test Page - - - - - - -
-

Test Header!

-

Some test content!

- -
- - - \ No newline at end of file diff --git a/src/builder.rs b/src/builder.rs new file mode 100644 index 0000000..072dbb2 --- /dev/null +++ b/src/builder.rs @@ -0,0 +1,90 @@ +use config::Config; +use template::Template; +use renderer; +use logger::{LogLevel, Logger}; +use error::Error; + +use std::fs::{create_dir_all, File}; +use std::io::prelude::*; +use std::path::Path; + +const DEFAULT_CSS: &'static str = include_str!("templates/default-css.css"); +const PAGE_TEMPLATE: &'static str = include_str!("templates/page-template.html"); +const NAVBAR_ITEM: &'static str = include_str!("templates/navbar/item-template.html"); +const NAVBAR_IMAGE_ITEM: &'static str = include_str!("templates/navbar/image-item-template.html"); + +fn fetch_config() -> Result { + match Config::new() { + Ok(config) => Ok(config), + Err(err) => Err(Error::from(err)), + } +} + +fn write_file, U: Into>(path_str: T, content: U) -> Result<(), Error> { + let path_str = path_str.into(); + let content = content.into(); + + let path = Path::new(&path_str); + if let Some(parent) = path.parent() { + create_dir_all(parent)?; + } else { + return Err(Error::new( + LogLevel::SEVERE, + format!("Could not find parent folder for {}", path_str), + )); + } + if path.exists() { + Err(Error::new( + LogLevel::SEVERE, + format!( + "File already exists: {} -- Consider using overwrite-flag", + path_str + ), + )) + } else { + match File::create(path) { + Ok(mut file) => Ok(file.write_all(content.as_bytes()).unwrap()), + Err(err) => Err(Error::from(err)), + } + } +} + +pub fn build(logger: &Logger) -> Result<(), Error> { + logger.log(LogLevel::INFO, "Starting build"); + let config = fetch_config()?; + + if config.global_config.website.use_default_css { + logger.log(LogLevel::DETAIL, "Adding public/css/default.css"); + write_file("public/css/default.css", DEFAULT_CSS)?; + } + + logger.log(LogLevel::INFO, "Generating page templates"); + let page_template = Template::new(PAGE_TEMPLATE); + + let mut navbar_content = String::new(); + if config.global_config.navbar.is_some() { + let navbar_item_template = Template::new(NAVBAR_ITEM); + let navbar_image_item_template = Template::new(NAVBAR_IMAGE_ITEM); + logger.log(LogLevel::DETAIL, "Rendering Navbar"); + navbar_content = + renderer::render_navbar(&config, navbar_item_template, navbar_image_item_template)?; + } + + logger.log(LogLevel::INFO, "Rendering"); + logger.log(LogLevel::DETAILER, "Rendering public/test.html"); + let rendered = match config.get_configs_for(0) { + Ok(page_config) => page_template.render(&Template::page_data_from( + page_config.clone(), + navbar_content, + renderer::render_markdown_content(&page_config).unwrap(), + )), + Err(err) => panic!(err), + }; + + logger.log(LogLevel::INFO, "Writing"); + logger.log(LogLevel::DETAILER, "Writing public/test.html"); + write_file("public/test.html", rendered)?; + + logger.log(LogLevel::INFO, "Done!"); + Ok(()) +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..2526042 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,36 @@ +use std::convert::From; +use std::io::Error as IOError; +use std::error::Error as STDError; + +use logger::LogLevel; + +pub struct Error { + description: String, + severity: LogLevel, +} + +impl Error { + pub fn new>(severity: LogLevel, description: T) -> Error { + Error { + severity, + description: description.into(), + } + } + + pub fn description(&self) -> String { + self.description.clone() + } + + pub fn severity(&self) -> LogLevel { + self.severity.clone() + } +} + +impl From for Error { + fn from(err: IOError) -> Error { + Error { + description: err.description().to_owned(), + severity: LogLevel::SEVERE, + } + } +} diff --git a/src/logger.rs b/src/logger.rs new file mode 100644 index 0000000..eada2a9 --- /dev/null +++ b/src/logger.rs @@ -0,0 +1,31 @@ +pub struct Logger { + log_level: LogLevel, +} + +impl Logger { + pub fn new(log_level: LogLevel) -> Logger { + Logger { log_level } + } + + pub fn log>(&self, log_level: LogLevel, message: T) { + if self.log_level.clone() as i32 >= log_level.clone() as i32 { + match log_level { + LogLevel::SEVERE => eprintln!("[SEVERE]: {}", message.into()), + LogLevel::INFO => println!("[INFO]: {}", message.into()), + LogLevel::WARNING => eprintln!("[WARNING]: {}", message.into()), + LogLevel::DETAIL => println!("[DETAIL]: {}", message.into()), + LogLevel::DETAILER => println!("[DETAILER]: {}", message.into()), + } + } + } +} + +#[allow(dead_code)] +#[derive(Clone)] +pub enum LogLevel { + SEVERE = 0, + INFO = 1, + WARNING = 2, // Default + DETAIL = 3, + DETAILER = 4, +} diff --git a/src/main.rs b/src/main.rs index 1fea15a..c9b6e15 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,65 +4,24 @@ extern crate regex; extern crate serde_derive; extern crate toml; +mod logger; +mod error; mod config_toml; mod config; mod template; mod renderer; +mod builder; -use config::Config; -use template::Template; - -use std::error::Error; -use std::fs::{create_dir_all, File}; -use std::io::prelude::*; - -const DEFAULT_CSS: &'static str = include_str!("templates/default-css.css"); -const PAGE_TEMPLATE: &'static str = include_str!("templates/page-template.html"); -const NAVBAR_ITEM: &'static str = include_str!("templates/navbar/item-template.html"); -const NAVBAR_IMAGE_ITEM: &'static str = include_str!("templates/navbar/image-item-template.html"); +use logger::{LogLevel, Logger}; fn main() { - println!("Fetching configs"); - let config = match Config::new() { - Ok(config) => config, - Err(err) => panic!(err.description().to_owned()), - }; + let logger = Logger::new(LogLevel::DETAILER); - if config.global_config.website.use_default_css { - println!("Adding public/css/default.css"); - create_dir_all("public/css").ok(); - let mut file = File::create("public/css/default.css").unwrap(); - file.write_all(DEFAULT_CSS.as_bytes()).ok(); - } - - println!("Generating page templates"); - let page_template = Template::new(PAGE_TEMPLATE); - - let mut navbar_content = String::new(); - if config.global_config.navbar.is_some() { - let navbar_item_template = Template::new(NAVBAR_ITEM); - let navbar_image_item_template = Template::new(NAVBAR_IMAGE_ITEM); - println!("Rendering navbar"); - match renderer::render_navbar(&config, navbar_item_template, navbar_image_item_template) { - Ok(navbar) => navbar_content = navbar, - Err(err) => panic!(err), + match builder::build(&logger) { + Ok(_) => logger.log(LogLevel::DETAILER, "Building finished successfully."), + Err(err) => { + logger.log(err.severity(), err.description()); + logger.log(LogLevel::SEVERE, "Aborting building due to error."); } } - - println!("Rendering public/test.html"); - let rendered = match config.get_configs_for(0) { - Ok(page_config) => page_template.render(&Template::page_data_from( - page_config.clone(), - navbar_content, - renderer::render_markdown_content(&page_config).unwrap(), - )), - Err(err) => panic!(err), - }; - - println!("Writing public/test.html"); - create_dir_all("public").ok(); - let mut file = File::create("public/test.html").unwrap(); - file.write_all(rendered.as_bytes()).ok(); - - println!("Done!"); } diff --git a/src/renderer.rs b/src/renderer.rs index 766a6da..30ae014 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -5,6 +5,8 @@ use pulldown_cmark::{html, Parser}; use config::{Config, SinglePageConfigs}; use template::Template; +use error::Error; +use logger::LogLevel; pub fn render_markdown_content(config: &SinglePageConfigs) -> Result { if let Some(parent) = config.page_config_path.parent() { @@ -33,7 +35,7 @@ pub fn render_navbar( config: &Config, item_template: Template, image_item_template: Template, -) -> Result { +) -> Result { let mut navbar_str = String::new(); if let Some(navbar) = config.global_config.navbar.clone() { @@ -46,14 +48,17 @@ pub fn render_navbar( navbar_str += &*item_template.render(&data); } } else { - return Err(format!( - "Navbar item does not exist: navbar.item.{}", - item_str + return Err(Error::new( + LogLevel::SEVERE, + format!("Navbar item does not exist: navbar.item.{}", item_str), )); } } Ok(navbar_str) } else { - Err("Attempted to render navbar without navbar".to_owned()) + Err(Error::new( + LogLevel::SEVERE, + "Attempted to render navbar without navbar".to_owned(), + )) } }