use std::collections::HashMap; use camino::Utf8PathBuf; use chrono::{DateTime, Utc}; use hauchiwa::{Content, Link, LinkDate, Linkable, Outline, Sack}; use hayagriva::Library; use hypertext::{html_elements, maud_move, GlobalAttributes, Raw, Renderable}; use serde::Deserialize; const CSS: &str = r#" .slides img { margin-left: auto; margin-right: auto; max-height: 60vh; } "#; /// Represents a slideshow #[derive(Deserialize, Debug, Clone)] pub(crate) struct Slideshow { pub title: String, #[serde(with = "super::isodate")] pub date: DateTime, pub desc: Option, } impl Content for Slideshow { fn parse( data: String, _: Option<&Library>, dir: Utf8PathBuf, hash: HashMap, ) -> (Outline, String, Option>) { let html = data .split("\n-----\n") .map(|chunk| { chunk .split("\n---\n") .map(|s| crate::text::md::parse(s.to_owned(), None, dir.clone(), hash.clone())) .map(|e| e.1) .collect::>() }) .map(|stack| match stack.len() > 1 { true => format!( "
{}
", stack .into_iter() .map(|slide| format!("
{slide}
")) .collect::() ), false => format!("
{}
", stack[0]), }) .collect::(); (Outline(vec![]), html, None) } fn render<'s, 'p, 'html>( self, sack: &'s Sack, parsed: impl Renderable + 'p, _: Outline, _: Option>, ) -> impl Renderable + 'html where 's: 'html, 'p: 'html, { show(self, sack, parsed) } fn as_link(&self, path: Utf8PathBuf) -> Option { Some(Linkable::Date(LinkDate { link: Link { path, name: self.title.to_owned(), desc: self.desc.to_owned(), }, date: self.date.to_owned(), })) } } pub fn show<'s, 'p, 'html>( fm: Slideshow, sack: &'s Sack, slides: impl Renderable + 'p, ) -> impl Renderable + 'html where 's: 'html, 'p: 'html, { crate::html::bare( sack, maud_move!( div .reveal { div .slides { (slides) } } script type="module" { (Raw("import 'reveal';")) } style { (Raw(CSS)) } ), fm.title.clone(), ) }