Rework summary handling.

Push summary handling into Markdown parsing, identifying the presence
of one by giving its length in the rendered markup.

Hopefully a better fix for #376.
This commit is contained in:
Thomas Hurst 2018-08-22 17:34:32 +01:00
parent e0291cec65
commit c069bfdafa
4 changed files with 33 additions and 25 deletions

View file

@ -185,19 +185,12 @@ impl Page {
context.tera_context.add("page", self); context.tera_context.add("page", self);
let res = render_content( let res = render_content(&self.raw_content, &context)
&self.raw_content.replacen("<!-- more -->", "<a name=\"continue-reading\"></a>", 1), .chain_err(|| format!("Failed to render content of {}", self.file.path.display()))?;
&context,
).chain_err(|| format!("Failed to render content of {}", self.file.path.display()))?; self.summary = res.summary_len.map(|l| res.body[0..l].to_owned());
self.content = res.0; self.content = res.body;
self.toc = res.1; self.toc = res.toc;
if self.raw_content.contains("<!-- more -->") {
self.summary = Some({
let summary = self.raw_content.splitn(2, "<!-- more -->").collect::<Vec<&str>>()[0];
render_content(summary, &context)
.chain_err(|| format!("Failed to render content of {}", self.file.path.display()))?.0
})
}
Ok(()) Ok(())
} }

View file

@ -137,8 +137,8 @@ impl Section {
let res = render_content(&self.raw_content, &context) let res = render_content(&self.raw_content, &context)
.chain_err(|| format!("Failed to render content of {}", self.file.path.display()))?; .chain_err(|| format!("Failed to render content of {}", self.file.path.display()))?;
self.content = res.0; self.content = res.body;
self.toc = res.1; self.toc = res.toc;
Ok(()) Ok(())
} }

View file

@ -32,7 +32,7 @@ pub use table_of_contents::Header;
pub use shortcode::render_shortcodes; pub use shortcode::render_shortcodes;
pub use context::RenderContext; pub use context::RenderContext;
pub fn render_content(content: &str, context: &RenderContext) -> Result<(String, Vec<Header>)> { pub fn render_content(content: &str, context: &RenderContext) -> Result<markdown::Rendered> {
// Don't do anything if there is nothing like a shortcode in the content // Don't do anything if there is nothing like a shortcode in the content
if content.contains("{{") || content.contains("{%") { if content.contains("{{") || content.contains("{%") {
let rendered = render_shortcodes(content, context)?; let rendered = render_shortcodes(content, context)?;

View file

@ -1,4 +1,4 @@
use std::borrow::Cow::Owned; use std::borrow::Cow::{Owned, Borrowed};
use pulldown_cmark as cmark; use pulldown_cmark as cmark;
use self::cmark::{Parser, Event, Tag, Options, OPTION_ENABLE_TABLES, OPTION_ENABLE_FOOTNOTES}; use self::cmark::{Parser, Event, Tag, Options, OPTION_ENABLE_TABLES, OPTION_ENABLE_FOOTNOTES};
@ -14,6 +14,14 @@ use link_checker::check_url;
use table_of_contents::{TempHeader, Header, make_table_of_contents}; use table_of_contents::{TempHeader, Header, make_table_of_contents};
use context::RenderContext; use context::RenderContext;
const CONTINUE_READING: &str = "<p><a name=\"continue-reading\"></a></p>\n";
pub struct Rendered {
pub body: String,
pub summary_len: Option<usize>,
pub toc: Vec<Header>
}
// We might have cases where the slug is already present in our list of anchor // We might have cases where the slug is already present in our list of anchor
// for example an article could have several titles named Example // for example an article could have several titles named Example
// We add a counter after the slug if the slug is already present, which // We add a counter after the slug if the slug is already present, which
@ -36,8 +44,7 @@ fn is_colocated_asset_link(link: &str) -> bool {
&& !link.starts_with("mailto:") && !link.starts_with("mailto:")
} }
pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<Rendered> {
pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(String, Vec<Header>)> {
// the rendered html // the rendered html
let mut html = String::with_capacity(content.len()); let mut html = String::with_capacity(content.len());
// Set while parsing // Set while parsing
@ -57,6 +64,7 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(Strin
let mut temp_header = TempHeader::default(); let mut temp_header = TempHeader::default();
let mut opts = Options::empty(); let mut opts = Options::empty();
let mut has_summary = false;
opts.insert(OPTION_ENABLE_TABLES); opts.insert(OPTION_ENABLE_TABLES);
opts.insert(OPTION_ENABLE_FOOTNOTES); opts.insert(OPTION_ENABLE_FOOTNOTES);
@ -208,6 +216,10 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(Strin
temp_header = TempHeader::default(); temp_header = TempHeader::default();
Event::Html(Owned(val)) Event::Html(Owned(val))
} }
Event::Html(ref markup) if markup.contains("<!-- more -->") => {
has_summary = true;
Event::Html(Borrowed(CONTINUE_READING))
}
_ => event, _ => event,
} }
}); });
@ -215,11 +227,14 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(Strin
cmark::html::push_html(&mut html, parser); cmark::html::push_html(&mut html, parser);
} }
match error { if let Some(e) = error {
Some(e) => Err(e), return Err(e)
None => Ok(( } else {
html.replace("<p></p>", "").replace("</p></p>", "</p>"), html = html.replace("<p></p>", "").replace("</p></p>", "</p>");
make_table_of_contents(&headers) Ok(Rendered {
)), summary_len: if has_summary { html.find(CONTINUE_READING) } else { None },
body: html,
toc: make_table_of_contents(&headers)
})
} }
} }