Refactor some things
For instance, `role=description` has been moved to a `description` class.
This commit is contained in:
parent
d0aa99d03e
commit
2e541cc951
7 changed files with 81 additions and 43 deletions
6
flake.lock
generated
6
flake.lock
generated
|
@ -20,11 +20,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1728492678,
|
"lastModified": 1749285348,
|
||||||
"narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=",
|
"narHash": "sha256-frdhQvPbmDYaScPFiCnfdh3B/Vh81Uuoo0w5TkWmmjU=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7",
|
"rev": "3e3afe5174c561dee0df6f2c2b2236990146329f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
54
justfile
54
justfile
|
@ -1,30 +1,50 @@
|
||||||
default:
|
[private]
|
||||||
@just --list
|
@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
|
|
||||||
|
|
||||||
|
[doc("Update file modification dates, comitting them to git")]
|
||||||
update-modification-dates:
|
update-modification-dates:
|
||||||
MOONYTHM_UPDATE_LAST_MODIFIED=1 cargo run
|
MOONYTHM_UPDATE_LAST_MODIFIED=1 cargo run
|
||||||
git add last_modified.toml
|
git add last_modified.toml
|
||||||
git commit -m "Update \`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
|
# {{{ Linting
|
||||||
|
[group("lint")]
|
||||||
lint: lint-vnu lint-css lint-htmltest lint-htmlvalidate
|
lint: lint-vnu lint-css lint-htmltest lint-htmlvalidate
|
||||||
|
|
||||||
|
[group("lint")]
|
||||||
|
[doc("Run htmltest on the generated html files")]
|
||||||
lint-htmltest:
|
lint-htmltest:
|
||||||
htmltest -c tooling/htmltest.yml dist
|
htmltest -c tooling/htmltest.yml dist
|
||||||
|
|
||||||
|
[group("lint")]
|
||||||
|
[doc("Run htmlvalidate on the generated html files")]
|
||||||
lint-htmlvalidate:
|
lint-htmlvalidate:
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
shopt -s globstar
|
shopt -s globstar
|
||||||
|
@ -32,6 +52,8 @@ lint-htmlvalidate:
|
||||||
npx --prefix tooling \
|
npx --prefix tooling \
|
||||||
html-validate -c tooling/htmlvalidate.json dist/**/*.html
|
html-validate -c tooling/htmlvalidate.json dist/**/*.html
|
||||||
|
|
||||||
|
[group("lint")]
|
||||||
|
[doc("Run the VNU linter on the generated html & svg files")]
|
||||||
lint-vnu:
|
lint-vnu:
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
shopt -s globstar
|
shopt -s globstar
|
||||||
|
@ -52,6 +74,8 @@ lint-vnu:
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
[group("lint")]
|
||||||
|
[doc("Run stylelint on the generated stylesheets")]
|
||||||
lint-css:
|
lint-css:
|
||||||
npx --prefix tooling stylelint dist/**/*.css \
|
npx --prefix tooling stylelint dist/**/*.css \
|
||||||
--config ./tooling/stylelintrc.json \
|
--config ./tooling/stylelintrc.json \
|
||||||
|
|
|
@ -7,6 +7,7 @@ runCommand "moonythm" { } ''
|
||||||
|
|
||||||
cd ${../.}
|
cd ${../.}
|
||||||
|
|
||||||
export MOONYTHM_BASE_URL="https://moonythm.dev"
|
export MOONYTHM_BASE_URL "https://moonythm.dev"
|
||||||
MOONYTHM_OUT_DIR="$out" ${moonythm-generator}/bin/moonythm
|
export MOONYTHM_OUT_DIR "$out"
|
||||||
|
${moonythm-generator}/bin/moonythm
|
||||||
''
|
''
|
||||||
|
|
|
@ -256,6 +256,7 @@ pre > code {
|
||||||
/* }}} */
|
/* }}} */
|
||||||
/* {{{ Figure */
|
/* {{{ Figure */
|
||||||
figure {
|
figure {
|
||||||
|
text-align: center;
|
||||||
margin: 2rem;
|
margin: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub struct Pages<'a> {
|
||||||
base_url: String,
|
base_url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Pages<'a> {
|
impl Pages<'_> {
|
||||||
pub fn new(content_root: PathBuf, out_root: PathBuf) -> anyhow::Result<Self> {
|
pub fn new(content_root: PathBuf, out_root: PathBuf) -> anyhow::Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
last_modified_cache: LastModifiedCache::from_file()?,
|
last_modified_cache: LastModifiedCache::from_file()?,
|
||||||
|
@ -51,8 +51,13 @@ impl<'a> Pages<'a> {
|
||||||
let source = Box::leak(Box::new(source));
|
let source = Box::leak(Box::new(source));
|
||||||
|
|
||||||
let events = jotdown::Parser::new(source);
|
let events = jotdown::Parser::new(source);
|
||||||
let metadata =
|
let metadata = PageMetadata::new(
|
||||||
PageMetadata::new(&mut self.last_modified_cache, content_path, source, events)?;
|
&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"
|
if std::env::var("MOONYTHM_DRAFTS").unwrap_or_default() == "1"
|
||||||
|| (metadata.config.created_at.is_some()
|
|| (metadata.config.created_at.is_some()
|
||||||
|
@ -75,7 +80,7 @@ impl<'a> Pages<'a> {
|
||||||
let path = path.join(filename);
|
let path = path.join(filename);
|
||||||
if file_path.is_dir() {
|
if file_path.is_dir() {
|
||||||
self.add_dir(&path)?;
|
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)?;
|
self.add_page(&path)?;
|
||||||
} else {
|
} else {
|
||||||
self.assets.push(path);
|
self.assets.push(path);
|
||||||
|
|
24
src/html.rs
24
src/html.rs
|
@ -424,7 +424,12 @@ impl<'s> Writer<'s> {
|
||||||
self.states.push(State::Ignore);
|
self.states.push(State::Ignore);
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
// {{{ Embed description
|
// {{{ Descriptions
|
||||||
|
Container::Div {
|
||||||
|
class: "description",
|
||||||
|
} => {
|
||||||
|
self.states.push(State::Ignore);
|
||||||
|
}
|
||||||
Container::Div {
|
Container::Div {
|
||||||
class: "embed-description",
|
class: "embed-description",
|
||||||
} => {
|
} => {
|
||||||
|
@ -455,21 +460,22 @@ impl<'s> Writer<'s> {
|
||||||
let src = attrs.get_value("src").ok_or_else(|| {
|
let src = attrs.get_value("src").ok_or_else(|| {
|
||||||
anyhow!("Figure element encountered without a `src` attribute")
|
anyhow!("Figure element encountered without a `src` attribute")
|
||||||
})?;
|
})?;
|
||||||
|
let width = attrs.get_value("width");
|
||||||
|
|
||||||
write!(out, r#"<figure><img alt=""#)?;
|
write!(out, r#"<figure><img alt=""#)?;
|
||||||
write_attribute(out, &alt)?;
|
write_attribute(out, &alt)?;
|
||||||
write!(out, r#"" src=""#)?;
|
write!(out, r#"" src=""#)?;
|
||||||
write_attribute(out, &src)?;
|
write_attribute(out, &src)?;
|
||||||
|
if let Some(width) = width {
|
||||||
|
write!(out, r#"" width=""#)?;
|
||||||
|
write_attribute(out, &width)?;
|
||||||
|
}
|
||||||
write!(out, r#""><figcaption>"#)?;
|
write!(out, r#""><figcaption>"#)?;
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
// {{{ Div
|
// {{{ Div
|
||||||
Container::Div { class } => {
|
Container::Div { class } => {
|
||||||
if has_role(attrs, "description") {
|
write!(out, "<div{}>", Attr("class", class))?;
|
||||||
self.states.push(State::Ignore);
|
|
||||||
} else {
|
|
||||||
write!(out, "<div{}>", Attr("class", class))?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
// {{{ Raw block
|
// {{{ Raw block
|
||||||
|
@ -976,7 +982,7 @@ impl<'s> Writer<'s> {
|
||||||
// {{{ HTMl escaper
|
// {{{ HTMl escaper
|
||||||
pub struct Escaped<'a>(&'a str);
|
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 {
|
fn fmt(&self, out: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let mut s = self.0;
|
let mut s = self.0;
|
||||||
let mut ent = "";
|
let mut ent = "";
|
||||||
|
@ -988,7 +994,7 @@ impl<'s> Display for Escaped<'s> {
|
||||||
'"' => Some("""),
|
'"' => Some("""),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
.map_or(false, |s| {
|
.is_some_and(|s| {
|
||||||
ent = s;
|
ent = s;
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
|
@ -1004,7 +1010,7 @@ impl<'s> Display for Escaped<'s> {
|
||||||
// {{{ Render attributes
|
// {{{ Render attributes
|
||||||
pub struct Attr<'a>(&'static str, &'a str);
|
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 {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
if !self.1.is_empty() {
|
if !self.1.is_empty() {
|
||||||
write!(f, r#" {}="{}""#, self.0, Escaped(self.1))?;
|
write!(f, r#" {}="{}""#, self.0, Escaped(self.1))?;
|
||||||
|
|
|
@ -166,17 +166,17 @@ pub struct PageMetadata<'s> {
|
||||||
impl<'a> PageMetadata<'a> {
|
impl<'a> PageMetadata<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
last_modified_cache: &mut LastModifiedCache,
|
last_modified_cache: &mut LastModifiedCache,
|
||||||
path: PathBuf,
|
path: &Path,
|
||||||
source: &'a str,
|
source: &'a str,
|
||||||
mut events: impl Iterator<Item = Event<'a>>,
|
mut events: impl Iterator<Item = Event<'a>>,
|
||||||
) -> anyhow::Result<Self> {
|
) -> 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 = if should_refresh_last_modified() {
|
||||||
let last_modified_output = Command::new("git")
|
let last_modified_output = Command::new("git")
|
||||||
.arg("log")
|
.arg("log")
|
||||||
.arg("-1")
|
.arg("-1")
|
||||||
.arg(r#"--pretty=format:%cI"#)
|
.arg(r#"--pretty=format:%cI"#)
|
||||||
.arg(&path)
|
.arg(path)
|
||||||
.output()
|
.output()
|
||||||
.with_context(|| anyhow!("Could not read the last modification date for file"))?
|
.with_context(|| anyhow!("Could not read the last modification date for file"))?
|
||||||
.stdout;
|
.stdout;
|
||||||
|
@ -219,7 +219,7 @@ impl<'a> PageMetadata<'a> {
|
||||||
route,
|
route,
|
||||||
title: title.clone(),
|
title: title.clone(),
|
||||||
last_modified,
|
last_modified,
|
||||||
source_path: path,
|
source_path: path.to_path_buf(),
|
||||||
source,
|
source,
|
||||||
config: w.config,
|
config: w.config,
|
||||||
description: w.description,
|
description: w.description,
|
||||||
|
@ -306,11 +306,12 @@ impl<'s> Writer<'s> {
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
// {{{ Descriptions
|
// {{{ Descriptions
|
||||||
Event::Start(Container::Div { .. }, attrs) if self.state == State::Toplevel => {
|
Event::Start(
|
||||||
if has_role(attrs, "description") {
|
Container::Div {
|
||||||
self.state = State::Description
|
class: "description",
|
||||||
}
|
},
|
||||||
}
|
_,
|
||||||
|
) if self.state == State::Toplevel => self.state = State::Description,
|
||||||
Event::End(Container::Div { .. }) if self.state == State::Description => {
|
Event::End(Container::Div { .. }) if self.state == State::Description => {
|
||||||
self.state = State::Toplevel;
|
self.state = State::Toplevel;
|
||||||
}
|
}
|
||||||
|
@ -336,7 +337,7 @@ impl<'s> Writer<'s> {
|
||||||
pub fn has_role(attrs: &Attributes, value: &str) -> bool {
|
pub fn has_role(attrs: &Attributes, value: &str) -> bool {
|
||||||
attrs
|
attrs
|
||||||
.get_value("role")
|
.get_value("role")
|
||||||
.map_or(false, |role| format!("{role}") == value)
|
.is_some_and(|role| format!("{role}") == value)
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
// {{{ Last modified cache
|
// {{{ Last modified cache
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue