summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock75
-rw-r--r--Cargo.toml1
-rw-r--r--riki.md23
-rw-r--r--src/directive/meta.rs16
-rw-r--r--src/error.rs3
-rw-r--r--src/lib.rs1
-rw-r--r--src/time.rs48
-rw-r--r--src/util.rs6
-rw-r--r--src/wikitext.rs2
9 files changed, 101 insertions, 74 deletions
diff --git a/Cargo.lock b/Cargo.lock
index da89cb7..783f318 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index b48ed36..2b08d0b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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]
diff --git a/riki.md b/riki.md
index 912dbac..dffd617 100644
--- a/riki.md
+++ b/riki.md
@@ -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),
}
diff --git a/src/lib.rs b/src/lib.rs
index a699e7d..58f6fc4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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());