use std::path::PathBuf; use crate::error::CustomError; use super::registry::Registry; use super::IDocumentElement; use super::IHeading; use super::ISection; #[derive(Debug)] pub(crate) struct BlogPostPage { /// Relative path from the root of the blog post. pub(crate) path: PathBuf, pub(crate) title: Option, pub(crate) children: Vec, } impl BlogPostPage { pub(crate) fn new>( path: P, registry: &mut Registry<'_>, document: &organic::types::Document<'_>, ) -> Result { let path = path.into(); let mut children = Vec::new(); if let Some(section) = document.zeroth_section.as_ref() { children.push(IDocumentElement::Section(ISection::new(registry, section)?)); } for heading in document.children.iter() { children.push(IDocumentElement::Heading(IHeading::new(registry, heading)?)); } Ok(BlogPostPage { path, title: get_title(&document), children, }) } /// Get the output path relative to the post directory. pub(crate) fn get_output_path(&self) -> PathBuf { let mut ret = self.path.clone(); ret.set_extension("html"); ret } } fn get_title(document: &organic::types::Document<'_>) -> Option { organic::types::AstNode::from(document) .iter_all_ast_nodes() .filter_map(|node| match node { organic::types::AstNode::Keyword(kw) if kw.key.eq_ignore_ascii_case("title") => { Some(kw) } _ => None, }) .last() .map(|kw| kw.value.to_owned()) }