Compare commits

..

No commits in common. "050b426f6f4b786792e15f8ec8ffe8440972b499" and "6968a5b02cef77e8b729b4b99752331cde805510" have entirely different histories.

102 changed files with 1405 additions and 1519 deletions

View File

@ -1,6 +1,6 @@
<div class="blog_post"> <div class="blog_post">
<div class="blog_post_intro"> <div class="blog_post_intro">
{?.title}{?.self_link}<a class="blog_post_title" href="{.self_link}">{.title}</a>{:else}<div class="blog_post_title">{.title}</div>{/.self_link}{/.title} {?.title}{?.self_link}<a class="blog_post_title" href="{.link}">{.title}</a>{:else}<div class="blog_post_title">{.title}</div>{/.self_link}{/.title}
{! TODO: date? !} {! TODO: date? !}
</div> </div>

View File

@ -1,31 +0,0 @@
<div class="blog_stream">
{#.children}
<div class="blog_stream_post">
<div class="blog_post_intro">
{?.title}{?.self_link}<a class="blog_post_title" href="{.self_link}">{.title}</a>{:else}<div class="blog_post_title">{.title}</div>{/.self_link}{/.title}
{! TODO: date? !}
</div>
{! TODO: Table of contents? !}
<div class="blog_post_body">
{#.children}
{>document_element/}
{/.children}
{?.footnotes}
<h2>Footnotes:</h2>
{#.footnotes}
{>real_footnote_definition/}
{/.footnotes}
{/.footnotes}
</div>
</div>
{/.children}
{#.stream_pagination}
<div class="stream_nav">
{?.older_link}<a href="{.older_link}">Older</a>{/.older_link}
{?.newer_link}<a href="{.newer_link}">Newer</a>{/.newer_link}
</div>
{/.stream_pagination}
</div>

View File

@ -11,7 +11,6 @@
<div class="main_content"> <div class="main_content">
{@select key=.type} {@select key=.type}
{@eq value="blog_post_page"}{>blog_post_page/}{/eq} {@eq value="blog_post_page"}{>blog_post_page/}{/eq}
{@eq value="blog_stream"}{>blog_stream/}{/eq}
{@none}{!TODO: make this panic!}ERROR: Unrecognized page content type{/none} {@none}{!TODO: make this panic!}ERROR: Unrecognized page content type{/none}
{/select} {/select}
</div> </div>

View File

@ -5,13 +5,8 @@ use include_dir::include_dir;
use include_dir::Dir; use include_dir::Dir;
use crate::config::Config; use crate::config::Config;
use crate::context::RenderBlogPostPage;
use crate::context::RenderBlogPostPageInput;
use crate::context::RenderBlogStream;
use crate::context::RenderBlogStreamInput;
use crate::context::RenderContext;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::get_web_path; use crate::intermediate::convert_blog_post_page_to_render_context;
use crate::intermediate::BlogPost; use crate::intermediate::BlogPost;
use crate::render::DusterRenderer; use crate::render::DusterRenderer;
use crate::render::RendererIntegration; use crate::render::RendererIntegration;
@ -39,7 +34,7 @@ impl SiteRenderer {
} }
} }
fn init_renderer_integration(&self) -> Result<DusterRenderer<'_>, CustomError> { pub(crate) async fn render_blog_posts(&self, config: &Config) -> Result<(), CustomError> {
let mut renderer_integration = DusterRenderer::new(); let mut renderer_integration = DusterRenderer::new();
let sources: Vec<_> = MAIN_TEMPLATES let sources: Vec<_> = MAIN_TEMPLATES
@ -67,27 +62,21 @@ impl SiteRenderer {
renderer_integration.load_template(name, contents)?; renderer_integration.load_template(name, contents)?;
} }
Ok(renderer_integration)
}
pub(crate) async fn render_blog_posts(&self, config: &Config) -> Result<(), CustomError> {
let renderer_integration = self.init_renderer_integration()?;
for blog_post in &self.blog_posts { for blog_post in &self.blog_posts {
for blog_post_page in &blog_post.pages { for blog_post_page in &blog_post.pages {
let output_path = self let output_path = self
.output_directory .output_directory
.join(config.get_relative_path_to_post(&blog_post.id)) .join("posts")
.join(&blog_post.id)
.join(blog_post_page.get_output_path()); .join(blog_post_page.get_output_path());
let convert_input = RenderBlogPostPageInput::new(blog_post, blog_post_page); let render_context = convert_blog_post_page_to_render_context(
let render_context = RenderContext::new(
config, config,
self.output_directory.as_path(), &self.output_directory,
output_path.as_path(), &output_path,
None, blog_post,
blog_post_page,
)?; )?;
let render_context = RenderBlogPostPage::new(render_context, &convert_input)?;
let rendered_output = renderer_integration.render(render_context)?; let rendered_output = renderer_integration.render(render_context)?;
let parent_directory = output_path let parent_directory = output_path
.parent() .parent()
@ -100,87 +89,6 @@ impl SiteRenderer {
Ok(()) Ok(())
} }
pub(crate) async fn render_blog_stream(&self, config: &Config) -> Result<(), CustomError> {
let renderer_integration = self.init_renderer_integration()?;
// Sort blog posts by date, newest first.
let sorted_blog_posts = {
let mut sorted_blog_posts: Vec<_> = self.blog_posts.iter().collect();
sorted_blog_posts
.sort_by_key(|blog_post| (blog_post.get_date(), blog_post.id.as_str()));
sorted_blog_posts.reverse();
sorted_blog_posts
};
for blog_post in &sorted_blog_posts {
if blog_post.get_date().is_none() {
return Err(format!("Blog post {} does not have a date.", blog_post.id).into());
}
}
// Group blog posts based on # of posts per page.
let stream_chunks: Vec<_> = sorted_blog_posts
.chunks(config.get_stream_entries_per_page())
.collect();
// For each group, create a RenderBlogStream.
let num_stream_pages = stream_chunks.len();
for (page_num, chunk) in stream_chunks.into_iter().enumerate() {
let output_file = if page_num == 0 {
self.output_directory.join("index.html")
} else {
self.output_directory
.join("stream")
.join(format!("{}.html", page_num))
};
let newer_link = if page_num == 0 {
None
} else if page_num == 1 {
Some(get_web_path(
config,
&self.output_directory,
&output_file,
"index.html",
)?)
} else {
Some(get_web_path(
config,
&self.output_directory,
&output_file,
format!("stream/{}.html", page_num - 1),
)?)
};
let older_link = if page_num == (num_stream_pages - 1) {
None
} else {
Some(get_web_path(
config,
&self.output_directory,
&output_file,
format!("stream/{}.html", page_num + 1),
)?)
};
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,
)?;
let blog_stream = RenderBlogStream::new(render_context, &convert_input)?;
// Pass each RenderBlogStream to dust as the context to render index.html and any additional stream pages.
let rendered_output = renderer_integration.render(blog_stream)?;
let parent_directory = output_file
.parent()
.ok_or("Output file should have a containing directory.")?;
tokio::fs::create_dir_all(parent_directory).await?;
tokio::fs::write(output_file, rendered_output).await?;
}
Ok(())
}
pub(crate) async fn render_stylesheets(&self) -> Result<(), CustomError> { pub(crate) async fn render_stylesheets(&self) -> Result<(), CustomError> {
let stylesheet_output_directory = self.output_directory.join("stylesheet"); let stylesheet_output_directory = self.output_directory.join("stylesheet");
if !stylesheet_output_directory.exists() { if !stylesheet_output_directory.exists() {

View File

@ -23,7 +23,6 @@ pub(crate) async fn build_site(args: BuildArgs) -> Result<(), CustomError> {
stylesheets, stylesheets,
); );
renderer.render_blog_posts(&config).await?; renderer.render_blog_posts(&config).await?;
renderer.render_blog_stream(&config).await?;
renderer.render_stylesheets().await?; renderer.render_stylesheets().await?;
Ok(()) Ok(())

View File

@ -8,7 +8,6 @@ use crate::error::CustomError;
use super::raw::RawConfig; use super::raw::RawConfig;
/// This is the config struct used by most of the code, which is an interpreted version of the RawConfig struct which is the raw disk-representation of the config. /// This is the config struct used by most of the code, which is an interpreted version of the RawConfig struct which is the raw disk-representation of the config.
#[derive(Debug)]
pub(crate) struct Config { pub(crate) struct Config {
raw: RawConfig, raw: RawConfig,
config_path: PathBuf, config_path: PathBuf,
@ -57,15 +56,6 @@ impl Config {
self.get_root_directory().join("posts") self.get_root_directory().join("posts")
} }
/// Get the relative path to the folder containing a blog post.
///
/// This could be appended to the output root directory to get the
/// blog post output folder or it could be used to generate a link
/// to the blog post.
pub(crate) fn get_relative_path_to_post<P: AsRef<Path>>(&self, post_id: P) -> PathBuf {
Path::new("posts").join(post_id)
}
pub(crate) fn get_output_directory(&self) -> PathBuf { pub(crate) fn get_output_directory(&self) -> PathBuf {
self.get_root_directory().join("output") self.get_root_directory().join("output")
} }
@ -81,13 +71,4 @@ impl Config {
pub(crate) fn get_site_title(&self) -> Option<&str> { pub(crate) fn get_site_title(&self) -> Option<&str> {
self.raw.site_title.as_deref() self.raw.site_title.as_deref()
} }
pub(crate) fn get_stream_entries_per_page(&self) -> usize {
self.raw
.stream
.as_ref()
.map(|stream| stream.entries_per_page)
.flatten()
.unwrap_or(5)
}
} }

View File

@ -2,14 +2,13 @@ use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
/// This is the struct for the writer.toml config file that ends up in each site's root directory. /// This is the struct for the writer.toml config file that ends up in each site's root directory.
#[derive(Debug, Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub(crate) struct RawConfig { pub(crate) struct RawConfig {
pub(super) site_title: Option<String>, pub(super) site_title: Option<String>,
author: Option<String>, author: Option<String>,
email: Option<String>, email: Option<String>,
pub(super) use_relative_paths: Option<bool>, pub(super) use_relative_paths: Option<bool>,
pub(super) web_root: Option<String>, pub(super) web_root: Option<String>,
pub(super) stream: Option<RawConfigStream>,
} }
impl Default for RawConfig { impl Default for RawConfig {
@ -20,20 +19,6 @@ impl Default for RawConfig {
email: None, email: None,
use_relative_paths: None, use_relative_paths: None,
web_root: None, web_root: None,
stream: None,
}
}
}
#[derive(Debug, Deserialize, Serialize)]
pub(crate) struct RawConfigStream {
pub(super) entries_per_page: Option<usize>,
}
impl Default for RawConfigStream {
fn default() -> Self {
RawConfigStream {
entries_per_page: None,
} }
} }
} }

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IAngleLink; use crate::intermediate::IAngleLink;

View File

@ -1,5 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IAstNode; use crate::intermediate::IAstNode;
@ -42,7 +45,6 @@ use super::quote_block::RenderQuoteBlock;
use super::radio_link::RenderRadioLink; use super::radio_link::RenderRadioLink;
use super::radio_target::RenderRadioTarget; use super::radio_target::RenderRadioTarget;
use super::regular_link::RenderRegularLink; use super::regular_link::RenderRegularLink;
use super::render_context::RenderContext;
use super::special_block::RenderSpecialBlock; use super::special_block::RenderSpecialBlock;
use super::src_block::RenderSrcBlock; use super::src_block::RenderSrcBlock;
use super::statistics_cookie::RenderStatisticsCookie; use super::statistics_cookie::RenderStatisticsCookie;
@ -119,207 +121,285 @@ pub(crate) enum RenderAstNode {
pub(crate) trait IntoRenderAstNode { pub(crate) trait IntoRenderAstNode {
fn into_render_ast_node( fn into_render_ast_node(
&self, &self,
render_context: RenderContext<'_>, config: &Config,
output_directory: &Path,
output_file: &Path,
) -> Result<RenderAstNode, CustomError>; ) -> Result<RenderAstNode, CustomError>;
} }
impl IntoRenderAstNode for IAstNode { impl IntoRenderAstNode for IAstNode {
fn into_render_ast_node( fn into_render_ast_node(
&self, &self,
render_context: RenderContext<'_>, config: &Config,
output_directory: &Path,
output_file: &Path,
) -> Result<RenderAstNode, CustomError> { ) -> Result<RenderAstNode, CustomError> {
match self { match self {
IAstNode::Heading(inner) => Ok(RenderAstNode::Heading(RenderHeading::new( IAstNode::Heading(inner) => Ok(RenderAstNode::Heading(RenderHeading::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Section(inner) => Ok(RenderAstNode::Section(RenderSection::new( IAstNode::Section(inner) => Ok(RenderAstNode::Section(RenderSection::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Paragraph(inner) => Ok(RenderAstNode::Paragraph(RenderParagraph::new( IAstNode::Paragraph(inner) => Ok(RenderAstNode::Paragraph(RenderParagraph::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::PlainList(inner) => Ok(RenderAstNode::PlainList(RenderPlainList::new( IAstNode::PlainList(inner) => Ok(RenderAstNode::PlainList(RenderPlainList::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::CenterBlock(inner) => Ok(RenderAstNode::CenterBlock(RenderCenterBlock::new( IAstNode::CenterBlock(inner) => Ok(RenderAstNode::CenterBlock(RenderCenterBlock::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::QuoteBlock(inner) => Ok(RenderAstNode::QuoteBlock(RenderQuoteBlock::new( IAstNode::QuoteBlock(inner) => Ok(RenderAstNode::QuoteBlock(RenderQuoteBlock::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::SpecialBlock(inner) => Ok(RenderAstNode::SpecialBlock( IAstNode::SpecialBlock(inner) => Ok(RenderAstNode::SpecialBlock(
RenderSpecialBlock::new(render_context, inner)?, RenderSpecialBlock::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::DynamicBlock(inner) => Ok(RenderAstNode::DynamicBlock( IAstNode::DynamicBlock(inner) => Ok(RenderAstNode::DynamicBlock(
RenderDynamicBlock::new(render_context, inner)?, RenderDynamicBlock::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::FootnoteDefinition(inner) => Ok(RenderAstNode::FootnoteDefinition( IAstNode::FootnoteDefinition(inner) => Ok(RenderAstNode::FootnoteDefinition(
RenderFootnoteDefinition::new(render_context, inner)?, RenderFootnoteDefinition::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::Comment(inner) => Ok(RenderAstNode::Comment(RenderComment::new( IAstNode::Comment(inner) => Ok(RenderAstNode::Comment(RenderComment::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Drawer(inner) => Ok(RenderAstNode::Drawer(RenderDrawer::new( IAstNode::Drawer(inner) => Ok(RenderAstNode::Drawer(RenderDrawer::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::PropertyDrawer(inner) => Ok(RenderAstNode::PropertyDrawer( IAstNode::PropertyDrawer(inner) => Ok(RenderAstNode::PropertyDrawer(
RenderPropertyDrawer::new(render_context, inner)?, RenderPropertyDrawer::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::Table(inner) => Ok(RenderAstNode::Table(RenderTable::new( IAstNode::Table(inner) => Ok(RenderAstNode::Table(RenderTable::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::VerseBlock(inner) => Ok(RenderAstNode::VerseBlock(RenderVerseBlock::new( IAstNode::VerseBlock(inner) => Ok(RenderAstNode::VerseBlock(RenderVerseBlock::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::CommentBlock(inner) => Ok(RenderAstNode::CommentBlock( IAstNode::CommentBlock(inner) => Ok(RenderAstNode::CommentBlock(
RenderCommentBlock::new(render_context, inner)?, RenderCommentBlock::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::ExampleBlock(inner) => Ok(RenderAstNode::ExampleBlock( IAstNode::ExampleBlock(inner) => Ok(RenderAstNode::ExampleBlock(
RenderExampleBlock::new(render_context, inner)?, RenderExampleBlock::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::ExportBlock(inner) => Ok(RenderAstNode::ExportBlock(RenderExportBlock::new( IAstNode::ExportBlock(inner) => Ok(RenderAstNode::ExportBlock(RenderExportBlock::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::SrcBlock(inner) => Ok(RenderAstNode::SrcBlock(RenderSrcBlock::new( IAstNode::SrcBlock(inner) => Ok(RenderAstNode::SrcBlock(RenderSrcBlock::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Clock(inner) => Ok(RenderAstNode::Clock(RenderClock::new( IAstNode::Clock(inner) => Ok(RenderAstNode::Clock(RenderClock::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::DiarySexp(inner) => Ok(RenderAstNode::DiarySexp(RenderDiarySexp::new( IAstNode::DiarySexp(inner) => Ok(RenderAstNode::DiarySexp(RenderDiarySexp::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Planning(inner) => Ok(RenderAstNode::Planning(RenderPlanning::new( IAstNode::Planning(inner) => Ok(RenderAstNode::Planning(RenderPlanning::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::FixedWidthArea(inner) => Ok(RenderAstNode::FixedWidthArea( IAstNode::FixedWidthArea(inner) => Ok(RenderAstNode::FixedWidthArea(
RenderFixedWidthArea::new(render_context, inner)?, RenderFixedWidthArea::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::HorizontalRule(inner) => Ok(RenderAstNode::HorizontalRule( IAstNode::HorizontalRule(inner) => Ok(RenderAstNode::HorizontalRule(
RenderHorizontalRule::new(render_context, inner)?, RenderHorizontalRule::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::Keyword(inner) => Ok(RenderAstNode::Keyword(RenderKeyword::new( IAstNode::Keyword(inner) => Ok(RenderAstNode::Keyword(RenderKeyword::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::BabelCall(inner) => Ok(RenderAstNode::BabelCall(RenderBabelCall::new( IAstNode::BabelCall(inner) => Ok(RenderAstNode::BabelCall(RenderBabelCall::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::LatexEnvironment(inner) => Ok(RenderAstNode::LatexEnvironment( IAstNode::LatexEnvironment(inner) => Ok(RenderAstNode::LatexEnvironment(
RenderLatexEnvironment::new(render_context, inner)?, RenderLatexEnvironment::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::Bold(inner) => { IAstNode::Bold(inner) => Ok(RenderAstNode::Bold(RenderBold::new(
Ok(RenderAstNode::Bold(RenderBold::new(render_context, inner)?)) config,
} output_directory,
output_file,
inner,
)?)),
IAstNode::Italic(inner) => Ok(RenderAstNode::Italic(RenderItalic::new( IAstNode::Italic(inner) => Ok(RenderAstNode::Italic(RenderItalic::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Underline(inner) => Ok(RenderAstNode::Underline(RenderUnderline::new( IAstNode::Underline(inner) => Ok(RenderAstNode::Underline(RenderUnderline::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::StrikeThrough(inner) => Ok(RenderAstNode::StrikeThrough( IAstNode::StrikeThrough(inner) => Ok(RenderAstNode::StrikeThrough(
RenderStrikeThrough::new(render_context, inner)?, RenderStrikeThrough::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::Code(inner) => { IAstNode::Code(inner) => Ok(RenderAstNode::Code(RenderCode::new(
Ok(RenderAstNode::Code(RenderCode::new(render_context, inner)?)) config,
} output_directory,
output_file,
inner,
)?)),
IAstNode::Verbatim(inner) => Ok(RenderAstNode::Verbatim(RenderVerbatim::new( IAstNode::Verbatim(inner) => Ok(RenderAstNode::Verbatim(RenderVerbatim::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::PlainText(inner) => Ok(RenderAstNode::PlainText(RenderPlainText::new( IAstNode::PlainText(inner) => Ok(RenderAstNode::PlainText(RenderPlainText::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::RegularLink(inner) => Ok(RenderAstNode::RegularLink(RenderRegularLink::new( IAstNode::RegularLink(inner) => Ok(RenderAstNode::RegularLink(RenderRegularLink::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::RadioLink(inner) => Ok(RenderAstNode::RadioLink(RenderRadioLink::new( IAstNode::RadioLink(inner) => Ok(RenderAstNode::RadioLink(RenderRadioLink::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::RadioTarget(inner) => Ok(RenderAstNode::RadioTarget(RenderRadioTarget::new( IAstNode::RadioTarget(inner) => Ok(RenderAstNode::RadioTarget(RenderRadioTarget::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::PlainLink(inner) => Ok(RenderAstNode::PlainLink(RenderPlainLink::new( IAstNode::PlainLink(inner) => Ok(RenderAstNode::PlainLink(RenderPlainLink::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::AngleLink(inner) => Ok(RenderAstNode::AngleLink(RenderAngleLink::new( IAstNode::AngleLink(inner) => Ok(RenderAstNode::AngleLink(RenderAngleLink::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::OrgMacro(inner) => Ok(RenderAstNode::OrgMacro(RenderOrgMacro::new( IAstNode::OrgMacro(inner) => Ok(RenderAstNode::OrgMacro(RenderOrgMacro::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Entity(inner) => Ok(RenderAstNode::Entity(RenderEntity::new( IAstNode::Entity(inner) => Ok(RenderAstNode::Entity(RenderEntity::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::LatexFragment(inner) => Ok(RenderAstNode::LatexFragment( IAstNode::LatexFragment(inner) => Ok(RenderAstNode::LatexFragment(
RenderLatexFragment::new(render_context, inner)?, RenderLatexFragment::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::ExportSnippet(inner) => Ok(RenderAstNode::ExportSnippet( IAstNode::ExportSnippet(inner) => Ok(RenderAstNode::ExportSnippet(
RenderExportSnippet::new(render_context, inner)?, RenderExportSnippet::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::FootnoteReference(inner) => Ok(RenderAstNode::FootnoteReference( IAstNode::FootnoteReference(inner) => Ok(RenderAstNode::FootnoteReference(
RenderFootnoteReference::new(render_context, inner)?, RenderFootnoteReference::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::Citation(inner) => Ok(RenderAstNode::Citation(RenderCitation::new( IAstNode::Citation(inner) => Ok(RenderAstNode::Citation(RenderCitation::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::CitationReference(inner) => Ok(RenderAstNode::CitationReference( IAstNode::CitationReference(inner) => Ok(RenderAstNode::CitationReference(
RenderCitationReference::new(render_context, inner)?, RenderCitationReference::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::InlineBabelCall(inner) => Ok(RenderAstNode::InlineBabelCall( IAstNode::InlineBabelCall(inner) => Ok(RenderAstNode::InlineBabelCall(
RenderInlineBabelCall::new(render_context, inner)?, RenderInlineBabelCall::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::InlineSourceBlock(inner) => Ok(RenderAstNode::InlineSourceBlock( IAstNode::InlineSourceBlock(inner) => Ok(RenderAstNode::InlineSourceBlock(
RenderInlineSourceBlock::new(render_context, inner)?, RenderInlineSourceBlock::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::LineBreak(inner) => Ok(RenderAstNode::LineBreak(RenderLineBreak::new( IAstNode::LineBreak(inner) => Ok(RenderAstNode::LineBreak(RenderLineBreak::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Target(inner) => Ok(RenderAstNode::Target(RenderTarget::new( IAstNode::Target(inner) => Ok(RenderAstNode::Target(RenderTarget::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::StatisticsCookie(inner) => Ok(RenderAstNode::StatisticsCookie( IAstNode::StatisticsCookie(inner) => Ok(RenderAstNode::StatisticsCookie(
RenderStatisticsCookie::new(render_context, inner)?, RenderStatisticsCookie::new(config, output_directory, output_file, inner)?,
)), )),
IAstNode::Subscript(inner) => Ok(RenderAstNode::Subscript(RenderSubscript::new( IAstNode::Subscript(inner) => Ok(RenderAstNode::Subscript(RenderSubscript::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Superscript(inner) => Ok(RenderAstNode::Superscript(RenderSuperscript::new( IAstNode::Superscript(inner) => Ok(RenderAstNode::Superscript(RenderSuperscript::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
IAstNode::Timestamp(inner) => Ok(RenderAstNode::Timestamp(RenderTimestamp::new( IAstNode::Timestamp(inner) => Ok(RenderAstNode::Timestamp(RenderTimestamp::new(
render_context, config,
output_directory,
output_file,
inner, inner,
)?)), )?)),
} }

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IBabelCall; use crate::intermediate::IBabelCall;

View File

@ -1,29 +1,10 @@
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext;
use crate::error::CustomError;
use crate::intermediate::get_web_path;
use crate::intermediate::BlogPost;
use crate::intermediate::BlogPostPage;
use super::footnote_definition::RenderRealFootnoteDefinition; use super::footnote_definition::RenderRealFootnoteDefinition;
use super::macros::render;
use super::GlobalSettings; use super::GlobalSettings;
use super::PageHeader; use super::PageHeader;
use super::RenderDocumentElement; use super::RenderDocumentElement;
#[derive(Debug)]
pub(crate) struct RenderBlogPostPageInput<'a> {
post: &'a BlogPost,
page: &'a BlogPostPage,
}
impl<'a> RenderBlogPostPageInput<'a> {
pub(crate) fn new(post: &'a BlogPost, page: &'a BlogPostPage) -> RenderBlogPostPageInput<'a> {
RenderBlogPostPageInput { post, page }
}
}
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(tag = "type")] #[serde(tag = "type")]
#[serde(rename = "blog_post_page")] #[serde(rename = "blog_post_page")]
@ -42,82 +23,23 @@ pub(crate) struct RenderBlogPostPage {
footnotes: Vec<RenderRealFootnoteDefinition>, footnotes: Vec<RenderRealFootnoteDefinition>,
} }
render!( impl RenderBlogPostPage {
RenderBlogPostPage, // TODO: Maybe these settings should be moved into a common struct so this can have the same type signature as the others.
RenderBlogPostPageInput, pub(crate) fn new(
original, global_settings: GlobalSettings,
render_context, page_header: Option<PageHeader>,
{ title: Option<String>,
let css_files = vec![ self_link: Option<String>,
get_web_path( children: Vec<RenderDocumentElement>,
render_context.config, footnotes: Vec<RenderRealFootnoteDefinition>,
render_context.output_root_directory, ) -> RenderBlogPostPage {
render_context.output_file, RenderBlogPostPage {
"stylesheet/reset.css",
)?,
get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
"stylesheet/main.css",
)?,
];
let js_files = vec![get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
"blog_post.js",
)?];
let global_settings = GlobalSettings::new(original.page.title.clone(), css_files, js_files);
let page_header = PageHeader::new(
render_context.config.get_site_title().map(str::to_string),
Some(get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
"",
)?),
);
let link_to_blog_post = get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
render_context
.output_file
.strip_prefix(render_context.output_root_directory)?,
)?;
let children = {
let mut children = Vec::new();
for child in original.page.children.iter() {
children.push(RenderDocumentElement::new(render_context.clone(), child)?);
}
children
};
let footnotes = {
let mut ret = Vec::new();
for footnote in original.page.footnotes.iter() {
ret.push(RenderRealFootnoteDefinition::new(
render_context.clone(),
footnote,
)?);
}
ret
};
let ret = RenderBlogPostPage {
global_settings, global_settings,
page_header: Some(page_header), page_header,
title: original.page.title.clone(), title,
self_link: Some(link_to_blog_post), self_link,
children, children,
footnotes, footnotes,
}; }
Ok(ret)
} }
); }

View File

@ -1,213 +0,0 @@
use serde::Serialize;
use super::macros::render;
use super::render_context::RenderContext;
use crate::context::RenderDocumentElement;
use crate::context::RenderRealFootnoteDefinition;
use crate::error::CustomError;
use crate::intermediate::get_web_path;
use crate::intermediate::BlogPost;
use super::GlobalSettings;
use super::PageHeader;
#[derive(Debug)]
pub(crate) struct RenderBlogStreamInput<'a, 'b> {
original: &'a [&'b BlogPost],
older_link: Option<String>,
newer_link: Option<String>,
}
impl<'a, 'b> RenderBlogStreamInput<'a, 'b> {
pub(crate) fn new(
original: &'a [&'b BlogPost],
older_link: Option<String>,
newer_link: Option<String>,
) -> RenderBlogStreamInput<'a, 'b> {
RenderBlogStreamInput {
original,
older_link,
newer_link,
}
}
}
#[derive(Debug, Serialize)]
#[serde(tag = "type")]
#[serde(rename = "blog_stream")]
pub(crate) struct RenderBlogStream {
global_settings: GlobalSettings,
page_header: Option<PageHeader>,
children: Vec<RenderBlogStreamEntry>,
stream_pagination: Option<RenderBlogStreamPagination>,
}
render!(
RenderBlogStream,
RenderBlogStreamInput,
original,
render_context,
{
let css_files = vec![
get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
"stylesheet/reset.css",
)?,
get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
"stylesheet/main.css",
)?,
];
let js_files = vec![get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
"blog_post.js",
)?];
let global_settings = GlobalSettings::new(
render_context.config.get_site_title().map(str::to_string),
css_files,
js_files,
);
let page_header = PageHeader::new(
render_context.config.get_site_title().map(str::to_string),
Some(get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
"",
)?),
);
let children = original
.original
.into_iter()
.enumerate()
.map(|(i, blog_post)| {
RenderBlogStreamEntry::new(
render_context.clone(),
&RenderBlogStreamEntryInput::new(blog_post, i),
)
})
.collect::<Result<Vec<_>, _>>()?;
let stream_pagination = if original.older_link.is_some() || original.newer_link.is_some() {
Some(RenderBlogStreamPagination::new(
original.older_link.clone(),
original.newer_link.clone(),
)?)
} else {
None
};
Ok(RenderBlogStream {
global_settings,
page_header: Some(page_header),
children,
stream_pagination,
})
}
);
#[derive(Debug)]
pub(crate) struct RenderBlogStreamEntryInput<'a> {
original: &'a BlogPost,
offset: usize,
}
impl<'a> RenderBlogStreamEntryInput<'a> {
fn new(original: &'a BlogPost, offset: usize) -> RenderBlogStreamEntryInput<'a> {
RenderBlogStreamEntryInput { original, offset }
}
}
#[derive(Debug, Serialize)]
pub(crate) struct RenderBlogStreamEntry {
/// The title that will be shown visibly on the page.
title: Option<String>,
self_link: Option<String>,
children: Vec<RenderDocumentElement>,
footnotes: Vec<RenderRealFootnoteDefinition>,
}
render!(
RenderBlogStreamEntry,
RenderBlogStreamEntryInput,
original,
render_context,
{
let offset_string = original.offset.to_string();
let render_context = {
let mut render_context = render_context.clone();
render_context.id_addition = Some(offset_string.as_str());
render_context
};
let link_to_blog_post = get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
render_context
.config
.get_relative_path_to_post(&original.original.id),
)?;
// TODO: Should I guess an index page instead of erroring out?
let index_page = original
.original
.get_index_page()
.ok_or_else(|| format!("Blog post {} needs an index page.", original.original.id))?;
let title = index_page.title.clone();
let children = index_page
.children
.iter()
.map(|child| RenderDocumentElement::new(render_context.clone(), child))
.collect::<Result<Vec<_>, _>>()?;
let footnotes = {
let mut ret = Vec::new();
for footnote in index_page.footnotes.iter() {
ret.push(RenderRealFootnoteDefinition::new(
render_context.clone(),
footnote,
)?);
}
ret
};
Ok(RenderBlogStreamEntry {
title,
self_link: Some(link_to_blog_post),
children,
footnotes,
})
}
);
#[derive(Debug, Serialize)]
pub(crate) struct RenderBlogStreamPagination {
older_link: Option<String>,
newer_link: Option<String>,
}
impl RenderBlogStreamPagination {
fn new(
older_link: Option<String>,
newer_link: Option<String>,
) -> Result<RenderBlogStreamPagination, CustomError> {
Ok(RenderBlogStreamPagination {
older_link,
newer_link,
})
}
}

View File

@ -1,10 +1,12 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IBold; use crate::intermediate::IBold;
use super::macros::render; use super::macros::render;
use super::render_context::RenderContext;
use super::RenderObject; use super::RenderObject;
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
@ -14,14 +16,27 @@ pub(crate) struct RenderBold {
children: Vec<RenderObject>, children: Vec<RenderObject>,
} }
render!(RenderBold, IBold, original, render_context, { render!(
let children = { RenderBold,
let mut ret = Vec::new(); IBold,
for obj in original.children.iter() { original,
ret.push(RenderObject::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderObject::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderBold { children }) Ok(RenderBold { children })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ICenterBlock; use crate::intermediate::ICenterBlock;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ICitation; use crate::intermediate::ICitation;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ICitationReference; use crate::intermediate::ICitationReference;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IClock; use crate::intermediate::IClock;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ICode; use crate::intermediate::ICode;
@ -13,8 +15,16 @@ pub(crate) struct RenderCode {
contents: String, contents: String,
} }
render!(RenderCode, ICode, original, _render_context, { render!(
Ok(RenderCode { RenderCode,
contents: original.contents.clone(), ICode,
}) original,
}); _config,
_output_directory,
_output_file,
{
Ok(RenderCode {
contents: original.contents.clone(),
})
}
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IComment; use crate::intermediate::IComment;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ICommentBlock; use crate::intermediate::ICommentBlock;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IDiarySexp; use crate::intermediate::IDiarySexp;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IDocumentElement; use crate::intermediate::IDocumentElement;
@ -19,14 +21,16 @@ render!(
RenderDocumentElement, RenderDocumentElement,
IDocumentElement, IDocumentElement,
original, original,
render_context, config,
output_directory,
output_file,
{ {
match original { match original {
IDocumentElement::Heading(inner) => Ok(RenderDocumentElement::Heading( IDocumentElement::Heading(inner) => Ok(RenderDocumentElement::Heading(
RenderHeading::new(render_context.clone(), inner)?, RenderHeading::new(config, output_directory, output_file, inner)?,
)), )),
IDocumentElement::Section(inner) => Ok(RenderDocumentElement::Section( IDocumentElement::Section(inner) => Ok(RenderDocumentElement::Section(
RenderSection::new(render_context.clone(), inner)?, RenderSection::new(config, output_directory, output_file, inner)?,
)), )),
} }
} }

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IDrawer; use crate::intermediate::IDrawer;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IDynamicBlock; use crate::intermediate::IDynamicBlock;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IElement; use crate::intermediate::IElement;
@ -59,98 +61,132 @@ pub(crate) enum RenderElement {
LatexEnvironment(RenderLatexEnvironment), LatexEnvironment(RenderLatexEnvironment),
} }
render!(RenderElement, IElement, original, render_context, { render!(
match original { RenderElement,
IElement::Paragraph(inner) => Ok(RenderElement::Paragraph(RenderParagraph::new( IElement,
render_context.clone(), original,
inner, config,
)?)), output_directory,
IElement::PlainList(inner) => Ok(RenderElement::PlainList(RenderPlainList::new( output_file,
render_context.clone(), {
inner, match original {
)?)), IElement::Paragraph(inner) => Ok(RenderElement::Paragraph(RenderParagraph::new(
IElement::CenterBlock(inner) => Ok(RenderElement::CenterBlock(RenderCenterBlock::new( config,
render_context.clone(), output_directory,
inner, output_file,
)?)), inner,
IElement::QuoteBlock(inner) => Ok(RenderElement::QuoteBlock(RenderQuoteBlock::new( )?)),
render_context.clone(), IElement::PlainList(inner) => Ok(RenderElement::PlainList(RenderPlainList::new(
inner, config,
)?)), output_directory,
IElement::SpecialBlock(inner) => Ok(RenderElement::SpecialBlock(RenderSpecialBlock::new( output_file,
render_context.clone(), inner,
inner, )?)),
)?)), IElement::CenterBlock(inner) => Ok(RenderElement::CenterBlock(RenderCenterBlock::new(
IElement::DynamicBlock(inner) => Ok(RenderElement::DynamicBlock(RenderDynamicBlock::new( config,
render_context.clone(), output_directory,
inner, output_file,
)?)), inner,
IElement::FootnoteDefinition(inner) => Ok(RenderElement::FootnoteDefinition( )?)),
RenderFootnoteDefinition::new(render_context.clone(), inner)?, IElement::QuoteBlock(inner) => Ok(RenderElement::QuoteBlock(RenderQuoteBlock::new(
)), config,
IElement::Comment(inner) => Ok(RenderElement::Comment(RenderComment::new( output_directory,
render_context.clone(), output_file,
inner, inner,
)?)), )?)),
IElement::Drawer(inner) => Ok(RenderElement::Drawer(RenderDrawer::new( IElement::SpecialBlock(inner) => Ok(RenderElement::SpecialBlock(
render_context.clone(), RenderSpecialBlock::new(config, output_directory, output_file, inner)?,
inner, )),
)?)), IElement::DynamicBlock(inner) => Ok(RenderElement::DynamicBlock(
IElement::PropertyDrawer(inner) => Ok(RenderElement::PropertyDrawer( RenderDynamicBlock::new(config, output_directory, output_file, inner)?,
RenderPropertyDrawer::new(render_context.clone(), inner)?, )),
)), IElement::FootnoteDefinition(inner) => Ok(RenderElement::FootnoteDefinition(
IElement::Table(inner) => Ok(RenderElement::Table(RenderTable::new( RenderFootnoteDefinition::new(config, output_directory, output_file, inner)?,
render_context.clone(), )),
inner, IElement::Comment(inner) => Ok(RenderElement::Comment(RenderComment::new(
)?)), config,
IElement::VerseBlock(inner) => Ok(RenderElement::VerseBlock(RenderVerseBlock::new( output_directory,
render_context.clone(), output_file,
inner, inner,
)?)), )?)),
IElement::CommentBlock(inner) => Ok(RenderElement::CommentBlock(RenderCommentBlock::new( IElement::Drawer(inner) => Ok(RenderElement::Drawer(RenderDrawer::new(
render_context.clone(), config,
inner, output_directory,
)?)), output_file,
IElement::ExampleBlock(inner) => Ok(RenderElement::ExampleBlock(RenderExampleBlock::new( inner,
render_context.clone(), )?)),
inner, IElement::PropertyDrawer(inner) => Ok(RenderElement::PropertyDrawer(
)?)), RenderPropertyDrawer::new(config, output_directory, output_file, inner)?,
IElement::ExportBlock(inner) => Ok(RenderElement::ExportBlock(RenderExportBlock::new( )),
render_context.clone(), IElement::Table(inner) => Ok(RenderElement::Table(RenderTable::new(
inner, config,
)?)), output_directory,
IElement::SrcBlock(inner) => Ok(RenderElement::SrcBlock(RenderSrcBlock::new( output_file,
render_context.clone(), inner,
inner, )?)),
)?)), IElement::VerseBlock(inner) => Ok(RenderElement::VerseBlock(RenderVerseBlock::new(
IElement::Clock(inner) => Ok(RenderElement::Clock(RenderClock::new( config,
render_context.clone(), output_directory,
inner, output_file,
)?)), inner,
IElement::DiarySexp(inner) => Ok(RenderElement::DiarySexp(RenderDiarySexp::new( )?)),
render_context.clone(), IElement::CommentBlock(inner) => Ok(RenderElement::CommentBlock(
inner, RenderCommentBlock::new(config, output_directory, output_file, inner)?,
)?)), )),
IElement::Planning(inner) => Ok(RenderElement::Planning(RenderPlanning::new( IElement::ExampleBlock(inner) => Ok(RenderElement::ExampleBlock(
render_context.clone(), RenderExampleBlock::new(config, output_directory, output_file, inner)?,
inner, )),
)?)), IElement::ExportBlock(inner) => Ok(RenderElement::ExportBlock(RenderExportBlock::new(
IElement::FixedWidthArea(inner) => Ok(RenderElement::FixedWidthArea( config,
RenderFixedWidthArea::new(render_context.clone(), inner)?, output_directory,
)), output_file,
IElement::HorizontalRule(inner) => Ok(RenderElement::HorizontalRule( inner,
RenderHorizontalRule::new(render_context.clone(), inner)?, )?)),
)), IElement::SrcBlock(inner) => Ok(RenderElement::SrcBlock(RenderSrcBlock::new(
IElement::Keyword(inner) => Ok(RenderElement::Keyword(RenderKeyword::new( config,
render_context.clone(), output_directory,
inner, output_file,
)?)), inner,
IElement::BabelCall(inner) => Ok(RenderElement::BabelCall(RenderBabelCall::new( )?)),
render_context.clone(), IElement::Clock(inner) => Ok(RenderElement::Clock(RenderClock::new(
inner, config,
)?)), output_directory,
IElement::LatexEnvironment(inner) => Ok(RenderElement::LatexEnvironment( output_file,
RenderLatexEnvironment::new(render_context.clone(), inner)?, inner,
)), )?)),
IElement::DiarySexp(inner) => Ok(RenderElement::DiarySexp(RenderDiarySexp::new(
config,
output_directory,
output_file,
inner,
)?)),
IElement::Planning(inner) => Ok(RenderElement::Planning(RenderPlanning::new(
config,
output_directory,
output_file,
inner,
)?)),
IElement::FixedWidthArea(inner) => Ok(RenderElement::FixedWidthArea(
RenderFixedWidthArea::new(config, output_directory, output_file, inner)?,
)),
IElement::HorizontalRule(inner) => Ok(RenderElement::HorizontalRule(
RenderHorizontalRule::new(config, output_directory, output_file, inner)?,
)),
IElement::Keyword(inner) => Ok(RenderElement::Keyword(RenderKeyword::new(
config,
output_directory,
output_file,
inner,
)?)),
IElement::BabelCall(inner) => Ok(RenderElement::BabelCall(RenderBabelCall::new(
config,
output_directory,
output_file,
inner,
)?)),
IElement::LatexEnvironment(inner) => Ok(RenderElement::LatexEnvironment(
RenderLatexEnvironment::new(config, output_directory, output_file, inner)?,
)),
}
} }
}); );

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IEntity; use crate::intermediate::IEntity;
@ -13,8 +15,16 @@ pub(crate) struct RenderEntity {
html: String, html: String,
} }
render!(RenderEntity, IEntity, original, _render_context, { render!(
Ok(RenderEntity { RenderEntity,
html: original.html.clone(), IEntity,
}) original,
}); _config,
_output_directory,
_output_file,
{
Ok(RenderEntity {
html: original.html.clone(),
})
}
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IExampleBlock; use crate::intermediate::IExampleBlock;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IExportBlock; use crate::intermediate::IExportBlock;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IExportSnippet; use crate::intermediate::IExportSnippet;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IFixedWidthArea; use crate::intermediate::IFixedWidthArea;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IFootnoteDefinition; use crate::intermediate::IFootnoteDefinition;
use crate::intermediate::IRealFootnoteDefinition; use crate::intermediate::IRealFootnoteDefinition;
@ -31,19 +33,21 @@ render!(
RenderRealFootnoteDefinition, RenderRealFootnoteDefinition,
IRealFootnoteDefinition, IRealFootnoteDefinition,
original, original,
render_context, config,
output_directory,
output_file,
{ {
let contents = { let contents = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.contents.iter() { for obj in original.contents.iter() {
ret.push(obj.into_render_ast_node(render_context.clone())?); ret.push(obj.into_render_ast_node(config, output_directory, output_file)?);
} }
ret ret
}; };
Ok(RenderRealFootnoteDefinition { Ok(RenderRealFootnoteDefinition {
definition_id: original.get_definition_id(render_context.id_addition), definition_id: original.get_definition_id(),
reference_link: format!("#{}", original.get_reference_id(render_context.id_addition)), reference_link: format!("#{}", original.get_reference_id()),
label: original.get_display_label(), label: original.get_display_label(),
contents, contents,
}) })

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IFootnoteReference; use crate::intermediate::IFootnoteReference;
@ -19,14 +21,13 @@ render!(
RenderFootnoteReference, RenderFootnoteReference,
IFootnoteReference, IFootnoteReference,
original, original,
render_context, _config,
_output_directory,
_output_file,
{ {
Ok(RenderFootnoteReference { Ok(RenderFootnoteReference {
reference_id: original.get_reference_id(render_context.id_addition), reference_id: original.get_reference_id(),
definition_link: format!( definition_link: format!("#{}", original.get_definition_id()),
"#{}",
original.get_definition_id(render_context.id_addition)
),
label: original.get_display_label(), label: original.get_display_label(),
}) })
} }

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IHeading; use crate::intermediate::IHeading;
@ -17,26 +19,44 @@ pub(crate) struct RenderHeading {
children: Vec<RenderDocumentElement>, children: Vec<RenderDocumentElement>,
} }
render!(RenderHeading, IHeading, original, render_context, { render!(
let title = { RenderHeading,
let mut ret = Vec::new(); IHeading,
for obj in original.title.iter() { original,
ret.push(RenderObject::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let title = {
let mut ret = Vec::new();
for obj in original.title.iter() {
ret.push(RenderObject::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.children.iter() { for obj in original.children.iter() {
ret.push(RenderDocumentElement::new(render_context.clone(), obj)?); ret.push(RenderDocumentElement::new(
} config,
ret output_directory,
}; output_file,
obj,
)?);
}
ret
};
Ok(RenderHeading { Ok(RenderHeading {
level: original.level + 1, // Adding 1 because the page title is going to be h1. level: original.level + 1, // Adding 1 because the page title is going to be h1.
title, title,
children, children,
}) })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IHorizontalRule; use crate::intermediate::IHorizontalRule;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IInlineBabelCall; use crate::intermediate::IInlineBabelCall;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IInlineSourceBlock; use crate::intermediate::IInlineSourceBlock;
@ -17,7 +19,9 @@ render!(
RenderInlineSourceBlock, RenderInlineSourceBlock,
IInlineSourceBlock, IInlineSourceBlock,
original, original,
_render_context, _config,
_output_directory,
_output_file,
{ {
Ok(RenderInlineSourceBlock { Ok(RenderInlineSourceBlock {
value: original.value.clone(), value: original.value.clone(),

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IItalic; use crate::intermediate::IItalic;
@ -14,14 +16,27 @@ pub(crate) struct RenderItalic {
children: Vec<RenderObject>, children: Vec<RenderObject>,
} }
render!(RenderItalic, IItalic, original, render_context, { render!(
let children = { RenderItalic,
let mut ret = Vec::new(); IItalic,
for obj in original.children.iter() { original,
ret.push(RenderObject::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderObject::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderItalic { children }) Ok(RenderItalic { children })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IKeyword; use crate::intermediate::IKeyword;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ILatexEnvironment; use crate::intermediate::ILatexEnvironment;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ILatexFragment; use crate::intermediate::ILatexFragment;
@ -17,7 +19,9 @@ render!(
RenderLatexFragment, RenderLatexFragment,
ILatexFragment, ILatexFragment,
original, original,
_render_context, _config,
_output_directory,
_output_file,
{ {
Ok(RenderLatexFragment { Ok(RenderLatexFragment {
value: original.value.clone(), value: original.value.clone(),

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ILineBreak; use crate::intermediate::ILineBreak;

View File

@ -2,12 +2,18 @@
/// ///
/// This exists to make changing the type signature easier. /// This exists to make changing the type signature easier.
macro_rules! render { macro_rules! render {
($rstruct:ident, $istruct:ident, $original:ident, $render_context:ident, $fnbody:tt) => { ($rstruct:ident, $istruct:ident, $original:ident, $config:ident, $output_directory:ident, $output_file:ident, $fnbody:tt) => {
impl $rstruct { impl $rstruct {
pub(crate) fn new( pub(crate) fn new(
$render_context: RenderContext<'_>, config: &Config,
$original: &$istruct, output_directory: &Path,
output_file: &Path,
original: &$istruct,
) -> Result<$rstruct, CustomError> { ) -> Result<$rstruct, CustomError> {
let $original = original;
let $config = config;
let $output_directory = output_directory;
let $output_file = output_file;
$fnbody $fnbody
} }
} }
@ -23,7 +29,9 @@ macro_rules! rnoop {
($rstruct:ident, $istruct:ident) => { ($rstruct:ident, $istruct:ident) => {
impl $rstruct { impl $rstruct {
pub(crate) fn new( pub(crate) fn new(
_render_context: RenderContext<'_>, _config: &Config,
_output_directory: &Path,
_output_file: &Path,
_original: &$istruct, _original: &$istruct,
) -> Result<$rstruct, CustomError> { ) -> Result<$rstruct, CustomError> {
Ok($rstruct {}) Ok($rstruct {})

View File

@ -2,7 +2,6 @@ mod angle_link;
mod ast_node; mod ast_node;
mod babel_call; mod babel_call;
mod blog_post_page; mod blog_post_page;
mod blog_stream;
mod bold; mod bold;
mod center_block; mod center_block;
mod citation; mod citation;
@ -48,7 +47,6 @@ mod quote_block;
mod radio_link; mod radio_link;
mod radio_target; mod radio_target;
mod regular_link; mod regular_link;
mod render_context;
mod section; mod section;
mod special_block; mod special_block;
mod src_block; mod src_block;
@ -66,9 +64,6 @@ mod verbatim;
mod verse_block; mod verse_block;
pub(crate) use blog_post_page::RenderBlogPostPage; 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 document_element::RenderDocumentElement; pub(crate) use document_element::RenderDocumentElement;
pub(crate) use element::RenderElement; pub(crate) use element::RenderElement;
pub(crate) use footnote_definition::RenderRealFootnoteDefinition; pub(crate) use footnote_definition::RenderRealFootnoteDefinition;
@ -76,5 +71,4 @@ pub(crate) use global_settings::GlobalSettings;
pub(crate) use heading::RenderHeading; pub(crate) use heading::RenderHeading;
pub(crate) use object::RenderObject; pub(crate) use object::RenderObject;
pub(crate) use page_header::PageHeader; pub(crate) use page_header::PageHeader;
pub(crate) use render_context::RenderContext;
pub(crate) use section::RenderSection; pub(crate) use section::RenderSection;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IObject; use crate::intermediate::IObject;
@ -65,110 +67,153 @@ pub(crate) enum RenderObject {
Timestamp(RenderTimestamp), Timestamp(RenderTimestamp),
} }
render!(RenderObject, IObject, original, render_context, { render!(
match original { RenderObject,
IObject::Bold(inner) => Ok(RenderObject::Bold(RenderBold::new( IObject,
render_context.clone(), original,
inner, config,
)?)), output_directory,
IObject::Italic(inner) => Ok(RenderObject::Italic(RenderItalic::new( output_file,
render_context.clone(), {
inner, match original {
)?)), IObject::Bold(inner) => Ok(RenderObject::Bold(RenderBold::new(
IObject::Underline(inner) => Ok(RenderObject::Underline(RenderUnderline::new( config,
render_context.clone(), output_directory,
inner, output_file,
)?)), inner,
IObject::StrikeThrough(inner) => Ok(RenderObject::StrikeThrough(RenderStrikeThrough::new( )?)),
render_context.clone(), IObject::Italic(inner) => Ok(RenderObject::Italic(RenderItalic::new(
inner, config,
)?)), output_directory,
IObject::Code(inner) => Ok(RenderObject::Code(RenderCode::new( output_file,
render_context.clone(), inner,
inner, )?)),
)?)), IObject::Underline(inner) => Ok(RenderObject::Underline(RenderUnderline::new(
IObject::Verbatim(inner) => Ok(RenderObject::Verbatim(RenderVerbatim::new( config,
render_context.clone(), output_directory,
inner, output_file,
)?)), inner,
IObject::PlainText(inner) => Ok(RenderObject::PlainText(RenderPlainText::new( )?)),
render_context.clone(), IObject::StrikeThrough(inner) => Ok(RenderObject::StrikeThrough(
inner, RenderStrikeThrough::new(config, output_directory, output_file, inner)?,
)?)), )),
IObject::RegularLink(inner) => Ok(RenderObject::RegularLink(RenderRegularLink::new( IObject::Code(inner) => Ok(RenderObject::Code(RenderCode::new(
render_context.clone(), config,
inner, output_directory,
)?)), output_file,
IObject::RadioLink(inner) => Ok(RenderObject::RadioLink(RenderRadioLink::new( inner,
render_context.clone(), )?)),
inner, IObject::Verbatim(inner) => Ok(RenderObject::Verbatim(RenderVerbatim::new(
)?)), config,
IObject::RadioTarget(inner) => Ok(RenderObject::RadioTarget(RenderRadioTarget::new( output_directory,
render_context.clone(), output_file,
inner, inner,
)?)), )?)),
IObject::PlainLink(inner) => Ok(RenderObject::PlainLink(RenderPlainLink::new( IObject::PlainText(inner) => Ok(RenderObject::PlainText(RenderPlainText::new(
render_context.clone(), config,
inner, output_directory,
)?)), output_file,
IObject::AngleLink(inner) => Ok(RenderObject::AngleLink(RenderAngleLink::new( inner,
render_context.clone(), )?)),
inner, IObject::RegularLink(inner) => Ok(RenderObject::RegularLink(RenderRegularLink::new(
)?)), config,
IObject::OrgMacro(inner) => Ok(RenderObject::OrgMacro(RenderOrgMacro::new( output_directory,
render_context.clone(), output_file,
inner, inner,
)?)), )?)),
IObject::Entity(inner) => Ok(RenderObject::Entity(RenderEntity::new( IObject::RadioLink(inner) => Ok(RenderObject::RadioLink(RenderRadioLink::new(
render_context.clone(), config,
inner, output_directory,
)?)), output_file,
IObject::LatexFragment(inner) => Ok(RenderObject::LatexFragment(RenderLatexFragment::new( inner,
render_context.clone(), )?)),
inner, IObject::RadioTarget(inner) => Ok(RenderObject::RadioTarget(RenderRadioTarget::new(
)?)), config,
IObject::ExportSnippet(inner) => Ok(RenderObject::ExportSnippet(RenderExportSnippet::new( output_directory,
render_context.clone(), output_file,
inner, inner,
)?)), )?)),
IObject::FootnoteReference(inner) => Ok(RenderObject::FootnoteReference( IObject::PlainLink(inner) => Ok(RenderObject::PlainLink(RenderPlainLink::new(
RenderFootnoteReference::new(render_context.clone(), inner)?, config,
)), output_directory,
IObject::Citation(inner) => Ok(RenderObject::Citation(RenderCitation::new( output_file,
render_context.clone(), inner,
inner, )?)),
)?)), IObject::AngleLink(inner) => Ok(RenderObject::AngleLink(RenderAngleLink::new(
IObject::CitationReference(inner) => Ok(RenderObject::CitationReference( config,
RenderCitationReference::new(render_context.clone(), inner)?, output_directory,
)), output_file,
IObject::InlineBabelCall(inner) => Ok(RenderObject::InlineBabelCall( inner,
RenderInlineBabelCall::new(render_context.clone(), inner)?, )?)),
)), IObject::OrgMacro(inner) => Ok(RenderObject::OrgMacro(RenderOrgMacro::new(
IObject::InlineSourceBlock(inner) => Ok(RenderObject::InlineSourceBlock( config,
RenderInlineSourceBlock::new(render_context.clone(), inner)?, output_directory,
)), output_file,
IObject::LineBreak(inner) => Ok(RenderObject::LineBreak(RenderLineBreak::new( inner,
render_context.clone(), )?)),
inner, IObject::Entity(inner) => Ok(RenderObject::Entity(RenderEntity::new(
)?)), config,
IObject::Target(inner) => Ok(RenderObject::Target(RenderTarget::new( output_directory,
render_context.clone(), output_file,
inner, inner,
)?)), )?)),
IObject::StatisticsCookie(inner) => Ok(RenderObject::StatisticsCookie( IObject::LatexFragment(inner) => Ok(RenderObject::LatexFragment(
RenderStatisticsCookie::new(render_context.clone(), inner)?, RenderLatexFragment::new(config, output_directory, output_file, inner)?,
)), )),
IObject::Subscript(inner) => Ok(RenderObject::Subscript(RenderSubscript::new( IObject::ExportSnippet(inner) => Ok(RenderObject::ExportSnippet(
render_context.clone(), RenderExportSnippet::new(config, output_directory, output_file, inner)?,
inner, )),
)?)), IObject::FootnoteReference(inner) => Ok(RenderObject::FootnoteReference(
IObject::Superscript(inner) => Ok(RenderObject::Superscript(RenderSuperscript::new( RenderFootnoteReference::new(config, output_directory, output_file, inner)?,
render_context.clone(), )),
inner, IObject::Citation(inner) => Ok(RenderObject::Citation(RenderCitation::new(
)?)), config,
IObject::Timestamp(inner) => Ok(RenderObject::Timestamp(RenderTimestamp::new( output_directory,
render_context.clone(), output_file,
inner, inner,
)?)), )?)),
IObject::CitationReference(inner) => Ok(RenderObject::CitationReference(
RenderCitationReference::new(config, output_directory, output_file, inner)?,
)),
IObject::InlineBabelCall(inner) => Ok(RenderObject::InlineBabelCall(
RenderInlineBabelCall::new(config, output_directory, output_file, inner)?,
)),
IObject::InlineSourceBlock(inner) => Ok(RenderObject::InlineSourceBlock(
RenderInlineSourceBlock::new(config, output_directory, output_file, inner)?,
)),
IObject::LineBreak(inner) => Ok(RenderObject::LineBreak(RenderLineBreak::new(
config,
output_directory,
output_file,
inner,
)?)),
IObject::Target(inner) => Ok(RenderObject::Target(RenderTarget::new(
config,
output_directory,
output_file,
inner,
)?)),
IObject::StatisticsCookie(inner) => Ok(RenderObject::StatisticsCookie(
RenderStatisticsCookie::new(config, output_directory, output_file, inner)?,
)),
IObject::Subscript(inner) => Ok(RenderObject::Subscript(RenderSubscript::new(
config,
output_directory,
output_file,
inner,
)?)),
IObject::Superscript(inner) => Ok(RenderObject::Superscript(RenderSuperscript::new(
config,
output_directory,
output_file,
inner,
)?)),
IObject::Timestamp(inner) => Ok(RenderObject::Timestamp(RenderTimestamp::new(
config,
output_directory,
output_file,
inner,
)?)),
}
} }
}); );

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IOrgMacro; use crate::intermediate::IOrgMacro;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IParagraph; use crate::intermediate::IParagraph;
@ -14,14 +16,27 @@ pub(crate) struct RenderParagraph {
children: Vec<RenderObject>, children: Vec<RenderObject>,
} }
render!(RenderParagraph, IParagraph, original, render_context, { render!(
let children = { RenderParagraph,
let mut ret = Vec::new(); IParagraph,
for obj in original.children.iter() { original,
ret.push(RenderObject::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderObject::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderParagraph { children }) Ok(RenderParagraph { children })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IPlainLink; use crate::intermediate::IPlainLink;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IPlainList; use crate::intermediate::IPlainList;
@ -15,22 +17,35 @@ pub(crate) struct RenderPlainList {
children: Vec<RenderPlainListItem>, children: Vec<RenderPlainListItem>,
} }
render!(RenderPlainList, IPlainList, original, render_context, { render!(
let list_type = match original.list_type { RenderPlainList,
organic::types::PlainListType::Unordered => "unordered".to_owned(), IPlainList,
organic::types::PlainListType::Ordered => "ordered".to_owned(), original,
organic::types::PlainListType::Descriptive => "descriptive".to_owned(), config,
}; output_directory,
let children = { output_file,
let mut ret = Vec::new(); {
for obj in original.children.iter() { let list_type = match original.list_type {
ret.push(RenderPlainListItem::new(render_context.clone(), obj)?); organic::types::PlainListType::Unordered => "unordered".to_owned(),
} organic::types::PlainListType::Ordered => "ordered".to_owned(),
ret organic::types::PlainListType::Descriptive => "descriptive".to_owned(),
}; };
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderPlainListItem::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderPlainList { Ok(RenderPlainList {
list_type, list_type,
children, children,
}) })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IPlainListItem; use crate::intermediate::IPlainListItem;
@ -20,12 +22,19 @@ render!(
RenderPlainListItem, RenderPlainListItem,
IPlainListItem, IPlainListItem,
original, original,
render_context, config,
output_directory,
output_file,
{ {
let tag = { let tag = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.tag.iter() { for obj in original.tag.iter() {
ret.push(RenderObject::new(render_context.clone(), obj)?); ret.push(RenderObject::new(
config,
output_directory,
output_file,
obj,
)?);
} }
ret ret
}; };
@ -33,7 +42,12 @@ render!(
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.children.iter() { for obj in original.children.iter() {
ret.push(RenderElement::new(render_context.clone(), obj)?); ret.push(RenderElement::new(
config,
output_directory,
output_file,
obj,
)?);
} }
ret ret
}; };

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IPlainText; use crate::intermediate::IPlainText;
@ -13,8 +15,16 @@ pub(crate) struct RenderPlainText {
source: String, source: String,
} }
render!(RenderPlainText, IPlainText, original, _render_context, { render!(
Ok(RenderPlainText { RenderPlainText,
source: original.source.clone(), IPlainText,
}) original,
}); _config,
_output_directory,
_output_file,
{
Ok(RenderPlainText {
source: original.source.clone(),
})
}
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IPlanning; use crate::intermediate::IPlanning;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IPropertyDrawer; use crate::intermediate::IPropertyDrawer;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IQuoteBlock; use crate::intermediate::IQuoteBlock;
@ -14,14 +16,27 @@ pub(crate) struct RenderQuoteBlock {
children: Vec<RenderElement>, children: Vec<RenderElement>,
} }
render!(RenderQuoteBlock, IQuoteBlock, original, render_context, { render!(
let children = { RenderQuoteBlock,
let mut ret = Vec::new(); IQuoteBlock,
for obj in original.children.iter() { original,
ret.push(RenderElement::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderElement::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderQuoteBlock { children }) Ok(RenderQuoteBlock { children })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IRadioLink; use crate::intermediate::IRadioLink;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IRadioTarget; use crate::intermediate::IRadioTarget;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IRegularLink; use crate::intermediate::IRegularLink;
@ -15,17 +17,30 @@ pub(crate) struct RenderRegularLink {
children: Vec<RenderObject>, children: Vec<RenderObject>,
} }
render!(RenderRegularLink, IRegularLink, original, render_context, { render!(
let children = { RenderRegularLink,
let mut ret = Vec::new(); IRegularLink,
for obj in original.children.iter() { original,
ret.push(RenderObject::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderObject::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderRegularLink { Ok(RenderRegularLink {
raw_link: original.raw_link.clone(), raw_link: original.raw_link.clone(),
children, children,
}) })
}); }
);

View File

@ -1,36 +0,0 @@
use std::path::Path;
use crate::config::Config;
use crate::error::CustomError;
/// The supporting information used for converting the intermediate representation into the dust context for rendering.
#[derive(Debug, Clone)]
pub(crate) struct RenderContext<'intermediate> {
pub(crate) config: &'intermediate Config,
// TODO: Perhaps rename to output_root_directory.
pub(crate) output_root_directory: &'intermediate Path,
pub(crate) output_file: &'intermediate Path,
/// An optional string that gets added to IDs in HTML.
///
/// This is useful for cases where you may have conflicting HTML
/// IDs, for example, multiple blog posts with footnotes in a blog
/// stream.
pub(crate) id_addition: Option<&'intermediate str>,
}
impl<'intermediate> RenderContext<'intermediate> {
pub(crate) fn new(
config: &'intermediate Config,
output_directory: &'intermediate Path,
output_file: &'intermediate Path,
id_addition: Option<&'intermediate str>,
) -> Result<RenderContext<'intermediate>, CustomError> {
Ok(RenderContext {
config,
output_root_directory: output_directory,
output_file,
id_addition,
})
}
}

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ISection; use crate::intermediate::ISection;
@ -14,14 +16,27 @@ pub(crate) struct RenderSection {
children: Vec<RenderElement>, children: Vec<RenderElement>,
} }
render!(RenderSection, ISection, original, render_context, { render!(
let children = { RenderSection,
let mut ret = Vec::new(); ISection,
for obj in original.children.iter() { original,
ret.push(RenderElement::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderElement::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderSection { children }) Ok(RenderSection { children })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ISpecialBlock; use crate::intermediate::ISpecialBlock;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ISrcBlock; use crate::intermediate::ISrcBlock;
@ -13,8 +15,16 @@ pub(crate) struct RenderSrcBlock {
lines: Vec<String>, lines: Vec<String>,
} }
render!(RenderSrcBlock, ISrcBlock, original, _render_context, { render!(
Ok(RenderSrcBlock { RenderSrcBlock,
lines: original.lines.clone(), ISrcBlock,
}) original,
}); _config,
_output_directory,
_output_file,
{
Ok(RenderSrcBlock {
lines: original.lines.clone(),
})
}
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IStatisticsCookie; use crate::intermediate::IStatisticsCookie;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IStrikeThrough; use crate::intermediate::IStrikeThrough;
@ -18,12 +20,19 @@ render!(
RenderStrikeThrough, RenderStrikeThrough,
IStrikeThrough, IStrikeThrough,
original, original,
render_context, config,
output_directory,
output_file,
{ {
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.children.iter() { for obj in original.children.iter() {
ret.push(RenderObject::new(render_context.clone(), obj)?); ret.push(RenderObject::new(
config,
output_directory,
output_file,
obj,
)?);
} }
ret ret
}; };

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ISubscript; use crate::intermediate::ISubscript;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ISuperscript; use crate::intermediate::ISuperscript;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ITable; use crate::intermediate::ITable;
@ -14,14 +16,27 @@ pub(crate) struct RenderTable {
children: Vec<RenderTableRow>, children: Vec<RenderTableRow>,
} }
render!(RenderTable, ITable, original, render_context, { render!(
let children = { RenderTable,
let mut ret = Vec::new(); ITable,
for obj in original.children.iter() { original,
ret.push(RenderTableRow::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderTableRow::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderTable { children }) Ok(RenderTable { children })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ITableCell; use crate::intermediate::ITableCell;
@ -14,14 +16,27 @@ pub(crate) struct RenderTableCell {
children: Vec<RenderObject>, children: Vec<RenderObject>,
} }
render!(RenderTableCell, ITableCell, original, render_context, { render!(
let children = { RenderTableCell,
let mut ret = Vec::new(); ITableCell,
for obj in original.children.iter() { original,
ret.push(RenderObject::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderObject::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderTableCell { children }) Ok(RenderTableCell { children })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ITableRow; use crate::intermediate::ITableRow;
@ -14,14 +16,27 @@ pub(crate) struct RenderTableRow {
children: Vec<RenderTableCell>, children: Vec<RenderTableCell>,
} }
render!(RenderTableRow, ITableRow, original, render_context, { render!(
let children = { RenderTableRow,
let mut ret = Vec::new(); ITableRow,
for obj in original.children.iter() { original,
ret.push(RenderTableCell::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderTableCell::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderTableRow { children }) Ok(RenderTableRow { children })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ITarget; use crate::intermediate::ITarget;
@ -13,8 +15,16 @@ pub(crate) struct RenderTarget {
id: String, id: String,
} }
render!(RenderTarget, ITarget, original, _render_context, { render!(
Ok(RenderTarget { RenderTarget,
id: original.id.clone(), ITarget,
}) original,
}); _config,
_output_directory,
_output_file,
{
Ok(RenderTarget {
id: original.id.clone(),
})
}
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::ITimestamp; use crate::intermediate::ITimestamp;

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IUnderline; use crate::intermediate::IUnderline;
@ -14,14 +16,27 @@ pub(crate) struct RenderUnderline {
children: Vec<RenderObject>, children: Vec<RenderObject>,
} }
render!(RenderUnderline, IUnderline, original, render_context, { render!(
let children = { RenderUnderline,
let mut ret = Vec::new(); IUnderline,
for obj in original.children.iter() { original,
ret.push(RenderObject::new(render_context.clone(), obj)?); config,
} output_directory,
ret output_file,
}; {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(RenderObject::new(
config,
output_directory,
output_file,
obj,
)?);
}
ret
};
Ok(RenderUnderline { children }) Ok(RenderUnderline { children })
}); }
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IVerbatim; use crate::intermediate::IVerbatim;
@ -13,8 +15,16 @@ pub(crate) struct RenderVerbatim {
contents: String, contents: String,
} }
render!(RenderVerbatim, IVerbatim, original, _render_context, { render!(
Ok(RenderVerbatim { RenderVerbatim,
contents: original.contents.clone(), IVerbatim,
}) original,
}); _config,
_output_directory,
_output_file,
{
Ok(RenderVerbatim {
contents: original.contents.clone(),
})
}
);

View File

@ -1,6 +1,8 @@
use std::path::Path;
use serde::Serialize; use serde::Serialize;
use super::render_context::RenderContext; use crate::config::Config;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::IVerseBlock; use crate::intermediate::IVerseBlock;

View File

@ -4,7 +4,6 @@ use std::string::FromUtf8Error;
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum CustomError { pub(crate) enum CustomError {
Static(&'static str), Static(&'static str),
String(String),
IO(std::io::Error), IO(std::io::Error),
TomlSerialize(toml::ser::Error), TomlSerialize(toml::ser::Error),
TomlDeserialize(toml::de::Error), TomlDeserialize(toml::de::Error),
@ -30,12 +29,6 @@ impl From<&'static str> for CustomError {
} }
} }
impl From<String> for CustomError {
fn from(value: String) -> Self {
CustomError::String(value)
}
}
impl From<toml::ser::Error> for CustomError { impl From<toml::ser::Error> for CustomError {
fn from(value: toml::ser::Error) -> Self { fn from(value: toml::ser::Error) -> Self {
CustomError::TomlSerialize(value) CustomError::TomlSerialize(value)

View File

@ -8,20 +8,14 @@ pub(crate) struct IBold {
pub(crate) children: Vec<IObject>, pub(crate) children: Vec<IObject>,
} }
intermediate!( intermediate!(IBold, Bold, original, registry, {
IBold, let children = {
&'orig organic::types::Bold<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(IObject::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
Ok(IBold { children }) Ok(IBold { children })
} });
);

View File

@ -7,15 +7,9 @@ pub(crate) struct ICode {
pub(crate) contents: String, pub(crate) contents: String,
} }
intermediate!( intermediate!(ICode, Code, original, _registry, {
ICode, Ok(ICode {
&'orig organic::types::Code<'parse>, // TODO: Should this coalesce whitespace like PlainText?
original, contents: original.contents.to_owned(),
_registry, })
{ });
Ok(ICode {
// TODO: Should this coalesce whitespace like PlainText?
contents: original.contents.to_owned(),
})
}
);

View File

@ -3,9 +3,94 @@ use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use crate::config::Config; use crate::config::Config;
use crate::context::GlobalSettings;
use crate::context::PageHeader;
use crate::context::RenderBlogPostPage;
use crate::context::RenderDocumentElement;
use crate::context::RenderRealFootnoteDefinition;
use crate::error::CustomError; use crate::error::CustomError;
pub(crate) fn get_web_path<D: AsRef<Path>, F: AsRef<Path>, P: AsRef<Path>>( use super::BlogPost;
use super::BlogPostPage;
pub(crate) fn convert_blog_post_page_to_render_context<D: AsRef<Path>, F: AsRef<Path>>(
config: &Config,
output_directory: D,
output_file: F,
_post: &BlogPost,
page: &BlogPostPage,
) -> Result<RenderBlogPostPage, CustomError> {
let output_directory = output_directory.as_ref();
let output_file = output_file.as_ref();
let css_files = vec![
get_web_path(
config,
output_directory,
output_file,
"stylesheet/reset.css",
)?,
get_web_path(config, output_directory, output_file, "stylesheet/main.css")?,
];
let js_files = vec![get_web_path(
config,
output_directory,
output_file,
"blog_post.js",
)?];
let global_settings = GlobalSettings::new(page.title.clone(), css_files, js_files);
let page_header = PageHeader::new(
config.get_site_title().map(str::to_string),
Some(get_web_path(config, output_directory, output_file, "")?),
);
let link_to_blog_post = get_web_path(
config,
output_directory,
output_file,
output_file.strip_prefix(output_directory)?,
)?;
let children = {
let mut children = Vec::new();
for child in page.children.iter() {
children.push(RenderDocumentElement::new(
config,
output_directory,
output_file,
child,
)?);
}
children
};
let footnotes = {
let mut ret = Vec::new();
for footnote in page.footnotes.iter() {
ret.push(RenderRealFootnoteDefinition::new(
config,
output_directory,
output_file,
footnote,
)?);
}
ret
};
let ret = RenderBlogPostPage::new(
global_settings,
Some(page_header),
page.title.clone(),
Some(link_to_blog_post),
children,
footnotes,
);
Ok(ret)
}
fn get_web_path<D: AsRef<Path>, F: AsRef<Path>, P: AsRef<Path>>(
config: &Config, config: &Config,
output_directory: D, output_directory: D,
containing_file: F, containing_file: F,

View File

@ -7,7 +7,6 @@ use tokio::task::JoinHandle;
use walkdir::WalkDir; use walkdir::WalkDir;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::page::BlogPostPageInput;
use crate::intermediate::registry::Registry; use crate::intermediate::registry::Registry;
use super::BlogPostPage; use super::BlogPostPage;
@ -64,11 +63,8 @@ impl BlogPost {
let registry = Arc::new(Mutex::new(registry)); let registry = Arc::new(Mutex::new(registry));
let relative_to_post_dir_path = real_path.strip_prefix(post_dir)?; let relative_to_post_dir_path = real_path.strip_prefix(post_dir)?;
ret.push( ret.push(
BlogPostPage::new( BlogPostPage::new(relative_to_post_dir_path, registry, parsed_document)
registry, .await?,
BlogPostPageInput::new(relative_to_post_dir_path, parsed_document),
)
.await?,
); );
} }
ret ret
@ -81,37 +77,6 @@ impl BlogPost {
} }
inner(root_dir.as_ref(), post_dir.as_ref()).await inner(root_dir.as_ref(), post_dir.as_ref()).await
} }
/// Get the date for a blog post.
///
/// The date is set by the "#+date" export setting. This will
/// first attempt to read the date from an index.org if such a
/// file exists. If that file does not exist or that file does not
/// contain a date export setting, then this will iterate through
/// all the pages under the blog post looking for any page that
/// contains a date export setting. It will return the first date
/// found.
pub(crate) fn get_date(&self) -> Option<&str> {
let index_page_date = self
.get_index_page()
.map(|index_page| index_page.date.as_ref().map(String::as_str))
.flatten();
if index_page_date.is_some() {
return index_page_date;
}
self.pages
.iter()
.filter_map(|page| page.date.as_ref().map(String::as_str))
.next()
}
/// Get the blog post page for index.org
pub(crate) fn get_index_page(&self) -> Option<&BlogPostPage> {
self.pages
.iter()
.find(|page| page.path == Path::new("index.org"))
}
} }
async fn read_file(path: PathBuf) -> std::io::Result<(PathBuf, String)> { async fn read_file(path: PathBuf) -> std::io::Result<(PathBuf, String)> {

View File

@ -7,14 +7,8 @@ pub(crate) struct IEntity {
pub(crate) html: String, pub(crate) html: String,
} }
intermediate!( intermediate!(IEntity, Entity, original, _registry, {
IEntity, Ok(IEntity {
&'orig organic::types::Entity<'parse>, html: original.html.to_owned(),
original, })
_registry, });
{
Ok(IEntity {
html: original.html.to_owned(),
})
}
);

View File

@ -10,7 +10,7 @@ pub(crate) struct IFootnoteDefinition {}
intermediate!( intermediate!(
IFootnoteDefinition, IFootnoteDefinition,
&'orig organic::types::FootnoteDefinition<'parse>, FootnoteDefinition,
original, original,
registry, registry,
{ {
@ -44,22 +44,14 @@ impl IRealFootnoteDefinition {
/// Get an ID to refer to the first reference to this footnote definition. /// Get an ID to refer to the first reference to this footnote definition.
/// ///
/// This ID could, for example, be used for the id attribute in HTML for the reference anchor tag. /// This ID could, for example, be used for the id attribute in HTML for the reference anchor tag.
pub(crate) fn get_reference_id(&self, id_addition: Option<&str>) -> String { pub(crate) fn get_reference_id(&self) -> String {
let id_addition = id_addition format!("fnr.{}", self.get_display_label())
.map(|id_addition| format!("sec{}.", id_addition))
.unwrap_or(String::default());
format!("{}fnr.{}", id_addition, self.get_display_label())
} }
/// Get an ID to refer to the footnote definition. /// Get an ID to refer to the footnote definition.
/// ///
/// This ID could, for example, be used for the id attribute in HTML for the definition anchor tag. /// This ID could, for example, be used for the id attribute in HTML for the definition anchor tag.
pub(crate) fn get_definition_id(&self, id_addition: Option<&str>) -> String { pub(crate) fn get_definition_id(&self) -> String {
let id_addition = id_addition format!("fn.{}", self.get_display_label())
.map(|id_addition| format!("sec{}.", id_addition))
.unwrap_or(String::default());
format!("{}fn.{}", id_addition, self.get_display_label())
} }
} }

View File

@ -9,20 +9,14 @@ pub(crate) struct IFootnoteReference {
duplicate_offset: usize, duplicate_offset: usize,
} }
intermediate!( intermediate!(IFootnoteReference, FootnoteReference, original, registry, {
IFootnoteReference, let (footnote_id, reference_count) =
&'orig organic::types::FootnoteReference<'parse>, get_footnote_reference_id(registry, original.label, &original.definition).await?;
original, Ok(IFootnoteReference {
registry, footnote_id,
{ duplicate_offset: reference_count,
let (footnote_id, reference_count) = })
get_footnote_reference_id(registry, original.label, &original.definition).await?; });
Ok(IFootnoteReference {
footnote_id,
duplicate_offset: reference_count,
})
}
);
impl IFootnoteReference { impl IFootnoteReference {
pub(crate) fn get_display_label(&self) -> String { pub(crate) fn get_display_label(&self) -> String {
@ -32,28 +26,20 @@ impl IFootnoteReference {
/// Get an ID to refer to this footnote reference. /// Get an ID to refer to this footnote reference.
/// ///
/// This ID could, for example, be used for the id attribute in HTML for the reference anchor tag. /// This ID could, for example, be used for the id attribute in HTML for the reference anchor tag.
pub(crate) fn get_reference_id(&self, id_addition: Option<&str>) -> String { pub(crate) fn get_reference_id(&self) -> String {
let id_addition = id_addition
.map(|id_addition| format!("sec{}.", id_addition))
.unwrap_or(String::default());
if self.duplicate_offset == 0 { if self.duplicate_offset == 0 {
format!("{}fnr.{}", id_addition, self.get_display_label()) format!("fnr.{}", self.get_display_label())
} else { } else {
// Org-mode makes all duplicates use "100" but I figure there is no harm in giving each a unique ID. // Org-mode makes all duplicates use "100" but I figure there is no harm in giving each a unique ID.
let append = 100 + self.duplicate_offset - 1; let append = 100 + self.duplicate_offset - 1;
format!("{}fnr.{}.{}", id_addition, self.get_display_label(), append) format!("fnr.{}.{}", self.get_display_label(), append)
} }
} }
/// Get an ID to refer to the footnote definition this footnote reference references. /// Get an ID to refer to the footnote definition this footnote reference references.
/// ///
/// This ID could, for example, be used for the id attribute in HTML for the definition anchor tag. /// This ID could, for example, be used for the id attribute in HTML for the definition anchor tag.
pub(crate) fn get_definition_id(&self, id_addition: Option<&str>) -> String { pub(crate) fn get_definition_id(&self) -> String {
let id_addition = id_addition format!("fn.{}", self.get_display_label())
.map(|id_addition| format!("sec{}.", id_addition))
.unwrap_or(String::default());
format!("{}fn.{}", id_addition, self.get_display_label())
} }
} }

View File

@ -11,30 +11,24 @@ pub(crate) struct IHeading {
pub(crate) children: Vec<IDocumentElement>, pub(crate) children: Vec<IDocumentElement>,
} }
intermediate!( intermediate!(IHeading, Heading, original, registry, {
IHeading, let title = {
&'orig organic::types::Heading<'parse>, let mut ret = Vec::new();
original, for obj in original.title.iter() {
registry, ret.push(IObject::new(registry.clone(), obj).await?);
{ }
let title = { ret
let mut ret = Vec::new(); };
for obj in original.title.iter() { let children = {
ret.push(IObject::new(registry.clone(), obj).await?); let mut ret = Vec::new();
} for obj in original.children.iter() {
ret ret.push(IDocumentElement::new(registry.clone(), obj).await?);
}; }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() { Ok(IHeading {
ret.push(IDocumentElement::new(registry.clone(), obj).await?); title,
} level: original.level,
ret children,
}; })
Ok(IHeading { });
title,
level: original.level,
children,
})
}
);

View File

@ -7,14 +7,8 @@ pub(crate) struct IInlineSourceBlock {
pub(crate) value: String, pub(crate) value: String,
} }
intermediate!( intermediate!(IInlineSourceBlock, InlineSourceBlock, original, _registry, {
IInlineSourceBlock, Ok(IInlineSourceBlock {
&'orig organic::types::InlineSourceBlock<'parse>, value: original.value.to_owned(),
original, })
_registry, });
{
Ok(IInlineSourceBlock {
value: original.value.to_owned(),
})
}
);

View File

@ -8,20 +8,14 @@ pub(crate) struct IItalic {
pub(crate) children: Vec<IObject>, pub(crate) children: Vec<IObject>,
} }
intermediate!( intermediate!(IItalic, Italic, original, registry, {
IItalic, let children = {
&'orig organic::types::Italic<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(IObject::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
Ok(IItalic { children }) Ok(IItalic { children })
} });
);

View File

@ -7,19 +7,13 @@ pub(crate) struct ILatexFragment {
pub(crate) value: String, pub(crate) value: String,
} }
intermediate!( intermediate!(ILatexFragment, LatexFragment, original, _registry, {
ILatexFragment, let value: String = if original.value.starts_with("$$") && original.value.ends_with("$$") {
&'orig organic::types::LatexFragment<'parse>, format!("\\[{}\\]", &original.value[2..(original.value.len() - 2)])
original, } else if original.value.starts_with("$") && original.value.ends_with("$") {
_registry, format!("\\({}\\)", &original.value[1..(original.value.len() - 1)])
{ } else {
let value: String = if original.value.starts_with("$$") && original.value.ends_with("$$") { original.value.to_owned()
format!("\\[{}\\]", &original.value[2..(original.value.len() - 2)]) };
} else if original.value.starts_with("$") && original.value.ends_with("$") { Ok(ILatexFragment { value })
format!("\\({}\\)", &original.value[1..(original.value.len() - 1)]) });
} else {
original.value.to_owned()
};
Ok(ILatexFragment { value })
}
);

View File

@ -23,12 +23,14 @@ pub(crate) use inoop;
/// ///
/// This exists to make changing the type signature easier. /// This exists to make changing the type signature easier.
macro_rules! intermediate { macro_rules! intermediate {
($istruct:ident, $pstruct:ty, $original:ident, $registry:ident, $fnbody:tt) => { ($istruct:ident, $pstruct:ident, $original:ident, $registry:ident, $fnbody:tt) => {
impl $istruct { impl $istruct {
pub(crate) async fn new<'orig, 'parse>( pub(crate) async fn new<'orig, 'parse>(
$registry: crate::intermediate::RefRegistry<'orig, 'parse>, registry: crate::intermediate::RefRegistry<'orig, 'parse>,
$original: $pstruct, original: &'orig organic::types::$pstruct<'parse>,
) -> Result<$istruct, CustomError> { ) -> Result<$istruct, CustomError> {
let $original = original;
let $registry = registry;
$fnbody $fnbody
} }
} }

View File

@ -1,7 +1,6 @@
mod angle_link; mod angle_link;
mod ast_node; mod ast_node;
mod babel_call; mod babel_call;
mod blog_post;
mod bold; mod bold;
mod center_block; mod center_block;
mod citation; mod citation;
@ -11,6 +10,7 @@ mod code;
mod comment; mod comment;
mod comment_block; mod comment_block;
mod convert; mod convert;
mod definition;
mod diary_sexp; mod diary_sexp;
mod document_element; mod document_element;
mod drawer; mod drawer;
@ -67,7 +67,6 @@ mod verse_block;
pub(crate) use angle_link::IAngleLink; pub(crate) use angle_link::IAngleLink;
pub(crate) use ast_node::IAstNode; pub(crate) use ast_node::IAstNode;
pub(crate) use babel_call::IBabelCall; pub(crate) use babel_call::IBabelCall;
pub(crate) use blog_post::BlogPost;
pub(crate) use bold::IBold; pub(crate) use bold::IBold;
pub(crate) use center_block::ICenterBlock; pub(crate) use center_block::ICenterBlock;
pub(crate) use citation::ICitation; pub(crate) use citation::ICitation;
@ -76,7 +75,8 @@ pub(crate) use clock::IClock;
pub(crate) use code::ICode; pub(crate) use code::ICode;
pub(crate) use comment::IComment; pub(crate) use comment::IComment;
pub(crate) use comment_block::ICommentBlock; pub(crate) use comment_block::ICommentBlock;
pub(crate) use convert::get_web_path; pub(crate) use convert::convert_blog_post_page_to_render_context;
pub(crate) use definition::BlogPost;
pub(crate) use diary_sexp::IDiarySexp; pub(crate) use diary_sexp::IDiarySexp;
pub(crate) use document_element::IDocumentElement; pub(crate) use document_element::IDocumentElement;
pub(crate) use drawer::IDrawer; pub(crate) use drawer::IDrawer;

View File

@ -4,28 +4,10 @@ use crate::error::CustomError;
use super::footnote_definition::IRealFootnoteDefinition; use super::footnote_definition::IRealFootnoteDefinition;
use super::macros::intermediate;
use super::IDocumentElement; use super::IDocumentElement;
use super::IHeading; use super::IHeading;
use super::ISection; use super::ISection;
use super::RefRegistry;
#[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)] #[derive(Debug)]
pub(crate) struct BlogPostPage { pub(crate) struct BlogPostPage {
@ -34,26 +16,26 @@ pub(crate) struct BlogPostPage {
pub(crate) title: Option<String>, pub(crate) title: Option<String>,
pub(crate) date: Option<String>,
pub(crate) children: Vec<IDocumentElement>, pub(crate) children: Vec<IDocumentElement>,
pub(crate) footnotes: Vec<IRealFootnoteDefinition>, pub(crate) footnotes: Vec<IRealFootnoteDefinition>,
} }
intermediate!( impl BlogPostPage {
BlogPostPage, // TODO: Move path into the registry so I can give this a standard interface like the others.
BlogPostPageInput<'orig, 'parse>, pub(crate) async fn new<'a, 'b, 'parse, P: Into<PathBuf>>(
original, path: P,
registry, registry: RefRegistry<'b, 'parse>,
{ document: &'b organic::types::Document<'parse>,
) -> Result<BlogPostPage, CustomError> {
let path = path.into();
let mut children = Vec::new(); let mut children = Vec::new();
if let Some(section) = original.document.zeroth_section.as_ref() { if let Some(section) = document.zeroth_section.as_ref() {
children.push(IDocumentElement::Section( children.push(IDocumentElement::Section(
ISection::new(registry.clone(), section).await?, ISection::new(registry.clone(), section).await?,
)); ));
} }
for heading in original.document.children.iter() { for heading in document.children.iter() {
children.push(IDocumentElement::Heading( children.push(IDocumentElement::Heading(
IHeading::new(registry.clone(), heading).await?, IHeading::new(registry.clone(), heading).await?,
)); ));
@ -76,16 +58,13 @@ intermediate!(
}; };
Ok(BlogPostPage { Ok(BlogPostPage {
path: original.path, path,
title: get_title(original.document), title: get_title(&document),
date: get_date(original.document),
children, children,
footnotes, footnotes,
}) })
} }
);
impl BlogPostPage {
/// Get the output path relative to the post directory. /// Get the output path relative to the post directory.
pub(crate) fn get_output_path(&self) -> PathBuf { pub(crate) fn get_output_path(&self) -> PathBuf {
let mut ret = self.path.clone(); let mut ret = self.path.clone();
@ -106,14 +85,3 @@ fn get_title(document: &organic::types::Document<'_>) -> Option<String> {
.last() .last()
.map(|kw| kw.value.to_owned()) .map(|kw| kw.value.to_owned())
} }
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

@ -8,20 +8,14 @@ pub(crate) struct IParagraph {
pub(crate) children: Vec<IObject>, pub(crate) children: Vec<IObject>,
} }
intermediate!( intermediate!(IParagraph, Paragraph, original, registry, {
IParagraph, let children = {
&'orig organic::types::Paragraph<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(IObject::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
Ok(IParagraph { children }) Ok(IParagraph { children })
} });
);

View File

@ -9,23 +9,17 @@ pub(crate) struct IPlainList {
pub(crate) children: Vec<IPlainListItem>, pub(crate) children: Vec<IPlainListItem>,
} }
intermediate!( intermediate!(IPlainList, PlainList, original, registry, {
IPlainList, let children = {
&'orig organic::types::PlainList<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(IPlainListItem::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() {
ret.push(IPlainListItem::new(registry.clone(), obj).await?);
}
ret
};
Ok(IPlainList { Ok(IPlainList {
list_type: original.list_type, list_type: original.list_type,
children, children,
}) })
} });
);

View File

@ -10,28 +10,22 @@ pub(crate) struct IPlainListItem {
pub(crate) children: Vec<IElement>, pub(crate) children: Vec<IElement>,
} }
intermediate!( intermediate!(IPlainListItem, PlainListItem, original, registry, {
IPlainListItem, let tag = {
&'orig organic::types::PlainListItem<'parse>, let mut ret = Vec::new();
original, for obj in original.tag.iter() {
registry, ret.push(IObject::new(registry.clone(), obj).await?);
{ }
let tag = { ret
let mut ret = Vec::new(); };
for obj in original.tag.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for elem in original.children.iter() { for elem in original.children.iter() {
ret.push(IElement::new(registry.clone(), elem).await?); ret.push(IElement::new(registry.clone(), elem).await?);
} }
ret ret
}; };
Ok(IPlainListItem { tag, children }) Ok(IPlainListItem { tag, children })
} });
);

View File

@ -8,14 +8,8 @@ pub(crate) struct IPlainText {
pub(crate) source: String, pub(crate) source: String,
} }
intermediate!( intermediate!(IPlainText, PlainText, original, _registry, {
IPlainText, Ok(IPlainText {
&'orig organic::types::PlainText<'parse>, source: coalesce_whitespace(original.source).into_owned(),
original, })
_registry, });
{
Ok(IPlainText {
source: coalesce_whitespace(original.source).into_owned(),
})
}
);

View File

@ -8,20 +8,14 @@ pub(crate) struct IQuoteBlock {
pub(crate) children: Vec<IElement>, pub(crate) children: Vec<IElement>,
} }
intermediate!( intermediate!(IQuoteBlock, QuoteBlock, original, registry, {
IQuoteBlock, let children = {
&'orig organic::types::QuoteBlock<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(IElement::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() {
ret.push(IElement::new(registry.clone(), obj).await?);
}
ret
};
Ok(IQuoteBlock { children }) Ok(IQuoteBlock { children })
} });
);

View File

@ -9,22 +9,16 @@ pub(crate) struct IRegularLink {
pub(crate) children: Vec<IObject>, pub(crate) children: Vec<IObject>,
} }
intermediate!( intermediate!(IRegularLink, RegularLink, original, registry, {
IRegularLink, let children = {
&'orig organic::types::RegularLink<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(IObject::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() { Ok(IRegularLink {
ret.push(IObject::new(registry.clone(), obj).await?); raw_link: original.get_raw_link().into_owned(),
} children,
ret })
}; });
Ok(IRegularLink {
raw_link: original.get_raw_link().into_owned(),
children,
})
}
);

View File

@ -8,20 +8,14 @@ pub(crate) struct ISection {
pub(crate) children: Vec<IElement>, pub(crate) children: Vec<IElement>,
} }
intermediate!( intermediate!(ISection, Section, original, registry, {
ISection, let children = {
&'orig organic::types::Section<'parse>, let mut ret = Vec::new();
original, for elem in original.children.iter() {
registry, ret.push(IElement::new(registry.clone(), elem).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for elem in original.children.iter() {
ret.push(IElement::new(registry.clone(), elem).await?);
}
ret
};
Ok(ISection { children }) Ok(ISection { children })
} });
);

View File

@ -7,17 +7,11 @@ pub(crate) struct ISrcBlock {
pub(crate) lines: Vec<String>, pub(crate) lines: Vec<String>,
} }
intermediate!( intermediate!(ISrcBlock, SrcBlock, original, _registry, {
ISrcBlock, let lines = original
&'orig organic::types::SrcBlock<'parse>, .get_value()
original, .split_inclusive('\n')
_registry, .map(|s| s.to_owned())
{ .collect();
let lines = original Ok(ISrcBlock { lines })
.get_value() });
.split_inclusive('\n')
.map(|s| s.to_owned())
.collect();
Ok(ISrcBlock { lines })
}
);

View File

@ -8,20 +8,14 @@ pub(crate) struct IStrikeThrough {
pub(crate) children: Vec<IObject>, pub(crate) children: Vec<IObject>,
} }
intermediate!( intermediate!(IStrikeThrough, StrikeThrough, original, registry, {
IStrikeThrough, let children = {
&'orig organic::types::StrikeThrough<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(IObject::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
Ok(IStrikeThrough { children }) Ok(IStrikeThrough { children })
} });
);

View File

@ -8,20 +8,14 @@ pub(crate) struct ITable {
pub(crate) children: Vec<ITableRow>, pub(crate) children: Vec<ITableRow>,
} }
intermediate!( intermediate!(ITable, Table, original, registry, {
ITable, let children = {
&'orig organic::types::Table<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(ITableRow::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() {
ret.push(ITableRow::new(registry.clone(), obj).await?);
}
ret
};
Ok(ITable { children }) Ok(ITable { children })
} });
);

View File

@ -8,20 +8,14 @@ pub(crate) struct ITableCell {
pub(crate) children: Vec<IObject>, pub(crate) children: Vec<IObject>,
} }
intermediate!( intermediate!(ITableCell, TableCell, original, registry, {
ITableCell, let children = {
&'orig organic::types::TableCell<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(IObject::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
Ok(ITableCell { children }) Ok(ITableCell { children })
} });
);

View File

@ -1,4 +1,5 @@
use super::macros::intermediate; use super::macros::intermediate;
use super::table_cell::ITableCell; use super::table_cell::ITableCell;
use crate::error::CustomError; use crate::error::CustomError;
@ -7,20 +8,14 @@ pub(crate) struct ITableRow {
pub(crate) children: Vec<ITableCell>, pub(crate) children: Vec<ITableCell>,
} }
intermediate!( intermediate!(ITableRow, TableRow, original, registry, {
ITableRow, let children = {
&'orig organic::types::TableRow<'parse>, let mut ret = Vec::new();
original, for obj in original.children.iter() {
registry, ret.push(ITableCell::new(registry.clone(), obj).await?);
{ }
let children = { ret
let mut ret = Vec::new(); };
for obj in original.children.iter() {
ret.push(ITableCell::new(registry.clone(), obj).await?);
}
ret
};
Ok(ITableRow { children }) Ok(ITableRow { children })
} });
);

View File

@ -8,17 +8,11 @@ pub(crate) struct ITarget {
value: String, value: String,
} }
intermediate!( intermediate!(ITarget, Target, original, registry, {
ITarget, let mut registry = registry.lock().unwrap();
&'orig organic::types::Target<'parse>, let id = registry.get_target(original.value);
original, Ok(ITarget {
registry, id: id.clone(),
{ value: original.value.to_owned(),
let mut registry = registry.lock().unwrap(); })
let id = registry.get_target(original.value); });
Ok(ITarget {
id: id.clone(),
value: original.value.to_owned(),
})
}
);

Some files were not shown because too many files have changed in this diff Show More