parent
de80de1628
commit
1e25117887
|
@ -3,6 +3,8 @@
|
||||||
## 0.3.2 (unreleased)
|
## 0.3.2 (unreleased)
|
||||||
|
|
||||||
- Fix `serve` command trying to read all files as markdown
|
- Fix `serve` command trying to read all files as markdown
|
||||||
|
- Add many syntax highlighting themes
|
||||||
|
- Fix date being serialised incorrectly in page `extra` section of front-matter
|
||||||
|
|
||||||
## 0.3.1 (2018-02-15)
|
## 0.3.1 (2018-02-15)
|
||||||
|
|
||||||
|
|
22
Cargo.lock
generated
22
Cargo.lock
generated
|
@ -192,7 +192,7 @@ dependencies = [
|
||||||
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slug 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slug 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"utils 0.1.0",
|
"utils 0.1.0",
|
||||||
]
|
]
|
||||||
|
@ -272,7 +272,7 @@ name = "errors"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ dependencies = [
|
||||||
"regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -794,7 +794,7 @@ dependencies = [
|
||||||
"front_matter 0.1.0",
|
"front_matter 0.1.0",
|
||||||
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"utils 0.1.0",
|
"utils 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1000,7 +1000,7 @@ dependencies = [
|
||||||
"slug 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slug 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syntect 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syntect 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"templates 0.1.0",
|
"templates 0.1.0",
|
||||||
"tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"utils 0.1.0",
|
"utils 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1123,7 +1123,7 @@ dependencies = [
|
||||||
"taxonomies 0.1.0",
|
"taxonomies 0.1.0",
|
||||||
"tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"templates 0.1.0",
|
"templates 0.1.0",
|
||||||
"tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"utils 0.1.0",
|
"utils 0.1.0",
|
||||||
"walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -1211,7 +1211,7 @@ dependencies = [
|
||||||
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slug 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slug 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"utils 0.1.0",
|
"utils 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1235,13 +1235,13 @@ dependencies = [
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"taxonomies 0.1.0",
|
"taxonomies 0.1.0",
|
||||||
"tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"utils 0.1.0",
|
"utils 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tera"
|
name = "tera"
|
||||||
version = "0.11.4"
|
version = "0.11.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1411,7 +1411,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"errors 0.1.0",
|
"errors 0.1.0",
|
||||||
"tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1638,7 +1638,7 @@ dependencies = [
|
||||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||||
"checksum syntect 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9fffcb25a761118df53811bd1cfcd54cf57fcbc51e1ea3167ae263477129ad"
|
"checksum syntect 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9fffcb25a761118df53811bd1cfcd54cf57fcbc51e1ea3167ae263477129ad"
|
||||||
"checksum tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f73eebdb68c14bcb24aef74ea96079830e7fa7b31a6106e42ea7ee887c1e134e"
|
"checksum tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f73eebdb68c14bcb24aef74ea96079830e7fa7b31a6106e42ea7ee887c1e134e"
|
||||||
"checksum tera 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d5fcce006fbde2ac587dc056940d2c329ee49f2e4de7d9ddfdbbc60efb9f9207"
|
"checksum tera 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fc1a35d04c2444875b1319293fbc72c00215ae6220f8c70f9f14fefa5eaae0c6"
|
||||||
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
|
"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
|
||||||
"checksum term-painter 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "dcaa948f0e3e38470cd8dc8dcfe561a75c9e43f28075bb183845be2b9b3c08cf"
|
"checksum term-painter 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "dcaa948f0e3e38470cd8dc8dcfe561a75c9e43f28075bb183845be2b9b3c08cf"
|
||||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||||
|
|
|
@ -223,12 +223,7 @@ impl ser::Serialize for Page {
|
||||||
state.serialize_field("content", &self.content)?;
|
state.serialize_field("content", &self.content)?;
|
||||||
state.serialize_field("title", &self.meta.title)?;
|
state.serialize_field("title", &self.meta.title)?;
|
||||||
state.serialize_field("description", &self.meta.description)?;
|
state.serialize_field("description", &self.meta.description)?;
|
||||||
// From a TOML datetime to a String first
|
state.serialize_field("date", &self.meta.date)?;
|
||||||
let date = match self.meta.date {
|
|
||||||
Some(ref d) => Some(d.to_string()),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
state.serialize_field("date", &date)?;
|
|
||||||
state.serialize_field("slug", &self.slug)?;
|
state.serialize_field("slug", &self.slug)?;
|
||||||
state.serialize_field("path", &self.path)?;
|
state.serialize_field("path", &self.path)?;
|
||||||
state.serialize_field("components", &self.components)?;
|
state.serialize_field("components", &self.components)?;
|
||||||
|
|
|
@ -98,16 +98,13 @@ pub fn populate_previous_and_next_pages(input: &[Page]) -> Vec<Page> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::str::FromStr;
|
|
||||||
use toml::value::Datetime;
|
|
||||||
|
|
||||||
use front_matter::{PageFrontMatter, SortBy};
|
use front_matter::{PageFrontMatter, SortBy};
|
||||||
use page::Page;
|
use page::Page;
|
||||||
use super::{sort_pages, populate_previous_and_next_pages};
|
use super::{sort_pages, populate_previous_and_next_pages};
|
||||||
|
|
||||||
fn create_page_with_date(date: &str) -> Page {
|
fn create_page_with_date(date: &str) -> Page {
|
||||||
let mut front_matter = PageFrontMatter::default();
|
let mut front_matter = PageFrontMatter::default();
|
||||||
front_matter.date = Some(Datetime::from_str(date).unwrap());
|
front_matter.date = Some(date.to_string());
|
||||||
Page::new("content/hello.md", front_matter)
|
Page::new("content/hello.md", front_matter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,65 @@
|
||||||
use std::collections::HashMap;
|
use std::result::{Result as StdResult};
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use tera::Value;
|
use tera::{Map, Value};
|
||||||
|
use serde::{Deserialize, Deserializer};
|
||||||
use toml;
|
use toml;
|
||||||
|
|
||||||
use errors::Result;
|
use errors::Result;
|
||||||
|
|
||||||
|
|
||||||
|
fn from_toml_datetime<'de, D>(deserializer: D) -> StdResult<Option<String>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
toml::value::Datetime::deserialize(deserializer)
|
||||||
|
.map(|s| Some(s.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns key/value for a converted date from TOML.
|
||||||
|
/// If the table itself is the TOML struct, only return its value without the key
|
||||||
|
fn convert_toml_date(table: Map<String, Value>) -> Value {
|
||||||
|
let mut new = Map::new();
|
||||||
|
|
||||||
|
for (k, v) in table.into_iter() {
|
||||||
|
if k == "$__toml_private_datetime" {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
match v {
|
||||||
|
Value::Object(mut o) => {
|
||||||
|
// that was a toml datetime object, just return the date
|
||||||
|
if let Some(toml_date) = o.remove("$__toml_private_datetime") {
|
||||||
|
new.insert(k, toml_date);
|
||||||
|
return Value::Object(new);
|
||||||
|
}
|
||||||
|
new.insert(k, convert_toml_date(o));
|
||||||
|
},
|
||||||
|
_ => { new.insert(k, v); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(new)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TOML datetimes will be serialized as a struct but we want the
|
||||||
|
/// stringified version for json, otherwise they are going to be weird
|
||||||
|
fn fix_toml_dates(table: Map<String, Value>) -> Value {
|
||||||
|
let mut new = Map::new();
|
||||||
|
|
||||||
|
for (key, value) in table {
|
||||||
|
match value {
|
||||||
|
Value::Object(mut o) => {
|
||||||
|
new.insert(key, convert_toml_date(o));
|
||||||
|
},
|
||||||
|
_ => { new.insert(key, value); },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Object(new)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// The front matter of every page
|
/// The front matter of every page
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct PageFrontMatter {
|
pub struct PageFrontMatter {
|
||||||
|
@ -15,7 +68,8 @@ pub struct PageFrontMatter {
|
||||||
/// Description in <meta> that appears when linked, e.g. on twitter
|
/// Description in <meta> that appears when linked, e.g. on twitter
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
/// Date if we want to order pages (ie blog post)
|
/// Date if we want to order pages (ie blog post)
|
||||||
pub date: Option<toml::value::Datetime>,
|
#[serde(default, deserialize_with = "from_toml_datetime")]
|
||||||
|
pub date: Option<String>,
|
||||||
/// Whether this page is a draft and should be ignored for pagination etc
|
/// Whether this page is a draft and should be ignored for pagination etc
|
||||||
pub draft: Option<bool>,
|
pub draft: Option<bool>,
|
||||||
/// The page slug. Will be used instead of the filename if present
|
/// The page slug. Will be used instead of the filename if present
|
||||||
|
@ -41,12 +95,13 @@ pub struct PageFrontMatter {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub template: Option<String>,
|
pub template: Option<String>,
|
||||||
/// Any extra parameter present in the front matter
|
/// Any extra parameter present in the front matter
|
||||||
pub extra: Option<HashMap<String, Value>>,
|
#[serde(default)]
|
||||||
|
pub extra: Map<String, Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PageFrontMatter {
|
impl PageFrontMatter {
|
||||||
pub fn parse(toml: &str) -> Result<PageFrontMatter> {
|
pub fn parse(toml: &str) -> Result<PageFrontMatter> {
|
||||||
let f: PageFrontMatter = match toml::from_str(toml) {
|
let mut f: PageFrontMatter = match toml::from_str(toml) {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(e) => bail!(e),
|
Err(e) => bail!(e),
|
||||||
};
|
};
|
||||||
|
@ -69,17 +124,20 @@ impl PageFrontMatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.extra = match fix_toml_dates(f.extra) {
|
||||||
|
Value::Object(o) => o,
|
||||||
|
_ => unreachable!("Got something other than a table in page extra"),
|
||||||
|
};
|
||||||
Ok(f)
|
Ok(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the TOML datetime to a Chrono naive datetime
|
/// Converts the TOML datetime to a Chrono naive datetime
|
||||||
pub fn date(&self) -> Option<NaiveDateTime> {
|
pub fn date(&self) -> Option<NaiveDateTime> {
|
||||||
if let Some(ref d) = self.date {
|
if let Some(ref d) = self.date {
|
||||||
let d2 = d.to_string();
|
if d.contains('T') {
|
||||||
if d2.contains('T') {
|
DateTime::parse_from_rfc3339(&d).ok().and_then(|s| Some(s.naive_local()))
|
||||||
DateTime::parse_from_rfc3339(&d2).ok().and_then(|s| Some(s.naive_local()))
|
|
||||||
} else {
|
} else {
|
||||||
NaiveDate::parse_from_str(&d2, "%Y-%m-%d").ok().and_then(|s| Some(s.and_hms(0, 0, 0)))
|
NaiveDate::parse_from_str(&d, "%Y-%m-%d").ok().and_then(|s| Some(s.and_hms(0, 0, 0)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -117,7 +175,7 @@ impl Default for PageFrontMatter {
|
||||||
weight: None,
|
weight: None,
|
||||||
aliases: None,
|
aliases: None,
|
||||||
template: None,
|
template: None,
|
||||||
extra: None,
|
extra: Map::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,12 +183,14 @@ impl Default for PageFrontMatter {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use tera::to_value;
|
||||||
use super::PageFrontMatter;
|
use super::PageFrontMatter;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_have_empty_front_matter() {
|
fn can_have_empty_front_matter() {
|
||||||
let content = r#" "#;
|
let content = r#" "#;
|
||||||
let res = PageFrontMatter::parse(content);
|
let res = PageFrontMatter::parse(content);
|
||||||
|
println!("{:?}", res);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,4 +311,32 @@ mod tests {
|
||||||
let res = PageFrontMatter::parse(content);
|
let res = PageFrontMatter::parse(content);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_parse_dates_in_extra() {
|
||||||
|
let content = r#"
|
||||||
|
title = "Hello"
|
||||||
|
description = "hey there"
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
some-date = 2002-14-01"#;
|
||||||
|
let res = PageFrontMatter::parse(content);
|
||||||
|
println!("{:?}", res);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
assert_eq!(res.unwrap().extra["some-date"], to_value("2002-14-01").unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_parse_nested_dates_in_extra() {
|
||||||
|
let content = r#"
|
||||||
|
title = "Hello"
|
||||||
|
description = "hey there"
|
||||||
|
|
||||||
|
[extra.something]
|
||||||
|
some-date = 2002-14-01"#;
|
||||||
|
let res = PageFrontMatter::parse(content);
|
||||||
|
println!("{:?}", res);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
assert_eq!(res.unwrap().extra["something"]["some-date"], to_value("2002-14-01").unwrap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue