@@ -54,7 +54,8 @@ use crate::html::render::small_url_encode;
5454use crate :: html:: toc:: TocBuilder ;
5555
5656use 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 ,
5859} ;
5960
6061#[ cfg( test) ]
@@ -242,7 +243,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
242243 let mut original_text = String :: new ( ) ;
243244 for event in & mut self . inner {
244245 match event {
245- Event :: End ( Tag :: CodeBlock ( .. ) ) => break ,
246+ Event :: End ( TagEnd :: CodeBlock ) => break ,
246247 Event :: Text ( ref s) => {
247248 original_text. push_str ( s) ;
248249 }
@@ -368,20 +369,20 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
368369 match & mut event {
369370 // This is a shortcut link that was resolved by the broken_link_callback: `[fn@f]`
370371 // Remove any disambiguator.
371- Some ( Event :: Start ( Tag :: Link (
372+ Some ( Event :: Start ( Tag :: Link {
372373 // [fn@f] or [fn@f][]
373- LinkType :: ShortcutUnknown | LinkType :: CollapsedUnknown ,
374- dest ,
374+ link_type : LinkType :: ShortcutUnknown | LinkType :: CollapsedUnknown ,
375+ dest_url ,
375376 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}" ) ;
378380 // If this is a shortcut link, it was resolved by the broken_link_callback.
379381 // 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 ) ;
381383 // Since this is an external iterator, we can't replace the inner text just yet.
382384 // Store that we saw a link so we know to replace it later.
383385 if let Some ( link) = link {
384- trace ! ( "it matched" ) ;
385386 assert ! ( self . shortcut_link. is_none( ) , "shortcut links cannot be nested" ) ;
386387 self . shortcut_link = Some ( link) ;
387388 if title. is_empty ( ) && !link. tooltip . is_empty ( ) {
@@ -390,21 +391,14 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
390391 }
391392 }
392393 // 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) ;
402397 }
403398 }
404399 // Handle backticks in inline code blocks, but only if we're in the middle of a shortcut link.
405400 // [`fn@f`]
406401 Some ( Event :: Code ( text) ) => {
407- trace ! ( "saw code {text}" ) ;
408402 if let Some ( link) = self . shortcut_link {
409403 // NOTE: this only replaces if the code block is the *entire* text.
410404 // 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> {
427421 // Replace plain text in links, but only in the middle of a shortcut link.
428422 // [fn@f]
429423 Some ( Event :: Text ( text) ) => {
430- trace ! ( "saw text {text}" ) ;
431424 if let Some ( link) = self . shortcut_link {
432425 // NOTE: same limitations as `Event::Code`
433426 if let Some ( link) = self
@@ -442,7 +435,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
442435 }
443436 // If this is a link, but not a shortcut link,
444437 // 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" ) ;
446440 if let Some ( link) = self . links . iter ( ) . find ( |& link| * link. original_text == * * dest) {
447441 * dest = CowStr :: Borrowed ( link. href . as_ref ( ) ) ;
448442 if title. is_empty ( ) && !link. tooltip . is_empty ( ) {
@@ -486,9 +480,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for TableWrapper<'a, I> {
486480 self . stored_events . push_back ( Event :: Start ( Tag :: Table ( t) ) ) ;
487481 Event :: Html ( CowStr :: Borrowed ( "<div>" ) )
488482 }
489- Event :: End ( Tag :: Table ( t ) ) => {
483+ Event :: End ( TagEnd :: Table ) => {
490484 self . stored_events . push_back ( Event :: Html ( CowStr :: Borrowed ( "</div>" ) ) ) ;
491- Event :: End ( Tag :: Table ( t ) )
485+ Event :: End ( TagEnd :: Table )
492486 }
493487 e => e,
494488 } )
@@ -528,11 +522,11 @@ impl<'a, 'b, 'ids, I: Iterator<Item = SpannedEvent<'a>>> Iterator
528522 }
529523
530524 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 {
532526 let mut id = String :: new ( ) ;
533527 for event in & mut self . inner {
534528 match & event. 0 {
535- Event :: End ( Tag :: Heading ( ..) ) => break ,
529+ Event :: End ( TagEnd :: Heading ( ..) ) => break ,
536530 Event :: Text ( text) | Event :: Code ( text) => {
537531 id. extend ( text. chars ( ) . filter_map ( slugify) ) ;
538532 self . buf . push_back ( event) ;
@@ -575,27 +569,27 @@ impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> {
575569 }
576570}
577571
578- fn check_if_allowed_tag ( t : & Tag < ' _ > ) -> bool {
572+ fn check_if_allowed_tag ( t : TagEnd ) -> bool {
579573 matches ! (
580574 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
587581 )
588582}
589583
590- fn is_forbidden_tag ( t : & Tag < ' _ > ) -> bool {
584+ fn is_forbidden_tag ( t : TagEnd ) -> bool {
591585 matches ! (
592586 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
599593 )
600594}
601595
@@ -613,14 +607,15 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
613607 let mut is_start = true ;
614608 let is_allowed_tag = match event {
615609 Event :: Start ( ref c) => {
616- if is_forbidden_tag ( c) {
610+ let end_tag = c. to_end ( ) ;
611+ if is_forbidden_tag ( end_tag) {
617612 self . skipped_tags += 1 ;
618613 return None ;
619614 }
620615 self . depth += 1 ;
621- check_if_allowed_tag ( c )
616+ check_if_allowed_tag ( end_tag )
622617 }
623- Event :: End ( ref c) => {
618+ Event :: End ( c) => {
624619 if is_forbidden_tag ( c) {
625620 self . skipped_tags += 1 ;
626621 return None ;
@@ -642,7 +637,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
642637 if is_start {
643638 Some ( Event :: Start ( Tag :: Paragraph ) )
644639 } else {
645- Some ( Event :: End ( Tag :: Paragraph ) )
640+ Some ( Event :: End ( TagEnd :: Paragraph ) )
646641 }
647642 } else {
648643 Some ( event)
@@ -688,7 +683,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
688683 Some ( ( Event :: Start ( Tag :: FootnoteDefinition ( def) ) , _) ) => {
689684 let mut content = Vec :: new ( ) ;
690685 for ( event, _) in & mut self . inner {
691- if let Event :: End ( Tag :: FootnoteDefinition ( .. ) ) = event {
686+ if let Event :: End ( TagEnd :: FootnoteDefinition ) = event {
692687 break ;
693688 }
694689 content. push ( event) ;
@@ -705,7 +700,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
705700 for ( mut content, id) in v {
706701 write ! ( ret, "<li id=\" fn{id}\" >" ) . unwrap ( ) ;
707702 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 ( ) {
709704 content. pop ( ) ;
710705 is_paragraph = true ;
711706 }
@@ -804,7 +799,7 @@ pub(crate) fn find_codes<T: doctest::Tester>(
804799 tests. add_test ( text, block_info, line) ;
805800 prev_offset = offset. start ;
806801 }
807- Event :: Start ( Tag :: Heading ( level, _ , _ ) ) => {
802+ Event :: Start ( Tag :: Heading { level, .. } ) => {
808803 register_header = Some ( level as u32 ) ;
809804 }
810805 Event :: Text ( ref s) if register_header. is_some ( ) => {
@@ -1488,7 +1483,7 @@ impl MarkdownItemInfo<'_> {
14881483 let p = Footnotes :: new ( p) ;
14891484 let p = TableWrapper :: new ( p. map ( |( ev, _) | ev) ) ;
14901485 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 ) )
14921487 } ) ;
14931488 html:: push_html ( & mut s, p) ;
14941489
@@ -1518,7 +1513,7 @@ impl MarkdownSummaryLine<'_> {
15181513 let mut s = String :: new ( ) ;
15191514
15201515 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 ) )
15221517 } ) ;
15231518
15241519 html:: push_html ( & mut s, without_paragraphs) ;
@@ -1590,8 +1585,8 @@ fn markdown_summary_with_limit(
15901585 _ => { }
15911586 } ,
15921587 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 ( ( ) ) ,
15951590 _ => { }
15961591 } ,
15971592 Event :: HardBreak | Event :: SoftBreak => buf. push ( " " ) ?,
@@ -1651,8 +1646,8 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
16511646 }
16521647 Event :: HardBreak | Event :: SoftBreak => s. push ( ' ' ) ,
16531648 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 ,
16561651 _ => ( ) ,
16571652 }
16581653 }
@@ -1811,7 +1806,7 @@ pub(crate) fn markdown_links<'md, R>(
18111806
18121807 while let Some ( ( event, span) ) = event_iter. next ( ) {
18131808 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) => {
18151810 let range = match link_type {
18161811 // Link is pulled from the link itself.
18171812 LinkType :: ReferenceUnknown | LinkType :: ShortcutUnknown => {
@@ -1821,7 +1816,7 @@ pub(crate) fn markdown_links<'md, R>(
18211816 LinkType :: Inline => span_for_offset_backward ( span, b'(' , b')' ) ,
18221817 // Link is pulled from elsewhere in the document.
18231818 LinkType :: Reference | LinkType :: Collapsed | LinkType :: Shortcut => {
1824- span_for_link ( & dest , span)
1819+ span_for_link ( & dest_url , span)
18251820 }
18261821 LinkType :: Autolink | LinkType :: Email => unreachable ! ( ) ,
18271822 } ;
@@ -1841,7 +1836,7 @@ pub(crate) fn markdown_links<'md, R>(
18411836
18421837 if let Some ( link) = preprocess_link ( MarkdownLink {
18431838 kind : link_type,
1844- link : dest . into_string ( ) ,
1839+ link : dest_url . into_string ( ) ,
18451840 display_text,
18461841 range,
18471842 } ) {
@@ -1856,9 +1851,10 @@ pub(crate) fn markdown_links<'md, R>(
18561851}
18571852
18581853/// 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+ {
18621858 let mut display_text: Option < String > = None ;
18631859 let mut append_text = |text : CowStr < ' _ > | {
18641860 if let Some ( display_text) = & mut display_text {
0 commit comments