rewrite wip
This commit is contained in:
parent
c74b1499a4
commit
70b5b6de9d
|
@ -1,4 +1,5 @@
|
||||||
use hauchiwa::{HashedStyle, Mode, Sack};
|
use camino::Utf8Path;
|
||||||
|
use hauchiwa::{Mode, Sack};
|
||||||
use hypertext::{html_elements, maud_move, Raw, Renderable};
|
use hypertext::{html_elements, maud_move, Raw, Renderable};
|
||||||
|
|
||||||
use crate::MyData;
|
use crate::MyData;
|
||||||
|
@ -21,9 +22,9 @@ where
|
||||||
's: 'r,
|
's: 'r,
|
||||||
{
|
{
|
||||||
let title = format!("{} | kamoshi.org", title);
|
let title = format!("{} | kamoshi.org", title);
|
||||||
let css = sack.get_style("styles").expect("Missing styles");
|
let css = sack.get_styles("styles").expect("Missing styles");
|
||||||
let css_r = sack.get_style("reveal").expect("Missing styles");
|
let css_r = sack.get_styles("reveal").expect("Missing styles");
|
||||||
let css_p = sack.get_style("leaflet").expect("Missing styles");
|
let css_p = sack.get_styles("leaflet").expect("Missing styles");
|
||||||
|
|
||||||
let scripts = match scripts {
|
let scripts = match scripts {
|
||||||
Some(scripts) => Some(emit_tags_script(sack, scripts)?),
|
Some(scripts) => Some(emit_tags_script(sack, scripts)?),
|
||||||
|
@ -47,9 +48,9 @@ where
|
||||||
link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png";
|
link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png";
|
||||||
link rel="icon" href="/favicon.ico" sizes="any";
|
link rel="icon" href="/favicon.ico" sizes="any";
|
||||||
|
|
||||||
script type="importmap" {(Raw(sack.get_import_map()))}
|
// script type="importmap" {(Raw(sack.get_import_map()))}
|
||||||
|
|
||||||
@if matches!(sack.ctx.mode, Mode::Watch) {
|
@if matches!(sack.get_context().mode, Mode::Watch) {
|
||||||
script { (Raw(JS_RELOAD)) }
|
script { (Raw(JS_RELOAD)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,9 +60,9 @@ where
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_style(style: &HashedStyle) -> impl Renderable + '_ {
|
fn render_style(path: &Utf8Path) -> impl Renderable + '_ {
|
||||||
maud_move!(
|
maud_move!(
|
||||||
link rel="stylesheet" href=(style.path.as_str());
|
link rel="stylesheet" href=(path.as_str());
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,11 +84,11 @@ fn emit_tags_script<'a>(
|
||||||
|
|
||||||
fn emit_tag_script<'a>(
|
fn emit_tag_script<'a>(
|
||||||
sack: &'a Sack<MyData>,
|
sack: &'a Sack<MyData>,
|
||||||
script: &'a str,
|
alias: &'a str,
|
||||||
) -> Result<impl Renderable + 'a, String> {
|
) -> Result<impl Renderable + 'a, String> {
|
||||||
let src = sack
|
let path = sack
|
||||||
.get_script(script)
|
.get_script(alias)
|
||||||
.ok_or(format!("Missing script {script}"))?;
|
.ok_or(format!("Missing script {}", alias))?;
|
||||||
|
|
||||||
Ok(maud_move!(script type="module" src=(src.path.as_str()) defer {}))
|
Ok(maud_move!(script type="module" src=(path.as_str()) defer {}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,15 +43,15 @@ fn photo() -> impl Renderable {
|
||||||
fn latest(sack: &Sack<MyData>) -> impl Renderable {
|
fn latest(sack: &Sack<MyData>) -> impl Renderable {
|
||||||
let links = {
|
let links = {
|
||||||
let mut list = sack
|
let mut list = sack
|
||||||
.get_meta::<Post>("**")
|
.get_content_list::<Post>("**")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(path, meta)| LinkDate {
|
.map(|query| LinkDate {
|
||||||
link: Link {
|
link: Link {
|
||||||
path: Utf8Path::new("/").join(path),
|
path: Utf8Path::new("/").join(query.slug),
|
||||||
name: meta.title.clone(),
|
name: query.meta.title.clone(),
|
||||||
desc: meta.desc.clone(),
|
desc: query.meta.desc.clone(),
|
||||||
},
|
},
|
||||||
date: meta.date,
|
date: query.meta.date,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
list.sort_by(|a, b| b.date.cmp(&a.date));
|
list.sort_by(|a, b| b.date.cmp(&a.date));
|
||||||
|
|
|
@ -78,20 +78,23 @@ impl TreePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the page tree
|
/// Render the page tree
|
||||||
pub(crate) fn show_page_tree<'a>(sack: &'a MySack, glob: &'a str) -> impl Renderable + 'a {
|
pub(crate) fn show_page_tree<'a>(
|
||||||
let tree =
|
path: &'a Utf8Path,
|
||||||
TreePage::from_iter(
|
sack: &'a MySack,
|
||||||
sack.get_meta::<Wiki>(glob)
|
glob: &'a str,
|
||||||
|
) -> impl Renderable + 'a {
|
||||||
|
let tree = sack
|
||||||
|
.get_content_list::<Wiki>(glob)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(path, meta)| Link {
|
.map(|query| Link {
|
||||||
path: Utf8Path::new("/").join(path.parent().unwrap()),
|
path: Utf8Path::new("/").join(query.slug),
|
||||||
name: meta.title.clone(),
|
name: query.meta.title.clone(),
|
||||||
desc: None,
|
desc: None,
|
||||||
}),
|
});
|
||||||
);
|
let tree = TreePage::from_iter(tree);
|
||||||
|
|
||||||
let parts = {
|
let parts = {
|
||||||
let mut parts = sack.path.iter().skip(1).collect::<Vec<_>>();
|
let mut parts = path.iter().skip(1).collect::<Vec<_>>();
|
||||||
parts.insert(0, "wiki");
|
parts.insert(0, "wiki");
|
||||||
parts
|
parts
|
||||||
};
|
};
|
||||||
|
|
|
@ -68,16 +68,20 @@ pub fn footer<'s, 'html>(sack: &'s MySack) -> impl Renderable + 'html
|
||||||
where
|
where
|
||||||
's: 'html,
|
's: 'html,
|
||||||
{
|
{
|
||||||
let copy = format!("Copyright © {} Maciej Jur", &sack.ctx.data.year);
|
let copy = format!(
|
||||||
|
"Copyright © {} Maciej Jur",
|
||||||
|
&sack.get_context().data.year
|
||||||
|
);
|
||||||
let mail = "maciej@kamoshi.org";
|
let mail = "maciej@kamoshi.org";
|
||||||
let href = format!("mailto:{}", mail);
|
let href = format!("mailto:{}", mail);
|
||||||
let link = Utf8Path::new(&sack.ctx.data.link)
|
let link = Utf8Path::new(&sack.get_context().data.link)
|
||||||
.join("src/commit")
|
.join("src/commit")
|
||||||
.join(&sack.ctx.data.hash);
|
.join(&sack.get_context().data.hash);
|
||||||
let link = match sack.get_file() {
|
|
||||||
Some(path) => link.join(path),
|
// let link = match sack.get_file() {
|
||||||
None => link,
|
// Some(path) => link.join(path),
|
||||||
};
|
// None => link,
|
||||||
|
// };
|
||||||
|
|
||||||
maud_move!(
|
maud_move!(
|
||||||
footer .footer {
|
footer .footer {
|
||||||
|
@ -91,10 +95,10 @@ where
|
||||||
}
|
}
|
||||||
div .repo {
|
div .repo {
|
||||||
a href=(link.as_str()) {
|
a href=(link.as_str()) {
|
||||||
(&sack.ctx.data.hash)
|
(&sack.get_context().data.hash)
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
(&sack.ctx.data.date)
|
(&sack.get_context().data.date)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a .right.footer__cc-wrap rel="license" href="http://creativecommons.org/licenses/by/4.0/" {
|
a .right.footer__cc-wrap rel="license" href="http://creativecommons.org/licenses/by/4.0/" {
|
||||||
|
|
|
@ -18,16 +18,18 @@ pub fn as_html(
|
||||||
meta: &Wiki,
|
meta: &Wiki,
|
||||||
parsed: &str,
|
parsed: &str,
|
||||||
sack: &MySack,
|
sack: &MySack,
|
||||||
|
path: &Utf8Path,
|
||||||
outline: Outline,
|
outline: Outline,
|
||||||
bibliography: Bibliography,
|
bibliography: Bibliography,
|
||||||
) -> String {
|
) -> String {
|
||||||
wiki(meta, parsed, sack, outline, bibliography)
|
wiki(meta, parsed, sack, path, outline, bibliography)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wiki(
|
fn wiki(
|
||||||
matter: &Wiki,
|
matter: &Wiki,
|
||||||
parsed: &str,
|
parsed: &str,
|
||||||
sack: &MySack,
|
sack: &MySack,
|
||||||
|
path: &Utf8Path,
|
||||||
_: Outline,
|
_: Outline,
|
||||||
bibliography: Bibliography,
|
bibliography: Bibliography,
|
||||||
) -> String {
|
) -> String {
|
||||||
|
@ -46,7 +48,7 @@ fn wiki(
|
||||||
// Navigation tree
|
// Navigation tree
|
||||||
section .link-tree {
|
section .link-tree {
|
||||||
div {
|
div {
|
||||||
(crate::html::misc::show_page_tree(sack, "wiki/**/*.html"))
|
(crate::html::misc::show_page_tree(path, sack, "wiki/**/*.html"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
210
src/main.rs
210
src/main.rs
|
@ -8,7 +8,7 @@ use std::process::Command;
|
||||||
use camino::{Utf8Path, Utf8PathBuf};
|
use camino::{Utf8Path, Utf8PathBuf};
|
||||||
use chrono::{DateTime, Datelike, Utc};
|
use chrono::{DateTime, Datelike, Utc};
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::{Parser, ValueEnum};
|
||||||
use hauchiwa::{Collection, Processor, Sack, Website};
|
use hauchiwa::{Collection, Sack, Website};
|
||||||
use hypertext::Renderable;
|
use hypertext::Renderable;
|
||||||
use model::{Post, Slideshow, Wiki};
|
use model::{Post, Slideshow, Wiki};
|
||||||
|
|
||||||
|
@ -73,51 +73,11 @@ fn main() {
|
||||||
|
|
||||||
let website = Website::setup()
|
let website = Website::setup()
|
||||||
.add_collections(vec![
|
.add_collections(vec![
|
||||||
Collection::glob_with::<Post>(
|
Collection::glob_with::<Post>("content", "about.md", ["md"].into()),
|
||||||
"content",
|
Collection::glob_with::<Post>("content", "posts/**/*", ["md", "mdx"].into()),
|
||||||
"about.md",
|
Collection::glob_with::<Slideshow>("content", "slides/**/*", ["md", "lhs"].into()),
|
||||||
["md"].into(),
|
Collection::glob_with::<Wiki>("content", "wiki/**/*", ["md"].into()),
|
||||||
Processor {
|
Collection::glob_with::<Post>("content", "projects/flox.md", ["md"].into()),
|
||||||
read_content: crate::html::post::parse_content,
|
|
||||||
to_html: crate::html::post::as_html,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Collection::glob_with::<Post>(
|
|
||||||
"content",
|
|
||||||
"posts/**/*",
|
|
||||||
["md", "mdx"].into(),
|
|
||||||
Processor {
|
|
||||||
read_content: crate::html::post::parse_content,
|
|
||||||
to_html: crate::html::post::as_html,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Collection::glob_with::<Slideshow>(
|
|
||||||
"content",
|
|
||||||
"slides/**/*",
|
|
||||||
["md", "lhs"].into(),
|
|
||||||
Processor {
|
|
||||||
read_content: crate::html::slideshow::parse_content,
|
|
||||||
to_html: crate::html::slideshow::as_html,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Collection::glob_with::<Wiki>(
|
|
||||||
"content",
|
|
||||||
"wiki/**/*",
|
|
||||||
["md"].into(),
|
|
||||||
Processor {
|
|
||||||
read_content: crate::html::wiki::parse_content,
|
|
||||||
to_html: crate::html::wiki::as_html,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Collection::glob_with::<Post>(
|
|
||||||
"content",
|
|
||||||
"projects/flox.md",
|
|
||||||
["md"].into(),
|
|
||||||
Processor {
|
|
||||||
read_content: crate::html::post::parse_content,
|
|
||||||
to_html: crate::html::as_html,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
])
|
])
|
||||||
.add_scripts(vec![
|
.add_scripts(vec![
|
||||||
("search", "./js/search/dist/search.js"),
|
("search", "./js/search/dist/search.js"),
|
||||||
|
@ -126,83 +86,133 @@ fn main() {
|
||||||
("editor", "./js/flox/main.ts"),
|
("editor", "./js/flox/main.ts"),
|
||||||
("lambda", "./js/flox/lambda.ts"),
|
("lambda", "./js/flox/lambda.ts"),
|
||||||
])
|
])
|
||||||
.add_virtual(
|
.add_task(|sack| {
|
||||||
|sack| crate::html::map(sack).unwrap().render().to_owned().into(),
|
let query = sack.get_content::<Post>("about").unwrap();
|
||||||
"map/index.html".into(),
|
let (parsed, outline, bib) =
|
||||||
)
|
html::post::parse_content(query.content, &sack, query.file, None);
|
||||||
.add_virtual(crate::html::search, "search/index.html".into())
|
let out_buff = html::post::as_html(query.meta, &parsed, &sack, outline, bib);
|
||||||
.add_virtual(
|
vec![(query.slug.join("index.html"), out_buff)]
|
||||||
|sack| {
|
})
|
||||||
crate::html::to_list(
|
// Task: generate posts
|
||||||
sack,
|
.add_task(|sack| {
|
||||||
sack.get_meta::<Post>("projects/**/*.html")
|
sack.get_content_list::<Post>("posts/**/*")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(path, meta)| LinkDate {
|
.map(|query| {
|
||||||
|
let (parsed, outline, bib) =
|
||||||
|
html::post::parse_content(query.content, &sack, query.file, None);
|
||||||
|
let out_buff = html::post::as_html(query.meta, &parsed, &sack, outline, bib);
|
||||||
|
(query.slug.join("index.html"), out_buff)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
// Task: generate slides
|
||||||
|
.add_task(|sack| {
|
||||||
|
sack.get_content_list::<Slideshow>("slides/**/*")
|
||||||
|
.into_iter()
|
||||||
|
.map(|query| {
|
||||||
|
let (parsed, outline, bib) =
|
||||||
|
html::slideshow::parse_content(query.content, &sack, query.file, None);
|
||||||
|
let out_buff =
|
||||||
|
html::slideshow::as_html(query.meta, &parsed, &sack, outline, bib);
|
||||||
|
(query.slug.join("index.html"), out_buff)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
// Task: generate wiki
|
||||||
|
.add_task(|sack| {
|
||||||
|
sack.get_content_list::<Wiki>("wiki/**/*")
|
||||||
|
.into_iter()
|
||||||
|
.map(|query| {
|
||||||
|
let (parsed, outline, bib) =
|
||||||
|
html::wiki::parse_content(query.content, &sack, query.file, None);
|
||||||
|
let out_buff =
|
||||||
|
html::wiki::as_html(query.meta, &parsed, &sack, query.file, outline, bib);
|
||||||
|
(query.slug.join("index.html"), out_buff)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
// Task: generate map
|
||||||
|
.add_task(|sack| {
|
||||||
|
vec![(
|
||||||
|
"map/index.html".into(),
|
||||||
|
crate::html::map(&sack).unwrap().render().to_owned().into(),
|
||||||
|
)]
|
||||||
|
})
|
||||||
|
// Task: generate search
|
||||||
|
.add_task(|sack| vec![("search/index.html".into(), crate::html::search(&sack))])
|
||||||
|
// Task: generate home page
|
||||||
|
.add_task(|sack| {
|
||||||
|
let data = std::fs::read_to_string("content/index.md").unwrap();
|
||||||
|
let (parsed, _, _) = text::md::parse(&data, &sack, "".into(), None);
|
||||||
|
vec![("index.html".into(), crate::html::home(&sack, &parsed))]
|
||||||
|
})
|
||||||
|
// Task: generate project index
|
||||||
|
.add_task(|sack| {
|
||||||
|
vec![(
|
||||||
|
"projects/index.html".into(),
|
||||||
|
crate::html::to_list(
|
||||||
|
&sack,
|
||||||
|
sack.get_content_list::<Post>("projects/**/*")
|
||||||
|
.into_iter()
|
||||||
|
.map(|query| LinkDate {
|
||||||
link: Link {
|
link: Link {
|
||||||
path: Utf8Path::new("/").join(path.parent().unwrap()),
|
path: Utf8Path::new("/").join(query.slug),
|
||||||
name: meta.title.clone(),
|
name: query.meta.title.clone(),
|
||||||
desc: meta.desc.clone(),
|
desc: query.meta.desc.clone(),
|
||||||
},
|
},
|
||||||
date: meta.date,
|
date: query.meta.date,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
"Projects".into(),
|
"Projects".into(),
|
||||||
)
|
),
|
||||||
},
|
)]
|
||||||
"projects/index.html".into(),
|
})
|
||||||
)
|
// Task: generate post index
|
||||||
.add_virtual(
|
.add_task(|sack| {
|
||||||
|sack| {
|
vec![(
|
||||||
|
"posts/index.html".into(),
|
||||||
crate::html::to_list(
|
crate::html::to_list(
|
||||||
sack,
|
&sack,
|
||||||
sack.get_meta::<Post>("posts/**/*.html")
|
sack.get_content_list::<Post>("posts/**/*")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(path, meta)| LinkDate {
|
.map(|query| LinkDate {
|
||||||
link: Link {
|
link: Link {
|
||||||
path: Utf8Path::new("/").join(path.parent().unwrap()),
|
path: Utf8Path::new("/").join(query.slug),
|
||||||
name: meta.title.clone(),
|
name: query.meta.title.clone(),
|
||||||
desc: meta.desc.clone(),
|
desc: query.meta.desc.clone(),
|
||||||
},
|
},
|
||||||
date: meta.date,
|
date: query.meta.date,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
"Posts".into(),
|
"Posts".into(),
|
||||||
)
|
),
|
||||||
},
|
)]
|
||||||
"posts/index.html".into(),
|
})
|
||||||
)
|
// Task: generate slideshow index
|
||||||
.add_virtual(
|
.add_task(|sack| {
|
||||||
|sack| {
|
vec![(
|
||||||
|
"slides/index.html".into(),
|
||||||
crate::html::to_list(
|
crate::html::to_list(
|
||||||
sack,
|
&sack,
|
||||||
sack.get_meta::<Slideshow>("slides/**/*.html")
|
sack.get_content_list::<Slideshow>("slides/**/*")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(path, meta)| LinkDate {
|
.map(|query| LinkDate {
|
||||||
link: Link {
|
link: Link {
|
||||||
path: Utf8Path::new("/").join(path.parent().unwrap()),
|
path: Utf8Path::new("/").join(query.slug),
|
||||||
name: meta.title.clone(),
|
name: query.meta.title.clone(),
|
||||||
desc: meta.desc.clone(),
|
desc: query.meta.desc.clone(),
|
||||||
},
|
},
|
||||||
date: meta.date,
|
date: query.meta.date,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
"Slideshows".into(),
|
"Slideshows".into(),
|
||||||
)
|
),
|
||||||
},
|
)]
|
||||||
"slides/index.html".into(),
|
})
|
||||||
)
|
|
||||||
.add_virtual(
|
|
||||||
|sack| {
|
|
||||||
let data = std::fs::read_to_string("content/index.md").unwrap();
|
|
||||||
let (parsed, _, _) = text::md::parse(&data, sack, "".into(), None);
|
|
||||||
crate::html::home(sack, &parsed)
|
|
||||||
},
|
|
||||||
"index.html".into(),
|
|
||||||
)
|
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
match args.mode {
|
match args.mode {
|
||||||
Mode::Build => website.build(MyData::new()),
|
Mode::Build => website.build(MyData::new()),
|
||||||
Mode::Watch => website.watch(MyData::new()),
|
Mode::Watch => (), //website.watch(MyData::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,7 +363,7 @@ fn swap_hashed_image<'a>(dir: &'a Utf8Path, sack: &'a MySack) -> impl Fn(Event)
|
||||||
id,
|
id,
|
||||||
} => {
|
} => {
|
||||||
let rel = dir.join(dest_url.as_ref());
|
let rel = dir.join(dest_url.as_ref());
|
||||||
let img = sack.get_image(&rel);
|
let img = sack.get_picture(&rel);
|
||||||
let hashed = img.map(|path| path.as_str().to_owned().into());
|
let hashed = img.map(|path| path.as_str().to_owned().into());
|
||||||
Event::Start(Tag::Image {
|
Event::Start(Tag::Image {
|
||||||
link_type,
|
link_type,
|
||||||
|
|
Loading…
Reference in a new issue