Add a prefix to footnote IDs.
This avoids a conflict with multiple blog posts rendering in the same stream.
This commit is contained in:
parent
d4b290ebe6
commit
2e1c979127
@ -85,6 +85,7 @@ impl SiteRenderer {
|
|||||||
config,
|
config,
|
||||||
self.output_directory.as_path(),
|
self.output_directory.as_path(),
|
||||||
output_path.as_path(),
|
output_path.as_path(),
|
||||||
|
None,
|
||||||
)?;
|
)?;
|
||||||
let render_context = RenderBlogPostPage::new(render_context, &convert_input)?;
|
let render_context = RenderBlogPostPage::new(render_context, &convert_input)?;
|
||||||
let rendered_output = renderer_integration.render(render_context)?;
|
let rendered_output = renderer_integration.render(render_context)?;
|
||||||
@ -165,6 +166,7 @@ impl SiteRenderer {
|
|||||||
config,
|
config,
|
||||||
self.output_directory.as_path(),
|
self.output_directory.as_path(),
|
||||||
output_file.as_path(),
|
output_file.as_path(),
|
||||||
|
None,
|
||||||
)?;
|
)?;
|
||||||
let blog_stream = RenderBlogStream::new(render_context, &convert_input)?;
|
let blog_stream = RenderBlogStream::new(render_context, &convert_input)?;
|
||||||
|
|
||||||
|
@ -86,7 +86,13 @@ render!(
|
|||||||
let children = original
|
let children = original
|
||||||
.original
|
.original
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|blog_post| RenderBlogStreamEntry::new(render_context.clone(), blog_post))
|
.enumerate()
|
||||||
|
.map(|(i, blog_post)| {
|
||||||
|
RenderBlogStreamEntry::new(
|
||||||
|
render_context.clone(),
|
||||||
|
&RenderBlogStreamEntryInput::new(blog_post, i),
|
||||||
|
)
|
||||||
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
let stream_pagination = if original.older_link.is_some() || original.newer_link.is_some() {
|
let stream_pagination = if original.older_link.is_some() || original.newer_link.is_some() {
|
||||||
@ -107,6 +113,18 @@ render!(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[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)]
|
#[derive(Debug, Serialize)]
|
||||||
pub(crate) struct RenderBlogStreamEntry {
|
pub(crate) struct RenderBlogStreamEntry {
|
||||||
/// The title that will be shown visibly on the page.
|
/// The title that will be shown visibly on the page.
|
||||||
@ -119,37 +137,62 @@ pub(crate) struct RenderBlogStreamEntry {
|
|||||||
footnotes: Vec<RenderRealFootnoteDefinition>,
|
footnotes: Vec<RenderRealFootnoteDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
render!(RenderBlogStreamEntry, BlogPost, original, render_context, {
|
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(
|
let link_to_blog_post = get_web_path(
|
||||||
render_context.config,
|
render_context.config,
|
||||||
render_context.output_directory,
|
render_context.output_directory,
|
||||||
render_context.output_file,
|
render_context.output_file,
|
||||||
render_context
|
render_context
|
||||||
.config
|
.config
|
||||||
.get_relative_path_to_post(&original.id),
|
.get_relative_path_to_post(&original.original.id),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// TODO: Should I guess an index page instead of erroring out?
|
// TODO: Should I guess an index page instead of erroring out?
|
||||||
let index_page = original
|
let index_page = original
|
||||||
|
.original
|
||||||
.get_index_page()
|
.get_index_page()
|
||||||
.ok_or_else(|| format!("Blog post {} needs an index page.", original.id))?;
|
.ok_or_else(|| format!("Blog post {} needs an index page.", original.original.id))?;
|
||||||
|
|
||||||
let title = index_page.title.clone();
|
let title = index_page.title.clone();
|
||||||
|
|
||||||
// TODO: Handle footnotes.
|
|
||||||
let children = index_page
|
let children = index_page
|
||||||
.children
|
.children
|
||||||
.iter()
|
.iter()
|
||||||
.map(|child| RenderDocumentElement::new(render_context.clone(), child))
|
.map(|child| RenderDocumentElement::new(render_context.clone(), child))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.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 {
|
Ok(RenderBlogStreamEntry {
|
||||||
title,
|
title,
|
||||||
self_link: Some(link_to_blog_post),
|
self_link: Some(link_to_blog_post),
|
||||||
children,
|
children,
|
||||||
footnotes: Vec::new(),
|
footnotes,
|
||||||
})
|
})
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub(crate) struct RenderBlogStreamPagination {
|
pub(crate) struct RenderBlogStreamPagination {
|
||||||
|
@ -42,8 +42,8 @@ render!(
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(RenderRealFootnoteDefinition {
|
Ok(RenderRealFootnoteDefinition {
|
||||||
definition_id: original.get_definition_id(),
|
definition_id: original.get_definition_id(render_context.id_addition),
|
||||||
reference_link: format!("#{}", original.get_reference_id()),
|
reference_link: format!("#{}", original.get_reference_id(render_context.id_addition)),
|
||||||
label: original.get_display_label(),
|
label: original.get_display_label(),
|
||||||
contents,
|
contents,
|
||||||
})
|
})
|
||||||
|
@ -19,11 +19,14 @@ render!(
|
|||||||
RenderFootnoteReference,
|
RenderFootnoteReference,
|
||||||
IFootnoteReference,
|
IFootnoteReference,
|
||||||
original,
|
original,
|
||||||
_render_context,
|
render_context,
|
||||||
{
|
{
|
||||||
Ok(RenderFootnoteReference {
|
Ok(RenderFootnoteReference {
|
||||||
reference_id: original.get_reference_id(),
|
reference_id: original.get_reference_id(render_context.id_addition),
|
||||||
definition_link: format!("#{}", original.get_definition_id()),
|
definition_link: format!(
|
||||||
|
"#{}",
|
||||||
|
original.get_definition_id(render_context.id_addition)
|
||||||
|
),
|
||||||
label: original.get_display_label(),
|
label: original.get_display_label(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,13 @@ pub(crate) struct RenderContext<'intermediate> {
|
|||||||
// TODO: Perhaps rename to output_root_directory.
|
// TODO: Perhaps rename to output_root_directory.
|
||||||
pub(crate) output_directory: &'intermediate Path,
|
pub(crate) output_directory: &'intermediate Path,
|
||||||
pub(crate) output_file: &'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> {
|
impl<'intermediate> RenderContext<'intermediate> {
|
||||||
@ -17,11 +24,13 @@ impl<'intermediate> RenderContext<'intermediate> {
|
|||||||
config: &'intermediate Config,
|
config: &'intermediate Config,
|
||||||
output_directory: &'intermediate Path,
|
output_directory: &'intermediate Path,
|
||||||
output_file: &'intermediate Path,
|
output_file: &'intermediate Path,
|
||||||
|
id_addition: Option<&'intermediate str>,
|
||||||
) -> Result<RenderContext<'intermediate>, CustomError> {
|
) -> Result<RenderContext<'intermediate>, CustomError> {
|
||||||
Ok(RenderContext {
|
Ok(RenderContext {
|
||||||
config,
|
config,
|
||||||
output_directory,
|
output_directory,
|
||||||
output_file,
|
output_file,
|
||||||
|
id_addition,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,14 +44,22 @@ impl IRealFootnoteDefinition {
|
|||||||
/// Get an ID to refer to the first reference to this footnote definition.
|
/// Get an ID to refer to the first reference to this footnote definition.
|
||||||
///
|
///
|
||||||
/// This ID could, for example, be used for the id attribute in HTML for the reference anchor tag.
|
/// This ID could, for example, be used for the id attribute in HTML for the reference anchor tag.
|
||||||
pub(crate) fn get_reference_id(&self) -> String {
|
pub(crate) fn get_reference_id(&self, id_addition: Option<&str>) -> String {
|
||||||
format!("fnr.{}", self.get_display_label())
|
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.
|
/// Get an ID to refer to the footnote definition.
|
||||||
///
|
///
|
||||||
/// This ID could, for example, be used for the id attribute in HTML for the definition anchor tag.
|
/// This ID could, for example, be used for the id attribute in HTML for the definition anchor tag.
|
||||||
pub(crate) fn get_definition_id(&self) -> String {
|
pub(crate) fn get_definition_id(&self, id_addition: Option<&str>) -> String {
|
||||||
format!("fn.{}", self.get_display_label())
|
let id_addition = id_addition
|
||||||
|
.map(|id_addition| format!("sec{}.", id_addition))
|
||||||
|
.unwrap_or(String::default());
|
||||||
|
|
||||||
|
format!("{}fn.{}", id_addition, self.get_display_label())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,20 +32,28 @@ impl IFootnoteReference {
|
|||||||
/// Get an ID to refer to this footnote reference.
|
/// Get an ID to refer to this footnote reference.
|
||||||
///
|
///
|
||||||
/// This ID could, for example, be used for the id attribute in HTML for the reference anchor tag.
|
/// This ID could, for example, be used for the id attribute in HTML for the reference anchor tag.
|
||||||
pub(crate) fn get_reference_id(&self) -> 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 {
|
if self.duplicate_offset == 0 {
|
||||||
format!("fnr.{}", self.get_display_label())
|
format!("{}fnr.{}", id_addition, self.get_display_label())
|
||||||
} else {
|
} else {
|
||||||
// Org-mode makes all duplicates use "100" but I figure there is no harm in giving each a unique ID.
|
// Org-mode makes all duplicates use "100" but I figure there is no harm in giving each a unique ID.
|
||||||
let append = 100 + self.duplicate_offset - 1;
|
let append = 100 + self.duplicate_offset - 1;
|
||||||
format!("fnr.{}.{}", 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.
|
/// Get an ID to refer to the footnote definition this footnote reference references.
|
||||||
///
|
///
|
||||||
/// This ID could, for example, be used for the id attribute in HTML for the definition anchor tag.
|
/// This ID could, for example, be used for the id attribute in HTML for the definition anchor tag.
|
||||||
pub(crate) fn get_definition_id(&self) -> String {
|
pub(crate) fn get_definition_id(&self, id_addition: Option<&str>) -> String {
|
||||||
format!("fn.{}", self.get_display_label())
|
let id_addition = id_addition
|
||||||
|
.map(|id_addition| format!("sec{}.", id_addition))
|
||||||
|
.unwrap_or(String::default());
|
||||||
|
|
||||||
|
format!("{}fn.{}", id_addition, self.get_display_label())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user