prepass: fix referenced headings with e.g. spaces
headings that did not exactly match their ids were previously not matched with their reference
This commit is contained in:
parent
45c86da274
commit
9efd4e4448
1 changed files with 59 additions and 2 deletions
61
src/lib.rs
61
src/lib.rs
|
@ -579,6 +579,8 @@ struct Heading {
|
||||||
location: usize,
|
location: usize,
|
||||||
/// Automatically generated id from heading text.
|
/// Automatically generated id from heading text.
|
||||||
id_auto: String,
|
id_auto: String,
|
||||||
|
/// Text of heading, formatting stripped.
|
||||||
|
text: String,
|
||||||
/// Overriding id from an explicit attribute on the heading.
|
/// Overriding id from an explicit attribute on the heading.
|
||||||
id_override: Option<String>,
|
id_override: Option<String>,
|
||||||
}
|
}
|
||||||
|
@ -630,6 +632,7 @@ impl<'s> PrePass<'s> {
|
||||||
.map(ToString::to_string);
|
.map(ToString::to_string);
|
||||||
|
|
||||||
let mut id_auto = String::new();
|
let mut id_auto = String::new();
|
||||||
|
let mut text = String::new();
|
||||||
let mut last_whitespace = true;
|
let mut last_whitespace = true;
|
||||||
let inlines = tree.take_inlines().collect::<Vec<_>>();
|
let inlines = tree.take_inlines().collect::<Vec<_>>();
|
||||||
inline_parser.reset();
|
inline_parser.reset();
|
||||||
|
@ -637,6 +640,7 @@ impl<'s> PrePass<'s> {
|
||||||
inline_parser.feed_line(*sp, i == inlines.len() - 1);
|
inline_parser.feed_line(*sp, i == inlines.len() - 1);
|
||||||
inline_parser.for_each(|ev| match ev.kind {
|
inline_parser.for_each(|ev| match ev.kind {
|
||||||
inline::EventKind::Str => {
|
inline::EventKind::Str => {
|
||||||
|
text.push_str(ev.span.of(src));
|
||||||
let mut chars = ev.span.of(src).chars().peekable();
|
let mut chars = ev.span.of(src).chars().peekable();
|
||||||
while let Some(c) = chars.next() {
|
while let Some(c) = chars.next() {
|
||||||
if c.is_whitespace() {
|
if c.is_whitespace() {
|
||||||
|
@ -654,6 +658,7 @@ impl<'s> PrePass<'s> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline::EventKind::Atom(inline::Atom::Softbreak) => {
|
inline::EventKind::Atom(inline::Atom::Softbreak) => {
|
||||||
|
text.push(' ');
|
||||||
id_auto.push('-');
|
id_auto.push('-');
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -686,6 +691,7 @@ impl<'s> PrePass<'s> {
|
||||||
headings.push(Heading {
|
headings.push(Heading {
|
||||||
location: e.span.start(),
|
location: e.span.start(),
|
||||||
id_auto,
|
id_auto,
|
||||||
|
text,
|
||||||
id_override,
|
id_override,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -703,7 +709,7 @@ impl<'s> PrePass<'s> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut headings_lex = (0..headings.len()).collect::<Vec<_>>();
|
let mut headings_lex = (0..headings.len()).collect::<Vec<_>>();
|
||||||
headings_lex.sort_by_key(|i| &headings[*i].id_auto);
|
headings_lex.sort_by_key(|i| &headings[*i].text);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
link_definitions,
|
link_definitions,
|
||||||
|
@ -726,7 +732,7 @@ impl<'s> PrePass<'s> {
|
||||||
|
|
||||||
fn heading_id_by_tag(&self, tag: &str) -> Option<&str> {
|
fn heading_id_by_tag(&self, tag: &str) -> Option<&str> {
|
||||||
self.headings_lex
|
self.headings_lex
|
||||||
.binary_search_by_key(&tag, |i| &self.headings[*i].id_auto)
|
.binary_search_by_key(&tag, |i| &self.headings[*i].text)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|i| self.heading_id(i))
|
.map(|i| self.heading_id(i))
|
||||||
}
|
}
|
||||||
|
@ -1149,6 +1155,57 @@ mod test {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn heading_ref() {
|
||||||
|
test_parse!(
|
||||||
|
concat!(
|
||||||
|
"A [link][Some Section] to another section.\n", //
|
||||||
|
"\n", //
|
||||||
|
"# Some Section", //
|
||||||
|
),
|
||||||
|
Start(Paragraph, Attributes::new()),
|
||||||
|
Str("A ".into()),
|
||||||
|
Start(
|
||||||
|
Link(
|
||||||
|
"#Some-Section".into(),
|
||||||
|
LinkType::Span(SpanLinkType::Reference)
|
||||||
|
),
|
||||||
|
Attributes::new()
|
||||||
|
),
|
||||||
|
Str("link".into()),
|
||||||
|
End(Link(
|
||||||
|
"#Some-Section".into(),
|
||||||
|
LinkType::Span(SpanLinkType::Reference)
|
||||||
|
)),
|
||||||
|
Str(" to another section.".into()),
|
||||||
|
End(Paragraph),
|
||||||
|
Blankline,
|
||||||
|
Start(
|
||||||
|
Section {
|
||||||
|
id: "Some-Section".into()
|
||||||
|
},
|
||||||
|
Attributes::new()
|
||||||
|
),
|
||||||
|
Start(
|
||||||
|
Heading {
|
||||||
|
level: 1,
|
||||||
|
has_section: true,
|
||||||
|
id: "Some-Section".into(),
|
||||||
|
},
|
||||||
|
Attributes::new(),
|
||||||
|
),
|
||||||
|
Str("Some Section".into()),
|
||||||
|
End(Heading {
|
||||||
|
level: 1,
|
||||||
|
has_section: true,
|
||||||
|
id: "Some-Section".into(),
|
||||||
|
}),
|
||||||
|
End(Section {
|
||||||
|
id: "Some-Section".into()
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn blockquote() {
|
fn blockquote() {
|
||||||
test_parse!(
|
test_parse!(
|
||||||
|
|
Loading…
Reference in a new issue