Add a build for regular non-blog-post pages from org source.

This commit is contained in:
Tom Alexander
2023-12-23 16:37:19 -05:00
parent 424a970014
commit 8905c9356b
9 changed files with 357 additions and 53 deletions

View File

@@ -7,7 +7,7 @@ use tokio::task::JoinHandle;
use walkdir::WalkDir;
use crate::error::CustomError;
use crate::intermediate::page::BlogPostPageInput;
use crate::intermediate::blog_post_page::BlogPostPageInput;
use crate::intermediate::registry::Registry;
use crate::intermediate::IntermediateContext;
@@ -119,7 +119,7 @@ async fn read_file(path: PathBuf) -> std::io::Result<(PathBuf, String)> {
Ok((path, contents))
}
fn get_org_files<P: AsRef<Path>>(
pub(crate) fn get_org_files<P: AsRef<Path>>(
root_dir: P,
) -> Result<impl Iterator<Item = JoinHandle<std::io::Result<(PathBuf, String)>>>, walkdir::Error> {
let org_files = WalkDir::new(root_dir)

View File

@@ -0,0 +1,121 @@
use std::path::PathBuf;
use crate::error::CustomError;
use super::footnote_definition::IRealFootnoteDefinition;
use super::macros::intermediate;
use super::IDocumentElement;
use super::IHeading;
use super::ISection;
#[derive(Debug)]
pub(crate) struct BlogPostPageInput<'b, 'parse> {
path: PathBuf,
document: &'b organic::types::Document<'parse>,
}
impl<'b, 'parse> BlogPostPageInput<'b, 'parse> {
pub(crate) fn new<P: Into<PathBuf>>(
path: P,
document: &'b organic::types::Document<'parse>,
) -> BlogPostPageInput<'b, 'parse> {
BlogPostPageInput {
path: path.into(),
document,
}
}
}
#[derive(Debug)]
pub(crate) struct BlogPostPage {
/// Relative path from the root of the blog post.
pub(crate) path: PathBuf,
pub(crate) title: Option<String>,
pub(crate) date: Option<String>,
pub(crate) children: Vec<IDocumentElement>,
pub(crate) footnotes: Vec<IRealFootnoteDefinition>,
}
intermediate!(
BlogPostPage,
BlogPostPageInput<'orig, 'parse>,
original,
intermediate_context,
{
let mut children = Vec::new();
if let Some(section) = original.document.zeroth_section.as_ref() {
children.push(IDocumentElement::Section(
ISection::new(intermediate_context.clone(), section).await?,
));
}
for heading in original.document.children.iter() {
children.push(IDocumentElement::Heading(
IHeading::new(intermediate_context.clone(), heading).await?,
));
}
let footnotes = {
let footnote_definitions: Vec<_> = {
let registry = intermediate_context.registry.lock().unwrap();
let ret = registry
.get_footnote_ids()
.map(|(id, def)| (id, def.clone()))
.collect();
ret
};
let mut ret = Vec::new();
for (id, def) in footnote_definitions.into_iter() {
ret.push(
IRealFootnoteDefinition::new(intermediate_context.clone(), id, def).await?,
);
}
ret
};
Ok(BlogPostPage {
path: original.path,
title: get_title(original.document),
date: get_date(original.document),
children,
footnotes,
})
}
);
impl BlogPostPage {
/// Get the output path relative to the post directory.
pub(crate) fn get_output_path(&self) -> PathBuf {
let mut ret = self.path.clone();
ret.set_extension("html");
ret
}
}
pub(crate) fn get_title(document: &organic::types::Document<'_>) -> Option<String> {
organic::types::AstNode::from(document)
.iter_all_ast_nodes()
.filter_map(|node| match node {
organic::types::AstNode::Keyword(kw) if kw.key.eq_ignore_ascii_case("title") => {
Some(kw)
}
_ => None,
})
.last()
.map(|kw| kw.value.to_owned())
}
pub(crate) fn get_date(document: &organic::types::Document<'_>) -> Option<String> {
organic::types::AstNode::from(document)
.iter_all_ast_nodes()
.filter_map(|node| match node {
organic::types::AstNode::Keyword(kw) if kw.key.eq_ignore_ascii_case("date") => Some(kw),
_ => None,
})
.last()
.map(|kw| kw.value.to_owned())
}

View File

@@ -2,6 +2,7 @@ mod angle_link;
mod ast_node;
mod babel_call;
mod blog_post;
mod blog_post_page;
mod bold;
mod center_block;
mod citation;
@@ -70,7 +71,9 @@ mod verse_block;
pub(crate) use angle_link::IAngleLink;
pub(crate) use ast_node::IAstNode;
pub(crate) use babel_call::IBabelCall;
pub(crate) use blog_post::get_org_files;
pub(crate) use blog_post::BlogPost;
pub(crate) use blog_post_page::BlogPostPage;
pub(crate) use bold::IBold;
pub(crate) use center_block::ICenterBlock;
pub(crate) use citation::ICitation;
@@ -105,7 +108,8 @@ pub(crate) use latex_fragment::ILatexFragment;
pub(crate) use line_break::ILineBreak;
pub(crate) use object::IObject;
pub(crate) use org_macro::IOrgMacro;
pub(crate) use page::BlogPostPage;
pub(crate) use page::IPage;
pub(crate) use page::PageInput;
pub(crate) use paragraph::IParagraph;
pub(crate) use plain_link::IPlainLink;
pub(crate) use plain_list::IPlainList;
@@ -117,6 +121,7 @@ pub(crate) use property_drawer::IPropertyDrawer;
pub(crate) use quote_block::IQuoteBlock;
pub(crate) use radio_link::IRadioLink;
pub(crate) use radio_target::IRadioTarget;
pub(crate) use registry::Registry;
pub(crate) use regular_link::IRegularLink;
pub(crate) use section::ISection;
pub(crate) use special_block::ISpecialBlock;

View File

@@ -1,39 +1,21 @@
use std::path::PathBuf;
use crate::error::CustomError;
use super::blog_post_page::get_date;
use super::blog_post_page::get_title;
use super::footnote_definition::IRealFootnoteDefinition;
use super::macros::intermediate;
use super::IDocumentElement;
use super::IHeading;
use super::ISection;
use crate::error::CustomError;
use std::path::PathBuf;
#[derive(Debug)]
pub(crate) struct BlogPostPageInput<'b, 'parse> {
path: PathBuf,
document: &'b organic::types::Document<'parse>,
}
impl<'b, 'parse> BlogPostPageInput<'b, 'parse> {
pub(crate) fn new<P: Into<PathBuf>>(
path: P,
document: &'b organic::types::Document<'parse>,
) -> BlogPostPageInput<'b, 'parse> {
BlogPostPageInput {
path: path.into(),
document,
}
}
}
#[derive(Debug)]
pub(crate) struct BlogPostPage {
/// Relative path from the root of the blog post.
pub(crate) struct IPage {
/// Relative path from the root of the pages directory.
pub(crate) path: PathBuf,
pub(crate) title: Option<String>,
#[allow(dead_code)]
pub(crate) date: Option<String>,
pub(crate) children: Vec<IDocumentElement>,
@@ -42,8 +24,8 @@ pub(crate) struct BlogPostPage {
}
intermediate!(
BlogPostPage,
BlogPostPageInput<'orig, 'parse>,
IPage,
PageInput<'orig, 'parse>,
original,
intermediate_context,
{
@@ -77,7 +59,7 @@ intermediate!(
ret
};
Ok(BlogPostPage {
Ok(IPage {
path: original.path,
title: get_title(original.document),
date: get_date(original.document),
@@ -87,8 +69,8 @@ intermediate!(
}
);
impl BlogPostPage {
/// Get the output path relative to the post directory.
impl IPage {
/// Get the output path relative to the pages directory.
pub(crate) fn get_output_path(&self) -> PathBuf {
let mut ret = self.path.clone();
ret.set_extension("html");
@@ -96,26 +78,20 @@ impl BlogPostPage {
}
}
fn get_title(document: &organic::types::Document<'_>) -> Option<String> {
organic::types::AstNode::from(document)
.iter_all_ast_nodes()
.filter_map(|node| match node {
organic::types::AstNode::Keyword(kw) if kw.key.eq_ignore_ascii_case("title") => {
Some(kw)
}
_ => None,
})
.last()
.map(|kw| kw.value.to_owned())
#[derive(Debug)]
pub(crate) struct PageInput<'b, 'parse> {
path: PathBuf,
document: &'b organic::types::Document<'parse>,
}
fn get_date(document: &organic::types::Document<'_>) -> Option<String> {
organic::types::AstNode::from(document)
.iter_all_ast_nodes()
.filter_map(|node| match node {
organic::types::AstNode::Keyword(kw) if kw.key.eq_ignore_ascii_case("date") => Some(kw),
_ => None,
})
.last()
.map(|kw| kw.value.to_owned())
impl<'b, 'parse> PageInput<'b, 'parse> {
pub(crate) fn new<P: Into<PathBuf>>(
path: P,
document: &'b organic::types::Document<'parse>,
) -> PageInput<'b, 'parse> {
PageInput {
path: path.into(),
document,
}
}
}