From 7b012302342669dff430d50b9243d14aede2a8c6 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 27 Oct 2023 14:54:54 -0400 Subject: [PATCH] Add target. --- src/context/mod.rs | 1 + src/context/object.rs | 8 ++++++++ src/context/target.rs | 27 +++++++++++++++++++++++++++ src/intermediate/heading.rs | 6 +++--- src/intermediate/mod.rs | 2 ++ src/intermediate/object.rs | 12 ++++++++---- src/intermediate/page.rs | 6 +++--- src/intermediate/registry.rs | 10 +++++----- src/intermediate/target.rs | 23 +++++++++++++++++++++++ 9 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 src/context/target.rs create mode 100644 src/intermediate/target.rs diff --git a/src/context/mod.rs b/src/context/mod.rs index bbfa0fc..3aadf32 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -6,6 +6,7 @@ mod heading; mod object; mod plain_text; mod section; +mod target; pub(crate) use blog_post_page::RenderBlogPostPage; pub(crate) use document_element::RenderDocumentElement; diff --git a/src/context/object.rs b/src/context/object.rs index 8cccc88..c54a619 100644 --- a/src/context/object.rs +++ b/src/context/object.rs @@ -7,11 +7,13 @@ use crate::error::CustomError; use crate::intermediate::IObject; use super::plain_text::RenderPlainText; +use super::target::RenderTarget; #[derive(Debug, Serialize)] #[serde(untagged)] pub(crate) enum RenderObject { PlainText(RenderPlainText), + Target(RenderTarget), } impl RenderObject { @@ -28,6 +30,12 @@ impl RenderObject { output_file, inner, )?)), + IObject::Target(inner) => Ok(RenderObject::Target(RenderTarget::new( + config, + output_directory, + output_file, + inner, + )?)), } } } diff --git a/src/context/target.rs b/src/context/target.rs new file mode 100644 index 0000000..ebdb69c --- /dev/null +++ b/src/context/target.rs @@ -0,0 +1,27 @@ +use std::path::Path; + +use serde::Serialize; + +use crate::config::Config; +use crate::error::CustomError; +use crate::intermediate::ITarget; + +#[derive(Debug, Serialize)] +#[serde(tag = "type")] +#[serde(rename = "target")] +pub(crate) struct RenderTarget { + id: String, +} + +impl RenderTarget { + pub(crate) fn new, F: AsRef>( + config: &Config, + output_directory: D, + output_file: F, + target: &ITarget, + ) -> Result { + Ok(RenderTarget { + id: target.id.clone(), + }) + } +} diff --git a/src/intermediate/heading.rs b/src/intermediate/heading.rs index 331b0b8..a12f550 100644 --- a/src/intermediate/heading.rs +++ b/src/intermediate/heading.rs @@ -10,9 +10,9 @@ pub(crate) struct IHeading { } impl IHeading { - pub(crate) fn new( - registry: &mut Registry<'_>, - heading: &organic::types::Heading<'_>, + pub(crate) fn new<'parse>( + registry: &mut Registry<'parse>, + heading: &organic::types::Heading<'parse>, ) -> Result { let title = heading .title diff --git a/src/intermediate/mod.rs b/src/intermediate/mod.rs index 75aab28..95185d7 100644 --- a/src/intermediate/mod.rs +++ b/src/intermediate/mod.rs @@ -8,6 +8,7 @@ mod page; mod plain_text; mod registry; mod section; +mod target; mod util; pub(crate) use convert::convert_blog_post_page_to_render_context; pub(crate) use definition::BlogPost; @@ -18,3 +19,4 @@ pub(crate) use object::IObject; pub(crate) use page::BlogPostPage; pub(crate) use plain_text::IPlainText; pub(crate) use section::ISection; +pub(crate) use target::ITarget; diff --git a/src/intermediate/object.rs b/src/intermediate/object.rs index 87864f4..c40059b 100644 --- a/src/intermediate/object.rs +++ b/src/intermediate/object.rs @@ -2,16 +2,18 @@ use crate::error::CustomError; use super::plain_text::IPlainText; use super::registry::Registry; +use super::ITarget; #[derive(Debug)] pub(crate) enum IObject { PlainText(IPlainText), + Target(ITarget), } impl IObject { - pub(crate) fn new( - registry: &mut Registry<'_>, - obj: &organic::types::Object<'_>, + pub(crate) fn new<'parse>( + registry: &mut Registry<'parse>, + obj: &organic::types::Object<'parse>, ) -> Result { match obj { organic::types::Object::Bold(_) => todo!(), @@ -38,7 +40,9 @@ impl IObject { organic::types::Object::InlineBabelCall(_) => todo!(), organic::types::Object::InlineSourceBlock(_) => todo!(), organic::types::Object::LineBreak(_) => todo!(), - organic::types::Object::Target(_) => todo!(), + organic::types::Object::Target(target) => { + Ok(IObject::Target(ITarget::new(registry, target)?)) + } organic::types::Object::StatisticsCookie(_) => todo!(), organic::types::Object::Subscript(_) => todo!(), organic::types::Object::Superscript(_) => todo!(), diff --git a/src/intermediate/page.rs b/src/intermediate/page.rs index 17d7ac0..a4e9532 100644 --- a/src/intermediate/page.rs +++ b/src/intermediate/page.rs @@ -18,10 +18,10 @@ pub(crate) struct BlogPostPage { } impl BlogPostPage { - pub(crate) fn new>( + pub(crate) fn new<'parse, P: Into>( path: P, - registry: &mut Registry<'_>, - document: &organic::types::Document<'_>, + registry: &mut Registry<'parse>, + document: &organic::types::Document<'parse>, ) -> Result { let path = path.into(); let mut children = Vec::new(); diff --git a/src/intermediate/registry.rs b/src/intermediate/registry.rs index d74e6d9..d53e2ba 100644 --- a/src/intermediate/registry.rs +++ b/src/intermediate/registry.rs @@ -2,20 +2,20 @@ use std::collections::HashMap; type IdCounter = u16; -pub(crate) struct Registry<'p> { +pub(crate) struct Registry<'parse> { id_counter: IdCounter, - targets: HashMap<&'p str, String>, + targets: HashMap<&'parse str, String>, } -impl<'p> Registry<'p> { - pub(crate) fn new() -> Registry<'p> { +impl<'parse> Registry<'parse> { + pub(crate) fn new() -> Registry<'parse> { Registry { id_counter: 0, targets: HashMap::new(), } } - pub(crate) fn get_target<'b>(&'b mut self, body: &'p str) -> &'b String { + pub(crate) fn get_target<'b>(&'b mut self, body: &'parse str) -> &'b String { self.targets.entry(body).or_insert_with(|| { self.id_counter += 1; format!("target_{}", self.id_counter) diff --git a/src/intermediate/target.rs b/src/intermediate/target.rs new file mode 100644 index 0000000..a62124b --- /dev/null +++ b/src/intermediate/target.rs @@ -0,0 +1,23 @@ +use crate::error::CustomError; +use crate::intermediate::util::coalesce_whitespace; + +use super::registry::Registry; + +#[derive(Debug)] +pub(crate) struct ITarget { + pub(crate) id: String, + value: String, +} + +impl ITarget { + pub(crate) fn new<'parse>( + registry: &mut Registry<'parse>, + target: &organic::types::Target<'parse>, + ) -> Result { + let id = registry.get_target(target.value); + Ok(ITarget { + id: id.clone(), + value: target.value.to_owned(), + }) + } +}