From c6cf5f75accb471832bf32da5a670b336d7083db Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 27 Oct 2023 14:43:06 -0400 Subject: [PATCH] Introduce a registry into the conversion to intermediate format. --- src/intermediate/definition.rs | 21 +++++++++++++++++---- src/intermediate/heading.rs | 8 ++++++-- src/intermediate/mod.rs | 1 + src/intermediate/object.rs | 8 ++++++-- src/intermediate/page.rs | 8 +++++--- src/intermediate/plain_text.rs | 3 +++ src/intermediate/registry.rs | 24 ++++++++++++++++++++++++ src/intermediate/section.rs | 7 ++++++- 8 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 src/intermediate/registry.rs diff --git a/src/intermediate/definition.rs b/src/intermediate/definition.rs index c81053a..897b49a 100644 --- a/src/intermediate/definition.rs +++ b/src/intermediate/definition.rs @@ -5,15 +5,14 @@ use tokio::task::JoinHandle; use walkdir::WalkDir; use crate::error::CustomError; +use crate::intermediate::registry::Registry; use super::BlogPostPage; -use super::IDocumentElement; #[derive(Debug)] pub(crate) struct BlogPost { pub(crate) id: String, pub(crate) pages: Vec, - pub(crate) children: Vec, } impl BlogPost { @@ -44,12 +43,27 @@ impl BlogPost { ret }; + let mut registry = Registry::new(); + + // Assign IDs to the targets + for (_real_path, _contents, parsed_document) in parsed_org_files.iter() { + organic::types::AstNode::from(parsed_document) + .iter_all_ast_nodes() + .for_each(|node| match node { + organic::types::AstNode::Target(target) => { + registry.get_target(target.value); + } + _ => {} + }); + } + let pages = { let mut ret = Vec::new(); - for (real_path, _contents, parsed_document) in parsed_org_files { + for (real_path, _contents, parsed_document) in parsed_org_files.iter() { let relative_to_post_dir_path = real_path.strip_prefix(post_dir)?; ret.push(BlogPostPage::new( relative_to_post_dir_path, + &mut registry, parsed_document, )?); } @@ -59,7 +73,6 @@ impl BlogPost { Ok(BlogPost { id: post_id.to_string_lossy().into_owned(), pages, - children: Vec::new(), }) } inner(root_dir.as_ref(), post_dir.as_ref()).await diff --git a/src/intermediate/heading.rs b/src/intermediate/heading.rs index c8bb925..331b0b8 100644 --- a/src/intermediate/heading.rs +++ b/src/intermediate/heading.rs @@ -1,5 +1,6 @@ use crate::error::CustomError; +use super::registry::Registry; use super::IObject; #[derive(Debug)] @@ -9,11 +10,14 @@ pub(crate) struct IHeading { } impl IHeading { - pub(crate) fn new(heading: &organic::types::Heading<'_>) -> Result { + pub(crate) fn new( + registry: &mut Registry<'_>, + heading: &organic::types::Heading<'_>, + ) -> Result { let title = heading .title .iter() - .map(IObject::new) + .map(|obj| IObject::new(registry, obj)) .collect::, _>>()?; Ok(IHeading { title, diff --git a/src/intermediate/mod.rs b/src/intermediate/mod.rs index b8760ff..75aab28 100644 --- a/src/intermediate/mod.rs +++ b/src/intermediate/mod.rs @@ -6,6 +6,7 @@ mod heading; mod object; mod page; mod plain_text; +mod registry; mod section; mod util; pub(crate) use convert::convert_blog_post_page_to_render_context; diff --git a/src/intermediate/object.rs b/src/intermediate/object.rs index f15e90f..87864f4 100644 --- a/src/intermediate/object.rs +++ b/src/intermediate/object.rs @@ -1,6 +1,7 @@ use crate::error::CustomError; use super::plain_text::IPlainText; +use super::registry::Registry; #[derive(Debug)] pub(crate) enum IObject { @@ -8,7 +9,10 @@ pub(crate) enum IObject { } impl IObject { - pub(crate) fn new(obj: &organic::types::Object<'_>) -> Result { + pub(crate) fn new( + registry: &mut Registry<'_>, + obj: &organic::types::Object<'_>, + ) -> Result { match obj { organic::types::Object::Bold(_) => todo!(), organic::types::Object::Italic(_) => todo!(), @@ -17,7 +21,7 @@ impl IObject { organic::types::Object::Code(_) => todo!(), organic::types::Object::Verbatim(_) => todo!(), organic::types::Object::PlainText(plain_text) => { - Ok(IObject::PlainText(IPlainText::new(plain_text)?)) + Ok(IObject::PlainText(IPlainText::new(registry, plain_text)?)) } organic::types::Object::RegularLink(_) => todo!(), organic::types::Object::RadioLink(_) => todo!(), diff --git a/src/intermediate/page.rs b/src/intermediate/page.rs index fde0ce8..17d7ac0 100644 --- a/src/intermediate/page.rs +++ b/src/intermediate/page.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use crate::error::CustomError; +use super::registry::Registry; use super::IDocumentElement; use super::IHeading; use super::ISection; @@ -19,15 +20,16 @@ pub(crate) struct BlogPostPage { impl BlogPostPage { pub(crate) fn new>( path: P, - document: organic::types::Document<'_>, + 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(section)?)); + children.push(IDocumentElement::Section(ISection::new(registry, section)?)); } for heading in document.children.iter() { - children.push(IDocumentElement::Heading(IHeading::new(heading)?)); + children.push(IDocumentElement::Heading(IHeading::new(registry, heading)?)); } Ok(BlogPostPage { diff --git a/src/intermediate/plain_text.rs b/src/intermediate/plain_text.rs index 24cebb2..f794680 100644 --- a/src/intermediate/plain_text.rs +++ b/src/intermediate/plain_text.rs @@ -1,6 +1,8 @@ use crate::error::CustomError; use crate::intermediate::util::coalesce_whitespace; +use super::registry::Registry; + #[derive(Debug)] pub(crate) struct IPlainText { source: String, @@ -8,6 +10,7 @@ pub(crate) struct IPlainText { impl IPlainText { pub(crate) fn new( + registry: &mut Registry<'_>, plain_text: &organic::types::PlainText<'_>, ) -> Result { Ok(IPlainText { diff --git a/src/intermediate/registry.rs b/src/intermediate/registry.rs new file mode 100644 index 0000000..d74e6d9 --- /dev/null +++ b/src/intermediate/registry.rs @@ -0,0 +1,24 @@ +use std::collections::HashMap; + +type IdCounter = u16; + +pub(crate) struct Registry<'p> { + id_counter: IdCounter, + targets: HashMap<&'p str, String>, +} + +impl<'p> Registry<'p> { + pub(crate) fn new() -> Registry<'p> { + Registry { + id_counter: 0, + targets: HashMap::new(), + } + } + + pub(crate) fn get_target<'b>(&'b mut self, body: &'p str) -> &'b String { + self.targets.entry(body).or_insert_with(|| { + self.id_counter += 1; + format!("target_{}", self.id_counter) + }) + } +} diff --git a/src/intermediate/section.rs b/src/intermediate/section.rs index d7b0069..2afd831 100644 --- a/src/intermediate/section.rs +++ b/src/intermediate/section.rs @@ -1,10 +1,15 @@ use crate::error::CustomError; +use super::registry::Registry; + #[derive(Debug)] pub(crate) struct ISection {} impl ISection { - pub(crate) fn new(section: &organic::types::Section<'_>) -> Result { + pub(crate) fn new( + registry: &mut Registry<'_>, + section: &organic::types::Section<'_>, + ) -> Result { Ok(ISection {}) } }