Skip to content

Commit

Permalink
Fix continue-reading parsing with inline HTML, add summary-cutoff tem…
Browse files Browse the repository at this point in the history
…plate
  • Loading branch information
clarfonthey committed Oct 16, 2024
1 parent ead17d0 commit ca4ea8e
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 26 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions components/content/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ markdown = { path = "../markdown" }
[dev-dependencies]
test-case = "3" # TODO: can we solve that usecase in src/page.rs in a simpler way? A custom macro_rules! maybe
tempfile = "3.3.0"
templates = { path = "../templates" }
14 changes: 7 additions & 7 deletions components/content/src/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ mod tests {
use std::path::{Path, PathBuf};

use libs::globset::{Glob, GlobSetBuilder};
use libs::tera::Tera;
use tempfile::tempdir;
use templates::ZOLA_TERA;

use crate::Page;
use config::{Config, LanguageOptions};
Expand All @@ -325,7 +325,7 @@ Hello world"#;
let mut page = res.unwrap();
page.render_markdown(
&HashMap::default(),
&Tera::default(),
&ZOLA_TERA,
&config,
InsertAnchor::None,
&HashMap::new(),
Expand Down Expand Up @@ -353,7 +353,7 @@ Hello world"#;
let mut page = res.unwrap();
page.render_markdown(
&HashMap::default(),
&Tera::default(),
&ZOLA_TERA,
&config,
InsertAnchor::None,
&HashMap::new(),
Expand Down Expand Up @@ -523,13 +523,13 @@ Hello world
let mut page = res.unwrap();
page.render_markdown(
&HashMap::default(),
&Tera::default(),
&ZOLA_TERA,
&config,
InsertAnchor::None,
&HashMap::new(),
)
.unwrap();
assert_eq!(page.summary, Some("<p>Hello world</p>\n".to_string()));
assert_eq!(page.summary, Some("<p>Hello world</p>".to_string()));
}

#[test]
Expand Down Expand Up @@ -557,15 +557,15 @@ And here's another. [^3]
let mut page = res.unwrap();
page.render_markdown(
&HashMap::default(),
&Tera::default(),
&ZOLA_TERA,
&config,
InsertAnchor::None,
&HashMap::new(),
)
.unwrap();
assert_eq!(
page.summary,
Some("<p>This page use <sup>1.5</sup> and has footnotes, here\'s one. </p>\n<p>Here's another. </p>\n".to_string())
Some("<p>This page use <sup>1.5</sup> and has footnotes, here\'s one. </p>\n<p>Here's another. </p>".to_string())
);
}

Expand Down
48 changes: 44 additions & 4 deletions components/markdown/src/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::codeblock::{CodeBlock, FenceSettings};
use crate::shortcode::{Shortcode, SHORTCODE_PLACEHOLDER};

const CONTINUE_READING: &str = "<span id=\"continue-reading\"></span>";
const SUMMARY_CUTOFF_TEMPLATE: &str = "summary-cutoff.html";
const ANCHOR_LINK_TEMPLATE: &str = "anchor-link.html";
static EMOJI_REPLACER: Lazy<EmojiReplacer> = Lazy::new(EmojiReplacer::new);

Expand Down Expand Up @@ -690,7 +691,9 @@ pub fn markdown_to_html(
event
});
}
Event::Html(text) if !has_summary && MORE_DIVIDER_RE.is_match(text.as_ref()) => {
Event::Html(text) | Event::InlineHtml(text)
if !has_summary && MORE_DIVIDER_RE.is_match(text.as_ref()) =>
{
has_summary = true;
events.push(Event::Html(CONTINUE_READING.into()));
}
Expand Down Expand Up @@ -793,15 +796,50 @@ pub fn markdown_to_html(
.position(|e| matches!(e, Event::Html(CowStr::Borrowed(CONTINUE_READING))))
.unwrap_or(events.len());

// determine closing tags missing from summary
let mut tags = Vec::new();
for event in &events[..continue_reading] {
match event {
Event::Start(Tag::HtmlBlock) | Event::End(TagEnd::HtmlBlock) => (),
Event::Start(tag) => tags.push(tag.to_end()),
Event::End(tag) => {
tags.truncate(tags.iter().rposition(|t| *t == *tag).unwrap_or(0));
}
_ => (),
}
}

let mut events = events.into_iter();

// emit everything up to summary
cmark::html::push_html(&mut html, events.by_ref().take(continue_reading));

if has_summary {
// remove footnotes
let summary_html = FOOTNOTES_RE.replace_all(&html, "").into_owned();
summary = Some(summary_html)
let mut summary_html = FOOTNOTES_RE.replace_all(&html, "").into_owned();

// truncate trailing whitespace
summary_html.truncate(summary_html.trim_end().len());

// add cutoff template
if !tags.is_empty() {
let mut c = tera::Context::new();
c.insert("summary", &summary_html);
c.insert("lang", &context.lang);
let summary_cutoff = utils::templates::render_template(
SUMMARY_CUTOFF_TEMPLATE,
&context.tera,
c,
&None,
)
.context("Failed to render summary cutoff template")?;
summary_html.push_str(&summary_cutoff);
}

// close remaining tags
cmark::html::push_html(&mut summary_html, tags.into_iter().rev().map(Event::End));

summary = Some(summary_html);
}

// emit everything after summary
Expand All @@ -826,6 +864,7 @@ mod tests {
use super::*;
use config::Config;
use insta::assert_snapshot;
use templates::ZOLA_TERA;

#[test]
fn insert_many_works() {
Expand Down Expand Up @@ -881,7 +920,8 @@ mod tests {
let mores =
["<!-- more -->", "<!--more-->", "<!-- MORE -->", "<!--MORE-->", "<!--\t MoRe \t-->"];
let config = Config::default();
let context = RenderContext::from_config(&config);
let mut context = RenderContext::from_config(&config);
context.tera.to_mut().extend(&ZOLA_TERA).unwrap();
for more in mores {
let content = format!("{top}\n\n{more}\n\n{bottom}");
let rendered = markdown_to_html(&content, &context, vec![]).unwrap();
Expand Down
19 changes: 19 additions & 0 deletions components/markdown/tests/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,25 @@ fn can_customise_anchor_template() {
insta::assert_snapshot!(body);
}

#[test]
fn can_customise_summary_template() {
let mut tera = Tera::default();
tera.extend(&ZOLA_TERA).unwrap();
tera.add_raw_template("summary-cutoff.html", " (in {{ lang }})").unwrap();
let permalinks_ctx = HashMap::new();
let config = Config::default_for_test();
let context = RenderContext::new(
&tera,
&config,
&config.default_language,
"",
&permalinks_ctx,
InsertAnchor::Right,
);
let summary = render_content("Hello <!-- more --> World!", &context).unwrap().summary.unwrap();
insta::assert_snapshot!(summary);
}

#[test]
fn can_use_smart_punctuation() {
let mut config = Config::default_for_test();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: components/markdown/tests/markdown.rs
expression: summary
---
<p>Hello (in en)</p>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
source: components/markdown/tests/summary.rs
expression: body
---
<p>Things to do:</p>
<ul>
<li>Program&hellip;
</li>
</ul>
9 changes: 4 additions & 5 deletions components/markdown/tests/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Hello world!
<!-- more -->
And some content after
"#,
"#,
);
insta::assert_snapshot!(body);
}
Expand All @@ -48,17 +48,16 @@ And some content after
}

#[test]
fn no_truncated_summary() {
let rendered = get_rendered(
fn truncated_summary() {
let body = get_summary(
r#"
Things to do:
* Program <!-- more --> something
* Eat
* Sleep
"#,
);
assert!(rendered.summary.is_none());
insta::assert_snapshot!(rendered.body);
insta::assert_snapshot!(body);
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions components/templates/src/builtins/summary-cutoff.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
&hellip;
1 change: 1 addition & 0 deletions components/templates/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub static ZOLA_TERA: Lazy<Tera> = Lazy::new(|| {
include_str!("builtins/split_sitemap_index.xml"),
),
("__zola_builtins/anchor-link.html", include_str!("builtins/anchor-link.html")),
("__zola_builtins/summary-cutoff.html", include_str!("builtins/summary-cutoff.html")),
("internal/alias.html", include_str!("builtins/internal/alias.html")),
])
.unwrap();
Expand Down
10 changes: 10 additions & 0 deletions docs/content/documentation/content/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,13 @@ available separately in the

A span element in this position with a `continue-reading` id is created, so you can link directly to it if needed. For example:
`<a href="{{ page.permalink }}#continue-reading">Continue Reading</a>`.

The `<!-- more -->` marker can also exist in the middle of a line, and it will ensure that this does not emit unclosed HTML tags.
You can use the `summary-cutoff.html` to show text after the summary (but before these closing tags) based
upon the summary before the cutoff.

By default, it will show an ellipsis (…) regardless of the content of the summary, but you can use a different template if you want to only show an ellipsis if the summary does not end in any punctuation:

```jinja
{% if summary is matching("\PP$") %}&hellip;{% endif %}
```

0 comments on commit ca4ea8e

Please sign in to comment.