diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2024-11-13 16:56:18 +0100 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2024-11-13 16:56:18 +0100 |
| commit | d9aac8cfcefcd4063fc39ff19e9ace373471bbbc (patch) | |
| tree | f8c866c1cf615775c6e50db93642b9f63f84bcc1 /src/librustdoc/html/markdown | |
| parent | 583b25d8d1bf934f593d9d9811f88305888032b5 (diff) | |
| download | rust-d9aac8cfcefcd4063fc39ff19e9ace373471bbbc.tar.gz rust-d9aac8cfcefcd4063fc39ff19e9ace373471bbbc.zip | |
Fix duplicated footnote IDs
Diffstat (limited to 'src/librustdoc/html/markdown')
| -rw-r--r-- | src/librustdoc/html/markdown/footnotes.rs | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/src/librustdoc/html/markdown/footnotes.rs b/src/librustdoc/html/markdown/footnotes.rs index 3f0e586b8e3..0958d446c2d 100644 --- a/src/librustdoc/html/markdown/footnotes.rs +++ b/src/librustdoc/html/markdown/footnotes.rs @@ -8,36 +8,35 @@ use super::SpannedEvent; /// Moves all footnote definitions to the end and add back links to the /// references. -pub(super) struct Footnotes<'a, I> { +pub(super) struct Footnotes<'a, 'b, I> { inner: I, footnotes: FxIndexMap<String, FootnoteDef<'a>>, + existing_footnotes: &'b mut usize, } /// The definition of a single footnote. struct FootnoteDef<'a> { content: Vec<Event<'a>>, /// The number that appears in the footnote reference and list. - id: u16, + id: usize, } -impl<'a, I> Footnotes<'a, I> { - pub(super) fn new(iter: I) -> Self { - Footnotes { inner: iter, footnotes: FxIndexMap::default() } +impl<'a, 'b, I> Footnotes<'a, 'b, I> { + pub(super) fn new(iter: I, existing_footnotes: &'b mut usize) -> Self { + Footnotes { inner: iter, footnotes: FxIndexMap::default(), existing_footnotes } } - fn get_entry(&mut self, key: &str) -> (&mut Vec<Event<'a>>, u16) { - let new_id = self.footnotes.len() + 1; + fn get_entry(&mut self, key: &str) -> (&mut Vec<Event<'a>>, usize) { + let new_id = self.footnotes.len() + 1 + *self.existing_footnotes; let key = key.to_owned(); - let FootnoteDef { content, id } = self - .footnotes - .entry(key) - .or_insert(FootnoteDef { content: Vec::new(), id: new_id as u16 }); + let FootnoteDef { content, id } = + self.footnotes.entry(key).or_insert(FootnoteDef { content: Vec::new(), id: new_id }); // Don't allow changing the ID of existing entrys, but allow changing the contents. (content, *id) } } -impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> { +impl<'a, 'b, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, 'b, I> { type Item = SpannedEvent<'a>; fn next(&mut self) -> Option<Self::Item> { @@ -47,8 +46,13 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> { // When we see a reference (to a footnote we may not know) the definition of, // reserve a number for it, and emit a link to that number. let (_, id) = self.get_entry(reference); - let reference = - format!("<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>", id); + let reference = format!( + "<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{1}</a></sup>", + id, + // Although the ID count is for the whole page, the footnote reference + // are local to the item so we make this ID "local" when displayed. + id - *self.existing_footnotes + ); return Some((Event::Html(reference.into()), range)); } Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => { @@ -64,6 +68,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> { // After all the markdown is emmited, emit an <hr> then all the footnotes // in a list. let defs: Vec<_> = self.footnotes.drain(..).map(|(_, x)| x).collect(); + *self.existing_footnotes += defs.len(); let defs_html = render_footnotes_defs(defs); return Some((Event::Html(defs_html.into()), 0..0)); } else { |
