parent
5e31a32166
commit
ade442a487
|
@ -2,9 +2,9 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler32"
|
name = "adler32"
|
||||||
version = "1.0.4"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
|
checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
|
@ -75,9 +75,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.12.1"
|
version = "0.12.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42"
|
checksum = "e223af0dc48c96d4f8342ec01a4974f139df863896b316681efd36742f22cc67"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bincode"
|
name = "bincode"
|
||||||
|
@ -104,7 +104,19 @@ dependencies = [
|
||||||
"block-padding",
|
"block-padding",
|
||||||
"byte-tools",
|
"byte-tools",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"generic-array",
|
"generic-array 0.12.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dbcf92448676f82bb7a334c58bbce8b0d43580fb5362a9d608b18879d12a3d31"
|
||||||
|
dependencies = [
|
||||||
|
"block-padding",
|
||||||
|
"byte-tools",
|
||||||
|
"byteorder",
|
||||||
|
"generic-array 0.14.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -366,7 +378,16 @@ version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array 0.12.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array 0.14.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -377,9 +398,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dtoa"
|
name = "dtoa"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3"
|
checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
|
@ -611,6 +632,16 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getopts"
|
name = "getopts"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
|
@ -912,9 +943,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
|
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jpeg-decoder"
|
name = "jpeg-decoder"
|
||||||
|
@ -1462,7 +1493,7 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b336d94e8e4ce29bf15bba393164629764744c567e8ad306cc1fdd0119967fd"
|
checksum = "7b336d94e8e4ce29bf15bba393164629764744c567e8ad306cc1fdd0119967fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.12.1",
|
"base64 0.12.2",
|
||||||
"chrono",
|
"chrono",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"line-wrap",
|
"line-wrap",
|
||||||
|
@ -1615,10 +1646,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
|
checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
"either",
|
"either",
|
||||||
"rayon-core",
|
"rayon-core",
|
||||||
|
@ -1626,9 +1658,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon-core"
|
name = "rayon-core"
|
||||||
version = "1.7.0"
|
version = "1.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
|
checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
|
@ -1718,7 +1750,7 @@ version = "0.10.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680"
|
checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.12.1",
|
"base64 0.12.2",
|
||||||
"bytes 0.5.4",
|
"bytes 0.5.4",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -1749,9 +1781,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.16.14"
|
version = "0.16.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06b3fefa4f12272808f809a0af618501fdaba41a58963c5fb72238ab0be09603"
|
checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1917,20 +1949,20 @@ version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer 0.7.3",
|
||||||
"digest",
|
"digest 0.8.1",
|
||||||
"fake-simd",
|
"fake-simd",
|
||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.8.2"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
|
checksum = "72377440080fd008550fe9b441e854e43318db116f90181eef92e9ae9aedab48"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer 0.8.0",
|
||||||
"digest",
|
"digest 0.9.0",
|
||||||
"fake-simd",
|
"fake-simd",
|
||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
@ -1984,12 +2016,6 @@ dependencies = [
|
||||||
"deunicode",
|
"deunicode",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smallvec"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.3.12"
|
version = "0.3.12"
|
||||||
|
@ -2131,7 +2157,7 @@ dependencies = [
|
||||||
name = "templates"
|
name = "templates"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.12.1",
|
"base64 0.12.2",
|
||||||
"config",
|
"config",
|
||||||
"csv",
|
"csv",
|
||||||
"errors",
|
"errors",
|
||||||
|
@ -2232,6 +2258,12 @@ dependencies = [
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
|
@ -2391,11 +2423,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
version = "0.1.12"
|
version = "0.1.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
|
checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"smallvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2698,9 +2730,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xmlparser"
|
name = "xmlparser"
|
||||||
version = "0.13.1"
|
version = "0.13.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ccb4240203dadf40be2de9369e5c6dec1bf427528115b030baca3334c18362d7"
|
checksum = "52613e655f6f11f63c0fe7d1c3b5ef69e44d96df9b65dab296b441ed0e1125f5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yaml-rust"
|
name = "yaml-rust"
|
||||||
|
|
|
@ -20,7 +20,7 @@ name = "zola"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
atty = "0.2.11"
|
atty = "0.2.11"
|
||||||
clap = "2"
|
clap = { version = "2", default-features = false }
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
lazy_static = "1.1.0"
|
lazy_static = "1.1.0"
|
||||||
termcolor = "1.0.4"
|
termcolor = "1.0.4"
|
||||||
|
|
|
@ -28,7 +28,7 @@ fn main() {
|
||||||
builder.add_plain_text_syntax();
|
builder.add_plain_text_syntax();
|
||||||
match builder.add_from_folder(package_dir, true) {
|
match builder.add_from_folder(package_dir, true) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => println!("Loading error: {:?}", e)
|
Err(e) => println!("Loading error: {:?}", e),
|
||||||
};
|
};
|
||||||
let ss = builder.build();
|
let ss = builder.build();
|
||||||
dump_to_file(&ss, packpath_newlines).unwrap();
|
dump_to_file(&ss, packpath_newlines).unwrap();
|
||||||
|
|
|
@ -4,7 +4,6 @@ use std::path::{Path, PathBuf};
|
||||||
use globset::{Glob, GlobSet, GlobSetBuilder};
|
use globset::{Glob, GlobSet, GlobSetBuilder};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use syntect::parsing::{SyntaxSet, SyntaxSetBuilder};
|
use syntect::parsing::{SyntaxSet, SyntaxSetBuilder};
|
||||||
use toml;
|
|
||||||
use toml::Value as Toml;
|
use toml::Value as Toml;
|
||||||
|
|
||||||
use crate::highlighting::THEME_SET;
|
use crate::highlighting::THEME_SET;
|
||||||
|
|
|
@ -3,7 +3,6 @@ use std::collections::HashMap;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use tera::{Map, Value};
|
use tera::{Map, Value};
|
||||||
use toml;
|
|
||||||
|
|
||||||
use errors::{bail, Result};
|
use errors::{bail, Result};
|
||||||
use utils::de::{fix_toml_dates, from_toml_datetime};
|
use utils::de::{fix_toml_dates, from_toml_datetime};
|
||||||
|
@ -57,15 +56,17 @@ pub struct PageFrontMatter {
|
||||||
pub extra: Map<String, Value>,
|
pub extra: Map<String, Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a TOML datetime from a string.
|
/// Parse a string for a datetime coming from one of the supported TOML format
|
||||||
/// There are three alternatives: an offset datetime (plain RFC3339), a local datetime
|
/// There are three alternatives:
|
||||||
/// (RFC3339 with timezone omitted) and a local date (YYYY-MM-DD). This tries each in
|
/// 1. an offset datetime (plain RFC3339)
|
||||||
/// order.
|
/// 2. a local datetime (RFC3339 with timezone omitted)
|
||||||
fn parse_datetime(d: &String) -> Option<NaiveDateTime> {
|
/// 3. a local date (YYYY-MM-DD).
|
||||||
|
/// This tries each in order.
|
||||||
|
fn parse_datetime(d: &str) -> Option<NaiveDateTime> {
|
||||||
DateTime::parse_from_rfc3339(d)
|
DateTime::parse_from_rfc3339(d)
|
||||||
.or(DateTime::parse_from_rfc3339(format!("{}Z", d).as_ref()))
|
.or_else(|_| DateTime::parse_from_rfc3339(format!("{}Z", d).as_ref()))
|
||||||
.map(|s| s.naive_local())
|
.map(|s| s.naive_local())
|
||||||
.or(NaiveDate::parse_from_str(d, "%Y-%m-%d").map(|s| s.and_hms(0, 0, 0)))
|
.or_else(|_| NaiveDate::parse_from_str(d, "%Y-%m-%d").map(|s| s.and_hms(0, 0, 0)))
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ impl PageFrontMatter {
|
||||||
/// Converts the TOML datetime to a Chrono naive datetime
|
/// Converts the TOML datetime to a Chrono naive datetime
|
||||||
/// Also grabs the year/month/day tuple that will be used in serialization
|
/// Also grabs the year/month/day tuple that will be used in serialization
|
||||||
pub fn date_to_datetime(&mut self) {
|
pub fn date_to_datetime(&mut self) {
|
||||||
self.datetime = self.date.as_ref().and_then(parse_datetime);
|
self.datetime = self.date.as_ref().map(|s| s.as_ref()).and_then(parse_datetime);
|
||||||
self.datetime_tuple = self.datetime.map(|dt| (dt.year(), dt.month(), dt.day()));
|
self.datetime_tuple = self.datetime.map(|dt| (dt.year(), dt.month(), dt.day()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,6 +320,23 @@ mod tests {
|
||||||
assert_eq!(res.unwrap().extra["something"]["some-date"], to_value("2002-14-01").unwrap());
|
assert_eq!(res.unwrap().extra["something"]["some-date"], to_value("2002-14-01").unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_parse_fully_nested_dates_in_extra() {
|
||||||
|
let content = r#"
|
||||||
|
title = "Hello"
|
||||||
|
description = "hey there"
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
date_example = 2020-05-04
|
||||||
|
[[extra.questions]]
|
||||||
|
date = 2020-05-03
|
||||||
|
name = "Who is the prime minister of Uganda?""#;
|
||||||
|
let res = PageFrontMatter::parse(content);
|
||||||
|
println!("{:?}", res);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
assert_eq!(res.unwrap().extra["questions"][0]["date"], to_value("2020-05-03").unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_parse_taxonomies() {
|
fn can_parse_taxonomies() {
|
||||||
let content = r#"
|
let content = r#"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use tera::{Map, Value};
|
use tera::{Map, Value};
|
||||||
use toml;
|
|
||||||
|
|
||||||
use super::{InsertAnchor, SortBy};
|
use super::{InsertAnchor, SortBy};
|
||||||
use errors::{bail, Result};
|
use errors::{bail, Result};
|
||||||
|
|
|
@ -534,8 +534,11 @@ impl Site {
|
||||||
pub fn register_early_global_fns(&mut self) {
|
pub fn register_early_global_fns(&mut self) {
|
||||||
self.tera.register_function(
|
self.tera.register_function(
|
||||||
"get_url",
|
"get_url",
|
||||||
global_fns::GetUrl::new(self.config.clone(), self.permalinks.clone(),
|
global_fns::GetUrl::new(
|
||||||
vec![self.static_path.clone(), self.output_path.clone(), self.content_path.clone()]),
|
self.config.clone(),
|
||||||
|
self.permalinks.clone(),
|
||||||
|
vec![self.static_path.clone(), self.output_path.clone(), self.content_path.clone()],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
self.tera.register_function(
|
self.tera.register_function(
|
||||||
"resize_image",
|
"resize_image",
|
||||||
|
@ -551,9 +554,14 @@ impl Site {
|
||||||
"get_taxonomy_url",
|
"get_taxonomy_url",
|
||||||
global_fns::GetTaxonomyUrl::new(&self.config.default_language, &self.taxonomies),
|
global_fns::GetTaxonomyUrl::new(&self.config.default_language, &self.taxonomies),
|
||||||
);
|
);
|
||||||
self.tera.register_function("get_file_hash", global_fns::GetFileHash::new(
|
self.tera.register_function(
|
||||||
vec![self.static_path.clone(), self.output_path.clone(), self.content_path.clone()]
|
"get_file_hash",
|
||||||
));
|
global_fns::GetFileHash::new(vec![
|
||||||
|
self.static_path.clone(),
|
||||||
|
self.output_path.clone(),
|
||||||
|
self.content_path.clone(),
|
||||||
|
]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_tera_global_fns(&mut self) {
|
pub fn register_tera_global_fns(&mut self) {
|
||||||
|
|
|
@ -696,8 +696,11 @@ fn can_cachebust_static_files() {
|
||||||
#[test]
|
#[test]
|
||||||
fn can_get_hash_for_static_files() {
|
fn can_get_hash_for_static_files() {
|
||||||
let (_, _tmp_dir, public) = build_site("test_site");
|
let (_, _tmp_dir, public) = build_site("test_site");
|
||||||
assert!(file_contains!(public, "index.html",
|
assert!(file_contains!(
|
||||||
"src=\"https://replace-this-with-your-url.com/scripts/hello.js\""));
|
public,
|
||||||
|
"index.html",
|
||||||
|
"src=\"https://replace-this-with-your-url.com/scripts/hello.js\""
|
||||||
|
));
|
||||||
assert!(file_contains!(public, "index.html",
|
assert!(file_contains!(public, "index.html",
|
||||||
"integrity=\"sha384-01422f31eaa721a6c4ac8c6fa09a27dd9259e0dfcf3c7593d7810d912a9de5ca2f582df978537bcd10f76896db61fbb9\""));
|
"integrity=\"sha384-01422f31eaa721a6c4ac8c6fa09a27dd9259e0dfcf3c7593d7810d912a9de5ca2f582df978537bcd10f76896db61fbb9\""));
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ toml = "0.5"
|
||||||
csv = "1"
|
csv = "1"
|
||||||
image = "0.23"
|
image = "0.23"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
sha2 = "0.8"
|
sha2 = "0.9"
|
||||||
url = "2"
|
url = "2"
|
||||||
|
|
||||||
errors = { path = "../errors" }
|
errors = { path = "../errors" }
|
||||||
|
|
|
@ -19,6 +19,7 @@ pub fn markdown<S: BuildHasher>(
|
||||||
opts.insert(cmark::Options::ENABLE_TABLES);
|
opts.insert(cmark::Options::ENABLE_TABLES);
|
||||||
opts.insert(cmark::Options::ENABLE_FOOTNOTES);
|
opts.insert(cmark::Options::ENABLE_FOOTNOTES);
|
||||||
opts.insert(cmark::Options::ENABLE_STRIKETHROUGH);
|
opts.insert(cmark::Options::ENABLE_STRIKETHROUGH);
|
||||||
|
opts.insert(cmark::Options::ENABLE_TASKLISTS);
|
||||||
|
|
||||||
let mut html = String::new();
|
let mut html = String::new();
|
||||||
let parser = cmark::Parser::new_ext(&s, opts);
|
let parser = cmark::Parser::new_ext(&s, opts);
|
||||||
|
|
|
@ -209,11 +209,9 @@ impl TeraFn for LoadData {
|
||||||
.header(header::ACCEPT, file_format.as_accept_header())
|
.header(header::ACCEPT, file_format.as_accept_header())
|
||||||
.send()
|
.send()
|
||||||
.and_then(|res| res.error_for_status())
|
.and_then(|res| res.error_for_status())
|
||||||
.map_err(|e| {
|
.map_err(|e| match e.status() {
|
||||||
match e.status() {
|
|
||||||
Some(status) => format!("Failed to request {}: {}", url, status),
|
Some(status) => format!("Failed to request {}: {}", url, status),
|
||||||
None => format!("Could not get response status for url: {}", url),
|
None => format!("Could not get response status for url: {}", url),
|
||||||
}
|
|
||||||
})?;
|
})?;
|
||||||
response
|
response
|
||||||
.text()
|
.text()
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::ffi::OsStr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::{fs, io, result};
|
use std::{fs, io, result};
|
||||||
use std::ffi::OsStr;
|
|
||||||
|
|
||||||
use sha2::{Digest, Sha256, Sha384, Sha512};
|
use sha2::{Digest, Sha256, Sha384, Sha512};
|
||||||
use tera::{from_value, to_value, Error, Function as TeraFn, Result, Value};
|
|
||||||
use svg_metadata as svg;
|
use svg_metadata as svg;
|
||||||
|
use tera::{from_value, to_value, Error, Function as TeraFn, Result, Value};
|
||||||
|
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use image;
|
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
use library::{Library, Taxonomy};
|
use library::{Library, Taxonomy};
|
||||||
use utils::site::resolve_internal_link;
|
use utils::site::resolve_internal_link;
|
||||||
|
|
||||||
use imageproc;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
|
@ -54,13 +51,17 @@ pub struct GetUrl {
|
||||||
search_paths: Vec<PathBuf>,
|
search_paths: Vec<PathBuf>,
|
||||||
}
|
}
|
||||||
impl GetUrl {
|
impl GetUrl {
|
||||||
pub fn new(config: Config, permalinks: HashMap<String, String>, search_paths: Vec<PathBuf>) -> Self {
|
pub fn new(
|
||||||
|
config: Config,
|
||||||
|
permalinks: HashMap<String, String>,
|
||||||
|
search_paths: Vec<PathBuf>,
|
||||||
|
) -> Self {
|
||||||
Self { config, permalinks, search_paths }
|
Self { config, permalinks, search_paths }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_path_with_lang(path: String, lang: &str, config: &Config) -> Result<String> {
|
fn make_path_with_lang(path: String, lang: &str, config: &Config) -> Result<String> {
|
||||||
if lang == &config.default_language {
|
if lang == config.default_language {
|
||||||
return Ok(path);
|
return Ok(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,18 +71,18 @@ fn make_path_with_lang(path: String, lang: &str, config: &Config) -> Result<Stri
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut splitted_path: Vec<String> = path.split(".").map(String::from).collect();
|
let mut splitted_path: Vec<String> = path.split('.').map(String::from).collect();
|
||||||
let ilast = splitted_path.len() - 1;
|
let ilast = splitted_path.len() - 1;
|
||||||
splitted_path[ilast] = format!("{}.{}", lang, splitted_path[ilast]);
|
splitted_path[ilast] = format!("{}.{}", lang, splitted_path[ilast]);
|
||||||
Ok(splitted_path.join("."))
|
Ok(splitted_path.join("."))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_file(search_paths: &Vec<PathBuf>, url: &String) -> result::Result<fs::File, io::Error> {
|
fn open_file(search_paths: &[PathBuf], url: &str) -> result::Result<fs::File, io::Error> {
|
||||||
let cleaned_url = url.trim_start_matches("@/").trim_start_matches("/");
|
let cleaned_url = url.trim_start_matches("@/").trim_start_matches('/');
|
||||||
for base_path in search_paths {
|
for base_path in search_paths {
|
||||||
match fs::File::open(base_path.join(cleaned_url)) {
|
match fs::File::open(base_path.join(cleaned_url)) {
|
||||||
Ok(f) => return Ok(f),
|
Ok(f) => return Ok(f),
|
||||||
Err(_) => continue
|
Err(_) => continue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Err(io::Error::from(io::ErrorKind::NotFound))
|
Err(io::Error::from(io::ErrorKind::NotFound))
|
||||||
|
@ -90,23 +91,28 @@ fn open_file(search_paths: &Vec<PathBuf>, url: &String) -> result::Result<fs::Fi
|
||||||
fn compute_file_sha256(mut file: fs::File) -> result::Result<String, io::Error> {
|
fn compute_file_sha256(mut file: fs::File) -> result::Result<String, io::Error> {
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
io::copy(&mut file, &mut hasher)?;
|
io::copy(&mut file, &mut hasher)?;
|
||||||
Ok(format!("{:x}", hasher.result()))
|
Ok(format!("{:x}", hasher.finalize()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_file_sha384(mut file: fs::File) -> result::Result<String, io::Error> {
|
fn compute_file_sha384(mut file: fs::File) -> result::Result<String, io::Error> {
|
||||||
let mut hasher = Sha384::new();
|
let mut hasher = Sha384::new();
|
||||||
io::copy(&mut file, &mut hasher)?;
|
io::copy(&mut file, &mut hasher)?;
|
||||||
Ok(format!("{:x}", hasher.result()))
|
Ok(format!("{:x}", hasher.finalize()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_file_sha512(mut file: fs::File) -> result::Result<String, io::Error> {
|
fn compute_file_sha512(mut file: fs::File) -> result::Result<String, io::Error> {
|
||||||
let mut hasher = Sha512::new();
|
let mut hasher = Sha512::new();
|
||||||
io::copy(&mut file, &mut hasher)?;
|
io::copy(&mut file, &mut hasher)?;
|
||||||
Ok(format!("{:x}", hasher.result()))
|
Ok(format!("{:x}", hasher.finalize()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_not_found_err(search_paths: &Vec<PathBuf>, url: &String) -> Result<Value> {
|
fn file_not_found_err(search_paths: &[PathBuf], url: &str) -> Result<Value> {
|
||||||
Err(format!("file `{}` not found; searched in{}", url,
|
Err(format!(
|
||||||
search_paths.iter().fold(String::new(),
|
"file `{}` not found; searched in{}",
|
||||||
|acc, arg| acc + " " + arg.to_str().unwrap())).into())
|
url,
|
||||||
|
search_paths.iter().fold(String::new(), |acc, arg| acc + " " + arg.to_str().unwrap())
|
||||||
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TeraFn for GetUrl {
|
impl TeraFn for GetUrl {
|
||||||
|
@ -151,8 +157,8 @@ impl TeraFn for GetUrl {
|
||||||
match open_file(&self.search_paths, &path).and_then(compute_file_sha256) {
|
match open_file(&self.search_paths, &path).and_then(compute_file_sha256) {
|
||||||
Ok(hash) => {
|
Ok(hash) => {
|
||||||
permalink = format!("{}?h={}", permalink, hash);
|
permalink = format!("{}?h={}", permalink, hash);
|
||||||
},
|
}
|
||||||
Err(_) => return file_not_found_err(&self.search_paths, &path)
|
Err(_) => return file_not_found_err(&self.search_paths, &path),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(to_value(permalink).unwrap())
|
Ok(to_value(permalink).unwrap())
|
||||||
|
@ -183,20 +189,21 @@ impl TeraFn for GetFileHash {
|
||||||
u16,
|
u16,
|
||||||
args.get("sha_type"),
|
args.get("sha_type"),
|
||||||
"`get_file_hash`: `sha_type` must be 256, 384 or 512"
|
"`get_file_hash`: `sha_type` must be 256, 384 or 512"
|
||||||
).unwrap_or(DEFAULT_SHA_TYPE);
|
)
|
||||||
|
.unwrap_or(DEFAULT_SHA_TYPE);
|
||||||
|
|
||||||
let compute_hash_fn = match sha_type {
|
let compute_hash_fn = match sha_type {
|
||||||
256 => compute_file_sha256,
|
256 => compute_file_sha256,
|
||||||
384 => compute_file_sha384,
|
384 => compute_file_sha384,
|
||||||
512 => compute_file_sha512,
|
512 => compute_file_sha512,
|
||||||
_ => return Err("`get_file_hash`: `sha_type` must be 256, 384 or 512".into())
|
_ => return Err("`get_file_hash`: `sha_type` must be 256, 384 or 512".into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let hash = open_file(&self.search_paths, &path).and_then(compute_hash_fn);
|
let hash = open_file(&self.search_paths, &path).and_then(compute_hash_fn);
|
||||||
|
|
||||||
match hash {
|
match hash {
|
||||||
Ok(digest) => Ok(to_value(digest).unwrap()),
|
Ok(digest) => Ok(to_value(digest).unwrap()),
|
||||||
Err(_) => file_not_found_err(&self.search_paths, &path)
|
Err(_) => file_not_found_err(&self.search_paths, &path),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,7 +304,7 @@ fn image_dimensions(path: &PathBuf) -> Result<(u32, u32)> {
|
||||||
match (img.height(), img.width(), img.view_box()) {
|
match (img.height(), img.width(), img.view_box()) {
|
||||||
(Some(h), Some(w), _) => Ok((h as u32, w as u32)),
|
(Some(h), Some(w), _) => Ok((h as u32, w as u32)),
|
||||||
(_, _, Some(view_box)) => Ok((view_box.height as u32, view_box.width as u32)),
|
(_, _, Some(view_box)) => Ok((view_box.height as u32, view_box.width as u32)),
|
||||||
_ => Err("Invalid dimensions: SVG width/height and viewbox not set.".into())
|
_ => Err("Invalid dimensions: SVG width/height and viewbox not set.".into()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let img = image::open(&path)
|
let img = image::open(&path)
|
||||||
|
@ -465,7 +472,7 @@ impl TeraFn for GetTaxonomy {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{GetTaxonomy, GetTaxonomyUrl, GetUrl, Trans, GetFileHash};
|
use super::{GetFileHash, GetTaxonomy, GetTaxonomyUrl, GetUrl, Trans};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env::temp_dir;
|
use std::env::temp_dir;
|
||||||
|
@ -786,7 +793,10 @@ title = "A title"
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("path".to_string(), to_value("app.css").unwrap());
|
args.insert("path".to_string(), to_value("app.css").unwrap());
|
||||||
args.insert("sha_type".to_string(), to_value(256).unwrap());
|
args.insert("sha_type".to_string(), to_value(256).unwrap());
|
||||||
assert_eq!(static_fn.call(&args).unwrap(), "572e691dc68c3fcd653ae463261bdb38f35dc6f01715d9ce68799319dd158840");
|
assert_eq!(
|
||||||
|
static_fn.call(&args).unwrap(),
|
||||||
|
"572e691dc68c3fcd653ae463261bdb38f35dc6f01715d9ce68799319dd158840"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -812,8 +822,10 @@ title = "A title"
|
||||||
let mut args = HashMap::new();
|
let mut args = HashMap::new();
|
||||||
args.insert("path".to_string(), to_value("doesnt-exist").unwrap());
|
args.insert("path".to_string(), to_value("doesnt-exist").unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("file `doesnt-exist` not found; searched in {}",
|
format!(
|
||||||
TEST_CONTEXT.static_path.to_str().unwrap()),
|
"file `doesnt-exist` not found; searched in {}",
|
||||||
|
TEST_CONTEXT.static_path.to_str().unwrap()
|
||||||
|
),
|
||||||
format!("{}", static_fn.call(&args).unwrap_err())
|
format!("{}", static_fn.call(&args).unwrap_err())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
use tera::{Map, Value};
|
use tera::{Map, Value};
|
||||||
use toml;
|
|
||||||
|
|
||||||
/// Used as an attribute when we want to convert from TOML to a string date
|
/// Used as an attribute when we want to convert from TOML to a string date
|
||||||
pub fn from_toml_datetime<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
|
pub fn from_toml_datetime<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
|
||||||
|
@ -43,6 +42,16 @@ pub fn fix_toml_dates(table: Map<String, Value>) -> Value {
|
||||||
Value::Object(o) => {
|
Value::Object(o) => {
|
||||||
new.insert(key, convert_toml_date(o));
|
new.insert(key, convert_toml_date(o));
|
||||||
}
|
}
|
||||||
|
Value::Array(arr) => {
|
||||||
|
let mut new_arr = Vec::with_capacity(arr.len());
|
||||||
|
for v in arr {
|
||||||
|
match v {
|
||||||
|
Value::Object(o) => new_arr.push(fix_toml_dates(o)),
|
||||||
|
_ => new_arr.push(v),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
new.insert(key, Value::Array(new_arr));
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
new.insert(key, value);
|
new.insert(key, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
command = "zola build"
|
command = "zola build"
|
||||||
|
|
||||||
[build.environment]
|
[build.environment]
|
||||||
ZOLA_VERSION = "0.8.0"
|
ZOLA_VERSION = "0.11.0"
|
||||||
|
|
||||||
[context.deploy-preview]
|
[context.deploy-preview]
|
||||||
command = "zola build --base-url $DEPLOY_PRIME_URL"
|
command = "zola build --base-url $DEPLOY_PRIME_URL"
|
||||||
|
|
|
@ -35,7 +35,6 @@ use hyper_staticfile::ResolveResult;
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use ctrlc;
|
|
||||||
use notify::{watcher, RecursiveMode, Watcher};
|
use notify::{watcher, RecursiveMode, Watcher};
|
||||||
use ws::{Message, Sender, WebSocket};
|
use ws::{Message, Sender, WebSocket};
|
||||||
|
|
||||||
|
@ -45,8 +44,6 @@ use site::Site;
|
||||||
use utils::fs::copy_file;
|
use utils::fs::copy_file;
|
||||||
|
|
||||||
use crate::console;
|
use crate::console;
|
||||||
use open;
|
|
||||||
use rebuild;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
enum ChangeKind {
|
enum ChangeKind {
|
||||||
|
|
|
@ -5,7 +5,6 @@ use std::error::Error as StdError;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use atty;
|
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue