2016-12-13 09:05:59 +00:00
|
|
|
use std::collections::HashMap;
|
2016-12-13 06:22:24 +00:00
|
|
|
use std::fs::{create_dir, remove_dir_all};
|
|
|
|
use std::path::Path;
|
|
|
|
|
2016-12-11 06:05:03 +00:00
|
|
|
use glob::glob;
|
2016-12-13 09:05:59 +00:00
|
|
|
use tera::{Tera, Context};
|
2016-12-06 08:27:03 +00:00
|
|
|
|
|
|
|
use config:: Config;
|
2016-12-11 06:05:03 +00:00
|
|
|
use errors::{Result, ResultExt};
|
2016-12-13 09:05:59 +00:00
|
|
|
use page::{Page, order_pages};
|
2016-12-13 06:22:24 +00:00
|
|
|
use utils::create_file;
|
2016-12-06 12:48:23 +00:00
|
|
|
|
|
|
|
|
2016-12-06 08:27:03 +00:00
|
|
|
|
|
|
|
pub fn build(config: Config) -> Result<()> {
|
2016-12-13 06:22:24 +00:00
|
|
|
if Path::new("public").exists() {
|
|
|
|
// Delete current `public` directory so we can start fresh
|
|
|
|
remove_dir_all("public").chain_err(|| "Couldn't delete `public` directory")?;
|
|
|
|
}
|
|
|
|
|
2016-12-11 06:05:03 +00:00
|
|
|
let tera = Tera::new("layouts/**/*").chain_err(|| "Error parsing templates")?;
|
2016-12-13 06:22:24 +00:00
|
|
|
|
|
|
|
// ok we got all the pages HTML, time to write them down to disk
|
|
|
|
create_dir("public")?;
|
|
|
|
let public = Path::new("public");
|
2016-12-13 09:05:59 +00:00
|
|
|
let mut pages: Vec<Page> = vec![];
|
|
|
|
let mut sections: HashMap<String, Vec<Page>> = HashMap::new();
|
2016-12-11 06:05:03 +00:00
|
|
|
|
2016-12-13 09:05:59 +00:00
|
|
|
// First step: do all the articles and group article by sections
|
2016-12-11 06:05:03 +00:00
|
|
|
// hardcoded pattern so can't error
|
|
|
|
for entry in glob("content/**/*.md").unwrap().filter_map(|e| e.ok()) {
|
|
|
|
let path = entry.as_path();
|
2016-12-13 06:22:24 +00:00
|
|
|
let mut page = Page::from_file(&path)?;
|
2016-12-11 06:05:03 +00:00
|
|
|
|
2016-12-13 06:22:24 +00:00
|
|
|
let mut current_path = public.clone().to_path_buf();
|
2016-12-13 09:05:59 +00:00
|
|
|
|
2016-12-13 06:22:24 +00:00
|
|
|
for section in &page.sections {
|
|
|
|
current_path.push(section);
|
2016-12-13 09:05:59 +00:00
|
|
|
|
2016-12-13 06:22:24 +00:00
|
|
|
if !current_path.exists() {
|
|
|
|
create_dir(¤t_path)?;
|
|
|
|
}
|
2016-12-13 09:05:59 +00:00
|
|
|
|
|
|
|
let str_path = current_path.as_path().to_string_lossy().to_string();
|
|
|
|
if sections.contains_key(&str_path) {
|
|
|
|
sections.get_mut(&str_path).unwrap().push(page.clone());
|
|
|
|
} else {
|
|
|
|
sections.insert(str_path, vec![page.clone()]);
|
|
|
|
}
|
|
|
|
|
2016-12-13 06:22:24 +00:00
|
|
|
}
|
2016-12-13 09:05:59 +00:00
|
|
|
|
2016-12-13 06:22:24 +00:00
|
|
|
current_path.push(&page.filename);
|
|
|
|
create_dir(¤t_path)?;
|
|
|
|
create_file(current_path.join("index.html"), &page.render_html(&tera, &config)?)?;
|
2016-12-13 09:05:59 +00:00
|
|
|
pages.push(page);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (section, pages) in sections {
|
|
|
|
render_section_index(section, pages, &tera, &config)?;
|
2016-12-11 06:05:03 +00:00
|
|
|
}
|
2016-12-06 08:27:03 +00:00
|
|
|
|
2016-12-13 06:22:24 +00:00
|
|
|
|
2016-12-06 08:27:03 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
2016-12-13 09:05:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
fn render_section_index(section: String, pages: Vec<Page>, tera: &Tera, config: &Config) -> Result<()> {
|
|
|
|
let path = Path::new(§ion);
|
|
|
|
let mut context = Context::new();
|
|
|
|
context.add("pages", &order_pages(pages));
|
|
|
|
context.add("config", &config);
|
|
|
|
|
|
|
|
let section_name = match path.components().into_iter().last() {
|
|
|
|
Some(s) => s.as_ref().to_string_lossy().to_string(),
|
|
|
|
None => bail!("Couldn't find a section name in {:?}", path.display())
|
|
|
|
};
|
|
|
|
|
|
|
|
create_file(path.join("index.html"), &tera.render(&format!("{}.html", section_name), context)?)
|
|
|
|
}
|