use std::fs::File; use std::io::Read; 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 { Some(url) => match File::open(PathBuf::from(&url)) { Ok(mut file) => { let mut content = String::new(); file.read_to_string(&mut content).unwrap(); Ok(content) } Err(err) => Err(Error::new( LogLevel::WARNING, format!("Failed to open {}, {}", url, err.description().to_owned()), )), }, None => Ok(String::new()), } } pub fn render_injections( logger: &Logger, config: &SinglePageConfigs, ) -> Result<(String, String, String), Error> { let before_navbar_url = match config.page_config.page.before_navbar_url.clone() { Some(url) => Some(url), None => config.global_config.website.before_navbar_url.clone(), }; let before_content_url = match config.page_config.page.before_content_url.clone() { Some(url) => Some(url), None => config.global_config.website.before_content_url.clone(), }; let after_content_url = match config.page_config.page.after_content_url.clone() { Some(url) => Some(url), None => config.global_config.website.after_content_url.clone(), }; let before_navbar = match get_file_contents(before_navbar_url) { Ok(content) => content, Err(error) => { logger.log(error.severity(), error.description()); String::new() } }; let before_content = match get_file_contents(before_content_url) { Ok(content) => content, Err(error) => { logger.log(error.severity(), error.description()); String::new() } }; let after_content = match get_file_contents(after_content_url) { Ok(content) => content, Err(error) => { logger.log(error.severity(), error.description()); String::new() } }; Ok((before_navbar, before_content, after_content)) } pub fn render_navbar( config: &Config, item_template: Template, image_item_template: Template, ) -> Result { let mut navbar_str = String::new(); if let Some(navbar) = config.global_config.navbar.clone() { for item_str in navbar.items { if let Some(item) = navbar.item_map.get(&item_str) { let data = Template::navbar_item_data_from(item.clone()); if item.image_url.is_some() { navbar_str += &*image_item_template.render(&data); } else { navbar_str += &*item_template.render(&data); } } else { return Err(Error::new( LogLevel::SEVERE, format!("Navbar item does not exist: navbar.item.{}", item_str), )); } } Ok(navbar_str) } else { Err(Error::new( LogLevel::SEVERE, "Attempted to render navbar without navbar".to_owned(), )) } } 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(), ), } }