@@ -50,7 +50,7 @@ use crate::html::format::Buffer;
5050use crate :: html:: highlight;
5151use crate :: html:: length_limit:: HtmlWithLimit ;
5252use crate :: html:: render:: small_url_encode;
53- use crate :: html:: toc:: TocBuilder ;
53+ use crate :: html:: toc:: { Toc , TocBuilder } ;
5454
5555use pulldown_cmark:: {
5656 html, BrokenLink , CodeBlockKind , CowStr , Event , LinkType , OffsetIter , Options , Parser , Tag ,
@@ -102,6 +102,7 @@ pub struct Markdown<'a> {
102102/// A struct like `Markdown` that renders the markdown with a table of contents.
103103pub ( crate ) struct MarkdownWithToc < ' a > {
104104 pub ( crate ) content : & ' a str ,
105+ pub ( crate ) links : & ' a [ RenderedLink ] ,
105106 pub ( crate ) ids : & ' a mut IdMap ,
106107 pub ( crate ) error_codes : ErrorCodes ,
107108 pub ( crate ) edition : Edition ,
@@ -540,9 +541,9 @@ impl<'a, 'b, 'ids, I: Iterator<Item = SpannedEvent<'a>>> Iterator
540541 let id = self . id_map . derive ( id) ;
541542
542543 if let Some ( ref mut builder) = self . toc {
543- let mut html_header = String :: new ( ) ;
544- html :: push_html ( & mut html_header , self . buf . iter ( ) . map ( |( ev, _) | ev. clone ( ) ) ) ;
545- let sec = builder. push ( level as u32 , html_header , id. clone ( ) ) ;
544+ let mut text_header = String :: new ( ) ;
545+ plain_text_from_events ( self . buf . iter ( ) . map ( |( ev, _) | ev. clone ( ) ) , & mut text_header ) ;
546+ let sec = builder. push ( level as u32 , text_header , id. clone ( ) ) ;
546547 self . buf . push_front ( ( Event :: Html ( format ! ( "{sec} " ) . into ( ) ) , 0 ..0 ) ) ;
547548 }
548549
@@ -1435,17 +1436,30 @@ impl Markdown<'_> {
14351436}
14361437
14371438impl MarkdownWithToc < ' _ > {
1438- pub ( crate ) fn into_string ( self ) -> String {
1439+ pub ( crate ) fn into_parts ( self ) -> ( Toc , String ) {
14391440 let MarkdownWithToc {
14401441 content : md,
1442+ links,
14411443 ids,
14421444 error_codes : codes,
14431445 edition,
14441446 playground,
14451447 custom_code_classes_in_docs,
14461448 } = self ;
14471449
1448- let p = Parser :: new_ext ( md, main_body_opts ( ) ) . into_offset_iter ( ) ;
1450+ // This is actually common enough to special-case
1451+ if md. is_empty ( ) {
1452+ return ( Toc { entries : Vec :: new ( ) } , String :: new ( ) ) ;
1453+ }
1454+ let mut replacer = |broken_link : BrokenLink < ' _ > | {
1455+ links
1456+ . iter ( )
1457+ . find ( |link| & * link. original_text == & * broken_link. reference )
1458+ . map ( |link| ( link. href . as_str ( ) . into ( ) , link. tooltip . as_str ( ) . into ( ) ) )
1459+ } ;
1460+
1461+ let p = Parser :: new_with_broken_link_callback ( md, main_body_opts ( ) , Some ( & mut replacer) ) ;
1462+ let p = p. into_offset_iter ( ) ;
14491463
14501464 let mut s = String :: with_capacity ( md. len ( ) * 3 / 2 ) ;
14511465
@@ -1459,7 +1473,11 @@ impl MarkdownWithToc<'_> {
14591473 html:: push_html ( & mut s, p) ;
14601474 }
14611475
1462- format ! ( "<nav id=\" TOC\" >{toc}</nav>{s}" , toc = toc. into_toc( ) . print( ) )
1476+ ( toc. into_toc ( ) , s)
1477+ }
1478+ pub ( crate ) fn into_string ( self ) -> String {
1479+ let ( toc, s) = self . into_parts ( ) ;
1480+ format ! ( "<nav id=\" TOC\" >{toc}</nav>{s}" , toc = toc. print( ) )
14631481 }
14641482}
14651483
@@ -1638,7 +1656,13 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
16381656
16391657 let p = Parser :: new_with_broken_link_callback ( md, summary_opts ( ) , Some ( & mut replacer) ) ;
16401658
1641- for event in p {
1659+ plain_text_from_events ( p, & mut s) ;
1660+
1661+ s
1662+ }
1663+
1664+ pub ( crate ) fn plain_text_from_events < ' a > ( events : impl Iterator < Item =pulldown_cmark:: Event < ' a > > , s : & mut String ) {
1665+ for event in events {
16421666 match & event {
16431667 Event :: Text ( text) => s. push_str ( text) ,
16441668 Event :: Code ( code) => {
@@ -1653,8 +1677,6 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
16531677 _ => ( ) ,
16541678 }
16551679 }
1656-
1657- s
16581680}
16591681
16601682#[ derive( Debug ) ]
0 commit comments