Fix handling of footnote reference in footnote definition
This commit is contained in:
parent
a4cedecc9e
commit
1d2f9118fe
1 changed files with 34 additions and 26 deletions
|
@ -1,7 +1,7 @@
|
||||||
//! Markdown footnote handling.
|
//! Markdown footnote handling.
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
|
|
||||||
use pulldown_cmark::{Event, Tag, TagEnd, html};
|
use pulldown_cmark::{CowStr, Event, Tag, TagEnd, html};
|
||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
|
|
||||||
use super::SpannedEvent;
|
use super::SpannedEvent;
|
||||||
|
@ -21,7 +21,7 @@ struct FootnoteDef<'a> {
|
||||||
id: usize,
|
id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, I> Footnotes<'a, 'b, I> {
|
impl<'a, 'b, I: Iterator<Item = SpannedEvent<'a>>> Footnotes<'a, 'b, I> {
|
||||||
pub(super) fn new(iter: I, existing_footnotes: &'b mut usize) -> Self {
|
pub(super) fn new(iter: I, existing_footnotes: &'b mut usize) -> Self {
|
||||||
Footnotes { inner: iter, footnotes: FxIndexMap::default(), existing_footnotes }
|
Footnotes { inner: iter, footnotes: FxIndexMap::default(), existing_footnotes }
|
||||||
}
|
}
|
||||||
|
@ -34,15 +34,8 @@ impl<'a, 'b, I> Footnotes<'a, 'b, I> {
|
||||||
// Don't allow changing the ID of existing entrys, but allow changing the contents.
|
// Don't allow changing the ID of existing entrys, but allow changing the contents.
|
||||||
(content, *id)
|
(content, *id)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'b, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, 'b, I> {
|
fn handle_footnote_reference(&mut self, reference: &CowStr<'a>) -> Event<'a> {
|
||||||
type Item = SpannedEvent<'a>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
loop {
|
|
||||||
match self.inner.next() {
|
|
||||||
Some((Event::FootnoteReference(ref reference), range)) => {
|
|
||||||
// When we see a reference (to a footnote we may not know) the definition of,
|
// 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.
|
// reserve a number for it, and emit a link to that number.
|
||||||
let (_, id) = self.get_entry(reference);
|
let (_, id) = self.get_entry(reference);
|
||||||
|
@ -53,12 +46,38 @@ impl<'a, 'b, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, 'b
|
||||||
// are local to the item so we make this ID "local" when displayed.
|
// are local to the item so we make this ID "local" when displayed.
|
||||||
id - *self.existing_footnotes
|
id - *self.existing_footnotes
|
||||||
);
|
);
|
||||||
return Some((Event::Html(reference.into()), range));
|
Event::Html(reference.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collect_footnote_def(&mut self) -> Vec<Event<'a>> {
|
||||||
|
let mut content = Vec::new();
|
||||||
|
while let Some((event, _)) = self.inner.next() {
|
||||||
|
match event {
|
||||||
|
Event::End(TagEnd::FootnoteDefinition) => break,
|
||||||
|
Event::FootnoteReference(ref reference) => {
|
||||||
|
content.push(self.handle_footnote_reference(reference));
|
||||||
|
}
|
||||||
|
event => content.push(event),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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> {
|
||||||
|
loop {
|
||||||
|
let next = self.inner.next();
|
||||||
|
match next {
|
||||||
|
Some((Event::FootnoteReference(ref reference), range)) => {
|
||||||
|
return Some((self.handle_footnote_reference(reference), range));
|
||||||
}
|
}
|
||||||
Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => {
|
Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => {
|
||||||
// When we see a footnote definition, collect the assocated content, and store
|
// When we see a footnote definition, collect the assocated content, and store
|
||||||
// that for rendering later.
|
// that for rendering later.
|
||||||
let content = collect_footnote_def(&mut self.inner);
|
let content = self.collect_footnote_def();
|
||||||
let (entry_content, _) = self.get_entry(&def);
|
let (entry_content, _) = self.get_entry(&def);
|
||||||
*entry_content = content;
|
*entry_content = content;
|
||||||
}
|
}
|
||||||
|
@ -80,17 +99,6 @@ impl<'a, 'b, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, 'b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_footnote_def<'a>(events: impl Iterator<Item = SpannedEvent<'a>>) -> Vec<Event<'a>> {
|
|
||||||
let mut content = Vec::new();
|
|
||||||
for (event, _) in events {
|
|
||||||
if let Event::End(TagEnd::FootnoteDefinition) = event {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
content.push(event);
|
|
||||||
}
|
|
||||||
content
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_footnotes_defs(mut footnotes: Vec<FootnoteDef<'_>>) -> String {
|
fn render_footnotes_defs(mut footnotes: Vec<FootnoteDef<'_>>) -> String {
|
||||||
let mut ret = String::from("<div class=\"footnotes\"><hr><ol>");
|
let mut ret = String::from("<div class=\"footnotes\"><hr><ol>");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue