use std::sync::LazyLock; use askama::Template; use askama_web::WebTemplate; use pulldown_cmark::{Event, Options, Parser, Tag, html}; static README_HTML: LazyLock = LazyLock::new(|| { let events: Vec<_> = Parser::new_ext( include_str!("../../README.md"), Options::ENABLE_TABLES | Options::ENABLE_STRIKETHROUGH | Options::ENABLE_TASKLISTS, ) .collect(); let anchored = events.iter().enumerate().map(|(index, event)| { if let Event::Start(Tag::Heading(level, None, _)) = event { let title: String = events[index + 1..] .iter() .take_while(|event| !matches!(event, Event::End(Tag::Heading(..)))) .filter_map(|event| match event { Event::Text(text) | Event::Code(text) => Some(text.as_ref()), _ => None, }) .collect(); let slug: String = title .to_lowercase() .chars() .filter(|character| { character.is_alphanumeric() || *character == '-' || character.is_whitespace() }) .collect(); let slug = slug.split_whitespace().collect::>().join("-"); return Event::Html(format!("<{level} id=\"{slug}\">").into()); } event.clone() }); let mut rendered = String::new(); html::push_html(&mut rendered, anchored); rendered }); #[derive(Template, WebTemplate)] #[template(path = "home.html")] pub struct HomePage { readme: &'static str, } pub async fn home_page() -> HomePage { HomePage { readme: &README_HTML, } }