@@ -344,35 +344,48 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
344344}
345345
346346/// Make headings links with anchor IDs and build up TOC.
347- struct LinkReplacer < ' a , I : Iterator < Item = Event < ' a > > > {
348- inner : I ,
347+ struct LinkReplacerInner < ' a > {
349348 links : & ' a [ RenderedLink ] ,
350349 shortcut_link : Option < & ' a RenderedLink > ,
351350}
352351
352+ struct LinkReplacer < ' a , I : Iterator < Item = Event < ' a > > > {
353+ iter : I ,
354+ inner : LinkReplacerInner < ' a > ,
355+ }
356+
353357impl < ' a , I : Iterator < Item = Event < ' a > > > LinkReplacer < ' a , I > {
354358 fn new ( iter : I , links : & ' a [ RenderedLink ] ) -> Self {
355- LinkReplacer { inner : iter , links, shortcut_link : None }
359+ LinkReplacer { iter , inner : { LinkReplacerInner { links, shortcut_link : None } } }
356360 }
357361}
358362
359- impl < ' a , I : Iterator < Item = Event < ' a > > > Iterator for LinkReplacer < ' a , I > {
360- type Item = Event < ' a > ;
363+ // FIXME: Once we have specialized trait impl (for `Iterator` impl on `LinkReplacer`),
364+ // we can remove this type and move back `LinkReplacerInner` fields into `LinkReplacer`.
365+ struct SpannedLinkReplacer < ' a , I : Iterator < Item = SpannedEvent < ' a > > > {
366+ iter : I ,
367+ inner : LinkReplacerInner < ' a > ,
368+ }
361369
362- fn next ( & mut self ) -> Option < Self :: Item > {
363- let mut event = self . inner . next ( ) ;
370+ impl < ' a , I : Iterator < Item = SpannedEvent < ' a > > > SpannedLinkReplacer < ' a , I > {
371+ fn new ( iter : I , links : & ' a [ RenderedLink ] ) -> Self {
372+ SpannedLinkReplacer { iter, inner : { LinkReplacerInner { links, shortcut_link : None } } }
373+ }
374+ }
364375
376+ impl < ' a > LinkReplacerInner < ' a > {
377+ fn handle_event ( & mut self , event : & mut Event < ' a > ) {
365378 // Replace intra-doc links and remove disambiguators from shortcut links (`[fn@f]`).
366- match & mut event {
379+ match event {
367380 // This is a shortcut link that was resolved by the broken_link_callback: `[fn@f]`
368381 // Remove any disambiguator.
369- Some ( Event :: Start ( Tag :: Link {
382+ Event :: Start ( Tag :: Link {
370383 // [fn@f] or [fn@f][]
371384 link_type : LinkType :: ShortcutUnknown | LinkType :: CollapsedUnknown ,
372385 dest_url,
373386 title,
374387 ..
375- } ) ) => {
388+ } ) => {
376389 debug ! ( "saw start of shortcut link to {dest_url} with title {title}" ) ;
377390 // If this is a shortcut link, it was resolved by the broken_link_callback.
378391 // So the URL will already be updated properly.
@@ -389,13 +402,13 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
389402 }
390403 }
391404 // Now that we're done with the shortcut link, don't replace any more text.
392- Some ( Event :: End ( TagEnd :: Link ) ) if self . shortcut_link . is_some ( ) => {
405+ Event :: End ( TagEnd :: Link ) if self . shortcut_link . is_some ( ) => {
393406 debug ! ( "saw end of shortcut link" ) ;
394407 self . shortcut_link = None ;
395408 }
396409 // Handle backticks in inline code blocks, but only if we're in the middle of a shortcut link.
397410 // [`fn@f`]
398- Some ( Event :: Code ( text) ) => {
411+ Event :: Code ( text) => {
399412 trace ! ( "saw code {text}" ) ;
400413 if let Some ( link) = self . shortcut_link {
401414 // NOTE: this only replaces if the code block is the *entire* text.
@@ -418,7 +431,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
418431 }
419432 // Replace plain text in links, but only in the middle of a shortcut link.
420433 // [fn@f]
421- Some ( Event :: Text ( text) ) => {
434+ Event :: Text ( text) => {
422435 trace ! ( "saw text {text}" ) ;
423436 if let Some ( link) = self . shortcut_link {
424437 // NOTE: same limitations as `Event::Code`
@@ -434,7 +447,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
434447 }
435448 // If this is a link, but not a shortcut link,
436449 // replace the URL, since the broken_link_callback was not called.
437- Some ( Event :: Start ( Tag :: Link { dest_url, title, .. } ) ) => {
450+ Event :: Start ( Tag :: Link { dest_url, title, .. } ) => {
438451 if let Some ( link) =
439452 self . links . iter ( ) . find ( |& link| * link. original_text == * * dest_url)
440453 {
@@ -447,12 +460,33 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
447460 // Anything else couldn't have been a valid Rust path, so no need to replace the text.
448461 _ => { }
449462 }
463+ }
464+ }
465+
466+ impl < ' a , I : Iterator < Item = Event < ' a > > > Iterator for LinkReplacer < ' a , I > {
467+ type Item = Event < ' a > ;
450468
469+ fn next ( & mut self ) -> Option < Self :: Item > {
470+ let mut event = self . iter . next ( ) ;
471+ if let Some ( ref mut event) = event {
472+ self . inner . handle_event ( event) ;
473+ }
451474 // Yield the modified event
452475 event
453476 }
454477}
455478
479+ impl < ' a , I : Iterator < Item = SpannedEvent < ' a > > > Iterator for SpannedLinkReplacer < ' a , I > {
480+ type Item = SpannedEvent < ' a > ;
481+
482+ fn next ( & mut self ) -> Option < Self :: Item > {
483+ let Some ( ( mut event, range) ) = self . iter . next ( ) else { return None } ;
484+ self . inner . handle_event ( & mut event) ;
485+ // Yield the modified event
486+ Some ( ( event, range) )
487+ }
488+ }
489+
456490/// Wrap HTML tables into `<div>` to prevent having the doc blocks width being too big.
457491struct TableWrapper < ' a , I : Iterator < Item = Event < ' a > > > {
458492 inner : I ,
@@ -1339,9 +1373,9 @@ impl<'a> Markdown<'a> {
13391373
13401374 ids. handle_footnotes ( |ids, existing_footnotes| {
13411375 let p = HeadingLinks :: new ( p, None , ids, heading_offset) ;
1376+ let p = SpannedLinkReplacer :: new ( p, links) ;
13421377 let p = footnotes:: Footnotes :: new ( p, existing_footnotes) ;
1343- let p = LinkReplacer :: new ( p. map ( |( ev, _) | ev) , links) ;
1344- let p = TableWrapper :: new ( p) ;
1378+ let p = TableWrapper :: new ( p. map ( |( ev, _) | ev) ) ;
13451379 CodeBlocks :: new ( p, codes, edition, playground)
13461380 } )
13471381 }
0 commit comments