From 2e541cc9518072b30dc2973bdeda086e48f6829c Mon Sep 17 00:00:00 2001
From: prescientmoon <git@moonythm.dev>
Date: Wed, 11 Jun 2025 07:18:22 +0200
Subject: [PATCH] Refactor some things

For instance, `role=description` has been moved to a `description`
class.
---
 flake.lock        |  6 +++---
 justfile          | 54 ++++++++++++++++++++++++++++++++++-------------
 nix/moonythm.nix  |  5 +++--
 public/styles.css |  1 +
 src/generate.rs   | 13 ++++++++----
 src/html.rs       | 24 +++++++++++++--------
 src/metadata.rs   | 21 +++++++++---------
 7 files changed, 81 insertions(+), 43 deletions(-)

diff --git a/flake.lock b/flake.lock
index c6cfbf9..885a0dd 100644
--- a/flake.lock
+++ b/flake.lock
@@ -20,11 +20,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1728492678,
-        "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=",
+        "lastModified": 1749285348,
+        "narHash": "sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU=",
         "owner": "nixos",
         "repo": "nixpkgs",
-        "rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7",
+        "rev": "3e3afe5174c561dee0df6f2c2b2236990146329f",
         "type": "github"
       },
       "original": {
diff --git a/justfile b/justfile
index 4a62748..5526656 100644
--- a/justfile
+++ b/justfile
@@ -1,30 +1,50 @@
-default:
-  @just --list
-
-minify-sitemap:
-  xmllint --noblanks dist/sitemap.xml --output dist/sitemap.xml
-
-serve-dev:
-  http-server dist
-
-# {{{ Building
-build:
-  cargo run
-
-build-dev:
-  MOONYTHM_DRAFTS=1 cargo run
+[private]
+@default:
+  just --list
 
+[doc("Update file modification dates, comitting them to git")]
 update-modification-dates:
   MOONYTHM_UPDATE_LAST_MODIFIED=1 cargo run
   git add last_modified.toml
   git commit -m "Update \`last_modified.toml\`"
+
+[doc("Copy the current date to clipboard in the required `created_at` format")]
+current-date:
+  date --rfc-3339=seconds | wl-copy
+
+[doc("Serve the build website locally")]
+serve-dev:
+  http-server dist
+
+# {{{ Building
+[private]
+[group("build")]
+[doc("Minify the sitemap .xml file")]
+minify-sitemap:
+  xmllint --noblanks dist/sitemap.xml --output dist/sitemap.xml
+
+[group("build")]
+[doc("Build the website")]
+build:
+  cargo run
+  just minify-sitemap
+
+[group("build")]
+[doc("Build the website, including draft posts")]
+build-dev:
+  MOONYTHM_DRAFTS=1 cargo run
 # }}}
 # {{{ Linting
+[group("lint")]
 lint: lint-vnu lint-css lint-htmltest lint-htmlvalidate
 
+[group("lint")]
+[doc("Run htmltest on the generated html files")]
 lint-htmltest:
   htmltest -c tooling/htmltest.yml dist
 
+[group("lint")]
+[doc("Run htmlvalidate on the generated html files")]
 lint-htmlvalidate:
   #!/usr/bin/env bash
   shopt -s globstar
@@ -32,6 +52,8 @@ lint-htmlvalidate:
   npx --prefix tooling \
     html-validate -c tooling/htmlvalidate.json dist/**/*.html
 
+[group("lint")]
+[doc("Run the VNU linter on the generated html & svg files")]
 lint-vnu:
   #!/usr/bin/env bash
   shopt -s globstar
@@ -52,6 +74,8 @@ lint-vnu:
     exit 0
   fi
 
+[group("lint")]
+[doc("Run stylelint on the generated stylesheets")]
 lint-css:
   npx --prefix tooling stylelint dist/**/*.css \
     --config ./tooling/stylelintrc.json \
diff --git a/nix/moonythm.nix b/nix/moonythm.nix
index 1af9833..c2aea0c 100644
--- a/nix/moonythm.nix
+++ b/nix/moonythm.nix
@@ -7,6 +7,7 @@ runCommand "moonythm" { } ''
 
   cd ${../.}
 
-  export MOONYTHM_BASE_URL="https://moonythm.dev"
-  MOONYTHM_OUT_DIR="$out" ${moonythm-generator}/bin/moonythm
+  export MOONYTHM_BASE_URL "https://moonythm.dev"
+  export MOONYTHM_OUT_DIR  "$out"
+  ${moonythm-generator}/bin/moonythm
 ''
diff --git a/public/styles.css b/public/styles.css
index 2b2953a..8f37baf 100644
--- a/public/styles.css
+++ b/public/styles.css
@@ -256,6 +256,7 @@ pre > code {
 /* }}} */
 /* {{{ Figure */
 figure {
+  text-align: center;
   margin: 2rem;
 }
 
diff --git a/src/generate.rs b/src/generate.rs
index 3262124..56555d1 100644
--- a/src/generate.rs
+++ b/src/generate.rs
@@ -23,7 +23,7 @@ pub struct Pages<'a> {
 	base_url: String,
 }
 
-impl<'a> Pages<'a> {
+impl Pages<'_> {
 	pub fn new(content_root: PathBuf, out_root: PathBuf) -> anyhow::Result<Self> {
 		Ok(Self {
 			last_modified_cache: LastModifiedCache::from_file()?,
@@ -51,8 +51,13 @@ impl<'a> Pages<'a> {
 		let source = Box::leak(Box::new(source));
 
 		let events = jotdown::Parser::new(source);
-		let metadata =
-			PageMetadata::new(&mut self.last_modified_cache, content_path, source, events)?;
+		let metadata = PageMetadata::new(
+			&mut self.last_modified_cache,
+			content_path.as_path(),
+			source,
+			events,
+		)
+		.with_context(|| format!("While reading file {content_path:?}"))?;
 
 		if std::env::var("MOONYTHM_DRAFTS").unwrap_or_default() == "1"
 			|| (metadata.config.created_at.is_some()
@@ -75,7 +80,7 @@ impl<'a> Pages<'a> {
 			let path = path.join(filename);
 			if file_path.is_dir() {
 				self.add_dir(&path)?;
-			} else if file_path.extension().map_or(false, |ext| ext == "dj") {
+			} else if file_path.extension().is_some_and(|ext| ext == "dj") {
 				self.add_page(&path)?;
 			} else {
 				self.assets.push(path);
diff --git a/src/html.rs b/src/html.rs
index 68da96e..9171531 100644
--- a/src/html.rs
+++ b/src/html.rs
@@ -424,7 +424,12 @@ impl<'s> Writer<'s> {
 						self.states.push(State::Ignore);
 					}
 					// }}}
-					// {{{ Embed description
+					// {{{ Descriptions
+					Container::Div {
+						class: "description",
+					} => {
+						self.states.push(State::Ignore);
+					}
 					Container::Div {
 						class: "embed-description",
 					} => {
@@ -455,21 +460,22 @@ impl<'s> Writer<'s> {
 						let src = attrs.get_value("src").ok_or_else(|| {
 							anyhow!("Figure element encountered without a `src` attribute")
 						})?;
+						let width = attrs.get_value("width");
 
 						write!(out, r#"<figure><img alt=""#)?;
 						write_attribute(out, &alt)?;
 						write!(out, r#"" src=""#)?;
 						write_attribute(out, &src)?;
+						if let Some(width) = width {
+							write!(out, r#"" width=""#)?;
+							write_attribute(out, &width)?;
+						}
 						write!(out, r#""><figcaption>"#)?;
 					}
 					// }}}
 					// {{{ Div
 					Container::Div { class } => {
-						if has_role(attrs, "description") {
-							self.states.push(State::Ignore);
-						} else {
-							write!(out, "<div{}>", Attr("class", class))?;
-						}
+						write!(out, "<div{}>", Attr("class", class))?;
 					}
 					// }}}
 					// {{{ Raw block
@@ -976,7 +982,7 @@ impl<'s> Writer<'s> {
 // {{{ HTMl escaper
 pub struct Escaped<'a>(&'a str);
 
-impl<'s> Display for Escaped<'s> {
+impl Display for Escaped<'_> {
 	fn fmt(&self, out: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 		let mut s = self.0;
 		let mut ent = "";
@@ -988,7 +994,7 @@ impl<'s> Display for Escaped<'s> {
 				'"' => Some("&quot;"),
 				_ => None,
 			}
-			.map_or(false, |s| {
+			.is_some_and(|s| {
 				ent = s;
 				true
 			})
@@ -1004,7 +1010,7 @@ impl<'s> Display for Escaped<'s> {
 // {{{ Render attributes
 pub struct Attr<'a>(&'static str, &'a str);
 
-impl<'s> Display for Attr<'s> {
+impl Display for Attr<'_> {
 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 		if !self.1.is_empty() {
 			write!(f, r#" {}="{}""#, self.0, Escaped(self.1))?;
diff --git a/src/metadata.rs b/src/metadata.rs
index b929580..ffa030c 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -166,17 +166,17 @@ pub struct PageMetadata<'s> {
 impl<'a> PageMetadata<'a> {
 	pub fn new(
 		last_modified_cache: &mut LastModifiedCache,
-		path: PathBuf,
+		path: &Path,
 		source: &'a str,
 		mut events: impl Iterator<Item = Event<'a>>,
 	) -> anyhow::Result<Self> {
-		let route = PageRoute::from_path(&path)?;
+		let route = PageRoute::from_path(path)?;
 		let last_modified = if should_refresh_last_modified() {
 			let last_modified_output = Command::new("git")
 				.arg("log")
 				.arg("-1")
 				.arg(r#"--pretty=format:%cI"#)
-				.arg(&path)
+				.arg(path)
 				.output()
 				.with_context(|| anyhow!("Could not read the last modification date for file"))?
 				.stdout;
@@ -219,7 +219,7 @@ impl<'a> PageMetadata<'a> {
 			route,
 			title: title.clone(),
 			last_modified,
-			source_path: path,
+			source_path: path.to_path_buf(),
 			source,
 			config: w.config,
 			description: w.description,
@@ -306,11 +306,12 @@ impl<'s> Writer<'s> {
 			}
 			// }}}
 			// {{{ Descriptions
-			Event::Start(Container::Div { .. }, attrs) if self.state == State::Toplevel => {
-				if has_role(attrs, "description") {
-					self.state = State::Description
-				}
-			}
+			Event::Start(
+				Container::Div {
+					class: "description",
+				},
+				_,
+			) if self.state == State::Toplevel => self.state = State::Description,
 			Event::End(Container::Div { .. }) if self.state == State::Description => {
 				self.state = State::Toplevel;
 			}
@@ -336,7 +337,7 @@ impl<'s> Writer<'s> {
 pub fn has_role(attrs: &Attributes, value: &str) -> bool {
 	attrs
 		.get_value("role")
-		.map_or(false, |role| format!("{role}") == value)
+		.is_some_and(|role| format!("{role}") == value)
 }
 // }}}
 // {{{ Last modified cache