From 2c78966fe8e3fa4b8d835353ed1423d587a39ff9 Mon Sep 17 00:00:00 2001 From: Teascade Date: Fri, 20 Apr 2018 02:52:48 +0300 Subject: [PATCH] Add custom markdown --- src/builder.rs | 1 + src/config_toml.rs | 87 ++++++-------------- src/error.rs | 1 + src/file_writer.rs | 42 ++++++++++ src/logger.rs | 2 +- src/renderer.rs | 127 ++++++++++++++++++++++------- src/templates/default-css.css | 5 +- test_page/other.md | 2 +- test_page/resources/some_list.toml | 11 +++ test_page/resources/template.html | 1 + 10 files changed, 181 insertions(+), 98 deletions(-) create mode 100644 test_page/resources/some_list.toml create mode 100644 test_page/resources/template.html diff --git a/src/builder.rs b/src/builder.rs index 65113ed..f8c2308 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -118,6 +118,7 @@ pub fn build(logger: &Logger, opt: &Opt, _: &BuildOpt) -> Result<(), Error> { logger.log(LogLevel::DETAILER, "Rendering"); let markdown = renderer::render_markdown_content(&config)?; + let markdown = renderer::render_custom_markdown(markdown)?; let data = Template::page_data_from( config.clone(), navbar_content.clone(), diff --git a/src/config_toml.rs b/src/config_toml.rs index afdf4c8..34efab4 100644 --- a/src/config_toml.rs +++ b/src/config_toml.rs @@ -1,13 +1,8 @@ -use toml; - use std::path::PathBuf; -use std::fs::File; -use std::io::Read; -use std::error::Error as STDError; use std::collections::HashMap; -use logger::LogLevel; use error::Error; +use file_writer; #[derive(Deserialize, Serialize, Clone, Debug)] pub struct GlobalConfigToml { @@ -75,25 +70,7 @@ pub struct NavbarItem { impl GlobalConfigToml { pub fn get_config() -> Result { - let mut file = File::open("config.toml")?; - let mut contents = String::new(); - file.read_to_string(&mut contents)?; - match toml::from_str(&contents) { - Ok(config) => Ok(config), - Err(err) => { - if let Some((line, col)) = err.line_col() { - Err(Error::new( - LogLevel::SEVERE, - format!("Erronous config.toml at {}:{}", line, col), - )) - } else { - Err(Error::new( - LogLevel::SEVERE, - format!("Failed to parse config.toml correctly. Check variable names!"), - )) - } - } - } + file_writer::get_toml(&PathBuf::from("config.toml")) } } @@ -104,45 +81,7 @@ pub struct PageConfigToml { impl PageConfigToml { pub fn get_from(path: &PathBuf) -> Result { - let path_str = match path.to_str() { - Some(path_str) => path_str, - None => "", - }; - - let mut file = match File::open(path.as_path()) { - Ok(file) => file, - Err(err) => { - return Err(Error::new( - LogLevel::SEVERE, - format!( - "Failed to open page config: {}, Reason: {}", - path.to_str().unwrap(), - err.description().to_owned() - ), - )) - } - }; - let mut contents = String::new(); - file.read_to_string(&mut contents)?; - match toml::from_str(&contents) { - Ok(config) => Ok(config), - Err(err) => { - if let Some((line, col)) = err.line_col() { - Err(Error::new( - LogLevel::SEVERE, - format!("Erronous toml: {} at {}:{}", path_str, line, col), - )) - } else { - Err(Error::new( - LogLevel::SEVERE, - format!( - "Failed to parse toml correctly: {}. Check variable names!", - path_str - ), - )) - } - } - } + file_writer::get_toml(path) } } @@ -159,3 +98,23 @@ pub struct PageConfig { pub javascript: Option>, pub css: Option>, } + +#[derive(Deserialize, Serialize, Clone, Debug)] +pub struct InjectionToml { + pub meta: MetaInjectionToml, + pub list: HashMap>, +} + +#[derive(Deserialize, Serialize, Clone, Debug)] +pub struct MetaInjectionToml { + pub rendered: Vec, + pub template: String, + pub list_classes: String, + pub is_list: bool, +} + +impl InjectionToml { + pub fn get_from(path: &PathBuf) -> Result { + file_writer::get_toml(path) + } +} diff --git a/src/error.rs b/src/error.rs index c94d8fd..4dbfb23 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,6 +4,7 @@ use std::error::Error as STDError; use logger::LogLevel; +#[derive(Debug)] pub struct Error { description: String, severity: LogLevel, diff --git a/src/file_writer.rs b/src/file_writer.rs index 12bd976..2b897db 100644 --- a/src/file_writer.rs +++ b/src/file_writer.rs @@ -4,6 +4,7 @@ use std::path::{Path, PathBuf}; use std::error::Error as STDError; use serde::Serialize; +use serde::de::DeserializeOwned; use toml; use error::Error; @@ -12,6 +13,47 @@ use logger::LogLevel; pub fn add_to_beginning>(path: PathBuf, to_add: T) -> PathBuf { Path::new(&to_add.into()).join(path) } +pub fn get_toml(path: &PathBuf) -> Result { + let path_str = match path.to_str() { + Some(path_str) => path_str, + None => "", + }; + + let mut file = match File::open(path.as_path()) { + Ok(file) => file, + Err(err) => { + return Err(Error::new( + LogLevel::SEVERE, + format!( + "Failed to open toml: {}, Reason: {}", + path.to_str().unwrap(), + err.description().to_owned() + ), + )) + } + }; + let mut contents: String = String::new(); + file.read_to_string(&mut contents)?; + match toml::from_str(&contents) { + Ok(config) => Ok(config), + Err(err) => { + if let Some((line, col)) = err.line_col() { + Err(Error::new( + LogLevel::SEVERE, + format!("Erronous toml: {} at {}:{}", path_str, line, col), + )) + } else { + Err(Error::new( + LogLevel::SEVERE, + format!( + "Failed to parse toml correctly: {}. Check variable names!", + path_str + ), + )) + } + } + } +} pub fn write_toml(path: &PathBuf, data: &T, overwrite: bool) -> Result<(), Error> { match toml::ser::to_string(data) { diff --git a/src/logger.rs b/src/logger.rs index acb9f4c..e8ae313 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -24,7 +24,7 @@ impl Logger { } #[allow(dead_code)] -#[derive(Clone)] +#[derive(Clone, Debug)] #[repr(u8)] pub enum LogLevel { QUIET = 0, diff --git a/src/renderer.rs b/src/renderer.rs index 0ff88b7..9fce141 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -4,11 +4,13 @@ use std::path::PathBuf; use std::error::Error as STDError; use pulldown_cmark::{html, Parser}; +use regex::{Captures, Regex}; use config::{Config, SinglePageConfigs}; use template::Template; use error::Error; use logger::{LogLevel, Logger}; +use config_toml::InjectionToml; fn get_file_contents(path: Option) -> Result { match path { @@ -69,35 +71,6 @@ pub fn render_injections( Ok((before_navbar, before_content, after_content)) } -pub fn render_markdown_content(config: &SinglePageConfigs) -> Result { - if let Some(parent) = config.page_config_path.parent() { - let path = parent.join(&config.page_config.page.content_path); - match File::open(&path) { - Ok(mut file) => { - let mut content = String::new(); - file.read_to_string(&mut content).ok(); - let parser = Parser::new(&content); - - let mut markdown = String::new(); - html::push_html(&mut markdown, parser); - Ok(markdown) - } - Err(_) => Err(Error::new( - LogLevel::SEVERE, - format!("Failed to open file: {}", path.to_str().unwrap()), - )), - } - } else { - Err(Error::new( - LogLevel::SEVERE, - format!( - "Failed to get page config parent: {}", - config.page_config_path.to_str().unwrap() - ), - )) - } -} - pub fn render_navbar( config: &Config, item_template: Template, @@ -129,3 +102,99 @@ pub fn render_navbar( )) } } + +pub fn render_markdown_content(config: &SinglePageConfigs) -> Result { + if let Some(parent) = config.page_config_path.parent() { + let path = parent.join(&config.page_config.page.content_path); + match File::open(&path) { + Ok(mut file) => { + let mut content = String::new(); + file.read_to_string(&mut content).ok(); + let parser = Parser::new(&content); + + let mut markdown = String::new(); + html::push_html(&mut markdown, parser); + Ok(markdown) + } + Err(_) => Err(Error::new( + LogLevel::SEVERE, + format!("Failed to open file: {}", path.to_str().unwrap()), + )), + } + } else { + Err(Error::new( + LogLevel::SEVERE, + format!( + "Failed to get page config parent: {}", + config.page_config_path.to_str().unwrap() + ), + )) + } +} + +pub fn render_custom_markdown(rendered_markdown: String) -> Result { + let regex = Regex::new(r"\[from_toml\$(?P.*)\]").unwrap(); + Ok(regex + .replace_all( + &rendered_markdown, + |caps: &Captures| match InjectionToml::get_from(&PathBuf::from(&caps["path"])) { + Ok(config) => replace(config), + Err(err) => format!( + "(Failed to get injection toml at {}: {})", + &caps["path"], + err.description() + ), + }, + ) + .to_string()) +} + +fn replace(config: InjectionToml) -> String { + match File::open(config.meta.template.clone()) { + Ok(mut file) => { + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + let template = Template::new(content); + + let mut to_return = String::new(); + + if config.meta.is_list { + to_return += &*format!("
    ", config.meta.list_classes); + } + + for item in config.meta.rendered { + match config.list.get(&item) { + Some(data) => { + if config.meta.is_list { + to_return += "
  • "; + to_return += &*template.render(data); + to_return += "
  • "; + } else { + to_return = template.render(data); + } + } + None => { + if config.meta.is_list { + to_return += "
  • "; + to_return += &*format!("Could not find item {}", item); + to_return += "
  • "; + } else { + to_return = format!("Could not find item {}", item); + } + } + } + } + + if config.meta.is_list { + to_return += "
"; + } + + to_return + } + Err(err) => format!( + "Failed to get template for custom markdown: {}, {}", + config.meta.template, + err.description().to_owned(), + ), + } +} diff --git a/src/templates/default-css.css b/src/templates/default-css.css index 50f60ef..f24a191 100644 --- a/src/templates/default-css.css +++ b/src/templates/default-css.css @@ -84,16 +84,15 @@ nav li:not(.image) a { } nav li:first-child a { - border-left: solid 5px var(--color-navbar-button-hover); + border-left: solid 3px var(--color-navbar-button-hover); } nav li:last-child a { - border-right: solid 5px var(--color-navbar-button-hover); + border-right: solid 3px var(--color-navbar-button-hover); } nav ul a:hover { background-color: var(--color-navbar-button-hover); - border-left: solid 5px var(--color-navbar-button-hover); } nav ul a:focus { diff --git a/test_page/other.md b/test_page/other.md index c0333c3..2c2ca55 100644 --- a/test_page/other.md +++ b/test_page/other.md @@ -6,4 +6,4 @@ Example stuff that makes this site different: [Hello! This is an internal link](/) -[from_toml$/test_page/config.toml] \ No newline at end of file +[from_toml$test_page/resources/some_list.toml] \ No newline at end of file diff --git a/test_page/resources/some_list.toml b/test_page/resources/some_list.toml new file mode 100644 index 0000000..32fa3d7 --- /dev/null +++ b/test_page/resources/some_list.toml @@ -0,0 +1,11 @@ +[meta] +rendered = ["one_thing", "another_thing"] +template = "test_page/resources/template.html" +list_classes = "test_class" +is_list = true + +[list.one_thing] +thing = "jotain" + +[list.another_thing] +thing = "jotain muuta" \ No newline at end of file diff --git a/test_page/resources/template.html b/test_page/resources/template.html new file mode 100644 index 0000000..2b6368a --- /dev/null +++ b/test_page/resources/template.html @@ -0,0 +1 @@ +A Thing: {{thing}} \ No newline at end of file