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);
let res = render_content(
&self.raw_content.replacen("<!-- more -->", "<a name=\"continue-reading\"></a>", 1),
&context,
).chain_err(|| format!("Failed to render content of {}", self.file.path.display()))?;
self.content = res.0;
self.toc = res.1;
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
})
}
let res = render_content(&self.raw_content, &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.body;
self.toc = res.toc;
Ok(())
}

View file

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

View file

@ -32,7 +32,7 @@ pub use table_of_contents::Header;
pub use shortcode::render_shortcodes;
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
if content.contains("{{") || content.contains("{%") {
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 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 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
// for example an article could have several titles named Example
// 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:")
}
pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(String, Vec<Header>)> {
pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<Rendered> {
// the rendered html
let mut html = String::with_capacity(content.len());
// 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 opts = Options::empty();
let mut has_summary = false;
opts.insert(OPTION_ENABLE_TABLES);
opts.insert(OPTION_ENABLE_FOOTNOTES);
@ -208,6 +216,10 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(Strin
temp_header = TempHeader::default();
Event::Html(Owned(val))
}
Event::Html(ref markup) if markup.contains("<!-- more -->") => {
has_summary = true;
Event::Html(Borrowed(CONTINUE_READING))
}
_ => event,
}
});
@ -215,11 +227,14 @@ pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result<(Strin
cmark::html::push_html(&mut html, parser);
}
match error {
Some(e) => Err(e),
None => Ok((
html.replace("<p></p>", "").replace("</p></p>", "</p>"),
make_table_of_contents(&headers)
)),
if let Some(e) = error {
return Err(e)
} else {
html = html.replace("<p></p>", "").replace("</p></p>", "</p>");
Ok(Rendered {
summary_len: if has_summary { html.find(CONTINUE_READING) } else { None },
body: html,
toc: make_table_of_contents(&headers)
})
}
}