Merge branch 'homepage'

This commit is contained in:
Tom Alexander 2023-12-19 18:08:50 -05:00
commit 050b426f6f
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
102 changed files with 1519 additions and 1405 deletions

View File

@ -1,6 +1,6 @@
<div class="blog_post">
<div class="blog_post_intro">
{?.title}{?.self_link}<a class="blog_post_title" href="{.link}">{.title}</a>{:else}<div class="blog_post_title">{.title}</div>{/.self_link}{/.title}
{?.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>

View File

@ -0,0 +1,31 @@
<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,6 +11,7 @@
<div class="main_content">
{@select key=.type}
{@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}
{/select}
</div>

View File

@ -5,8 +5,13 @@ use include_dir::include_dir;
use include_dir::Dir;
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::intermediate::convert_blog_post_page_to_render_context;
use crate::intermediate::get_web_path;
use crate::intermediate::BlogPost;
use crate::render::DusterRenderer;
use crate::render::RendererIntegration;
@ -34,7 +39,7 @@ impl SiteRenderer {
}
}
pub(crate) async fn render_blog_posts(&self, config: &Config) -> Result<(), CustomError> {
fn init_renderer_integration(&self) -> Result<DusterRenderer<'_>, CustomError> {
let mut renderer_integration = DusterRenderer::new();
let sources: Vec<_> = MAIN_TEMPLATES
@ -62,21 +67,27 @@ impl SiteRenderer {
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_page in &blog_post.pages {
let output_path = self
.output_directory
.join("posts")
.join(&blog_post.id)
.join(config.get_relative_path_to_post(&blog_post.id))
.join(blog_post_page.get_output_path());
let render_context = convert_blog_post_page_to_render_context(
let convert_input = RenderBlogPostPageInput::new(blog_post, blog_post_page);
let render_context = RenderContext::new(
config,
&self.output_directory,
&output_path,
blog_post,
blog_post_page,
self.output_directory.as_path(),
output_path.as_path(),
None,
)?;
let render_context = RenderBlogPostPage::new(render_context, &convert_input)?;
let rendered_output = renderer_integration.render(render_context)?;
let parent_directory = output_path
.parent()
@ -89,6 +100,87 @@ impl SiteRenderer {
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> {
let stylesheet_output_directory = self.output_directory.join("stylesheet");
if !stylesheet_output_directory.exists() {

View File

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

View File

@ -8,6 +8,7 @@ use crate::error::CustomError;
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.
#[derive(Debug)]
pub(crate) struct Config {
raw: RawConfig,
config_path: PathBuf,
@ -56,6 +57,15 @@ impl Config {
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 {
self.get_root_directory().join("output")
}
@ -71,4 +81,13 @@ impl Config {
pub(crate) fn get_site_title(&self) -> Option<&str> {
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,13 +2,14 @@ use serde::Deserialize;
use serde::Serialize;
/// This is the struct for the writer.toml config file that ends up in each site's root directory.
#[derive(Deserialize, Serialize)]
#[derive(Debug, Deserialize, Serialize)]
pub(crate) struct RawConfig {
pub(super) site_title: Option<String>,
author: Option<String>,
email: Option<String>,
pub(super) use_relative_paths: Option<bool>,
pub(super) web_root: Option<String>,
pub(super) stream: Option<RawConfigStream>,
}
impl Default for RawConfig {
@ -19,6 +20,20 @@ impl Default for RawConfig {
email: None,
use_relative_paths: 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,8 +1,6 @@
use std::path::Path;
use serde::Serialize;
use crate::config::Config;
use super::render_context::RenderContext;
use crate::error::CustomError;
use crate::intermediate::IAngleLink;

View File

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

View File

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

View File

@ -1,10 +1,29 @@
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::macros::render;
use super::GlobalSettings;
use super::PageHeader;
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)]
#[serde(tag = "type")]
#[serde(rename = "blog_post_page")]
@ -23,23 +42,82 @@ pub(crate) struct RenderBlogPostPage {
footnotes: Vec<RenderRealFootnoteDefinition>,
}
impl RenderBlogPostPage {
// TODO: Maybe these settings should be moved into a common struct so this can have the same type signature as the others.
pub(crate) fn new(
global_settings: GlobalSettings,
page_header: Option<PageHeader>,
title: Option<String>,
self_link: Option<String>,
children: Vec<RenderDocumentElement>,
footnotes: Vec<RenderRealFootnoteDefinition>,
) -> RenderBlogPostPage {
RenderBlogPostPage {
render!(
RenderBlogPostPage,
RenderBlogPostPageInput,
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(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,
page_header,
title,
self_link,
page_header: Some(page_header),
title: original.page.title.clone(),
self_link: Some(link_to_blog_post),
children,
footnotes,
}
};
Ok(ret)
}
}
);

213
src/context/blog_stream.rs Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,6 +7,7 @@ use tokio::task::JoinHandle;
use walkdir::WalkDir;
use crate::error::CustomError;
use crate::intermediate::page::BlogPostPageInput;
use crate::intermediate::registry::Registry;
use super::BlogPostPage;
@ -63,8 +64,11 @@ impl BlogPost {
let registry = Arc::new(Mutex::new(registry));
let relative_to_post_dir_path = real_path.strip_prefix(post_dir)?;
ret.push(
BlogPostPage::new(relative_to_post_dir_path, registry, parsed_document)
.await?,
BlogPostPage::new(
registry,
BlogPostPageInput::new(relative_to_post_dir_path, parsed_document),
)
.await?,
);
}
ret
@ -77,6 +81,37 @@ impl BlogPost {
}
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)> {

View File

@ -8,14 +8,20 @@ pub(crate) struct IBold {
pub(crate) children: Vec<IObject>,
}
intermediate!(IBold, Bold, original, registry, {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
intermediate!(
IBold,
&'orig organic::types::Bold<'parse>,
original,
registry,
{
let children = {
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,9 +7,15 @@ pub(crate) struct ICode {
pub(crate) contents: String,
}
intermediate!(ICode, Code, original, _registry, {
Ok(ICode {
// TODO: Should this coalesce whitespace like PlainText?
contents: original.contents.to_owned(),
})
});
intermediate!(
ICode,
&'orig organic::types::Code<'parse>,
original,
_registry,
{
Ok(ICode {
// TODO: Should this coalesce whitespace like PlainText?
contents: original.contents.to_owned(),
})
}
);

View File

@ -3,94 +3,9 @@ use std::path::Path;
use std::path::PathBuf;
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 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>>(
pub(crate) fn get_web_path<D: AsRef<Path>, F: AsRef<Path>, P: AsRef<Path>>(
config: &Config,
output_directory: D,
containing_file: F,

View File

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

View File

@ -10,7 +10,7 @@ pub(crate) struct IFootnoteDefinition {}
intermediate!(
IFootnoteDefinition,
FootnoteDefinition,
&'orig organic::types::FootnoteDefinition<'parse>,
original,
registry,
{
@ -44,14 +44,22 @@ impl IRealFootnoteDefinition {
/// 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.
pub(crate) fn get_reference_id(&self) -> String {
format!("fnr.{}", self.get_display_label())
pub(crate) fn get_reference_id(&self, id_addition: Option<&str>) -> String {
let id_addition = id_addition
.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.
///
/// 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) -> String {
format!("fn.{}", self.get_display_label())
pub(crate) fn get_definition_id(&self, id_addition: Option<&str>) -> String {
let id_addition = id_addition
.map(|id_addition| format!("sec{}.", id_addition))
.unwrap_or(String::default());
format!("{}fn.{}", id_addition, self.get_display_label())
}
}

View File

@ -9,14 +9,20 @@ pub(crate) struct IFootnoteReference {
duplicate_offset: usize,
}
intermediate!(IFootnoteReference, FootnoteReference, original, registry, {
let (footnote_id, reference_count) =
get_footnote_reference_id(registry, original.label, &original.definition).await?;
Ok(IFootnoteReference {
footnote_id,
duplicate_offset: reference_count,
})
});
intermediate!(
IFootnoteReference,
&'orig organic::types::FootnoteReference<'parse>,
original,
registry,
{
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 {
pub(crate) fn get_display_label(&self) -> String {
@ -26,20 +32,28 @@ impl IFootnoteReference {
/// 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.
pub(crate) fn get_reference_id(&self) -> String {
pub(crate) fn get_reference_id(&self, id_addition: Option<&str>) -> String {
let id_addition = id_addition
.map(|id_addition| format!("sec{}.", id_addition))
.unwrap_or(String::default());
if self.duplicate_offset == 0 {
format!("fnr.{}", self.get_display_label())
format!("{}fnr.{}", id_addition, self.get_display_label())
} else {
// 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;
format!("fnr.{}.{}", self.get_display_label(), append)
format!("{}fnr.{}.{}", id_addition, self.get_display_label(), append)
}
}
/// 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.
pub(crate) fn get_definition_id(&self) -> String {
format!("fn.{}", self.get_display_label())
pub(crate) fn get_definition_id(&self, id_addition: Option<&str>) -> String {
let id_addition = id_addition
.map(|id_addition| format!("sec{}.", id_addition))
.unwrap_or(String::default());
format!("{}fn.{}", id_addition, self.get_display_label())
}
}

View File

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

View File

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

View File

@ -8,14 +8,20 @@ pub(crate) struct IItalic {
pub(crate) children: Vec<IObject>,
}
intermediate!(IItalic, Italic, original, registry, {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
intermediate!(
IItalic,
&'orig organic::types::Italic<'parse>,
original,
registry,
{
let children = {
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,13 +7,19 @@ pub(crate) struct ILatexFragment {
pub(crate) value: String,
}
intermediate!(ILatexFragment, LatexFragment, original, _registry, {
let value: String = if original.value.starts_with("$$") && original.value.ends_with("$$") {
format!("\\[{}\\]", &original.value[2..(original.value.len() - 2)])
} else if original.value.starts_with("$") && original.value.ends_with("$") {
format!("\\({}\\)", &original.value[1..(original.value.len() - 1)])
} else {
original.value.to_owned()
};
Ok(ILatexFragment { value })
});
intermediate!(
ILatexFragment,
&'orig organic::types::LatexFragment<'parse>,
original,
_registry,
{
let value: String = if original.value.starts_with("$$") && original.value.ends_with("$$") {
format!("\\[{}\\]", &original.value[2..(original.value.len() - 2)])
} else if original.value.starts_with("$") && original.value.ends_with("$") {
format!("\\({}\\)", &original.value[1..(original.value.len() - 1)])
} else {
original.value.to_owned()
};
Ok(ILatexFragment { value })
}
);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,14 +8,20 @@ pub(crate) struct ISection {
pub(crate) children: Vec<IElement>,
}
intermediate!(ISection, Section, original, registry, {
let children = {
let mut ret = Vec::new();
for elem in original.children.iter() {
ret.push(IElement::new(registry.clone(), elem).await?);
}
ret
};
intermediate!(
ISection,
&'orig organic::types::Section<'parse>,
original,
registry,
{
let children = {
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,11 +7,17 @@ pub(crate) struct ISrcBlock {
pub(crate) lines: Vec<String>,
}
intermediate!(ISrcBlock, SrcBlock, original, _registry, {
let lines = original
.get_value()
.split_inclusive('\n')
.map(|s| s.to_owned())
.collect();
Ok(ISrcBlock { lines })
});
intermediate!(
ISrcBlock,
&'orig organic::types::SrcBlock<'parse>,
original,
_registry,
{
let lines = original
.get_value()
.split_inclusive('\n')
.map(|s| s.to_owned())
.collect();
Ok(ISrcBlock { lines })
}
);

View File

@ -8,14 +8,20 @@ pub(crate) struct IStrikeThrough {
pub(crate) children: Vec<IObject>,
}
intermediate!(IStrikeThrough, StrikeThrough, original, registry, {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
intermediate!(
IStrikeThrough,
&'orig organic::types::StrikeThrough<'parse>,
original,
registry,
{
let children = {
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,14 +8,20 @@ pub(crate) struct ITable {
pub(crate) children: Vec<ITableRow>,
}
intermediate!(ITable, Table, original, registry, {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(ITableRow::new(registry.clone(), obj).await?);
}
ret
};
intermediate!(
ITable,
&'orig organic::types::Table<'parse>,
original,
registry,
{
let children = {
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,14 +8,20 @@ pub(crate) struct ITableCell {
pub(crate) children: Vec<IObject>,
}
intermediate!(ITableCell, TableCell, original, registry, {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(IObject::new(registry.clone(), obj).await?);
}
ret
};
intermediate!(
ITableCell,
&'orig organic::types::TableCell<'parse>,
original,
registry,
{
let children = {
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,5 +1,4 @@
use super::macros::intermediate;
use super::table_cell::ITableCell;
use crate::error::CustomError;
@ -8,14 +7,20 @@ pub(crate) struct ITableRow {
pub(crate) children: Vec<ITableCell>,
}
intermediate!(ITableRow, TableRow, original, registry, {
let children = {
let mut ret = Vec::new();
for obj in original.children.iter() {
ret.push(ITableCell::new(registry.clone(), obj).await?);
}
ret
};
intermediate!(
ITableRow,
&'orig organic::types::TableRow<'parse>,
original,
registry,
{
let children = {
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,11 +8,17 @@ pub(crate) struct ITarget {
value: String,
}
intermediate!(ITarget, Target, original, registry, {
let mut registry = registry.lock().unwrap();
let id = registry.get_target(original.value);
Ok(ITarget {
id: id.clone(),
value: original.value.to_owned(),
})
});
intermediate!(
ITarget,
&'orig organic::types::Target<'parse>,
original,
registry,
{
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