@@ -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,8 @@ 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, .. } ) ) => {
439
+ assert ! ( self . shortcut_link. is_none( ) , "links cannot be nested" ) ;
446
440
if let Some ( link) = self . links . iter ( ) . find ( |& link| * link. original_text == * * dest) {
447
441
* dest = CowStr :: Borrowed ( link. href . as_ref ( ) ) ;
448
442
if title. is_empty ( ) && !link. tooltip . is_empty ( ) {
@@ -486,9 +480,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for TableWrapper<'a, I> {
486
480
self . stored_events . push_back ( Event :: Start ( Tag :: Table ( t) ) ) ;
487
481
Event :: Html ( CowStr :: Borrowed ( "<div>" ) )
488
482
}
489
- Event :: End ( Tag :: Table ( t ) ) => {
483
+ Event :: End ( TagEnd :: Table ) => {
490
484
self . stored_events . push_back ( Event :: Html ( CowStr :: Borrowed ( "</div>" ) ) ) ;
491
- Event :: End ( Tag :: Table ( t ) )
485
+ Event :: End ( TagEnd :: Table )
492
486
}
493
487
e => e,
494
488
} )
@@ -528,11 +522,11 @@ impl<'a, 'b, 'ids, I: Iterator<Item = SpannedEvent<'a>>> Iterator
528
522
}
529
523
530
524
let event = self . inner . next ( ) ;
531
- if let Some ( ( Event :: Start ( Tag :: Heading ( level, _ , _ ) ) , _) ) = event {
525
+ if let Some ( ( Event :: Start ( Tag :: Heading { level, .. } ) , _) ) = event {
532
526
let mut id = String :: new ( ) ;
533
527
for event in & mut self . inner {
534
528
match & event. 0 {
535
- Event :: End ( Tag :: Heading ( ..) ) => break ,
529
+ Event :: End ( TagEnd :: Heading ( ..) ) => break ,
536
530
Event :: Text ( text) | Event :: Code ( text) => {
537
531
id. extend ( text. chars ( ) . filter_map ( slugify) ) ;
538
532
self . buf . push_back ( event) ;
@@ -575,27 +569,27 @@ impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> {
575
569
}
576
570
}
577
571
578
- fn check_if_allowed_tag ( t : & Tag < ' _ > ) -> bool {
572
+ fn check_if_allowed_tag ( t : TagEnd ) -> bool {
579
573
matches ! (
580
574
t,
581
- Tag :: Paragraph
582
- | Tag :: Emphasis
583
- | Tag :: Strong
584
- | Tag :: Strikethrough
585
- | Tag :: Link ( .. )
586
- | Tag :: BlockQuote
575
+ TagEnd :: Paragraph
576
+ | TagEnd :: Emphasis
577
+ | TagEnd :: Strong
578
+ | TagEnd :: Strikethrough
579
+ | TagEnd :: Link
580
+ | TagEnd :: BlockQuote
587
581
)
588
582
}
589
583
590
- fn is_forbidden_tag ( t : & Tag < ' _ > ) -> bool {
584
+ fn is_forbidden_tag ( t : TagEnd ) -> bool {
591
585
matches ! (
592
586
t,
593
- Tag :: CodeBlock ( _ )
594
- | Tag :: Table ( _ )
595
- | Tag :: TableHead
596
- | Tag :: TableRow
597
- | Tag :: TableCell
598
- | Tag :: FootnoteDefinition ( _ )
587
+ TagEnd :: CodeBlock
588
+ | TagEnd :: Table
589
+ | TagEnd :: TableHead
590
+ | TagEnd :: TableRow
591
+ | TagEnd :: TableCell
592
+ | TagEnd :: FootnoteDefinition
599
593
)
600
594
}
601
595
@@ -613,14 +607,15 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
613
607
let mut is_start = true ;
614
608
let is_allowed_tag = match event {
615
609
Event :: Start ( ref c) => {
616
- if is_forbidden_tag ( c) {
610
+ let end_tag = c. to_end ( ) ;
611
+ if is_forbidden_tag ( end_tag) {
617
612
self . skipped_tags += 1 ;
618
613
return None ;
619
614
}
620
615
self . depth += 1 ;
621
- check_if_allowed_tag ( c )
616
+ check_if_allowed_tag ( end_tag )
622
617
}
623
- Event :: End ( ref c) => {
618
+ Event :: End ( c) => {
624
619
if is_forbidden_tag ( c) {
625
620
self . skipped_tags += 1 ;
626
621
return None ;
@@ -642,7 +637,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
642
637
if is_start {
643
638
Some ( Event :: Start ( Tag :: Paragraph ) )
644
639
} else {
645
- Some ( Event :: End ( Tag :: Paragraph ) )
640
+ Some ( Event :: End ( TagEnd :: Paragraph ) )
646
641
}
647
642
} else {
648
643
Some ( event)
@@ -688,7 +683,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
688
683
Some ( ( Event :: Start ( Tag :: FootnoteDefinition ( def) ) , _) ) => {
689
684
let mut content = Vec :: new ( ) ;
690
685
for ( event, _) in & mut self . inner {
691
- if let Event :: End ( Tag :: FootnoteDefinition ( .. ) ) = event {
686
+ if let Event :: End ( TagEnd :: FootnoteDefinition ) = event {
692
687
break ;
693
688
}
694
689
content. push ( event) ;
@@ -705,7 +700,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
705
700
for ( mut content, id) in v {
706
701
write ! ( ret, "<li id=\" fn{id}\" >" ) . unwrap ( ) ;
707
702
let mut is_paragraph = false ;
708
- if let Some ( & Event :: End ( Tag :: Paragraph ) ) = content. last ( ) {
703
+ if let Some ( & Event :: End ( TagEnd :: Paragraph ) ) = content. last ( ) {
709
704
content. pop ( ) ;
710
705
is_paragraph = true ;
711
706
}
@@ -804,7 +799,7 @@ pub(crate) fn find_codes<T: doctest::Tester>(
804
799
tests. add_test ( text, block_info, line) ;
805
800
prev_offset = offset. start ;
806
801
}
807
- Event :: Start ( Tag :: Heading ( level, _ , _ ) ) => {
802
+ Event :: Start ( Tag :: Heading { level, .. } ) => {
808
803
register_header = Some ( level as u32 ) ;
809
804
}
810
805
Event :: Text ( ref s) if register_header. is_some ( ) => {
@@ -1488,7 +1483,7 @@ impl MarkdownItemInfo<'_> {
1488
1483
let p = Footnotes :: new ( p) ;
1489
1484
let p = TableWrapper :: new ( p. map ( |( ev, _) | ev) ) ;
1490
1485
let p = p. filter ( |event| {
1491
- !matches ! ( event, Event :: Start ( Tag :: Paragraph ) | Event :: End ( Tag :: Paragraph ) )
1486
+ !matches ! ( event, Event :: Start ( Tag :: Paragraph ) | Event :: End ( TagEnd :: Paragraph ) )
1492
1487
} ) ;
1493
1488
html:: push_html ( & mut s, p) ;
1494
1489
@@ -1518,7 +1513,7 @@ impl MarkdownSummaryLine<'_> {
1518
1513
let mut s = String :: new ( ) ;
1519
1514
1520
1515
let without_paragraphs = LinkReplacer :: new ( & mut summary, links) . filter ( |event| {
1521
- !matches ! ( event, Event :: Start ( Tag :: Paragraph ) | Event :: End ( Tag :: Paragraph ) )
1516
+ !matches ! ( event, Event :: Start ( Tag :: Paragraph ) | Event :: End ( TagEnd :: Paragraph ) )
1522
1517
} ) ;
1523
1518
1524
1519
html:: push_html ( & mut s, without_paragraphs) ;
@@ -1590,8 +1585,8 @@ fn markdown_summary_with_limit(
1590
1585
_ => { }
1591
1586
} ,
1592
1587
Event :: End ( tag) => match tag {
1593
- Tag :: Emphasis | Tag :: Strong => buf. close_tag ( ) ,
1594
- Tag :: Paragraph | Tag :: Heading ( ..) => return ControlFlow :: Break ( ( ) ) ,
1588
+ TagEnd :: Emphasis | TagEnd :: Strong => buf. close_tag ( ) ,
1589
+ TagEnd :: Paragraph | TagEnd :: Heading ( ..) => return ControlFlow :: Break ( ( ) ) ,
1595
1590
_ => { }
1596
1591
} ,
1597
1592
Event :: HardBreak | Event :: SoftBreak => buf. push ( " " ) ?,
@@ -1651,8 +1646,8 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
1651
1646
}
1652
1647
Event :: HardBreak | Event :: SoftBreak => s. push ( ' ' ) ,
1653
1648
Event :: Start ( Tag :: CodeBlock ( ..) ) => break ,
1654
- Event :: End ( Tag :: Paragraph ) => break ,
1655
- Event :: End ( Tag :: Heading ( ..) ) => break ,
1649
+ Event :: End ( TagEnd :: Paragraph ) => break ,
1650
+ Event :: End ( TagEnd :: Heading ( ..) ) => break ,
1656
1651
_ => ( ) ,
1657
1652
}
1658
1653
}
@@ -1811,7 +1806,7 @@ pub(crate) fn markdown_links<'md, R>(
1811
1806
1812
1807
while let Some ( ( event, span) ) = event_iter. next ( ) {
1813
1808
match event {
1814
- Event :: Start ( Tag :: Link ( link_type, dest , _ ) ) if may_be_doc_link ( link_type) => {
1809
+ Event :: Start ( Tag :: Link { link_type, dest_url , .. } ) if may_be_doc_link ( link_type) => {
1815
1810
let range = match link_type {
1816
1811
// Link is pulled from the link itself.
1817
1812
LinkType :: ReferenceUnknown | LinkType :: ShortcutUnknown => {
@@ -1821,7 +1816,7 @@ pub(crate) fn markdown_links<'md, R>(
1821
1816
LinkType :: Inline => span_for_offset_backward ( span, b'(' , b')' ) ,
1822
1817
// Link is pulled from elsewhere in the document.
1823
1818
LinkType :: Reference | LinkType :: Collapsed | LinkType :: Shortcut => {
1824
- span_for_link ( & dest , span)
1819
+ span_for_link ( & dest_url , span)
1825
1820
}
1826
1821
LinkType :: Autolink | LinkType :: Email => unreachable ! ( ) ,
1827
1822
} ;
@@ -1841,7 +1836,7 @@ pub(crate) fn markdown_links<'md, R>(
1841
1836
1842
1837
if let Some ( link) = preprocess_link ( MarkdownLink {
1843
1838
kind : link_type,
1844
- link : dest . into_string ( ) ,
1839
+ link : dest_url . into_string ( ) ,
1845
1840
display_text,
1846
1841
range,
1847
1842
} ) {
@@ -1856,9 +1851,10 @@ pub(crate) fn markdown_links<'md, R>(
1856
1851
}
1857
1852
1858
1853
/// Collects additional data of link.
1859
- fn collect_link_data < ' input , ' callback > (
1860
- event_iter : & mut OffsetIter < ' input , ' callback > ,
1861
- ) -> Option < String > {
1854
+ fn collect_link_data < ' input , F > ( event_iter : & mut OffsetIter < ' input , F > ) -> Option < String >
1855
+ where
1856
+ F : BrokenLinkCallback < ' input > ,
1857
+ {
1862
1858
let mut display_text: Option < String > = None ;
1863
1859
let mut append_text = |text : CowStr < ' _ > | {
1864
1860
if let Some ( display_text) = & mut display_text {
0 commit comments