@@ -418,7 +418,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
418418struct HeadingLinks < ' a , ' b , ' ids , I > {
419419 inner : I ,
420420 toc : Option < & ' b mut TocBuilder > ,
421- buf : VecDeque < ( Event < ' a > , Range < usize > ) > ,
421+ buf : VecDeque < Event < ' a > > ,
422422 id_map : & ' ids mut IdMap ,
423423}
424424
@@ -428,48 +428,48 @@ impl<'a, 'b, 'ids, I> HeadingLinks<'a, 'b, 'ids, I> {
428428 }
429429}
430430
431- impl < ' a , ' b , ' ids , I : Iterator < Item = ( Event < ' a > , Range < usize > ) > > Iterator
432- for HeadingLinks < ' a , ' b , ' ids , I >
433- {
434- type Item = ( Event < ' a > , Range < usize > ) ;
431+ impl < ' a , ' b , ' ids , I : Iterator < Item = Event < ' a > > > Iterator for HeadingLinks < ' a , ' b , ' ids , I > {
432+ type Item = Event < ' a > ;
435433
436434 fn next ( & mut self ) -> Option < Self :: Item > {
437435 if let Some ( e) = self . buf . pop_front ( ) {
438436 return Some ( e) ;
439437 }
440438
441439 let event = self . inner . next ( ) ;
442- if let Some ( ( Event :: Start ( Tag :: Heading ( level) ) , _ ) ) = event {
440+ if let Some ( Event :: Start ( Tag :: Heading ( level) ) ) = event {
443441 let mut id = String :: new ( ) ;
444442 for event in & mut self . inner {
445- match & event. 0 {
443+ match & event {
446444 Event :: End ( Tag :: Heading ( ..) ) => break ,
447- Event :: Start ( Tag :: Link ( _, _, _) ) | Event :: End ( Tag :: Link ( ..) ) => { }
448445 Event :: Text ( text) | Event :: Code ( text) => {
449446 id. extend ( text. chars ( ) . filter_map ( slugify) ) ;
450- self . buf . push_back ( event) ;
451447 }
452- _ => self . buf . push_back ( event) ,
448+ _ => { }
449+ }
450+ match event {
451+ Event :: Start ( Tag :: Link ( _, _, _) ) | Event :: End ( Tag :: Link ( ..) ) => { }
452+ event => self . buf . push_back ( event) ,
453453 }
454454 }
455455 let id = self . id_map . derive ( id) ;
456456
457457 if let Some ( ref mut builder) = self . toc {
458458 let mut html_header = String :: new ( ) ;
459- html:: push_html ( & mut html_header, self . buf . iter ( ) . map ( | ( ev , _ ) | ev . clone ( ) ) ) ;
459+ html:: push_html ( & mut html_header, self . buf . iter ( ) . cloned ( ) ) ;
460460 let sec = builder. push ( level as u32 , html_header, id. clone ( ) ) ;
461- self . buf . push_front ( ( Event :: Html ( format ! ( "{} " , sec) . into ( ) ) , 0 .. 0 ) ) ;
461+ self . buf . push_front ( Event :: Html ( format ! ( "{} " , sec) . into ( ) ) ) ;
462462 }
463463
464- self . buf . push_back ( ( Event :: Html ( format ! ( "</a></h{}>" , level) . into ( ) ) , 0 .. 0 ) ) ;
464+ self . buf . push_back ( Event :: Html ( format ! ( "</a></h{}>" , level) . into ( ) ) ) ;
465465
466466 let start_tags = format ! (
467467 "<h{level} id=\" {id}\" class=\" section-header\" >\
468468 <a href=\" #{id}\" >",
469469 id = id,
470470 level = level
471471 ) ;
472- return Some ( ( Event :: Html ( start_tags. into ( ) ) , 0 .. 0 ) ) ;
472+ return Some ( Event :: Html ( start_tags. into ( ) ) ) ;
473473 }
474474 event
475475 }
@@ -560,23 +560,23 @@ impl<'a, I> Footnotes<'a, I> {
560560 }
561561}
562562
563- impl < ' a , I : Iterator < Item = ( Event < ' a > , Range < usize > ) > > Iterator for Footnotes < ' a , I > {
564- type Item = ( Event < ' a > , Range < usize > ) ;
563+ impl < ' a , I : Iterator < Item = Event < ' a > > > Iterator for Footnotes < ' a , I > {
564+ type Item = Event < ' a > ;
565565
566566 fn next ( & mut self ) -> Option < Self :: Item > {
567567 loop {
568568 match self . inner . next ( ) {
569- Some ( ( Event :: FootnoteReference ( ref reference) , range ) ) => {
569+ Some ( Event :: FootnoteReference ( ref reference) ) => {
570570 let entry = self . get_entry ( & reference) ;
571571 let reference = format ! (
572572 "<sup id=\" fnref{0}\" ><a href=\" #fn{0}\" >{0}</a></sup>" ,
573573 ( * entry) . 1
574574 ) ;
575- return Some ( ( Event :: Html ( reference. into ( ) ) , range ) ) ;
575+ return Some ( Event :: Html ( reference. into ( ) ) ) ;
576576 }
577- Some ( ( Event :: Start ( Tag :: FootnoteDefinition ( def) ) , _ ) ) => {
577+ Some ( Event :: Start ( Tag :: FootnoteDefinition ( def) ) ) => {
578578 let mut content = Vec :: new ( ) ;
579- for ( event, _ ) in & mut self . inner {
579+ for event in & mut self . inner {
580580 if let Event :: End ( Tag :: FootnoteDefinition ( ..) ) = event {
581581 break ;
582582 }
@@ -607,7 +607,7 @@ impl<'a, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator for Footnotes<'
607607 ret. push_str ( "</li>" ) ;
608608 }
609609 ret. push_str ( "</ol></div>" ) ;
610- return Some ( ( Event :: Html ( ret. into ( ) ) , 0 .. 0 ) ) ;
610+ return Some ( Event :: Html ( ret. into ( ) ) ) ;
611611 } else {
612612 return None ;
613613 }
@@ -917,14 +917,13 @@ impl Markdown<'_> {
917917 } ;
918918
919919 let p = Parser :: new_with_broken_link_callback ( md, opts ( ) , Some ( & mut replacer) ) ;
920- let p = p. into_offset_iter ( ) ;
921920
922921 let mut s = String :: with_capacity ( md. len ( ) * 3 / 2 ) ;
923922
924923 let p = HeadingLinks :: new ( p, None , & mut ids) ;
925- let p = Footnotes :: new ( p) ;
926- let p = LinkReplacer :: new ( p. map ( |( ev, _) | ev) , links) ;
924+ let p = LinkReplacer :: new ( p, links) ;
927925 let p = CodeBlocks :: new ( p, codes, edition, playground) ;
926+ let p = Footnotes :: new ( p) ;
928927 html:: push_html ( & mut s, p) ;
929928
930929 s
@@ -935,16 +934,16 @@ impl MarkdownWithToc<'_> {
935934 crate fn into_string ( self ) -> String {
936935 let MarkdownWithToc ( md, mut ids, codes, edition, playground) = self ;
937936
938- let p = Parser :: new_ext ( md, opts ( ) ) . into_offset_iter ( ) ;
937+ let p = Parser :: new_ext ( md, opts ( ) ) ;
939938
940939 let mut s = String :: with_capacity ( md. len ( ) * 3 / 2 ) ;
941940
942941 let mut toc = TocBuilder :: new ( ) ;
943942
944943 {
945944 let p = HeadingLinks :: new ( p, Some ( & mut toc) , & mut ids) ;
945+ let p = CodeBlocks :: new ( p, codes, edition, playground) ;
946946 let p = Footnotes :: new ( p) ;
947- let p = CodeBlocks :: new ( p. map ( |( ev, _) | ev) , codes, edition, playground) ;
948947 html:: push_html ( & mut s, p) ;
949948 }
950949
@@ -960,19 +959,19 @@ impl MarkdownHtml<'_> {
960959 if md. is_empty ( ) {
961960 return String :: new ( ) ;
962961 }
963- let p = Parser :: new_ext ( md, opts ( ) ) . into_offset_iter ( ) ;
962+ let p = Parser :: new_ext ( md, opts ( ) ) ;
964963
965964 // Treat inline HTML as plain text.
966- let p = p. map ( |event| match event. 0 {
967- Event :: Html ( text) => ( Event :: Text ( text) , event . 1 ) ,
965+ let p = p. map ( |event| match event {
966+ Event :: Html ( text) => Event :: Text ( text) ,
968967 _ => event,
969968 } ) ;
970969
971970 let mut s = String :: with_capacity ( md. len ( ) * 3 / 2 ) ;
972971
973972 let p = HeadingLinks :: new ( p, None , & mut ids) ;
973+ let p = CodeBlocks :: new ( p, codes, edition, playground) ;
974974 let p = Footnotes :: new ( p) ;
975- let p = CodeBlocks :: new ( p. map ( |( ev, _) | ev) , codes, edition, playground) ;
976975 html:: push_html ( & mut s, p) ;
977976
978977 s
@@ -1125,45 +1124,50 @@ crate fn plain_text_summary(md: &str) -> String {
11251124 s
11261125}
11271126
1128- crate fn markdown_links ( md : & str ) -> Vec < ( String , Range < usize > ) > {
1127+ crate fn markdown_links ( md : & str ) -> Vec < ( String , Option < Range < usize > > ) > {
11291128 if md. is_empty ( ) {
11301129 return vec ! [ ] ;
11311130 }
11321131
11331132 let mut links = vec ! [ ] ;
1134- // Used to avoid mutable borrow issues in the `push` closure
1135- // Probably it would be more efficient to use a `RefCell` but it doesn't seem worth the churn.
11361133 let mut shortcut_links = vec ! [ ] ;
11371134
1138- let span_for_link = |link : & str , span : Range < usize > | {
1139- // Pulldown includes the `[]` as well as the URL. Only highlight the relevant span.
1140- // NOTE: uses `rfind` in case the title and url are the same: `[Ok][Ok]`
1141- match md[ span. clone ( ) ] . rfind ( link) {
1142- Some ( start) => {
1143- let start = span. start + start;
1144- start..start + link. len ( )
1135+ {
1136+ let locate = |s : & str | unsafe {
1137+ let s_start = s. as_ptr ( ) ;
1138+ let s_end = s_start. add ( s. len ( ) ) ;
1139+ let md_start = md. as_ptr ( ) ;
1140+ let md_end = md_start. add ( md. len ( ) ) ;
1141+ if md_start <= s_start && s_end <= md_end {
1142+ let start = s_start. offset_from ( md_start) as usize ;
1143+ let end = s_end. offset_from ( md_start) as usize ;
1144+ Some ( start..end)
1145+ } else {
1146+ None
1147+ }
1148+ } ;
1149+
1150+ let mut push = |link : BrokenLink < ' _ > | {
1151+ // FIXME: use `link.span` instead of `locate`
1152+ // (doing it now includes the `[]` as well as the text)
1153+ shortcut_links. push ( ( link. reference . to_owned ( ) , locate ( link. reference ) ) ) ;
1154+ None
1155+ } ;
1156+ let p = Parser :: new_with_broken_link_callback ( md, opts ( ) , Some ( & mut push) ) ;
1157+
1158+ // There's no need to thread an IdMap through to here because
1159+ // the IDs generated aren't going to be emitted anywhere.
1160+ let mut ids = IdMap :: new ( ) ;
1161+ let iter = Footnotes :: new ( HeadingLinks :: new ( p, None , & mut ids) ) ;
1162+
1163+ for ev in iter {
1164+ if let Event :: Start ( Tag :: Link ( _, dest, _) ) = ev {
1165+ debug ! ( "found link: {}" , dest) ;
1166+ links. push ( match dest {
1167+ CowStr :: Borrowed ( s) => ( s. to_owned ( ) , locate ( s) ) ,
1168+ s @ ( CowStr :: Boxed ( ..) | CowStr :: Inlined ( ..) ) => ( s. into_string ( ) , None ) ,
1169+ } ) ;
11451170 }
1146- // This can happen for things other than intra-doc links, like `#1` expanded to `https://github.com/rust-lang/rust/issues/1`.
1147- None => span,
1148- }
1149- } ;
1150- let mut push = |link : BrokenLink < ' _ > | {
1151- let span = span_for_link ( link. reference , link. span ) ;
1152- shortcut_links. push ( ( link. reference . to_owned ( ) , span) ) ;
1153- None
1154- } ;
1155- let p = Parser :: new_with_broken_link_callback ( md, opts ( ) , Some ( & mut push) ) ;
1156-
1157- // There's no need to thread an IdMap through to here because
1158- // the IDs generated aren't going to be emitted anywhere.
1159- let mut ids = IdMap :: new ( ) ;
1160- let iter = Footnotes :: new ( HeadingLinks :: new ( p. into_offset_iter ( ) , None , & mut ids) ) ;
1161-
1162- for ev in iter {
1163- if let Event :: Start ( Tag :: Link ( _, dest, _) ) = ev. 0 {
1164- debug ! ( "found link: {}" , dest) ;
1165- let span = span_for_link ( & dest, ev. 1 ) ;
1166- links. push ( ( dest. into_string ( ) , span) ) ;
11671171 }
11681172 }
11691173
0 commit comments