diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..a5f9492 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "nightly" +profile = "default" +components = ["clippy", "rustfmt"] diff --git a/src/command/build/render.rs b/src/command/build/render.rs index 5108ccd..7ec4410 100644 --- a/src/command/build/render.rs +++ b/src/command/build/render.rs @@ -7,6 +7,7 @@ use tokio::fs::DirEntry; use tokio::task::JoinHandle; use crate::config::Config; +use crate::context::DependencyManager; use crate::context::RenderBlogPostPage; use crate::context::RenderBlogPostPageInput; use crate::context::RenderBlogStream; @@ -85,11 +86,14 @@ impl SiteRenderer { for page in &self.pages { let output_path = self.output_directory.join(page.get_output_path()); + let dependency_manager = + std::sync::Arc::new(std::sync::Mutex::new(DependencyManager::new())); let render_context = RenderContext::new( config, self.output_directory.as_path(), output_path.as_path(), None, + dependency_manager, )?; let render_context = RenderPage::new(render_context, page)?; let rendered_output = renderer_integration.render(render_context)?; @@ -113,12 +117,15 @@ impl SiteRenderer { .join(config.get_relative_path_to_post(&blog_post.id)) .join(blog_post_page.get_output_path()); + let dependency_manager = + std::sync::Arc::new(std::sync::Mutex::new(DependencyManager::new())); let convert_input = RenderBlogPostPageInput::new(blog_post, blog_post_page); let render_context = RenderContext::new( config, self.output_directory.as_path(), output_path.as_path(), None, + dependency_manager, )?; let render_context = RenderBlogPostPage::new(render_context, &convert_input)?; let rendered_output = renderer_integration.render(render_context)?; @@ -127,6 +134,9 @@ impl SiteRenderer { .ok_or("Output file should have a containing directory.")?; tokio::fs::create_dir_all(parent_directory).await?; tokio::fs::write(output_path, rendered_output).await?; + + // TODO: Copy post files to output. + // TODO: Update link src to generate path correct for where the page is rendered. } } @@ -194,12 +204,15 @@ impl SiteRenderer { )?) }; + let dependency_manager = + std::sync::Arc::new(std::sync::Mutex::new(DependencyManager::new())); let convert_input = RenderBlogStreamInput::new(chunk, older_link, newer_link); let render_context = RenderContext::new( config, self.output_directory.as_path(), output_file.as_path(), None, + dependency_manager, )?; let blog_stream = RenderBlogStream::new(render_context, &convert_input)?; diff --git a/src/context/dependency_manager.rs b/src/context/dependency_manager.rs new file mode 100644 index 0000000..0e32026 --- /dev/null +++ b/src/context/dependency_manager.rs @@ -0,0 +1,19 @@ +use std::path::PathBuf; + +pub(crate) type RefDependencyManager = std::sync::Arc>; + +#[derive(Debug)] +pub(crate) struct DependencyManager { + /// A stack of paths for the files being visited. + /// + /// The last entry is the current file being processed. This can be used for handling relative-path links. + file_stack: Vec, +} + +impl DependencyManager { + pub(crate) fn new() -> Self { + DependencyManager { + file_stack: Vec::new(), + } + } +} diff --git a/src/context/mod.rs b/src/context/mod.rs index cea8689..997ce1c 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -11,6 +11,7 @@ mod clock; mod code; mod comment; mod comment_block; +mod dependency_manager; mod diary_sexp; mod document_element; mod drawer; @@ -72,6 +73,7 @@ pub(crate) use blog_post_page::RenderBlogPostPage; pub(crate) use blog_post_page::RenderBlogPostPageInput; pub(crate) use blog_stream::RenderBlogStream; pub(crate) use blog_stream::RenderBlogStreamInput; +pub(crate) use dependency_manager::DependencyManager; pub(crate) use document_element::RenderDocumentElement; pub(crate) use element::RenderElement; pub(crate) use footnote_definition::RenderRealFootnoteDefinition; diff --git a/src/context/render_context.rs b/src/context/render_context.rs index 7cb9b0b..122b415 100644 --- a/src/context/render_context.rs +++ b/src/context/render_context.rs @@ -3,6 +3,8 @@ use std::path::Path; use crate::config::Config; use crate::error::CustomError; +use super::dependency_manager::RefDependencyManager; + /// The supporting information used for converting the intermediate representation into the dust context for rendering. #[derive(Debug, Clone)] pub(crate) struct RenderContext<'intermediate> { @@ -16,6 +18,13 @@ pub(crate) struct RenderContext<'intermediate> { /// IDs, for example, multiple blog posts with footnotes in a blog /// stream. pub(crate) id_addition: Option<&'intermediate str>, + + /// Tracks dependencies from rendering Org document(s). + /// + /// Examples of dependencies would be: + /// - Static files that need to be copied to the output folder + /// - Code blocks that need to be executed (for example, gnuplot graphs) + pub(crate) dependency_manager: RefDependencyManager, } impl<'intermediate> RenderContext<'intermediate> { @@ -24,12 +33,14 @@ impl<'intermediate> RenderContext<'intermediate> { output_directory: &'intermediate Path, output_file: &'intermediate Path, id_addition: Option<&'intermediate str>, + dependency_manager: RefDependencyManager, ) -> Result, CustomError> { Ok(RenderContext { config, output_root_directory: output_directory, output_file, id_addition, + dependency_manager, }) } }