From 8b85c02ef1167f948e4519c2bc9fa54cb2450119 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Thu, 21 Dec 2023 13:53:56 -0500 Subject: [PATCH] Wrap the intermediate Registry in an IntermediateContext. This is currently just to maintain consistency with the render phase's RenderContext but in the future it should allow us to include immutable data that is not locked behind the ArcMutex. --- src/intermediate/ast_node.rs | 251 ++++++++++++----------- src/intermediate/blog_post.rs | 4 +- src/intermediate/bold.rs | 4 +- src/intermediate/code.rs | 2 +- src/intermediate/document_element.rs | 38 ++-- src/intermediate/element.rs | 4 +- src/intermediate/entity.rs | 2 +- src/intermediate/footnote_definition.rs | 9 +- src/intermediate/footnote_reference.rs | 5 +- src/intermediate/heading.rs | 6 +- src/intermediate/inline_source_block.rs | 2 +- src/intermediate/intermediate_context.rs | 15 ++ src/intermediate/italic.rs | 4 +- src/intermediate/latex_fragment.rs | 2 +- src/intermediate/macros.rs | 18 +- src/intermediate/mod.rs | 2 + src/intermediate/object.rs | 4 +- src/intermediate/page.rs | 12 +- src/intermediate/paragraph.rs | 4 +- src/intermediate/plain_list.rs | 4 +- src/intermediate/plain_list_item.rs | 6 +- src/intermediate/plain_text.rs | 2 +- src/intermediate/quote_block.rs | 4 +- src/intermediate/registry.rs | 55 ++--- src/intermediate/regular_link.rs | 4 +- src/intermediate/section.rs | 4 +- src/intermediate/src_block.rs | 2 +- src/intermediate/strike_through.rs | 4 +- src/intermediate/table.rs | 4 +- src/intermediate/table_cell.rs | 4 +- src/intermediate/table_row.rs | 4 +- src/intermediate/target.rs | 4 +- src/intermediate/underline.rs | 4 +- src/intermediate/verbatim.rs | 2 +- 34 files changed, 266 insertions(+), 229 deletions(-) create mode 100644 src/intermediate/intermediate_context.rs diff --git a/src/intermediate/ast_node.rs b/src/intermediate/ast_node.rs index 1288eee..1b3110c 100644 --- a/src/intermediate/ast_node.rs +++ b/src/intermediate/ast_node.rs @@ -18,7 +18,6 @@ use super::plain_link::IPlainLink; use super::plain_text::IPlainText; use super::radio_link::IRadioLink; use super::radio_target::IRadioTarget; - use super::regular_link::IRegularLink; use super::statistics_cookie::IStatisticsCookie; use super::strike_through::IStrikeThrough; @@ -52,7 +51,7 @@ use super::ITimestamp; use super::IUnderline; use super::IVerbatim; use super::IVerseBlock; -use super::RefRegistry; +use super::IntermediateContext; use crate::error::CustomError; use futures::future::{BoxFuture, FutureExt}; @@ -116,23 +115,23 @@ pub(crate) enum IAstNode { pub(crate) trait IntoIAstNode<'parse> { fn into_ast_node<'orig>( &'orig self, - registry: RefRegistry<'orig, 'parse>, + intermediate_context: IntermediateContext<'orig, 'parse>, ) -> BoxFuture<'orig, Result>; } impl<'parse> IntoIAstNode<'parse> for organic::types::DocumentElement<'parse> { fn into_ast_node<'orig>( &'orig self, - registry: RefRegistry<'orig, 'parse>, + intermediate_context: IntermediateContext<'orig, 'parse>, ) -> BoxFuture<'orig, Result> { async move { match self { - organic::types::DocumentElement::Heading(inner) => { - Ok(IAstNode::Heading(IHeading::new(registry, inner).await?)) - } - organic::types::DocumentElement::Section(inner) => { - Ok(IAstNode::Section(ISection::new(registry, inner).await?)) - } + organic::types::DocumentElement::Heading(inner) => Ok(IAstNode::Heading( + IHeading::new(intermediate_context, inner).await?, + )), + organic::types::DocumentElement::Section(inner) => Ok(IAstNode::Section( + ISection::new(intermediate_context, inner).await?, + )), } } .boxed() @@ -142,81 +141,83 @@ impl<'parse> IntoIAstNode<'parse> for organic::types::DocumentElement<'parse> { impl<'parse> IntoIAstNode<'parse> for organic::types::Element<'parse> { fn into_ast_node<'orig>( &'orig self, - registry: RefRegistry<'orig, 'parse>, + intermediate_context: IntermediateContext<'orig, 'parse>, ) -> BoxFuture<'orig, Result> { async move { match self { - organic::types::Element::Paragraph(inner) => { - Ok(IAstNode::Paragraph(IParagraph::new(registry, inner).await?)) - } - organic::types::Element::PlainList(inner) => { - Ok(IAstNode::PlainList(IPlainList::new(registry, inner).await?)) - } + organic::types::Element::Paragraph(inner) => Ok(IAstNode::Paragraph( + IParagraph::new(intermediate_context, inner).await?, + )), + organic::types::Element::PlainList(inner) => Ok(IAstNode::PlainList( + IPlainList::new(intermediate_context, inner).await?, + )), organic::types::Element::CenterBlock(inner) => Ok(IAstNode::CenterBlock( - ICenterBlock::new(registry, inner).await?, + ICenterBlock::new(intermediate_context, inner).await?, )), organic::types::Element::QuoteBlock(inner) => Ok(IAstNode::QuoteBlock( - IQuoteBlock::new(registry, inner).await?, + IQuoteBlock::new(intermediate_context, inner).await?, )), organic::types::Element::SpecialBlock(inner) => Ok(IAstNode::SpecialBlock( - ISpecialBlock::new(registry, inner).await?, + ISpecialBlock::new(intermediate_context, inner).await?, )), organic::types::Element::DynamicBlock(inner) => Ok(IAstNode::DynamicBlock( - IDynamicBlock::new(registry, inner).await?, + IDynamicBlock::new(intermediate_context, inner).await?, )), - organic::types::Element::FootnoteDefinition(inner) => Ok( - IAstNode::FootnoteDefinition(IFootnoteDefinition::new(registry, inner).await?), - ), - organic::types::Element::Comment(inner) => { - Ok(IAstNode::Comment(IComment::new(registry, inner).await?)) - } - organic::types::Element::Drawer(inner) => { - Ok(IAstNode::Drawer(IDrawer::new(registry, inner).await?)) + organic::types::Element::FootnoteDefinition(inner) => { + Ok(IAstNode::FootnoteDefinition( + IFootnoteDefinition::new(intermediate_context, inner).await?, + )) } + organic::types::Element::Comment(inner) => Ok(IAstNode::Comment( + IComment::new(intermediate_context, inner).await?, + )), + organic::types::Element::Drawer(inner) => Ok(IAstNode::Drawer( + IDrawer::new(intermediate_context, inner).await?, + )), organic::types::Element::PropertyDrawer(inner) => Ok(IAstNode::PropertyDrawer( - IPropertyDrawer::new(registry, inner).await?, + IPropertyDrawer::new(intermediate_context, inner).await?, + )), + organic::types::Element::Table(inner) => Ok(IAstNode::Table( + ITable::new(intermediate_context, inner).await?, )), - organic::types::Element::Table(inner) => { - Ok(IAstNode::Table(ITable::new(registry, inner).await?)) - } organic::types::Element::VerseBlock(inner) => Ok(IAstNode::VerseBlock( - IVerseBlock::new(registry, inner).await?, + IVerseBlock::new(intermediate_context, inner).await?, )), organic::types::Element::CommentBlock(inner) => Ok(IAstNode::CommentBlock( - ICommentBlock::new(registry, inner).await?, + ICommentBlock::new(intermediate_context, inner).await?, )), organic::types::Element::ExampleBlock(inner) => Ok(IAstNode::ExampleBlock( - IExampleBlock::new(registry, inner).await?, + IExampleBlock::new(intermediate_context, inner).await?, )), organic::types::Element::ExportBlock(inner) => Ok(IAstNode::ExportBlock( - IExportBlock::new(registry, inner).await?, + IExportBlock::new(intermediate_context, inner).await?, + )), + organic::types::Element::SrcBlock(inner) => Ok(IAstNode::SrcBlock( + ISrcBlock::new(intermediate_context, inner).await?, + )), + organic::types::Element::Clock(inner) => Ok(IAstNode::Clock( + IClock::new(intermediate_context, inner).await?, + )), + organic::types::Element::DiarySexp(inner) => Ok(IAstNode::DiarySexp( + IDiarySexp::new(intermediate_context, inner).await?, + )), + organic::types::Element::Planning(inner) => Ok(IAstNode::Planning( + IPlanning::new(intermediate_context, inner).await?, )), - organic::types::Element::SrcBlock(inner) => { - Ok(IAstNode::SrcBlock(ISrcBlock::new(registry, inner).await?)) - } - organic::types::Element::Clock(inner) => { - Ok(IAstNode::Clock(IClock::new(registry, inner).await?)) - } - organic::types::Element::DiarySexp(inner) => { - Ok(IAstNode::DiarySexp(IDiarySexp::new(registry, inner).await?)) - } - organic::types::Element::Planning(inner) => { - Ok(IAstNode::Planning(IPlanning::new(registry, inner).await?)) - } organic::types::Element::FixedWidthArea(inner) => Ok(IAstNode::FixedWidthArea( - IFixedWidthArea::new(registry, inner).await?, + IFixedWidthArea::new(intermediate_context, inner).await?, )), organic::types::Element::HorizontalRule(inner) => Ok(IAstNode::HorizontalRule( - IHorizontalRule::new(registry, inner).await?, + IHorizontalRule::new(intermediate_context, inner).await?, + )), + organic::types::Element::Keyword(inner) => Ok(IAstNode::Keyword( + IKeyword::new(intermediate_context, inner).await?, + )), + organic::types::Element::BabelCall(inner) => Ok(IAstNode::BabelCall( + IBabelCall::new(intermediate_context, inner).await?, )), - organic::types::Element::Keyword(inner) => { - Ok(IAstNode::Keyword(IKeyword::new(registry, inner).await?)) - } - organic::types::Element::BabelCall(inner) => { - Ok(IAstNode::BabelCall(IBabelCall::new(registry, inner).await?)) - } organic::types::Element::LatexEnvironment(inner) => Ok(IAstNode::LatexEnvironment( - ILatexEnvironment::new(registry, inner).await?, + ILatexEnvironment::new(intermediate_context, inner).await?, )), } } @@ -227,91 +228,97 @@ impl<'parse> IntoIAstNode<'parse> for organic::types::Element<'parse> { impl<'parse> IntoIAstNode<'parse> for organic::types::Object<'parse> { fn into_ast_node<'orig>( &'orig self, - registry: RefRegistry<'orig, 'parse>, + intermediate_context: IntermediateContext<'orig, 'parse>, ) -> BoxFuture<'orig, Result> { async move { match self { - organic::types::Object::Bold(inner) => { - Ok(IAstNode::Bold(IBold::new(registry, inner).await?)) - } - organic::types::Object::Italic(inner) => { - Ok(IAstNode::Italic(IItalic::new(registry, inner).await?)) - } - organic::types::Object::Underline(inner) => { - Ok(IAstNode::Underline(IUnderline::new(registry, inner).await?)) - } + organic::types::Object::Bold(inner) => Ok(IAstNode::Bold( + IBold::new(intermediate_context, inner).await?, + )), + organic::types::Object::Italic(inner) => Ok(IAstNode::Italic( + IItalic::new(intermediate_context, inner).await?, + )), + organic::types::Object::Underline(inner) => Ok(IAstNode::Underline( + IUnderline::new(intermediate_context, inner).await?, + )), organic::types::Object::StrikeThrough(inner) => Ok(IAstNode::StrikeThrough( - IStrikeThrough::new(registry, inner).await?, + IStrikeThrough::new(intermediate_context, inner).await?, + )), + organic::types::Object::Code(inner) => Ok(IAstNode::Code( + ICode::new(intermediate_context, inner).await?, + )), + organic::types::Object::Verbatim(inner) => Ok(IAstNode::Verbatim( + IVerbatim::new(intermediate_context, inner).await?, + )), + organic::types::Object::PlainText(inner) => Ok(IAstNode::PlainText( + IPlainText::new(intermediate_context, inner).await?, )), - organic::types::Object::Code(inner) => { - Ok(IAstNode::Code(ICode::new(registry, inner).await?)) - } - organic::types::Object::Verbatim(inner) => { - Ok(IAstNode::Verbatim(IVerbatim::new(registry, inner).await?)) - } - organic::types::Object::PlainText(inner) => { - Ok(IAstNode::PlainText(IPlainText::new(registry, inner).await?)) - } organic::types::Object::RegularLink(inner) => Ok(IAstNode::RegularLink( - IRegularLink::new(registry, inner).await?, + IRegularLink::new(intermediate_context, inner).await?, + )), + organic::types::Object::RadioLink(inner) => Ok(IAstNode::RadioLink( + IRadioLink::new(intermediate_context, inner).await?, )), - organic::types::Object::RadioLink(inner) => { - Ok(IAstNode::RadioLink(IRadioLink::new(registry, inner).await?)) - } organic::types::Object::RadioTarget(inner) => Ok(IAstNode::RadioTarget( - IRadioTarget::new(registry, inner).await?, + IRadioTarget::new(intermediate_context, inner).await?, + )), + organic::types::Object::PlainLink(inner) => Ok(IAstNode::PlainLink( + IPlainLink::new(intermediate_context, inner).await?, + )), + organic::types::Object::AngleLink(inner) => Ok(IAstNode::AngleLink( + IAngleLink::new(intermediate_context, inner).await?, + )), + organic::types::Object::OrgMacro(inner) => Ok(IAstNode::OrgMacro( + IOrgMacro::new(intermediate_context, inner).await?, + )), + organic::types::Object::Entity(inner) => Ok(IAstNode::Entity( + IEntity::new(intermediate_context, inner).await?, )), - organic::types::Object::PlainLink(inner) => { - Ok(IAstNode::PlainLink(IPlainLink::new(registry, inner).await?)) - } - organic::types::Object::AngleLink(inner) => { - Ok(IAstNode::AngleLink(IAngleLink::new(registry, inner).await?)) - } - organic::types::Object::OrgMacro(inner) => { - Ok(IAstNode::OrgMacro(IOrgMacro::new(registry, inner).await?)) - } - organic::types::Object::Entity(inner) => { - Ok(IAstNode::Entity(IEntity::new(registry, inner).await?)) - } organic::types::Object::LatexFragment(inner) => Ok(IAstNode::LatexFragment( - ILatexFragment::new(registry, inner).await?, + ILatexFragment::new(intermediate_context, inner).await?, )), organic::types::Object::ExportSnippet(inner) => Ok(IAstNode::ExportSnippet( - IExportSnippet::new(registry, inner).await?, + IExportSnippet::new(intermediate_context, inner).await?, )), - organic::types::Object::FootnoteReference(inner) => Ok( - IAstNode::FootnoteReference(IFootnoteReference::new(registry, inner).await?), - ), - organic::types::Object::Citation(inner) => { - Ok(IAstNode::Citation(ICitation::new(registry, inner).await?)) + organic::types::Object::FootnoteReference(inner) => { + Ok(IAstNode::FootnoteReference( + IFootnoteReference::new(intermediate_context, inner).await?, + )) + } + organic::types::Object::Citation(inner) => Ok(IAstNode::Citation( + ICitation::new(intermediate_context, inner).await?, + )), + organic::types::Object::CitationReference(inner) => { + Ok(IAstNode::CitationReference( + ICitationReference::new(intermediate_context, inner).await?, + )) } - organic::types::Object::CitationReference(inner) => Ok( - IAstNode::CitationReference(ICitationReference::new(registry, inner).await?), - ), organic::types::Object::InlineBabelCall(inner) => Ok(IAstNode::InlineBabelCall( - IInlineBabelCall::new(registry, inner).await?, + IInlineBabelCall::new(intermediate_context, inner).await?, )), - organic::types::Object::InlineSourceBlock(inner) => Ok( - IAstNode::InlineSourceBlock(IInlineSourceBlock::new(registry, inner).await?), - ), - organic::types::Object::LineBreak(inner) => { - Ok(IAstNode::LineBreak(ILineBreak::new(registry, inner).await?)) - } - organic::types::Object::Target(inner) => { - Ok(IAstNode::Target(ITarget::new(registry, inner).await?)) + organic::types::Object::InlineSourceBlock(inner) => { + Ok(IAstNode::InlineSourceBlock( + IInlineSourceBlock::new(intermediate_context, inner).await?, + )) } + organic::types::Object::LineBreak(inner) => Ok(IAstNode::LineBreak( + ILineBreak::new(intermediate_context, inner).await?, + )), + organic::types::Object::Target(inner) => Ok(IAstNode::Target( + ITarget::new(intermediate_context, inner).await?, + )), organic::types::Object::StatisticsCookie(inner) => Ok(IAstNode::StatisticsCookie( - IStatisticsCookie::new(registry, inner).await?, + IStatisticsCookie::new(intermediate_context, inner).await?, + )), + organic::types::Object::Subscript(inner) => Ok(IAstNode::Subscript( + ISubscript::new(intermediate_context, inner).await?, )), - organic::types::Object::Subscript(inner) => { - Ok(IAstNode::Subscript(ISubscript::new(registry, inner).await?)) - } organic::types::Object::Superscript(inner) => Ok(IAstNode::Superscript( - ISuperscript::new(registry, inner).await?, + ISuperscript::new(intermediate_context, inner).await?, + )), + organic::types::Object::Timestamp(inner) => Ok(IAstNode::Timestamp( + ITimestamp::new(intermediate_context, inner).await?, )), - organic::types::Object::Timestamp(inner) => { - Ok(IAstNode::Timestamp(ITimestamp::new(registry, inner).await?)) - } } } .boxed() diff --git a/src/intermediate/blog_post.rs b/src/intermediate/blog_post.rs index 6116653..ad74e79 100644 --- a/src/intermediate/blog_post.rs +++ b/src/intermediate/blog_post.rs @@ -9,6 +9,7 @@ use walkdir::WalkDir; use crate::error::CustomError; use crate::intermediate::page::BlogPostPageInput; use crate::intermediate::registry::Registry; +use crate::intermediate::IntermediateContext; use super::BlogPostPage; @@ -62,10 +63,11 @@ impl BlogPost { }); let registry = Arc::new(Mutex::new(registry)); + let intermediate_context = IntermediateContext::new(registry)?; let relative_to_post_dir_path = real_path.strip_prefix(post_dir)?; ret.push( BlogPostPage::new( - registry, + intermediate_context, BlogPostPageInput::new(relative_to_post_dir_path, parsed_document), ) .await?, diff --git a/src/intermediate/bold.rs b/src/intermediate/bold.rs index 6774fb0..7d7e751 100644 --- a/src/intermediate/bold.rs +++ b/src/intermediate/bold.rs @@ -12,12 +12,12 @@ intermediate!( IBold, &'orig organic::types::Bold<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IObject::new(registry.clone(), obj).await?); + ret.push(IObject::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/code.rs b/src/intermediate/code.rs index 6f32ac6..d166683 100644 --- a/src/intermediate/code.rs +++ b/src/intermediate/code.rs @@ -11,7 +11,7 @@ intermediate!( ICode, &'orig organic::types::Code<'parse>, original, - _registry, + _intermediate_context, { Ok(ICode { // TODO: Should this coalesce whitespace like PlainText? diff --git a/src/intermediate/document_element.rs b/src/intermediate/document_element.rs index d8ee0f5..57356bc 100644 --- a/src/intermediate/document_element.rs +++ b/src/intermediate/document_element.rs @@ -12,19 +12,25 @@ pub(crate) enum IDocumentElement { Section(ISection), } -iselector!(IDocumentElement, DocumentElement, original, registry, { - iitem!( - registry, - original, - ( - organic::types::DocumentElement::Heading, - IDocumentElement::Heading, - IHeading - ), - ( - organic::types::DocumentElement::Section, - IDocumentElement::Section, - ISection - ), - ) -}); +iselector!( + IDocumentElement, + DocumentElement, + original, + intermediate_context, + { + iitem!( + intermediate_context, + original, + ( + organic::types::DocumentElement::Heading, + IDocumentElement::Heading, + IHeading + ), + ( + organic::types::DocumentElement::Section, + IDocumentElement::Section, + ISection + ), + ) + } +); diff --git a/src/intermediate/element.rs b/src/intermediate/element.rs index 4769986..5072ea4 100644 --- a/src/intermediate/element.rs +++ b/src/intermediate/element.rs @@ -56,9 +56,9 @@ pub(crate) enum IElement { LatexEnvironment(ILatexEnvironment), } -iselector!(IElement, Element, original, registry, { +iselector!(IElement, Element, original, intermediate_context, { iitem!( - registry, + intermediate_context, original, ( organic::types::Element::Paragraph, diff --git a/src/intermediate/entity.rs b/src/intermediate/entity.rs index 071daa0..11dff6d 100644 --- a/src/intermediate/entity.rs +++ b/src/intermediate/entity.rs @@ -11,7 +11,7 @@ intermediate!( IEntity, &'orig organic::types::Entity<'parse>, original, - _registry, + _intermediate_context, { Ok(IEntity { html: original.html.to_owned(), diff --git a/src/intermediate/footnote_definition.rs b/src/intermediate/footnote_definition.rs index 265c215..bef6779 100644 --- a/src/intermediate/footnote_definition.rs +++ b/src/intermediate/footnote_definition.rs @@ -1,9 +1,9 @@ use super::macros::intermediate; use super::registry::register_footnote_definition; +use super::IntermediateContext; use super::IAstNode; use crate::error::CustomError; -use crate::intermediate::RefRegistry; #[derive(Debug, Clone)] pub(crate) struct IFootnoteDefinition {} @@ -12,9 +12,10 @@ intermediate!( IFootnoteDefinition, &'orig organic::types::FootnoteDefinition<'parse>, original, - registry, + intermediate_context, { - register_footnote_definition(registry, original.label, &original.children).await?; + register_footnote_definition(intermediate_context, original.label, &original.children) + .await?; Ok(IFootnoteDefinition {}) } ); @@ -27,7 +28,7 @@ pub(crate) struct IRealFootnoteDefinition { impl IRealFootnoteDefinition { pub(crate) async fn new<'orig, 'parse>( - _registry: RefRegistry<'orig, 'parse>, + _intermediate_context: IntermediateContext<'orig, 'parse>, footnote_id: usize, contents: Vec, ) -> Result { diff --git a/src/intermediate/footnote_reference.rs b/src/intermediate/footnote_reference.rs index 175edd2..5aef79d 100644 --- a/src/intermediate/footnote_reference.rs +++ b/src/intermediate/footnote_reference.rs @@ -13,10 +13,11 @@ intermediate!( IFootnoteReference, &'orig organic::types::FootnoteReference<'parse>, original, - registry, + intermediate_context, { let (footnote_id, reference_count) = - get_footnote_reference_id(registry, original.label, &original.definition).await?; + get_footnote_reference_id(intermediate_context, original.label, &original.definition) + .await?; Ok(IFootnoteReference { footnote_id, duplicate_offset: reference_count, diff --git a/src/intermediate/heading.rs b/src/intermediate/heading.rs index 74830b3..fbaba46 100644 --- a/src/intermediate/heading.rs +++ b/src/intermediate/heading.rs @@ -15,19 +15,19 @@ intermediate!( IHeading, &'orig organic::types::Heading<'parse>, original, - registry, + intermediate_context, { let title = { let mut ret = Vec::new(); for obj in original.title.iter() { - ret.push(IObject::new(registry.clone(), obj).await?); + ret.push(IObject::new(intermediate_context.clone(), obj).await?); } ret }; let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IDocumentElement::new(registry.clone(), obj).await?); + ret.push(IDocumentElement::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/inline_source_block.rs b/src/intermediate/inline_source_block.rs index 68e31b2..ab32a9c 100644 --- a/src/intermediate/inline_source_block.rs +++ b/src/intermediate/inline_source_block.rs @@ -11,7 +11,7 @@ intermediate!( IInlineSourceBlock, &'orig organic::types::InlineSourceBlock<'parse>, original, - _registry, + _intermediate_context, { Ok(IInlineSourceBlock { value: original.value.to_owned(), diff --git a/src/intermediate/intermediate_context.rs b/src/intermediate/intermediate_context.rs new file mode 100644 index 0000000..ca369a2 --- /dev/null +++ b/src/intermediate/intermediate_context.rs @@ -0,0 +1,15 @@ +use crate::error::CustomError; + +/// The supporting information used for converting the parsed org source representation into the intermediate representation used in this project. +#[derive(Debug, Clone)] +pub(crate) struct IntermediateContext<'orig, 'parse> { + pub(crate) registry: crate::intermediate::RefRegistry<'orig, 'parse>, +} + +impl<'orig, 'parse> IntermediateContext<'orig, 'parse> { + pub(crate) fn new( + registry: crate::intermediate::RefRegistry<'orig, 'parse>, + ) -> Result, CustomError> { + Ok(IntermediateContext { registry }) + } +} diff --git a/src/intermediate/italic.rs b/src/intermediate/italic.rs index 23ecdc3..44bb165 100644 --- a/src/intermediate/italic.rs +++ b/src/intermediate/italic.rs @@ -12,12 +12,12 @@ intermediate!( IItalic, &'orig organic::types::Italic<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IObject::new(registry.clone(), obj).await?); + ret.push(IObject::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/latex_fragment.rs b/src/intermediate/latex_fragment.rs index 75cf59e..ee4195d 100644 --- a/src/intermediate/latex_fragment.rs +++ b/src/intermediate/latex_fragment.rs @@ -11,7 +11,7 @@ intermediate!( ILatexFragment, &'orig organic::types::LatexFragment<'parse>, original, - _registry, + _intermediate_context, { let value: String = if original.value.starts_with("$$") && original.value.ends_with("$$") { format!("\\[{}\\]", &original.value[2..(original.value.len() - 2)]) diff --git a/src/intermediate/macros.rs b/src/intermediate/macros.rs index b3c5465..8b9623f 100644 --- a/src/intermediate/macros.rs +++ b/src/intermediate/macros.rs @@ -8,7 +8,7 @@ macro_rules! inoop { impl $istruct { pub(crate) async fn new<'reg, 'orig, 'parse>( - _registry: crate::intermediate::RefRegistry<'orig, 'parse>, + _intermediate_context: crate::intermediate::IntermediateContext<'orig, 'parse>, _original: &'orig organic::types::$pstruct<'parse>, ) -> Result<$istruct, CustomError> { Ok($istruct {}) @@ -23,10 +23,10 @@ pub(crate) use inoop; /// /// This exists to make changing the type signature easier. macro_rules! intermediate { - ($istruct:ident, $pstruct:ty, $original:ident, $registry:ident, $fnbody:tt) => { + ($istruct:ident, $pstruct:ty, $original:ident, $intermediate_context:ident, $fnbody:tt) => { impl $istruct { pub(crate) async fn new<'orig, 'parse>( - $registry: crate::intermediate::RefRegistry<'orig, 'parse>, + $intermediate_context: crate::intermediate::IntermediateContext<'orig, 'parse>, $original: $pstruct, ) -> Result<$istruct, CustomError> { $fnbody @@ -41,14 +41,12 @@ pub(crate) use intermediate; /// /// This exists to make changing the type signature easier. macro_rules! iselector { - ($istruct:ident, $pstruct:ident, $original:ident, $registry:ident, $fnbody:tt) => { + ($istruct:ident, $pstruct:ident, $original:ident, $intermediate_context:ident, $fnbody:tt) => { impl $istruct { pub(crate) fn new<'orig, 'parse>( - registry: crate::intermediate::RefRegistry<'orig, 'parse>, - original: &'orig organic::types::$pstruct<'parse>, + $intermediate_context: crate::intermediate::IntermediateContext<'orig, 'parse>, + $original: &'orig organic::types::$pstruct<'parse>, ) -> BoxFuture<'orig, Result<$istruct, CustomError>> { - let $registry = registry; - let $original = original; async move { $fnbody }.boxed() } } @@ -58,11 +56,11 @@ macro_rules! iselector { pub(crate) use iselector; macro_rules! iitem { - ($registry:expr, $original:expr, $(($penum:path, $ienum:path, $istruct:ident),)*) => { + ($intermediate_context:expr, $original:expr, $(($penum:path, $ienum:path, $istruct:ident),)*) => { match $original { $( $penum(inner) => Ok($ienum( - $istruct::new($registry.clone(), inner).await?, + $istruct::new($intermediate_context.clone(), inner).await?, )), )* } diff --git a/src/intermediate/mod.rs b/src/intermediate/mod.rs index 4a7595f..ea61ba1 100644 --- a/src/intermediate/mod.rs +++ b/src/intermediate/mod.rs @@ -27,6 +27,7 @@ mod heading; mod horizontal_rule; mod inline_babel_call; mod inline_source_block; +mod intermediate_context; mod italic; mod keyword; mod latex_environment; @@ -94,6 +95,7 @@ pub(crate) use heading::IHeading; pub(crate) use horizontal_rule::IHorizontalRule; pub(crate) use inline_babel_call::IInlineBabelCall; pub(crate) use inline_source_block::IInlineSourceBlock; +pub(crate) use intermediate_context::IntermediateContext; pub(crate) use italic::IItalic; pub(crate) use keyword::IKeyword; pub(crate) use latex_environment::ILatexEnvironment; diff --git a/src/intermediate/object.rs b/src/intermediate/object.rs index 533651f..651ac99 100644 --- a/src/intermediate/object.rs +++ b/src/intermediate/object.rs @@ -63,9 +63,9 @@ pub(crate) enum IObject { Timestamp(ITimestamp), } -iselector!(IObject, Object, original, registry, { +iselector!(IObject, Object, original, intermediate_context, { iitem!( - registry, + intermediate_context, original, (organic::types::Object::Bold, IObject::Bold, IBold), (organic::types::Object::Italic, IObject::Italic, IItalic), diff --git a/src/intermediate/page.rs b/src/intermediate/page.rs index 8de8e24..bc0603d 100644 --- a/src/intermediate/page.rs +++ b/src/intermediate/page.rs @@ -45,23 +45,23 @@ intermediate!( BlogPostPage, BlogPostPageInput<'orig, 'parse>, original, - registry, + intermediate_context, { let mut children = Vec::new(); if let Some(section) = original.document.zeroth_section.as_ref() { children.push(IDocumentElement::Section( - ISection::new(registry.clone(), section).await?, + ISection::new(intermediate_context.clone(), section).await?, )); } for heading in original.document.children.iter() { children.push(IDocumentElement::Heading( - IHeading::new(registry.clone(), heading).await?, + IHeading::new(intermediate_context.clone(), heading).await?, )); } let footnotes = { let footnote_definitions: Vec<_> = { - let registry = registry.lock().unwrap(); + let registry = intermediate_context.registry.lock().unwrap(); let ret = registry .get_footnote_ids() .map(|(id, def)| (id, def.clone())) @@ -70,7 +70,9 @@ intermediate!( }; let mut ret = Vec::new(); for (id, def) in footnote_definitions.into_iter() { - ret.push(IRealFootnoteDefinition::new(registry.clone(), id, def).await?); + ret.push( + IRealFootnoteDefinition::new(intermediate_context.clone(), id, def).await?, + ); } ret }; diff --git a/src/intermediate/paragraph.rs b/src/intermediate/paragraph.rs index 2c2e112..a93eb57 100644 --- a/src/intermediate/paragraph.rs +++ b/src/intermediate/paragraph.rs @@ -12,12 +12,12 @@ intermediate!( IParagraph, &'orig organic::types::Paragraph<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IObject::new(registry.clone(), obj).await?); + ret.push(IObject::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/plain_list.rs b/src/intermediate/plain_list.rs index 68dc0b8..063305e 100644 --- a/src/intermediate/plain_list.rs +++ b/src/intermediate/plain_list.rs @@ -13,12 +13,12 @@ intermediate!( IPlainList, &'orig organic::types::PlainList<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IPlainListItem::new(registry.clone(), obj).await?); + ret.push(IPlainListItem::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/plain_list_item.rs b/src/intermediate/plain_list_item.rs index ca971c6..02f3241 100644 --- a/src/intermediate/plain_list_item.rs +++ b/src/intermediate/plain_list_item.rs @@ -14,12 +14,12 @@ intermediate!( IPlainListItem, &'orig organic::types::PlainListItem<'parse>, original, - registry, + intermediate_context, { let tag = { let mut ret = Vec::new(); for obj in original.tag.iter() { - ret.push(IObject::new(registry.clone(), obj).await?); + ret.push(IObject::new(intermediate_context.clone(), obj).await?); } ret }; @@ -27,7 +27,7 @@ intermediate!( let children = { let mut ret = Vec::new(); for elem in original.children.iter() { - ret.push(IElement::new(registry.clone(), elem).await?); + ret.push(IElement::new(intermediate_context.clone(), elem).await?); } ret }; diff --git a/src/intermediate/plain_text.rs b/src/intermediate/plain_text.rs index ee419ad..a346cbe 100644 --- a/src/intermediate/plain_text.rs +++ b/src/intermediate/plain_text.rs @@ -12,7 +12,7 @@ intermediate!( IPlainText, &'orig organic::types::PlainText<'parse>, original, - _registry, + _intermediate_context, { Ok(IPlainText { source: coalesce_whitespace(original.source).into_owned(), diff --git a/src/intermediate/quote_block.rs b/src/intermediate/quote_block.rs index e7485d0..68daeda 100644 --- a/src/intermediate/quote_block.rs +++ b/src/intermediate/quote_block.rs @@ -12,12 +12,12 @@ intermediate!( IQuoteBlock, &'orig organic::types::QuoteBlock<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IElement::new(registry.clone(), obj).await?); + ret.push(IElement::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/registry.rs b/src/intermediate/registry.rs index 3ae276e..64d1800 100644 --- a/src/intermediate/registry.rs +++ b/src/intermediate/registry.rs @@ -5,10 +5,11 @@ use std::collections::HashMap; use super::ast_node::IAstNode; use super::ast_node::IntoIAstNode; -use super::RefRegistry; +use super::IntermediateContext; type IdCounter = u16; +#[derive(Debug)] pub(crate) struct Registry<'orig, 'parse> { id_counter: IdCounter, targets: HashMap<&'parse str, String>, @@ -47,15 +48,15 @@ impl<'orig, 'parse> Registry<'orig, 'parse> { /// /// This needs to be incremented to be 1-indexed for render. pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( - registry: RefRegistry<'orig, 'parse>, + intermediate_context: IntermediateContext<'orig, 'parse>, label: Option<&'parse str>, definition: &'orig Vec>, ) -> Result<(usize, usize), CustomError> { if let None = label { // If it has no label then it must always get a new ID. - let contents = convert_reference_contents(registry.clone(), definition).await?; + let contents = convert_reference_contents(intermediate_context.clone(), definition).await?; let pos = { - let mut registry = registry.lock().unwrap(); + let mut registry = intermediate_context.registry.lock().unwrap(); registry.footnote_ids.push((None, contents)); registry.footnote_ids.len() - 1 }; @@ -63,8 +64,8 @@ pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( } let reference_count = if let Some(label) = label { - promote_footnote_definition(registry.clone(), label).await?; - let mut registry = registry.lock().unwrap(); + promote_footnote_definition(intermediate_context.clone(), label).await?; + let mut registry = intermediate_context.registry.lock().unwrap(); let reference_count = registry .footnote_reference_counts .entry(label) @@ -75,7 +76,8 @@ pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( 0 }; - let existing_index = registry + let existing_index = intermediate_context + .registry .lock() .unwrap() .footnote_ids @@ -83,8 +85,9 @@ pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( .position(|(id, _definition)| *id == label); if let Some(existing_id) = existing_index { if !definition.is_empty() { - let contents = convert_reference_contents(registry.clone(), definition).await?; - let mut registry = registry.lock().unwrap(); + let contents = + convert_reference_contents(intermediate_context.clone(), definition).await?; + let mut registry = intermediate_context.registry.lock().unwrap(); let entry = registry .footnote_ids .get_mut(existing_id) @@ -94,13 +97,13 @@ pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( Ok((existing_id, reference_count)) } else { let existing_id = { - let mut registry = registry.lock().unwrap(); + let mut registry = intermediate_context.registry.lock().unwrap(); registry.footnote_ids.push((label, Vec::new())); registry.footnote_ids.len() - 1 }; - let contents = convert_reference_contents(registry.clone(), definition).await?; + let contents = convert_reference_contents(intermediate_context.clone(), definition).await?; { - let mut registry = registry.lock().unwrap(); + let mut registry = intermediate_context.registry.lock().unwrap(); let entry = registry .footnote_ids .get_mut(existing_id) @@ -113,24 +116,24 @@ pub(crate) async fn get_footnote_reference_id<'orig, 'parse>( /// Update the definition to a footnote but do not mark it as referenced. pub(crate) async fn register_footnote_definition<'orig, 'parse>( - registry: RefRegistry<'orig, 'parse>, + intermediate_context: IntermediateContext<'orig, 'parse>, label: &'parse str, definition: &'orig Vec>, ) -> Result<(), CustomError> { let has_existing: bool = { - let mut registry = registry.lock().unwrap(); + let mut registry = intermediate_context.registry.lock().unwrap(); registry .footnote_ids .iter_mut() .any(|(id, _definition)| *id == Some(label)) }; if !has_existing { - let mut registry = registry.lock().unwrap(); + let mut registry = intermediate_context.registry.lock().unwrap(); registry.on_deck_footnote_ids.insert(label, definition); return Ok(()); } - let contents = convert_definition_contents(registry.clone(), definition).await?; - let mut registry = registry.lock().unwrap(); + let contents = convert_definition_contents(intermediate_context.clone(), definition).await?; + let mut registry = intermediate_context.registry.lock().unwrap(); if let Some((_existing_id, existing_definition)) = registry .footnote_ids .iter_mut() @@ -142,13 +145,13 @@ pub(crate) async fn register_footnote_definition<'orig, 'parse>( } async fn convert_reference_contents<'orig, 'parse>( - registry: RefRegistry<'orig, 'parse>, + intermediate_context: IntermediateContext<'orig, 'parse>, contents: &'orig Vec>, ) -> Result, CustomError> { let contents = { let mut ret = Vec::new(); for obj in contents.iter() { - ret.push(obj.into_ast_node(registry.clone()).await?); + ret.push(obj.into_ast_node(intermediate_context.clone()).await?); } ret }; @@ -157,13 +160,13 @@ async fn convert_reference_contents<'orig, 'parse>( } async fn convert_definition_contents<'orig, 'parse>( - registry: RefRegistry<'orig, 'parse>, + intermediate_context: IntermediateContext<'orig, 'parse>, contents: &'orig Vec>, ) -> Result, CustomError> { let contents = { let mut ret = Vec::new(); for obj in contents.iter() { - ret.push(obj.into_ast_node(registry.clone()).await?); + ret.push(obj.into_ast_node(intermediate_context.clone()).await?); } ret }; @@ -173,23 +176,23 @@ async fn convert_definition_contents<'orig, 'parse>( /// Take a footnote definition that has not yet received a reference and move it into the active footnotes. pub(crate) async fn promote_footnote_definition<'orig, 'parse>( - registry: RefRegistry<'orig, 'parse>, + intermediate_context: IntermediateContext<'orig, 'parse>, label: &'parse str, ) -> Result<(), CustomError> { let definition = { - let mut registry = registry.lock().unwrap(); + let mut registry = intermediate_context.registry.lock().unwrap(); let definition = registry.on_deck_footnote_ids.remove(label); definition }; if let Some(elements) = definition { let existing_id = { - let mut registry = registry.lock().unwrap(); + let mut registry = intermediate_context.registry.lock().unwrap(); registry.footnote_ids.push((Some(label), Vec::new())); registry.footnote_ids.len() - 1 }; - let contents = convert_definition_contents(registry.clone(), elements).await?; + let contents = convert_definition_contents(intermediate_context.clone(), elements).await?; { - let mut registry = registry.lock().unwrap(); + let mut registry = intermediate_context.registry.lock().unwrap(); let entry = registry .footnote_ids .get_mut(existing_id) diff --git a/src/intermediate/regular_link.rs b/src/intermediate/regular_link.rs index 5f10fb0..14262ee 100644 --- a/src/intermediate/regular_link.rs +++ b/src/intermediate/regular_link.rs @@ -13,12 +13,12 @@ intermediate!( IRegularLink, &'orig organic::types::RegularLink<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IObject::new(registry.clone(), obj).await?); + ret.push(IObject::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/section.rs b/src/intermediate/section.rs index 9dc1119..defca30 100644 --- a/src/intermediate/section.rs +++ b/src/intermediate/section.rs @@ -12,12 +12,12 @@ intermediate!( ISection, &'orig organic::types::Section<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for elem in original.children.iter() { - ret.push(IElement::new(registry.clone(), elem).await?); + ret.push(IElement::new(intermediate_context.clone(), elem).await?); } ret }; diff --git a/src/intermediate/src_block.rs b/src/intermediate/src_block.rs index 145f2ed..6bc9ef0 100644 --- a/src/intermediate/src_block.rs +++ b/src/intermediate/src_block.rs @@ -12,7 +12,7 @@ intermediate!( ISrcBlock, &'orig organic::types::SrcBlock<'parse>, original, - _registry, + _intermediate_context, { let source_code = original.get_value(); let prefix_content_pairs: Vec<_> = source_code diff --git a/src/intermediate/strike_through.rs b/src/intermediate/strike_through.rs index 40d0fb5..151a4ee 100644 --- a/src/intermediate/strike_through.rs +++ b/src/intermediate/strike_through.rs @@ -12,12 +12,12 @@ intermediate!( IStrikeThrough, &'orig organic::types::StrikeThrough<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IObject::new(registry.clone(), obj).await?); + ret.push(IObject::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/table.rs b/src/intermediate/table.rs index 396d05b..cc99add 100644 --- a/src/intermediate/table.rs +++ b/src/intermediate/table.rs @@ -12,12 +12,12 @@ intermediate!( ITable, &'orig organic::types::Table<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(ITableRow::new(registry.clone(), obj).await?); + ret.push(ITableRow::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/table_cell.rs b/src/intermediate/table_cell.rs index 37691c4..deca27d 100644 --- a/src/intermediate/table_cell.rs +++ b/src/intermediate/table_cell.rs @@ -12,12 +12,12 @@ intermediate!( ITableCell, &'orig organic::types::TableCell<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IObject::new(registry.clone(), obj).await?); + ret.push(IObject::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/table_row.rs b/src/intermediate/table_row.rs index 666519d..2faa9e4 100644 --- a/src/intermediate/table_row.rs +++ b/src/intermediate/table_row.rs @@ -11,12 +11,12 @@ intermediate!( ITableRow, &'orig organic::types::TableRow<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(ITableCell::new(registry.clone(), obj).await?); + ret.push(ITableCell::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/target.rs b/src/intermediate/target.rs index de3b32e..3030fe9 100644 --- a/src/intermediate/target.rs +++ b/src/intermediate/target.rs @@ -12,9 +12,9 @@ intermediate!( ITarget, &'orig organic::types::Target<'parse>, original, - registry, + intermediate_context, { - let mut registry = registry.lock().unwrap(); + let mut registry = intermediate_context.registry.lock().unwrap(); let id = registry.get_target(original.value); Ok(ITarget { id: id.clone(), diff --git a/src/intermediate/underline.rs b/src/intermediate/underline.rs index 1fd1b3c..ebbde2f 100644 --- a/src/intermediate/underline.rs +++ b/src/intermediate/underline.rs @@ -12,12 +12,12 @@ intermediate!( IUnderline, &'orig organic::types::Underline<'parse>, original, - registry, + intermediate_context, { let children = { let mut ret = Vec::new(); for obj in original.children.iter() { - ret.push(IObject::new(registry.clone(), obj).await?); + ret.push(IObject::new(intermediate_context.clone(), obj).await?); } ret }; diff --git a/src/intermediate/verbatim.rs b/src/intermediate/verbatim.rs index 6e83727..787c244 100644 --- a/src/intermediate/verbatim.rs +++ b/src/intermediate/verbatim.rs @@ -11,7 +11,7 @@ intermediate!( IVerbatim, &'orig organic::types::Verbatim<'parse>, original, - _registry, + _intermediate_context, { Ok(IVerbatim { // TODO: Should this coalesce whitespace like PlainText?