Copy assets found in content folders

This commit is contained in:
Vincent Prouillet 2017-03-12 12:54:57 +09:00
parent 60e30edce0
commit dde9af3efd
3 changed files with 42 additions and 8 deletions

View file

@ -37,6 +37,7 @@ Gallery at https://tmtheme-editor.herokuapp.com/#!/editor/theme/Agola%20Dark
# TODO: # TODO:
- find a way to add tests
- syntax highlighting - syntax highlighting
- pass a --config arg to the CLI to change from `config.toml` - pass a --config arg to the CLI to change from `config.toml`
- have verbosity levels with a `verbosity` config variable with a default - have verbosity levels with a `verbosity` config variable with a default

View file

@ -1,8 +1,8 @@
/// A page, can be a blog post or a basic page /// A page, can be a blog post or a basic page
use std::cmp::Ordering; use std::cmp::Ordering;
use std::fs::File; use std::fs::{File, read_dir};
use std::io::prelude::*; use std::io::prelude::*;
use std::path::Path; use std::path::{Path, PathBuf};
use std::result::Result as StdResult; use std::result::Result as StdResult;
@ -21,6 +21,27 @@ lazy_static! {
static ref PAGE_RE: Regex = Regex::new(r"^\n?\+\+\+\n((?s).*(?-s))\+\+\+\n((?s).*(?-s))$").unwrap(); static ref PAGE_RE: Regex = Regex::new(r"^\n?\+\+\+\n((?s).*(?-s))\+\+\+\n((?s).*(?-s))$").unwrap();
} }
/// Looks into the current folder for the path and see if there's anything that is not a .md
/// file. Those will be copied next to the rendered .html file
fn find_related_assets(path: &Path) -> Vec<PathBuf> {
let mut assets = vec![];
for entry in read_dir(path.parent().unwrap()).unwrap().filter_map(|e| e.ok()) {
let entry_path = entry.path();
if entry_path.is_file() {
match entry_path.extension() {
Some(e) => match e.to_str() {
Some("md") => continue,
_ => assets.push(entry_path.to_path_buf()),
},
None => continue,
}
}
}
assets
}
#[derive(Clone, Debug, PartialEq, Deserialize)] #[derive(Clone, Debug, PartialEq, Deserialize)]
pub struct Page { pub struct Page {
@ -38,6 +59,9 @@ pub struct Page {
/// The actual content of the page, in markdown /// The actual content of the page, in markdown
#[serde(skip_serializing)] #[serde(skip_serializing)]
pub raw_content: String, pub raw_content: String,
/// All the non-md files we found next to the .md file
#[serde(skip_serializing)]
pub assets: Vec<PathBuf>,
/// The HTML rendered of the page /// The HTML rendered of the page
pub content: String, pub content: String,
/// The front matter meta-data /// The front matter meta-data
@ -69,6 +93,7 @@ impl Page {
filename: "".to_string(), filename: "".to_string(),
sections: vec![], sections: vec![],
raw_content: "".to_string(), raw_content: "".to_string(),
assets: vec![],
content: "".to_string(), content: "".to_string(),
slug: "".to_string(), slug: "".to_string(),
url: "".to_string(), url: "".to_string(),
@ -80,7 +105,7 @@ impl Page {
} }
} }
// Get word count and estimated reading time /// Get word count and estimated reading time
pub fn get_reading_analytics(&self) -> (usize, usize) { pub fn get_reading_analytics(&self) -> (usize, usize) {
// Only works for latin language but good enough for a start // Only works for latin language but good enough for a start
let word_count: usize = self.raw_content.split_whitespace().count(); let word_count: usize = self.raw_content.split_whitespace().count();
@ -90,9 +115,9 @@ impl Page {
(word_count, (word_count / 200)) (word_count, (word_count / 200))
} }
// Parse a page given the content of the .md file /// Parse a page given the content of the .md file
// Files without front matter or with invalid front matter are considered /// Files without front matter or with invalid front matter are considered
// erroneous /// erroneous
pub fn parse(filepath: &str, content: &str, config: &Config) -> Result<Page> { pub fn parse(filepath: &str, content: &str, config: &Config) -> Result<Page> {
// 1. separate front matter from content // 1. separate front matter from content
if !PAGE_RE.is_match(content) { if !PAGE_RE.is_match(content) {
@ -169,6 +194,7 @@ impl Page {
Ok(page) Ok(page)
} }
/// Read and parse a .md file into a Page struct
pub fn from_file<P: AsRef<Path>>(path: P, config: &Config) -> Result<Page> { pub fn from_file<P: AsRef<Path>>(path: P, config: &Config) -> Result<Page> {
let path = path.as_ref(); let path = path.as_ref();
@ -178,8 +204,10 @@ impl Page {
.read_to_string(&mut content)?; .read_to_string(&mut content)?;
// Remove the content string from name // Remove the content string from name
// Maybe get a path as an arg instead and use strip_prefix? let mut page = Page::parse(&path.strip_prefix("content").unwrap().to_string_lossy(), &content, config)?;
Page::parse(&path.strip_prefix("content").unwrap().to_string_lossy(), &content, config) page.assets = find_related_assets(&path);
Ok(page)
} }
/// Renders the page using the default layout, unless specified in front-matter /// Renders the page using the default layout, unless specified in front-matter

View file

@ -192,6 +192,11 @@ impl Site {
// Finally, create a index.html file there with the page rendered // Finally, create a index.html file there with the page rendered
let output = page.render_html(&self.templates, &self.config)?; let output = page.render_html(&self.templates, &self.config)?;
create_file(current_path.join("index.html"), &self.inject_livereload(output))?; create_file(current_path.join("index.html"), &self.inject_livereload(output))?;
// Copy any asset we found previously into the same directory as the index.html
for asset in &page.assets {
let asset_path = asset.as_path();
copy(&asset_path, &current_path.join(asset_path.file_name().unwrap()))?;
}
pages.push(page); pages.push(page);
if let Some(ref category) = page.meta.category { if let Some(ref category) = page.meta.category {