diff --git a/src/intermediate/ast_node.rs b/src/intermediate/ast_node.rs new file mode 100644 index 0000000..da23f24 --- /dev/null +++ b/src/intermediate/ast_node.rs @@ -0,0 +1,322 @@ +use super::angle_link::IAngleLink; +use super::bold::IBold; +use super::citation::ICitation; +use super::citation_reference::ICitationReference; +use super::code::ICode; +use super::comment::IComment; +use super::entity::IEntity; +use super::export_snippet::IExportSnippet; +use super::footnote_reference::IFootnoteReference; +use super::inline_babel_call::IInlineBabelCall; +use super::inline_source_block::IInlineSourceBlock; +use super::italic::IItalic; +use super::keyword::IKeyword; +use super::latex_fragment::ILatexFragment; +use super::line_break::ILineBreak; +use super::org_macro::IOrgMacro; +use super::plain_link::IPlainLink; +use super::plain_text::IPlainText; +use super::radio_link::IRadioLink; +use super::radio_target::IRadioTarget; +use super::registry::Registry; +use super::regular_link::IRegularLink; +use super::statistics_cookie::IStatisticsCookie; +use super::strike_through::IStrikeThrough; +use super::subscript::ISubscript; +use super::superscript::ISuperscript; +use super::IBabelCall; +use super::ICenterBlock; +use super::IClock; +use super::ICommentBlock; +use super::IDiarySexp; +use super::IDrawer; +use super::IDynamicBlock; +use super::IExampleBlock; +use super::IExportBlock; +use super::IFixedWidthArea; +use super::IFootnoteDefinition; +use super::IHeading; +use super::IHorizontalRule; +use super::ILatexEnvironment; +use super::IParagraph; +use super::IPlainList; +use super::IPlanning; +use super::IPropertyDrawer; +use super::IQuoteBlock; +use super::ISection; +use super::ISpecialBlock; +use super::ISrcBlock; +use super::ITable; +use super::ITarget; +use super::ITimestamp; +use super::IUnderline; +use super::IVerbatim; +use super::IVerseBlock; +use crate::error::CustomError; +use futures::future::{BoxFuture, FutureExt}; + +#[derive(Debug)] +pub(crate) enum IAstNode { + Heading(IHeading), + Section(ISection), + Paragraph(IParagraph), + PlainList(IPlainList), + CenterBlock(ICenterBlock), + QuoteBlock(IQuoteBlock), + SpecialBlock(ISpecialBlock), + DynamicBlock(IDynamicBlock), + FootnoteDefinition(IFootnoteDefinition), + Comment(IComment), + Drawer(IDrawer), + PropertyDrawer(IPropertyDrawer), + Table(ITable), + VerseBlock(IVerseBlock), + CommentBlock(ICommentBlock), + ExampleBlock(IExampleBlock), + ExportBlock(IExportBlock), + SrcBlock(ISrcBlock), + Clock(IClock), + DiarySexp(IDiarySexp), + Planning(IPlanning), + FixedWidthArea(IFixedWidthArea), + HorizontalRule(IHorizontalRule), + Keyword(IKeyword), + BabelCall(IBabelCall), + LatexEnvironment(ILatexEnvironment), + Bold(IBold), + Italic(IItalic), + Underline(IUnderline), + StrikeThrough(IStrikeThrough), + Code(ICode), + Verbatim(IVerbatim), + PlainText(IPlainText), + RegularLink(IRegularLink), + RadioLink(IRadioLink), + RadioTarget(IRadioTarget), + PlainLink(IPlainLink), + AngleLink(IAngleLink), + OrgMacro(IOrgMacro), + Entity(IEntity), + LatexFragment(ILatexFragment), + ExportSnippet(IExportSnippet), + FootnoteReference(IFootnoteReference), + Citation(ICitation), + CitationReference(ICitationReference), + InlineBabelCall(IInlineBabelCall), + InlineSourceBlock(IInlineSourceBlock), + LineBreak(ILineBreak), + Target(ITarget), + StatisticsCookie(IStatisticsCookie), + Subscript(ISubscript), + Superscript(ISuperscript), + Timestamp(ITimestamp), +} + +trait IntoIAstNode<'intermediate, 'parse> { + fn new<'b>( + &'intermediate self, + registry: &'b mut Registry<'intermediate, 'parse>, + ) -> BoxFuture<'b, Result>; +} + +impl<'intermediate, 'parse> IntoIAstNode<'intermediate, 'parse> + for organic::types::DocumentElement<'parse> +{ + fn new<'b>( + &'intermediate self, + registry: &'b mut Registry<'intermediate, 'parse>, + ) -> BoxFuture<'b, 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?)) + } + } + } + .boxed() + } +} + +impl<'intermediate, 'parse> IntoIAstNode<'intermediate, 'parse> + for organic::types::Element<'parse> +{ + fn new<'b>( + &'intermediate self, + registry: &'b mut Registry<'intermediate, 'parse>, + ) -> BoxFuture<'b, 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::CenterBlock(inner) => Ok(IAstNode::CenterBlock( + ICenterBlock::new(registry, inner).await?, + )), + organic::types::Element::QuoteBlock(inner) => Ok(IAstNode::QuoteBlock( + IQuoteBlock::new(registry, inner).await?, + )), + organic::types::Element::SpecialBlock(inner) => Ok(IAstNode::SpecialBlock( + ISpecialBlock::new(registry, inner).await?, + )), + organic::types::Element::DynamicBlock(inner) => Ok(IAstNode::DynamicBlock( + IDynamicBlock::new(registry, 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::PropertyDrawer(inner) => Ok(IAstNode::PropertyDrawer( + IPropertyDrawer::new(registry, 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?, + )), + organic::types::Element::CommentBlock(inner) => Ok(IAstNode::CommentBlock( + ICommentBlock::new(registry, inner).await?, + )), + organic::types::Element::ExampleBlock(inner) => Ok(IAstNode::ExampleBlock( + IExampleBlock::new(registry, inner).await?, + )), + organic::types::Element::ExportBlock(inner) => Ok(IAstNode::ExportBlock( + IExportBlock::new(registry, 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?, + )), + organic::types::Element::HorizontalRule(inner) => Ok(IAstNode::HorizontalRule( + IHorizontalRule::new(registry, 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?, + )), + } + } + .boxed() + } +} + +impl<'intermediate, 'parse> IntoIAstNode<'intermediate, 'parse> for organic::types::Object<'parse> { + fn new<'b>( + &'intermediate self, + registry: &'b mut Registry<'intermediate, 'parse>, + ) -> BoxFuture<'b, 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::StrikeThrough(inner) => Ok(IAstNode::StrikeThrough( + IStrikeThrough::new(registry, 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?, + )), + 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?, + )), + 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?, + )), + organic::types::Object::ExportSnippet(inner) => Ok(IAstNode::ExportSnippet( + IExportSnippet::new(registry, 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::CitationReference(inner) => Ok( + IAstNode::CitationReference(ICitationReference::new(registry, inner).await?), + ), + organic::types::Object::InlineBabelCall(inner) => Ok(IAstNode::InlineBabelCall( + IInlineBabelCall::new(registry, 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::StatisticsCookie(inner) => Ok(IAstNode::StatisticsCookie( + IStatisticsCookie::new(registry, 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?, + )), + organic::types::Object::Timestamp(inner) => { + Ok(IAstNode::Timestamp(ITimestamp::new(registry, inner).await?)) + } + } + } + .boxed() + } +} diff --git a/src/intermediate/definition.rs b/src/intermediate/definition.rs index 2f62ca7..6e21bb6 100644 --- a/src/intermediate/definition.rs +++ b/src/intermediate/definition.rs @@ -43,23 +43,21 @@ 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.iter() { + let mut registry = Registry::new(); + + // Assign IDs to the targets + 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 relative_to_post_dir_path = real_path.strip_prefix(post_dir)?; ret.push( BlogPostPage::new( diff --git a/src/intermediate/footnote_definition.rs b/src/intermediate/footnote_definition.rs index f6da6c3..2f2b645 100644 --- a/src/intermediate/footnote_definition.rs +++ b/src/intermediate/footnote_definition.rs @@ -1,6 +1,10 @@ use crate::error::CustomError; +use super::ast_node::IAstNode; +use super::registry::FootnoteDefinitionContents; use super::registry::Registry; +use super::IElement; +use super::IObject; #[derive(Debug)] pub(crate) struct IFootnoteDefinition {} @@ -14,3 +18,44 @@ impl IFootnoteDefinition { Ok(IFootnoteDefinition {}) } } + +#[derive(Debug)] +pub(crate) struct IRealFootnoteDefinition { + footnote_id: usize, + contents: Vec, +} + +impl IRealFootnoteDefinition { + pub(crate) async fn new<'intermediate, 'parse>( + registry: &mut Registry<'intermediate, 'parse>, + footnote_id: usize, + original: &FootnoteDefinitionContents<'intermediate, 'parse>, + ) -> Result { + let contents = match original { + FootnoteDefinitionContents::FromReference(inner) => { + let contents = { + let mut ret = Vec::new(); + for obj in inner.iter() { + ret.push(IAstNode::Object(IObject::new(registry, obj).await?)); + } + ret + }; + contents + } + FootnoteDefinitionContents::FromDefinition(inner) => { + let contents = { + let mut ret = Vec::new(); + for obj in inner.iter() { + ret.push(IAstNode::Element(IElement::new(registry, obj).await?)); + } + ret + }; + contents + } + }; + Ok(IRealFootnoteDefinition { + footnote_id, + contents, + }) + } +} diff --git a/src/intermediate/mod.rs b/src/intermediate/mod.rs index ac1f411..dd316f9 100644 --- a/src/intermediate/mod.rs +++ b/src/intermediate/mod.rs @@ -1,4 +1,5 @@ mod angle_link; +mod ast_node; mod babel_call; mod bold; mod center_block; diff --git a/src/intermediate/page.rs b/src/intermediate/page.rs index ba2f754..4b83943 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::footnote_definition::IRealFootnoteDefinition; use super::registry::Registry; use super::IDocumentElement; use super::IHeading; @@ -15,6 +16,8 @@ pub(crate) struct BlogPostPage { pub(crate) title: Option, pub(crate) children: Vec, + + pub(crate) footnotes: Vec, } impl BlogPostPage { @@ -36,10 +39,13 @@ impl BlogPostPage { )); } + // TODO: Get footnote definitions + Ok(BlogPostPage { path, title: get_title(&document), children, + footnotes: Vec::new(), // TODO }) } diff --git a/src/intermediate/registry.rs b/src/intermediate/registry.rs index a56cbc6..a2d8d33 100644 --- a/src/intermediate/registry.rs +++ b/src/intermediate/registry.rs @@ -3,15 +3,14 @@ use std::collections::HashMap; use organic::types::Element; use organic::types::Object; +use super::ast_node::IAstNode; + type IdCounter = u16; pub(crate) struct Registry<'intermediate, 'parse> { id_counter: IdCounter, targets: HashMap<&'parse str, String>, - footnote_ids: Vec<( - Option<&'parse str>, - FootnoteDefinitionContents<'intermediate, 'parse>, - )>, + footnote_ids: Vec<(Option<&'parse str>, Vec)>, } impl<'intermediate, 'parse> Registry<'intermediate, 'parse> {