Skip to content

Commit

Permalink
feat(front): Set published_date from filename
Browse files Browse the repository at this point in the history
This is inspired by #197 and Jekyll.

Jekyll gets the filename from a file.  The main difference between
Jekyll and this change is that we aren't supporting 2-digit years.

In #197, the idea was brought up of extracting the date from the
directory structure.  I like this approach.  I could imagine having at
least year directories (don't blog enough to make day directories worth
while).  The challenge comes in how to detect this.
  • Loading branch information
epage committed Nov 4, 2017
1 parent 200458d commit ad69b1f
Showing 1 changed file with 102 additions and 0 deletions.
102 changes: 102 additions & 0 deletions src/frontmatter.rs
@@ -1,7 +1,9 @@
use std::path;
use std::collections::HashMap;

use chrono::Datelike;
use liquid;
use regex;

use error::Result;
use datetime;
Expand Down Expand Up @@ -286,6 +288,11 @@ impl FrontmatterBuilder {
self.title = Some(title);
}

if self.published_date.is_none() {
let file_stem = file_stem(relpath);
self.published_date = extract_date(file_stem);
}

self
}

Expand Down Expand Up @@ -377,6 +384,33 @@ fn file_stem_path(p: &path::Path) -> String {
.unwrap_or_else(|| "".to_owned())
}

fn extract_date(stem: String) -> Option<datetime::DateTime> {
lazy_static!{
static ref DATE_PREFIX_REF: regex::Regex = regex::Regex::new(r"^(\d{4})-(\d{1,2})-(\d{1,2})[- ].*$").unwrap();
}

DATE_PREFIX_REF.captures(&stem).and_then(|caps| {
let year: i32 = caps.get(1)
.expect("unconditional capture")
.as_str()
.parse()
.expect("regex gets back an integer");
let month: u32 = caps.get(2)
.expect("unconditional capture")
.as_str()
.parse()
.expect("regex gets back an integer");
let day: u32 = caps.get(3)
.expect("unconditional capture")
.as_str()
.parse()
.expect("regex gets back an integer");
datetime::DateTime::default()
.with_year(year)
.and_then(|d| d.with_month(month))
.and_then(|d| d.with_day(day))
})
}

#[cfg(test)]
mod test {
Expand All @@ -389,6 +423,74 @@ mod test {
assert_eq!(actual, "___filE-worlD-__09___");
}

#[test]
fn extract_date_empty() {
assert_eq!(extract_date("".to_owned()), None);
}

#[test]
fn extract_date_none() {
assert_eq!(extract_date("First Blog Post".to_owned()), None);
}

#[test]
fn extract_date_out_of_range_month() {
assert_eq!(extract_date("2017-30-5 First Blog Post".to_owned()), None);
}

#[test]
fn extract_date_out_of_range_day() {
assert_eq!(extract_date("2017-3-50 First Blog Post".to_owned()), None);
}

#[test]
fn extract_date_single_digit() {
assert_eq!(extract_date("2017-3-5 First Blog Post".to_owned()),
Some(datetime::DateTime::default()
.with_year(2017)
.unwrap()
.with_month(3)
.unwrap()
.with_day(5)
.unwrap()));
}

#[test]
fn extract_date_double_digit() {
assert_eq!(extract_date("2017-12-25 First Blog Post".to_owned()),
Some(datetime::DateTime::default()
.with_year(2017)
.unwrap()
.with_month(12)
.unwrap()
.with_day(25)
.unwrap()));
}

#[test]
fn extract_date_double_digit_leading_zero() {
assert_eq!(extract_date("2017-03-05 First Blog Post".to_owned()),
Some(datetime::DateTime::default()
.with_year(2017)
.unwrap()
.with_month(3)
.unwrap()
.with_day(5)
.unwrap()));
}

#[test]
fn extract_date_dashed() {
assert_eq!(extract_date("2017-3-5-First-Blog-Post".to_owned()),
Some(datetime::DateTime::default()
.with_year(2017)
.unwrap()
.with_month(3)
.unwrap()
.with_day(5)
.unwrap()));
}

#[test]
fn frontmatter_title_from_path() {
let front = FrontmatterBuilder::new()
Expand Down

0 comments on commit ad69b1f

Please sign in to comment.