@@ -344,35 +344,48 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
344
344
}
345
345
346
346
/// 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 > {
349
348
links : & ' a [ RenderedLink ] ,
350
349
shortcut_link : Option < & ' a RenderedLink > ,
351
350
}
352
351
352
+ struct LinkReplacer < ' a , I : Iterator < Item = Event < ' a > > > {
353
+ iter : I ,
354
+ inner : LinkReplacerInner < ' a > ,
355
+ }
356
+
353
357
impl < ' a , I : Iterator < Item = Event < ' a > > > LinkReplacer < ' a , I > {
354
358
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 } } }
356
360
}
357
361
}
358
362
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
+ }
361
369
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
+ }
364
375
376
+ impl < ' a > LinkReplacerInner < ' a > {
377
+ fn handle_event ( & mut self , event : & mut Event < ' a > ) {
365
378
// Replace intra-doc links and remove disambiguators from shortcut links (`[fn@f]`).
366
- match & mut event {
379
+ match event {
367
380
// This is a shortcut link that was resolved by the broken_link_callback: `[fn@f]`
368
381
// Remove any disambiguator.
369
- Some ( Event :: Start ( Tag :: Link {
382
+ Event :: Start ( Tag :: Link {
370
383
// [fn@f] or [fn@f][]
371
384
link_type : LinkType :: ShortcutUnknown | LinkType :: CollapsedUnknown ,
372
385
dest_url,
373
386
title,
374
387
..
375
- } ) ) => {
388
+ } ) => {
376
389
debug ! ( "saw start of shortcut link to {dest_url} with title {title}" ) ;
377
390
// If this is a shortcut link, it was resolved by the broken_link_callback.
378
391
// So the URL will already be updated properly.
@@ -389,13 +402,13 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
389
402
}
390
403
}
391
404
// 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 ( ) => {
393
406
debug ! ( "saw end of shortcut link" ) ;
394
407
self . shortcut_link = None ;
395
408
}
396
409
// Handle backticks in inline code blocks, but only if we're in the middle of a shortcut link.
397
410
// [`fn@f`]
398
- Some ( Event :: Code ( text) ) => {
411
+ Event :: Code ( text) => {
399
412
trace ! ( "saw code {text}" ) ;
400
413
if let Some ( link) = self . shortcut_link {
401
414
// 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> {
418
431
}
419
432
// Replace plain text in links, but only in the middle of a shortcut link.
420
433
// [fn@f]
421
- Some ( Event :: Text ( text) ) => {
434
+ Event :: Text ( text) => {
422
435
trace ! ( "saw text {text}" ) ;
423
436
if let Some ( link) = self . shortcut_link {
424
437
// NOTE: same limitations as `Event::Code`
@@ -434,7 +447,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
434
447
}
435
448
// If this is a link, but not a shortcut link,
436
449
// 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, .. } ) => {
438
451
if let Some ( link) =
439
452
self . links . iter ( ) . find ( |& link| * link. original_text == * * dest_url)
440
453
{
@@ -447,12 +460,33 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
447
460
// Anything else couldn't have been a valid Rust path, so no need to replace the text.
448
461
_ => { }
449
462
}
463
+ }
464
+ }
465
+
466
+ impl < ' a , I : Iterator < Item = Event < ' a > > > Iterator for LinkReplacer < ' a , I > {
467
+ type Item = Event < ' a > ;
450
468
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
+ }
451
474
// Yield the modified event
452
475
event
453
476
}
454
477
}
455
478
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
+
456
490
/// Wrap HTML tables into `<div>` to prevent having the doc blocks width being too big.
457
491
struct TableWrapper < ' a , I : Iterator < Item = Event < ' a > > > {
458
492
inner : I ,
@@ -1339,9 +1373,9 @@ impl<'a> Markdown<'a> {
1339
1373
1340
1374
ids. handle_footnotes ( |ids, existing_footnotes| {
1341
1375
let p = HeadingLinks :: new ( p, None , ids, heading_offset) ;
1376
+ let p = SpannedLinkReplacer :: new ( p, links) ;
1342
1377
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) ) ;
1345
1379
CodeBlocks :: new ( p, codes, edition, playground)
1346
1380
} )
1347
1381
}
0 commit comments