Skip to content

Commit e3e2c69

Browse files
clarfontheyberdandy
authored andcommitted
Match <!--more--> in addition to <!-- more --> (getzola#2397)
* Match <!-- more --> without spaces * Add tests for new <!-- more --> handling, with a note on pulldown-cmark bug
1 parent b5a8730 commit e3e2c69

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

components/markdown/src/markdown.rs

+40-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use utils::net::is_external_link;
1010
use crate::context::RenderContext;
1111
use errors::{Context, Error, Result};
1212
use libs::pulldown_cmark::escape::escape_html;
13-
use libs::regex::Regex;
13+
use libs::regex::{Regex, RegexBuilder};
1414
use utils::site::resolve_internal_link;
1515
use utils::slugs::slugify_anchors;
1616
use utils::table_of_contents::{make_table_of_contents, Heading};
@@ -24,6 +24,15 @@ const CONTINUE_READING: &str = "<span id=\"continue-reading\"></span>";
2424
const ANCHOR_LINK_TEMPLATE: &str = "anchor-link.html";
2525
static EMOJI_REPLACER: Lazy<EmojiReplacer> = Lazy::new(EmojiReplacer::new);
2626

27+
/// Set as a regex to help match some extra cases. This way, spaces and case don't matter.
28+
static MORE_DIVIDER_RE: Lazy<Regex> = Lazy::new(|| {
29+
RegexBuilder::new(r#"<!--\s*more\s*-->"#)
30+
.case_insensitive(true)
31+
.dot_matches_new_line(true)
32+
.build()
33+
.unwrap()
34+
});
35+
2736
/// Although there exists [a list of registered URI schemes][uri-schemes], a link may use arbitrary,
2837
/// private schemes. This regex checks if the given string starts with something that just looks
2938
/// like a scheme, i.e., a case-insensitive identifier followed by a colon.
@@ -485,7 +494,7 @@ pub fn markdown_to_html(
485494
});
486495
}
487496
Event::Html(text) => {
488-
if text.contains("<!-- more -->") {
497+
if !has_summary && MORE_DIVIDER_RE.is_match(&text) {
489498
has_summary = true;
490499
events.push(Event::Html(CONTINUE_READING.into()));
491500
continue;
@@ -600,6 +609,8 @@ pub fn markdown_to_html(
600609

601610
#[cfg(test)]
602611
mod tests {
612+
use config::Config;
613+
603614
use super::*;
604615
#[test]
605616

@@ -644,4 +655,31 @@ mod tests {
644655
assert!(!is_colocated_asset_link(link));
645656
}
646657
}
658+
659+
#[test]
660+
// Tests for summary being split out
661+
fn test_summary_split() {
662+
let top = "Here's a compelling summary.";
663+
let top_rendered = format!("<p>{top}</p>");
664+
let bottom = "Here's the compelling conclusion.";
665+
let bottom_rendered = format!("<p>{bottom}</p>");
666+
// FIXME: would add a test that includes newlines, but due to the way pulldown-cmark parses HTML nodes, these are passed as separate HTML events. see: https://github.com/raphlinus/pulldown-cmark/issues/803
667+
let mores =
668+
["<!-- more -->", "<!--more-->", "<!-- MORE -->", "<!--MORE-->", "<!--\t MoRe \t-->"];
669+
let config = Config::default();
670+
let context = RenderContext::from_config(&config);
671+
for more in mores {
672+
let content = format!("{top}\n\n{more}\n\n{bottom}");
673+
let rendered = markdown_to_html(&content, &context, vec![]).unwrap();
674+
assert!(rendered.summary_len.is_some(), "no summary when splitting on {more}");
675+
let summary_len = rendered.summary_len.unwrap();
676+
let summary = &rendered.body[..summary_len].trim();
677+
let body = &rendered.body[summary_len..].trim();
678+
let continue_reading = &body[..CONTINUE_READING.len()];
679+
let body = &body[CONTINUE_READING.len()..].trim();
680+
assert_eq!(summary, &top_rendered);
681+
assert_eq!(continue_reading, CONTINUE_READING);
682+
assert_eq!(body, &bottom_rendered);
683+
}
684+
}
647685
}

0 commit comments

Comments
 (0)