diff options
-rw-r--r-- | Cargo.lock | 75 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | riki.md | 23 | ||||
-rw-r--r-- | src/directive/meta.rs | 16 | ||||
-rw-r--r-- | src/error.rs | 3 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/time.rs | 48 | ||||
-rw-r--r-- | src/util.rs | 6 | ||||
-rw-r--r-- | src/wikitext.rs | 2 |
9 files changed, 101 insertions, 74 deletions
@@ -74,12 +74,6 @@ dependencies = [ ] [[package]] -name = "bumpalo" -version = "3.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" - -[[package]] name = "cc" version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -529,15 +523,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] -name = "js-sys" -version = "0.3.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" -dependencies = [ - "wasm-bindgen", -] - -[[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -934,6 +919,7 @@ dependencies = [ "subplot-build 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "subplotlib", "thiserror", + "time", "walkdir", ] @@ -1370,12 +1356,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b7cc93fc23ba97fde84f7eea56c55d1ba183f495c6715defdfc7b9cb8c870f" +checksum = "db76ff9fa4b1458b3c7f077f3ff9887394058460d21e634355b273aaf11eea45" dependencies = [ "itoa", - "js-sys", "libc", "num_threads", "time-macros", @@ -1595,60 +1580,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "wasm-bindgen" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" - -[[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -16,6 +16,7 @@ pulldown-cmark = "0.9.0" regex = "1.5.6" structopt = "0.3.25" thiserror = "1.0.31" +time = { version = "0.3.13", features = ["macros", "parsing"] } walkdir = "2.3.2" [build-dependencies] @@ -582,3 +582,26 @@ when I run riki build site output then file output/index.html has a very old modification time then file output/index.jpg has a very old modification time ~~~ + +### Output files have source `meta date` modification times + +_Requirement: Files in the output directory have the time stamp +specified in a `meta date` directive._ + +Note that due to limitations in the Subplot `lib/files` library, our +check for modification times is imprecise. + +~~~scenario +given an installed riki +given file site/index.mdwn from dated +given file site/index.mdwn has modification time 2022-02-02 01:02:03 +when I run riki build site output +then file output/index.html has a very old modification time +~~~ + + +~~~{#dated .file .markdown} +[[!meta date="1970-01-01 00:00:00"]] + +Hello. +~~~ diff --git a/src/directive/meta.rs b/src/directive/meta.rs index 6f47d45..ddbdeaa 100644 --- a/src/directive/meta.rs +++ b/src/directive/meta.rs @@ -2,10 +2,12 @@ use crate::error::SiteError; use crate::page::PageMeta; use crate::site::Site; use crate::wikitext::ParsedDirective; +use crate::time::parse_timestamp; #[derive(Default, Debug, Eq, PartialEq)] pub struct Meta { title: Option<String>, + date: Option<String>, } impl Meta { @@ -13,6 +15,10 @@ impl Meta { pub const ALLOWED: &'static [&'static str] = &["date", "link", "title", "author"]; pub const ALLOW_ANY_UNNAMED: bool = false; + fn set_date(&mut self, date: &str) { + self.date = Some(date.into()); + } + fn set_title(&mut self, title: &str) { self.title = Some(title.into()); } @@ -21,6 +27,9 @@ impl Meta { if let Some(title) = &self.title { meta.set_title(title.into()); } + if let Some(mtime) = &self.date { + meta.set_mtime(parse_timestamp(mtime)?); + } Ok("".into()) } } @@ -32,6 +41,13 @@ impl From<&ParsedDirective> for Meta { if let Some(title) = args.get("title") { meta.set_title(title); } + if let Some(date) = args.get("date") { + meta.set_date(date); + } meta } } + +#[cfg(test)] +mod test { +} diff --git a/src/error.rs b/src/error.rs index 4fdcc1f..b258cda 100644 --- a/src/error.rs +++ b/src/error.rs @@ -73,4 +73,7 @@ pub enum SiteError { #[error("git {0} in in {1}:\n{2}")] GitError(String, PathBuf, String), + + #[error("failed to parse date: {0:?}")] + UnknownTimestamp(String), } @@ -17,4 +17,5 @@ pub mod site; pub mod token; pub mod git; pub mod util; +pub mod time; pub mod wikitext; diff --git a/src/time.rs b/src/time.rs new file mode 100644 index 0000000..94767cd --- /dev/null +++ b/src/time.rs @@ -0,0 +1,48 @@ +use crate::error::SiteError; +use std::time::{Duration, SystemTime}; +use time::{ + format_description::well_known::{Iso8601, Rfc2822}, + format_description::FormatItem, + macros::format_description, + parsing::Parsable, + OffsetDateTime, PrimitiveDateTime, +}; + +pub fn parse_timestamp(timestamp: &str) -> Result<SystemTime, SiteError> { + let odt = parse(timestamp)?; + let unix = odt.unix_timestamp(); + Ok(system_time(unix)) +} + +fn system_time(unix: i64) -> SystemTime { + let offset = Duration::from_secs(unix as u64); + SystemTime::UNIX_EPOCH.checked_add(offset).unwrap() +} + +fn parse(timestamp: &str) -> Result<OffsetDateTime, SiteError> { + const SIMPLIFIED_ISO9601: &[FormatItem<'static>] = + format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"); + + if let Ok(t) = parse_one_time_format(timestamp, "simplified", SIMPLIFIED_ISO9601) { + Ok(t) + } else if let Ok(t) = parse_one_time_format(timestamp, "ISO8601", &Iso8601::PARSING) { + Ok(t) + } else if let Ok(t) = parse_one_time_format(timestamp, "RFC2822", &Rfc2822) { + Ok(t) + } else { + Err(SiteError::UnknownTimestamp(timestamp.into())) + } +} + +fn parse_one_time_format( + timestamp: &str, + _what: &str, + fmt: &(impl Parsable + ?Sized), +) -> Result<OffsetDateTime, time::error::Parse> { + let r = PrimitiveDateTime::parse(timestamp, fmt); + if let Ok(t) = r { + Ok(t.assume_utc()) + } else { + Err(r.err().unwrap()) + } +} diff --git a/src/util.rs b/src/util.rs index 7909080..064e556 100644 --- a/src/util.rs +++ b/src/util.rs @@ -34,7 +34,11 @@ pub fn get_mtime(src: &Path) -> Result<SystemTime, SiteError> { } pub fn set_mtime(filename: &Path, mtime: SystemTime) -> Result<(), SiteError> { - trace!("set_mtime: filename={} mtime={:?}", filename.display(), mtime); + trace!( + "set_mtime: filename={} mtime={:?}", + filename.display(), + mtime + ); let mtime = timespec(mtime)?; let times = [mtime, mtime]; diff --git a/src/wikitext.rs b/src/wikitext.rs index 91ac30b..a73e004 100644 --- a/src/wikitext.rs +++ b/src/wikitext.rs @@ -27,7 +27,7 @@ impl Snippet { if let Ok(d) = e { d.process(site, meta)? } else if let Some(shortcut) = site.shortcut(p.name()) { - let arg = p.unnamed_args().get(0).unwrap().to_string(); + let arg = p.unnamed_args().first().unwrap().to_string(); format!("[{}]({})", shortcut.desc(&arg), shortcut.url(&arg)) } else { return Err(e.unwrap_err()); |