pub mod store; #[allow(unused)] use anyhow::Result; use lazy_static::lazy_static; pub use store::{InMemoryStore, Store, StoreMut}; use digest::Digest; pub type Id = String; pub type Tag = String; pub type TagRef<'a> = &'a str; const TAGWIKI_PAGE_ID_KEY: &str = "tagwiki-page-id"; #[derive(Debug, Default, Clone)] pub struct Source(String); #[derive(Debug, Default, Clone)] pub struct Parsed { pub source: Source, pub source_body: String, pub html: String, pub headers: Headers, pub tags: Vec, pub title: String, } fn split_headers_and_body(source: &Source) -> (&str, &str) { lazy_static! { static ref RE: regex::Regex = regex::RegexBuilder::new(r"\A[[:space:]]*\n" } } fn parse_tags(body: &str) -> Vec { lazy_static! { static ref RE: regex::Regex = regex::Regex::new(r"#([a-zA-Z0-9]+)").expect("correct regex"); } RE.captures_iter(&body) .map(|m| m.get(1).expect("a value").as_str().to_lowercase()) .collect() } impl Parsed { fn from_full_source(source: Source) -> Parsed { let (headers, body) = split_headers_and_body(&source); let headers = Headers::parse(headers, &source); Self::from_headers_and_body(headers, body.to_owned()) } fn from_headers_and_body(headers: Headers, body: String) -> Parsed { let source = headers.to_markdown_string() + &body; let parser = pulldown_cmark::Parser::new(&body); let mut html_output = String::new(); pulldown_cmark::html::push_html(&mut html_output, parser); let tags = parse_tags(&body); Parsed { headers, html: html_output, source_body: body, source: Source(source), tags, title: "TODO".into(), } } pub fn with_new_source_body(&self, new_body_source: &str) -> Self { Self::from_headers_and_body(self.headers.clone(), new_body_source.to_owned()) } } #[test] fn split_headers_and_body_test() -> Result<()> { let s = Source( r#" banana"# .into(), ); let (headers, body) = split_headers_and_body(&s); assert_eq!( headers, r#" a: b c: d "# ); assert_eq!(body, "banana"); Ok(()) } #[test] fn parse_markdown_metadata_test() -> Result<()> { let page = Parsed::from_full_source(Source( r#" bar "# .to_owned(), )); println!("{:#?}", page); assert_eq!(page.headers.id, "xyz"); Ok(()) }