1
1
//! Markdown footnote handling.
2
2
use std:: fmt:: Write as _;
3
3
4
- use pulldown_cmark:: { Event , Tag , TagEnd , html} ;
4
+ use pulldown_cmark:: { CowStr , Event , Tag , TagEnd , html} ;
5
5
use rustc_data_structures:: fx:: FxIndexMap ;
6
6
7
7
use super :: SpannedEvent ;
@@ -21,7 +21,7 @@ struct FootnoteDef<'a> {
21
21
id : usize ,
22
22
}
23
23
24
- impl < ' a , ' b , I > Footnotes < ' a , ' b , I > {
24
+ impl < ' a , ' b , I : Iterator < Item = SpannedEvent < ' a > > > Footnotes < ' a , ' b , I > {
25
25
pub ( super ) fn new ( iter : I , existing_footnotes : & ' b mut usize ) -> Self {
26
26
Footnotes { inner : iter, footnotes : FxIndexMap :: default ( ) , existing_footnotes }
27
27
}
@@ -34,31 +34,50 @@ impl<'a, 'b, I> Footnotes<'a, 'b, I> {
34
34
// Don't allow changing the ID of existing entrys, but allow changing the contents.
35
35
( content, * id)
36
36
}
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
+ }
37
65
}
38
66
39
67
impl < ' a , ' b , I : Iterator < Item = SpannedEvent < ' a > > > Iterator for Footnotes < ' a , ' b , I > {
40
68
type Item = SpannedEvent < ' a > ;
41
69
42
70
fn next ( & mut self ) -> Option < Self :: Item > {
43
71
loop {
44
- match self . inner . next ( ) {
72
+ let next = self . inner . next ( ) ;
73
+ match next {
45
74
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) ) ;
57
76
}
58
77
Some ( ( Event :: Start ( Tag :: FootnoteDefinition ( def) ) , _) ) => {
59
78
// When we see a footnote definition, collect the assocated content, and store
60
79
// that for rendering later.
61
- let content = collect_footnote_def ( & mut self . inner ) ;
80
+ let content = self . collect_footnote_def ( ) ;
62
81
let ( entry_content, _) = self . get_entry ( & def) ;
63
82
* entry_content = content;
64
83
}
@@ -80,17 +99,6 @@ impl<'a, 'b, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, 'b
80
99
}
81
100
}
82
101
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
-
94
102
fn render_footnotes_defs ( mut footnotes : Vec < FootnoteDef < ' _ > > ) -> String {
95
103
let mut ret = String :: from ( "<div class=\" footnotes\" ><hr><ol>" ) ;
96
104
0 commit comments