@@ -36,6 +36,10 @@ static MORE_DIVIDER_RE: Lazy<Regex> = Lazy::new(|| {
36
36
. unwrap ( )
37
37
} ) ;
38
38
39
+ static FOOTNOTES_RE : Lazy < Regex > = Lazy :: new ( || {
40
+ Regex :: new ( r#"<sup class="footnote-reference"><a href=\s*.*?>\s*.*?</a></sup>"# ) . unwrap ( )
41
+ } ) ;
42
+
39
43
/// Although there exists [a list of registered URI schemes][uri-schemes], a link may use arbitrary,
40
44
/// private schemes. This regex checks if the given string starts with something that just looks
41
45
/// like a scheme, i.e., a case-insensitive identifier followed by a colon.
@@ -78,7 +82,7 @@ fn is_colocated_asset_link(link: &str) -> bool {
78
82
#[ derive( Debug ) ]
79
83
pub struct Rendered {
80
84
pub body : String ,
81
- pub summary_len : Option < usize > ,
85
+ pub summary : Option < String > ,
82
86
pub toc : Vec < Heading > ,
83
87
/// Links to site-local pages: relative path plus optional anchor target.
84
88
pub internal_links : Vec < ( String , Option < String > ) > ,
@@ -405,6 +409,7 @@ pub fn markdown_to_html(
405
409
. map ( |x| x. as_object ( ) . unwrap ( ) . get ( "relative_path" ) . unwrap ( ) . as_str ( ) . unwrap ( ) ) ;
406
410
// the rendered html
407
411
let mut html = String :: with_capacity ( content. len ( ) ) ;
412
+ let mut summary = None ;
408
413
// Set while parsing
409
414
let mut error = None ;
410
415
@@ -679,17 +684,15 @@ pub fn markdown_to_html(
679
684
event
680
685
} ) ;
681
686
}
682
- Event :: Html ( text) => {
683
- if !has_summary && MORE_DIVIDER_RE . is_match ( & text) {
684
- has_summary = true ;
685
- events. push ( Event :: Html ( CONTINUE_READING . into ( ) ) ) ;
686
- continue ;
687
- }
688
- if !contains_shortcode ( text. as_ref ( ) ) {
689
- events. push ( Event :: Html ( text) ) ;
690
- continue ;
691
- }
692
-
687
+ Event :: Html ( text) | Event :: InlineHtml ( text)
688
+ if !has_summary && MORE_DIVIDER_RE . is_match ( text. as_ref ( ) ) =>
689
+ {
690
+ has_summary = true ;
691
+ events. push ( Event :: Html ( CONTINUE_READING . into ( ) ) ) ;
692
+ }
693
+ Event :: Html ( text) | Event :: InlineHtml ( text)
694
+ if contains_shortcode ( text. as_ref ( ) ) =>
695
+ {
693
696
render_shortcodes ! ( false , text, range) ;
694
697
}
695
698
_ => events. push ( event) ,
@@ -781,14 +784,31 @@ pub fn markdown_to_html(
781
784
convert_footnotes_to_github_style ( & mut events) ;
782
785
}
783
786
784
- cmark:: html:: push_html ( & mut html, events. into_iter ( ) ) ;
787
+ let continue_reading = events
788
+ . iter ( )
789
+ . position ( |e| matches ! ( e, Event :: Html ( CowStr :: Borrowed ( CONTINUE_READING ) ) ) )
790
+ . unwrap_or ( events. len ( ) ) ;
791
+
792
+ let mut events = events. into_iter ( ) ;
793
+
794
+ // emit everything up to summary
795
+ cmark:: html:: push_html ( & mut html, events. by_ref ( ) . take ( continue_reading) ) ;
796
+
797
+ if has_summary {
798
+ // remove footnotes
799
+ let summary_html = FOOTNOTES_RE . replace_all ( & html, "" ) . into_owned ( ) ;
800
+ summary = Some ( summary_html)
801
+ }
802
+
803
+ // emit everything after summary
804
+ cmark:: html:: push_html ( & mut html, events) ;
785
805
}
786
806
787
807
if let Some ( e) = error {
788
808
Err ( e)
789
809
} else {
790
810
Ok ( Rendered {
791
- summary_len : if has_summary { html . find ( CONTINUE_READING ) } else { None } ,
811
+ summary ,
792
812
body : html,
793
813
toc : make_table_of_contents ( headings) ,
794
814
internal_links,
@@ -861,10 +881,10 @@ mod tests {
861
881
for more in mores {
862
882
let content = format ! ( "{top}\n \n {more}\n \n {bottom}" ) ;
863
883
let rendered = markdown_to_html ( & content, & context, vec ! [ ] ) . unwrap ( ) ;
864
- assert ! ( rendered. summary_len . is_some( ) , "no summary when splitting on {more}" ) ;
865
- let summary_len = rendered. summary_len . unwrap ( ) ;
866
- let summary = & rendered . body [ ..summary_len ] . trim ( ) ;
867
- let body = & rendered. body [ summary_len ..] . trim ( ) ;
884
+ assert ! ( rendered. summary . is_some( ) , "no summary when splitting on {more}" ) ;
885
+ let summary = rendered. summary . unwrap ( ) ;
886
+ let summary = summary . trim ( ) ;
887
+ let body = rendered. body [ summary . len ( ) ..] . trim ( ) ;
868
888
let continue_reading = & body[ ..CONTINUE_READING . len ( ) ] ;
869
889
let body = & body[ CONTINUE_READING . len ( ) ..] . trim ( ) ;
870
890
assert_eq ! ( summary, & top_rendered) ;
0 commit comments