11//! Markdown footnote handling. 
22use  std:: fmt:: Write  as  _; 
33
4- use  pulldown_cmark:: { Event ,  Tag ,  TagEnd ,  html} ; 
4+ use  pulldown_cmark:: { CowStr ,   Event ,  Tag ,  TagEnd ,  html} ; 
55use  rustc_data_structures:: fx:: FxIndexMap ; 
66
77use  super :: SpannedEvent ; 
@@ -21,7 +21,7 @@ struct FootnoteDef<'a> {
2121id :  usize , 
2222} 
2323
24- impl < ' a ,  ' b ,  I >  Footnotes < ' a ,  ' b ,  I >  { 
24+ impl < ' a ,  ' b ,  I :   Iterator < Item  =  SpannedEvent < ' a > > >  Footnotes < ' a ,  ' b ,  I >  { 
2525    pub ( super )  fn  new ( iter :  I ,  existing_footnotes :  & ' b  mut  usize )  -> Self  { 
2626        Footnotes  {  inner :  iter,  footnotes :  FxIndexMap :: default ( ) ,  existing_footnotes } 
2727    } 
@@ -34,31 +34,50 @@ impl<'a, 'b, I> Footnotes<'a, 'b, I> {
3434        // Don't allow changing the ID of existing entrys, but allow changing the contents. 
3535        ( content,  * id) 
3636    } 
37+ 
38+     fn  handle_footnote_reference ( & mut  self ,  reference :  & CowStr < ' a > )  -> Event < ' a >  { 
39+         // When we see a reference (to a footnote we may not know) the definition of, 
40+         // reserve a number for it, and emit a link to that number. 
41+         let  ( _,  id)  = self . get_entry ( reference) ; 
42+         let  reference = format ! ( 
43+             "<sup id=\" fnref{0}\" ><a href=\" #fn{0}\" >{1}</a></sup>" , 
44+             id, 
45+             // Although the ID count is for the whole page, the footnote reference 
46+             // are local to the item so we make this ID "local" when displayed. 
47+             id - * self . existing_footnotes
48+         ) ; 
49+         Event :: Html ( reference. into ( ) ) 
50+     } 
51+ 
52+     fn  collect_footnote_def ( & mut  self )  -> Vec < Event < ' a > >  { 
53+         let  mut  content = Vec :: new ( ) ; 
54+         while  let  Some ( ( event,  _) )  = self . inner . next ( )  { 
55+             match  event { 
56+                 Event :: End ( TagEnd :: FootnoteDefinition )  => break , 
57+                 Event :: FootnoteReference ( ref  reference)  => { 
58+                     content. push ( self . handle_footnote_reference ( reference) ) ; 
59+                 } 
60+                 event => content. push ( event) , 
61+             } 
62+         } 
63+         content
64+     } 
3765} 
3866
3967impl < ' a ,  ' b ,  I :  Iterator < Item  = SpannedEvent < ' a > > >  Iterator  for  Footnotes < ' a ,  ' b ,  I >  { 
4068    type  Item  = SpannedEvent < ' a > ; 
4169
4270    fn  next ( & mut  self )  -> Option < Self :: Item >  { 
4371        loop  { 
44-             match  self . inner . next ( )  { 
72+             let  next = self . inner . next ( ) ; 
73+             match  next { 
4574                Some ( ( Event :: FootnoteReference ( ref  reference) ,  range) )  => { 
46-                     // When we see a reference (to a footnote we may not know) the definition of, 
47-                     // reserve a number for it, and emit a link to that number. 
48-                     let  ( _,  id)  = self . get_entry ( reference) ; 
49-                     let  reference = format ! ( 
50-                         "<sup id=\" fnref{0}\" ><a href=\" #fn{0}\" >{1}</a></sup>" , 
51-                         id, 
52-                         // Although the ID count is for the whole page, the footnote reference 
53-                         // are local to the item so we make this ID "local" when displayed. 
54-                         id - * self . existing_footnotes
55-                     ) ; 
56-                     return  Some ( ( Event :: Html ( reference. into ( ) ) ,  range) ) ; 
75+                     return  Some ( ( self . handle_footnote_reference ( reference) ,  range) ) ; 
5776                } 
5877                Some ( ( Event :: Start ( Tag :: FootnoteDefinition ( def) ) ,  _) )  => { 
5978                    // When we see a footnote definition, collect the assocated content, and store 
6079                    // that for rendering later. 
61-                     let  content = collect_footnote_def ( & mut   self . inner ) ; 
80+                     let  content = self . collect_footnote_def ( ) ; 
6281                    let  ( entry_content,  _)  = self . get_entry ( & def) ; 
6382                    * entry_content = content; 
6483                } 
@@ -80,17 +99,6 @@ impl<'a, 'b, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, 'b
8099    } 
81100} 
82101
83- fn  collect_footnote_def < ' a > ( events :  impl  Iterator < Item  = SpannedEvent < ' a > > )  -> Vec < Event < ' a > >  { 
84-     let  mut  content = Vec :: new ( ) ; 
85-     for  ( event,  _)  in  events { 
86-         if  let  Event :: End ( TagEnd :: FootnoteDefinition )  = event { 
87-             break ; 
88-         } 
89-         content. push ( event) ; 
90-     } 
91-     content
92- } 
93- 
94102fn  render_footnotes_defs ( mut  footnotes :  Vec < FootnoteDef < ' _ > > )  -> String  { 
95103    let  mut  ret = String :: from ( "<div class=\" footnotes\" ><hr><ol>" ) ; 
96104
0 commit comments