@@ -54,7 +54,8 @@ use crate::html::render::small_url_encode;
54
54
use crate :: html:: toc:: TocBuilder ;
55
55
56
56
use pulldown_cmark:: {
57
- html, BrokenLink , CodeBlockKind , CowStr , Event , LinkType , OffsetIter , Options , Parser , Tag ,
57
+ html, BrokenLink , BrokenLinkCallback , CodeBlockKind , CowStr , Event , LinkType , OffsetIter ,
58
+ Options , Parser , Tag , TagEnd ,
58
59
} ;
59
60
60
61
#[ cfg( test) ]
@@ -242,7 +243,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
242
243
let mut original_text = String :: new ( ) ;
243
244
for event in & mut self . inner {
244
245
match event {
245
- Event :: End ( Tag :: CodeBlock ( .. ) ) => break ,
246
+ Event :: End ( TagEnd :: CodeBlock ) => break ,
246
247
Event :: Text ( ref s) => {
247
248
original_text. push_str ( s) ;
248
249
}
@@ -368,20 +369,20 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
368
369
match & mut event {
369
370
// This is a shortcut link that was resolved by the broken_link_callback: `[fn@f]`
370
371
// Remove any disambiguator.
371
- Some ( Event :: Start ( Tag :: Link (
372
+ Some ( Event :: Start ( Tag :: Link {
372
373
// [fn@f] or [fn@f][]
373
- LinkType :: ShortcutUnknown | LinkType :: CollapsedUnknown ,
374
- dest ,
374
+ link_type : LinkType :: ShortcutUnknown | LinkType :: CollapsedUnknown ,
375
+ dest_url ,
375
376
title,
376
- ) ) ) => {
377
- debug ! ( "saw start of shortcut link to {dest} with title {title}" ) ;
377
+ ..
378
+ } ) ) => {
379
+ debug ! ( "saw start of shortcut link to {dest_url} with title {title}" ) ;
378
380
// If this is a shortcut link, it was resolved by the broken_link_callback.
379
381
// So the URL will already be updated properly.
380
- let link = self . links . iter ( ) . find ( |& link| * link. href == * * dest ) ;
382
+ let link = self . links . iter ( ) . find ( |& link| * link. href == * * dest_url ) ;
381
383
// Since this is an external iterator, we can't replace the inner text just yet.
382
384
// Store that we saw a link so we know to replace it later.
383
385
if let Some ( link) = link {
384
- trace ! ( "it matched" ) ;
385
386
assert ! ( self . shortcut_link. is_none( ) , "shortcut links cannot be nested" ) ;
386
387
self . shortcut_link = Some ( link) ;
387
388
if title. is_empty ( ) && !link. tooltip . is_empty ( ) {
@@ -390,21 +391,14 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
390
391
}
391
392
}
392
393
// Now that we're done with the shortcut link, don't replace any more text.
393
- Some ( Event :: End ( Tag :: Link (
394
- LinkType :: ShortcutUnknown | LinkType :: CollapsedUnknown ,
395
- dest,
396
- _,
397
- ) ) ) => {
398
- debug ! ( "saw end of shortcut link to {dest}" ) ;
399
- if self . links . iter ( ) . any ( |link| * link. href == * * dest) {
400
- assert ! ( self . shortcut_link. is_some( ) , "saw closing link without opening tag" ) ;
401
- self . shortcut_link = None ;
394
+ Some ( Event :: End ( TagEnd :: Link ) ) => {
395
+ if let Some ( link) = self . shortcut_link . take ( ) {
396
+ debug ! ( "saw end of shortcut link to {}" , link. href) ;
402
397
}
403
398
}
404
399
// Handle backticks in inline code blocks, but only if we're in the middle of a shortcut link.
405
400
// [`fn@f`]
406
401
Some ( Event :: Code ( text) ) => {
407
- trace ! ( "saw code {text}" ) ;
408
402
if let Some ( link) = self . shortcut_link {
409
403
// NOTE: this only replaces if the code block is the *entire* text.
410
404
// If only part of the link has code highlighting, the disambiguator will not be removed.
@@ -427,7 +421,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
427
421
// Replace plain text in links, but only in the middle of a shortcut link.
428
422
// [fn@f]
429
423
Some ( Event :: Text ( text) ) => {
430
- trace ! ( "saw text {text}" ) ;
431
424
if let Some ( link) = self . shortcut_link {
432
425
// NOTE: same limitations as `Event::Code`
433
426
if let Some ( link) = self
@@ -442,7 +435,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
442
435
}
443
436
// If this is a link, but not a shortcut link,
444
437
// replace the URL, since the broken_link_callback was not called.
445
- Some ( Event :: Start ( Tag :: Link ( _ , dest, title) ) ) => {
438
+ Some ( Event :: Start ( Tag :: Link { dest_url : dest, title, .. } ) ) => {
446
439
if let Some ( link) = self . links . iter ( ) . find ( |& link| * link. original_text == * * dest) {
447
440
* dest = CowStr :: Borrowed ( link. href . as_ref ( ) ) ;
448
441
if title. is_empty ( ) && !link. tooltip . is_empty ( ) {
@@ -486,9 +479,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for TableWrapper<'a, I> {
486
479
self . stored_events . push_back ( Event :: Start ( Tag :: Table ( t) ) ) ;
487
480
Event :: Html ( CowStr :: Borrowed ( "<div>" ) )
488
481
}
489
- Event :: End ( Tag :: Table ( t ) ) => {
482
+ Event :: End ( TagEnd :: Table ) => {
490
483
self . stored_events . push_back ( Event :: Html ( CowStr :: Borrowed ( "</div>" ) ) ) ;
491
- Event :: End ( Tag :: Table ( t ) )
484
+ Event :: End ( TagEnd :: Table )
492
485
}
493
486
e => e,
494
487
} )
@@ -528,11 +521,11 @@ impl<'a, 'b, 'ids, I: Iterator<Item = SpannedEvent<'a>>> Iterator
528
521
}
529
522
530
523
let event = self . inner . next ( ) ;
531
- if let Some ( ( Event :: Start ( Tag :: Heading ( level, _ , _ ) ) , _) ) = event {
524
+ if let Some ( ( Event :: Start ( Tag :: Heading { level, .. } ) , _) ) = event {
532
525
let mut id = String :: new ( ) ;
533
526
for event in & mut self . inner {
534
527
match & event. 0 {
535
- Event :: End ( Tag :: Heading ( ..) ) => break ,
528
+ Event :: End ( TagEnd :: Heading ( ..) ) => break ,
536
529
Event :: Text ( text) | Event :: Code ( text) => {
537
530
id. extend ( text. chars ( ) . filter_map ( slugify) ) ;
538
531
self . buf . push_back ( event) ;
@@ -575,27 +568,27 @@ impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> {
575
568
}
576
569
}
577
570
578
- fn check_if_allowed_tag ( t : & Tag < ' _ > ) -> bool {
571
+ fn check_if_allowed_tag ( t : TagEnd ) -> bool {
579
572
matches ! (
580
573
t,
581
- Tag :: Paragraph
582
- | Tag :: Emphasis
583
- | Tag :: Strong
584
- | Tag :: Strikethrough
585
- | Tag :: Link ( .. )
586
- | Tag :: BlockQuote
574
+ TagEnd :: Paragraph
575
+ | TagEnd :: Emphasis
576
+ | TagEnd :: Strong
577
+ | TagEnd :: Strikethrough
578
+ | TagEnd :: Link
579
+ | TagEnd :: BlockQuote
587
580
)
588
581
}
589
582
590
- fn is_forbidden_tag ( t : & Tag < ' _ > ) -> bool {
583
+ fn is_forbidden_tag ( t : TagEnd ) -> bool {
591
584
matches ! (
592
585
t,
593
- Tag :: CodeBlock ( _ )
594
- | Tag :: Table ( _ )
595
- | Tag :: TableHead
596
- | Tag :: TableRow
597
- | Tag :: TableCell
598
- | Tag :: FootnoteDefinition ( _ )
586
+ TagEnd :: CodeBlock
587
+ | TagEnd :: Table
588
+ | TagEnd :: TableHead
589
+ | TagEnd :: TableRow
590
+ | TagEnd :: TableCell
591
+ | TagEnd :: FootnoteDefinition
599
592
)
600
593
}
601
594
@@ -613,14 +606,15 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
613
606
let mut is_start = true ;
614
607
let is_allowed_tag = match event {
615
608
Event :: Start ( ref c) => {
616
- if is_forbidden_tag ( c) {
609
+ let end_tag = c. to_end ( ) ;
610
+ if is_forbidden_tag ( end_tag) {
617
611
self . skipped_tags += 1 ;
618
612
return None ;
619
613
}
620
614
self . depth += 1 ;
621
- check_if_allowed_tag ( c )
615
+ check_if_allowed_tag ( end_tag )
622
616
}
623
- Event :: End ( ref c) => {
617
+ Event :: End ( c) => {
624
618
if is_forbidden_tag ( c) {
625
619
self . skipped_tags += 1 ;
626
620
return None ;
@@ -642,7 +636,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
642
636
if is_start {
643
637
Some ( Event :: Start ( Tag :: Paragraph ) )
644
638
} else {
645
- Some ( Event :: End ( Tag :: Paragraph ) )
639
+ Some ( Event :: End ( TagEnd :: Paragraph ) )
646
640
}
647
641
} else {
648
642
Some ( event)
@@ -688,7 +682,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
688
682
Some ( ( Event :: Start ( Tag :: FootnoteDefinition ( def) ) , _) ) => {
689
683
let mut content = Vec :: new ( ) ;
690
684
for ( event, _) in & mut self . inner {
691
- if let Event :: End ( Tag :: FootnoteDefinition ( .. ) ) = event {
685
+ if let Event :: End ( TagEnd :: FootnoteDefinition ) = event {
692
686
break ;
693
687
}
694
688
content. push ( event) ;
@@ -705,7 +699,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
705
699
for ( mut content, id) in v {
706
700
write ! ( ret, "<li id=\" fn{id}\" >" ) . unwrap ( ) ;
707
701
let mut is_paragraph = false ;
708
- if let Some ( & Event :: End ( Tag :: Paragraph ) ) = content. last ( ) {
702
+ if let Some ( & Event :: End ( TagEnd :: Paragraph ) ) = content. last ( ) {
709
703
content. pop ( ) ;
710
704
is_paragraph = true ;
711
705
}
@@ -804,7 +798,7 @@ pub(crate) fn find_codes<T: doctest::Tester>(
804
798
tests. add_test ( text, block_info, line) ;
805
799
prev_offset = offset. start ;
806
800
}
807
- Event :: Start ( Tag :: Heading ( level, _ , _ ) ) => {
801
+ Event :: Start ( Tag :: Heading { level, .. } ) => {
808
802
register_header = Some ( level as u32 ) ;
809
803
}
810
804
Event :: Text ( ref s) if register_header. is_some ( ) => {
@@ -1488,7 +1482,7 @@ impl MarkdownItemInfo<'_> {
1488
1482
let p = Footnotes :: new ( p) ;
1489
1483
let p = TableWrapper :: new ( p. map ( |( ev, _) | ev) ) ;
1490
1484
let p = p. filter ( |event| {
1491
- !matches ! ( event, Event :: Start ( Tag :: Paragraph ) | Event :: End ( Tag :: Paragraph ) )
1485
+ !matches ! ( event, Event :: Start ( Tag :: Paragraph ) | Event :: End ( TagEnd :: Paragraph ) )
1492
1486
} ) ;
1493
1487
html:: push_html ( & mut s, p) ;
1494
1488
@@ -1518,7 +1512,7 @@ impl MarkdownSummaryLine<'_> {
1518
1512
let mut s = String :: new ( ) ;
1519
1513
1520
1514
let without_paragraphs = LinkReplacer :: new ( & mut summary, links) . filter ( |event| {
1521
- !matches ! ( event, Event :: Start ( Tag :: Paragraph ) | Event :: End ( Tag :: Paragraph ) )
1515
+ !matches ! ( event, Event :: Start ( Tag :: Paragraph ) | Event :: End ( TagEnd :: Paragraph ) )
1522
1516
} ) ;
1523
1517
1524
1518
html:: push_html ( & mut s, without_paragraphs) ;
@@ -1590,8 +1584,8 @@ fn markdown_summary_with_limit(
1590
1584
_ => { }
1591
1585
} ,
1592
1586
Event :: End ( tag) => match tag {
1593
- Tag :: Emphasis | Tag :: Strong => buf. close_tag ( ) ,
1594
- Tag :: Paragraph | Tag :: Heading ( ..) => return ControlFlow :: Break ( ( ) ) ,
1587
+ TagEnd :: Emphasis | TagEnd :: Strong => buf. close_tag ( ) ,
1588
+ TagEnd :: Paragraph | TagEnd :: Heading ( ..) => return ControlFlow :: Break ( ( ) ) ,
1595
1589
_ => { }
1596
1590
} ,
1597
1591
Event :: HardBreak | Event :: SoftBreak => buf. push ( " " ) ?,
@@ -1651,8 +1645,8 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
1651
1645
}
1652
1646
Event :: HardBreak | Event :: SoftBreak => s. push ( ' ' ) ,
1653
1647
Event :: Start ( Tag :: CodeBlock ( ..) ) => break ,
1654
- Event :: End ( Tag :: Paragraph ) => break ,
1655
- Event :: End ( Tag :: Heading ( ..) ) => break ,
1648
+ Event :: End ( TagEnd :: Paragraph ) => break ,
1649
+ Event :: End ( TagEnd :: Heading ( ..) ) => break ,
1656
1650
_ => ( ) ,
1657
1651
}
1658
1652
}
@@ -1811,7 +1805,7 @@ pub(crate) fn markdown_links<'md, R>(
1811
1805
1812
1806
while let Some ( ( event, span) ) = event_iter. next ( ) {
1813
1807
match event {
1814
- Event :: Start ( Tag :: Link ( link_type, dest , _ ) ) if may_be_doc_link ( link_type) => {
1808
+ Event :: Start ( Tag :: Link { link_type, dest_url , .. } ) if may_be_doc_link ( link_type) => {
1815
1809
let range = match link_type {
1816
1810
// Link is pulled from the link itself.
1817
1811
LinkType :: ReferenceUnknown | LinkType :: ShortcutUnknown => {
@@ -1821,7 +1815,7 @@ pub(crate) fn markdown_links<'md, R>(
1821
1815
LinkType :: Inline => span_for_offset_backward ( span, b'(' , b')' ) ,
1822
1816
// Link is pulled from elsewhere in the document.
1823
1817
LinkType :: Reference | LinkType :: Collapsed | LinkType :: Shortcut => {
1824
- span_for_link ( & dest , span)
1818
+ span_for_link ( & dest_url , span)
1825
1819
}
1826
1820
LinkType :: Autolink | LinkType :: Email => unreachable ! ( ) ,
1827
1821
} ;
@@ -1841,7 +1835,7 @@ pub(crate) fn markdown_links<'md, R>(
1841
1835
1842
1836
if let Some ( link) = preprocess_link ( MarkdownLink {
1843
1837
kind : link_type,
1844
- link : dest . into_string ( ) ,
1838
+ link : dest_url . into_string ( ) ,
1845
1839
display_text,
1846
1840
range,
1847
1841
} ) {
@@ -1856,9 +1850,10 @@ pub(crate) fn markdown_links<'md, R>(
1856
1850
}
1857
1851
1858
1852
/// Collects additional data of link.
1859
- fn collect_link_data < ' input , ' callback > (
1860
- event_iter : & mut OffsetIter < ' input , ' callback > ,
1861
- ) -> Option < String > {
1853
+ fn collect_link_data < ' input , F > ( event_iter : & mut OffsetIter < ' input , F > ) -> Option < String >
1854
+ where
1855
+ F : BrokenLinkCallback < ' input > ,
1856
+ {
1862
1857
let mut display_text: Option < String > = None ;
1863
1858
let mut append_text = |text : CowStr < ' _ > | {
1864
1859
if let Some ( display_text) = & mut display_text {
0 commit comments