Create an intermediate ast node type.
This commit is contained in:
		
							parent
							
								
									cd27869122
								
							
						
					
					
						commit
						6109902945
					
				
							
								
								
									
										322
									
								
								src/intermediate/ast_node.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										322
									
								
								src/intermediate/ast_node.rs
									
									
									
									
									
										Normal file
									
								
							| @ -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<IAstNode, CustomError>>; | ||||
| } | ||||
| 
 | ||||
| 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<IAstNode, CustomError>> { | ||||
|         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<IAstNode, CustomError>> { | ||||
|         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<IAstNode, CustomError>> { | ||||
|         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() | ||||
|     } | ||||
| } | ||||
| @ -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( | ||||
|  | ||||
| @ -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<IAstNode>, | ||||
| } | ||||
| 
 | ||||
| impl IRealFootnoteDefinition { | ||||
|     pub(crate) async fn new<'intermediate, 'parse>( | ||||
|         registry: &mut Registry<'intermediate, 'parse>, | ||||
|         footnote_id: usize, | ||||
|         original: &FootnoteDefinitionContents<'intermediate, 'parse>, | ||||
|     ) -> Result<IRealFootnoteDefinition, CustomError> { | ||||
|         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, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| mod angle_link; | ||||
| mod ast_node; | ||||
| mod babel_call; | ||||
| mod bold; | ||||
| mod center_block; | ||||
|  | ||||
| @ -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<String>, | ||||
| 
 | ||||
|     pub(crate) children: Vec<IDocumentElement>, | ||||
| 
 | ||||
|     pub(crate) footnotes: Vec<IRealFootnoteDefinition>, | ||||
| } | ||||
| 
 | ||||
| impl BlogPostPage { | ||||
| @ -36,10 +39,13 @@ impl BlogPostPage { | ||||
|             )); | ||||
|         } | ||||
| 
 | ||||
|         // TODO: Get footnote definitions
 | ||||
| 
 | ||||
|         Ok(BlogPostPage { | ||||
|             path, | ||||
|             title: get_title(&document), | ||||
|             children, | ||||
|             footnotes: Vec::new(), // TODO
 | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -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<IAstNode>)>, | ||||
| } | ||||
| 
 | ||||
| impl<'intermediate, 'parse> Registry<'intermediate, 'parse> { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander