From c069bfdafadf38cb39fd3b5d81298460b8052d3a Mon Sep 17 00:00:00 2001
From: Thomas Hurst
Date: Wed, 22 Aug 2018 17:34:32 +0100
Subject: [PATCH] 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.
---
components/content/src/page.rs | 19 +++++-----------
components/content/src/section.rs | 4 ++--
components/rendering/src/lib.rs | 2 +-
components/rendering/src/markdown.rs | 33 ++++++++++++++++++++--------
4 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/components/content/src/page.rs b/components/content/src/page.rs
index 3a0bf066..4162d6d3 100644
--- a/components/content/src/page.rs
+++ b/components/content/src/page.rs
@@ -185,19 +185,12 @@ impl Page {
context.tera_context.add("page", self);
- let res = render_content(
- &self.raw_content.replacen("", "", 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("") {
- self.summary = Some({
- let summary = self.raw_content.splitn(2, "").collect::>()[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(())
}
diff --git a/components/content/src/section.rs b/components/content/src/section.rs
index dcff1f5c..07ddde2b 100644
--- a/components/content/src/section.rs
+++ b/components/content/src/section.rs
@@ -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(())
}
diff --git a/components/rendering/src/lib.rs b/components/rendering/src/lib.rs
index 9e6d7257..acc08953 100644
--- a/components/rendering/src/lib.rs
+++ b/components/rendering/src/lib.rs
@@ -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)> {
+pub fn render_content(content: &str, context: &RenderContext) -> Result {
// 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)?;
diff --git a/components/rendering/src/markdown.rs b/components/rendering/src/markdown.rs
index 56bea619..a9c3b3e6 100644
--- a/components/rendering/src/markdown.rs
+++ b/components/rendering/src/markdown.rs
@@ -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 = "
\n";
+
+pub struct Rendered {
+ pub body: String,
+ pub summary_len: Option,
+ pub toc: Vec
+}
+
// 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)> {
+pub fn markdown_to_html(content: &str, context: &RenderContext) -> Result {
// 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("") => {
+ 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("", "").replace("
", ""),
- make_table_of_contents(&headers)
- )),
+ if let Some(e) = error {
+ return Err(e)
+ } else {
+ html = html.replace("", "").replace("", "");
+ Ok(Rendered {
+ summary_len: if has_summary { html.find(CONTINUE_READING) } else { None },
+ body: html,
+ toc: make_table_of_contents(&headers)
+ })
}
}