block: specify heading pos in event

instead of using span
This commit is contained in:
Noah Hellman 2023-04-29 20:02:18 +02:00
parent 898ed90a24
commit ee9ea2e023
2 changed files with 97 additions and 57 deletions

View file

@ -58,7 +58,11 @@ pub enum Leaf<'s> {
/// Span is `#` characters.
/// Each inline is a line.
Heading { level: u16, has_section: bool },
Heading {
level: u16,
has_section: bool,
pos: u32,
},
/// Span is empty.
DescriptionTerm,
@ -103,7 +107,7 @@ pub enum Container<'s> {
TableRow { head: bool },
/// Span is '#' characters of heading.
Section,
Section { pos: u32 },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -259,6 +263,7 @@ impl<'s> TreeParser<'s> {
Kind::Heading { level } => Block::Leaf(Heading {
level: level.try_into().unwrap(),
has_section: top_level,
pos: span.start() as u32,
}),
Kind::Fenced {
kind: FenceKind::CodeBlock(..),
@ -343,7 +348,12 @@ impl<'s> TreeParser<'s> {
self.tree.exit(); // section
});
self.open_sections.push(*level);
self.tree.enter(Node::Container(Section), span);
self.tree.enter(
Node::Container(Section {
pos: span.start() as u32,
}),
span,
);
}
// trim '#' characters
@ -1110,11 +1120,12 @@ mod test {
"# a\n",
"## b\n", //
),
(Enter(Container(Section)), "#"),
(Enter(Container(Section { pos: 0 })), "#"),
(
Enter(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0
})),
"#"
),
@ -1122,15 +1133,17 @@ mod test {
(
Exit(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0
})),
"#"
),
(Enter(Container(Section)), "##"),
(Enter(Container(Section { pos: 4 })), "##"),
(
Enter(Leaf(Heading {
level: 2,
has_section: true
has_section: true,
pos: 4
})),
"##"
),
@ -1138,12 +1151,13 @@ mod test {
(
Exit(Leaf(Heading {
level: 2,
has_section: true
has_section: true,
pos: 4
})),
"##"
),
(Exit(Container(Section)), "##"),
(Exit(Container(Section)), "#"),
(Exit(Container(Section { pos: 4 })), "##"),
(Exit(Container(Section { pos: 0 })), "#"),
);
}
@ -1154,11 +1168,12 @@ mod test {
"#\n",
"heading\n", //
),
(Enter(Container(Section)), "#"),
(Enter(Container(Section { pos: 0 })), "#"),
(
Enter(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0
})),
"#"
),
@ -1166,11 +1181,12 @@ mod test {
(
Exit(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0
})),
"#"
),
(Exit(Container(Section)), "#"),
(Exit(Container(Section { pos: 0 })), "#"),
);
}
@ -1184,11 +1200,12 @@ mod test {
" 12\n",
"15\n", //
),
(Enter(Container(Section)), "#"),
(Enter(Container(Section { pos: 0 })), "#"),
(
Enter(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0,
})),
"#"
),
@ -1196,17 +1213,19 @@ mod test {
(
Exit(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0,
})),
"#"
),
(Atom(Blankline), "\n"),
(Exit(Container(Section)), "#"),
(Enter(Container(Section)), "#"),
(Exit(Container(Section { pos: 0 })), "#"),
(Enter(Container(Section { pos: 6 })), "#"),
(
Enter(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 6,
})),
"#"
),
@ -1216,11 +1235,12 @@ mod test {
(
Exit(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 6,
})),
"#"
),
(Exit(Container(Section)), "#"),
(Exit(Container(Section { pos: 6 })), "#"),
);
}
@ -1232,11 +1252,12 @@ mod test {
"# b\n",
"c\n", //
),
(Enter(Container(Section)), "#"),
(Enter(Container(Section { pos: 0 })), "#"),
(
Enter(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0
})),
"#"
),
@ -1246,11 +1267,12 @@ mod test {
(
Exit(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0
})),
"#"
),
(Exit(Container(Section)), "#"),
(Exit(Container(Section { pos: 0 })), "#"),
);
}
@ -1270,11 +1292,12 @@ mod test {
"\n",
"# b\n",
),
(Enter(Container(Section)), "#"),
(Enter(Container(Section { pos: 0 })), "#"),
(
Enter(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0,
})),
"#"
),
@ -1282,16 +1305,18 @@ mod test {
(
Exit(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 0,
})),
"#"
),
(Atom(Blankline), "\n"),
(Enter(Container(Section)), "##"),
(Enter(Container(Section { pos: 5 })), "##"),
(
Enter(Leaf(Heading {
level: 2,
has_section: true
has_section: true,
pos: 5,
})),
"##"
),
@ -1299,16 +1324,18 @@ mod test {
(
Exit(Leaf(Heading {
level: 2,
has_section: true
has_section: true,
pos: 5,
})),
"##"
),
(Atom(Blankline), "\n"),
(Enter(Container(Section)), "####"),
(Enter(Container(Section { pos: 12 })), "####"),
(
Enter(Leaf(Heading {
level: 4,
has_section: true
has_section: true,
pos: 12,
})),
"####"
),
@ -1316,18 +1343,20 @@ mod test {
(
Exit(Leaf(Heading {
level: 4,
has_section: true
has_section: true,
pos: 12,
})),
"####"
),
(Atom(Blankline), "\n"),
(Exit(Container(Section)), "####"),
(Exit(Container(Section)), "##"),
(Enter(Container(Section)), "##"),
(Exit(Container(Section { pos: 12 })), "####"),
(Exit(Container(Section { pos: 5 })), "##"),
(Enter(Container(Section { pos: 23 })), "##"),
(
Enter(Leaf(Heading {
level: 2,
has_section: true
has_section: true,
pos: 23,
})),
"##"
),
@ -1335,16 +1364,18 @@ mod test {
(
Exit(Leaf(Heading {
level: 2,
has_section: true
has_section: true,
pos: 23,
})),
"##"
),
(Atom(Blankline), "\n"),
(Enter(Container(Section)), "###"),
(Enter(Container(Section { pos: 30 })), "###"),
(
Enter(Leaf(Heading {
level: 3,
has_section: true
has_section: true,
pos: 30,
})),
"###"
),
@ -1352,19 +1383,21 @@ mod test {
(
Exit(Leaf(Heading {
level: 3,
has_section: true
has_section: true,
pos: 30,
})),
"###"
),
(Atom(Blankline), "\n"),
(Exit(Container(Section)), "###"),
(Exit(Container(Section)), "##"),
(Exit(Container(Section)), "#"),
(Enter(Container(Section)), "#"),
(Exit(Container(Section { pos: 30 })), "###"),
(Exit(Container(Section { pos: 23 })), "##"),
(Exit(Container(Section { pos: 0 })), "#"),
(Enter(Container(Section { pos: 39 })), "#"),
(
Enter(Leaf(Heading {
level: 1,
has_section: true
has_section: true,
pos: 39,
})),
"#"
),
@ -1373,10 +1406,11 @@ mod test {
Exit(Leaf(Heading {
level: 1,
has_section: true,
pos: 39,
})),
"#"
),
(Exit(Container(Section)), "#"),
(Exit(Container(Section { pos: 39 })), "#"),
);
}
@ -1417,6 +1451,7 @@ mod test {
Enter(Leaf(Heading {
level: 2,
has_section: false,
pos: 8,
})),
"##"
),
@ -1425,6 +1460,7 @@ mod test {
Exit(Leaf(Heading {
level: 2,
has_section: false,
pos: 8,
})),
"##"
),

View file

@ -576,7 +576,7 @@ pub struct Parser<'s> {
#[derive(Clone)]
struct Heading {
/// Location of heading in src.
location: usize,
location: u32,
/// Automatically generated id from heading text.
id_auto: String,
/// Text of heading, formatting stripped.
@ -694,7 +694,7 @@ impl<'s> PrePass<'s> {
std::mem::transmute::<&str, &'static str>(id_auto.as_ref())
});
headings.push(Heading {
location: e.span.start(),
location: e.span.start() as u32,
id_auto,
text,
id_override,
@ -728,7 +728,7 @@ impl<'s> PrePass<'s> {
h.id_override.as_ref().unwrap_or(&h.id_auto)
}
fn heading_id_by_location(&self, location: usize) -> Option<&str> {
fn heading_id_by_location(&self, location: u32) -> Option<&str> {
self.headings
.binary_search_by_key(&location, |h| h.location)
.ok()
@ -886,12 +886,16 @@ impl<'s> Parser<'s> {
self.inline_parser.reset();
match l {
block::Leaf::Paragraph => Container::Paragraph,
block::Leaf::Heading { level, has_section } => Container::Heading {
block::Leaf::Heading {
level,
has_section,
pos,
} => Container::Heading {
level,
has_section,
id: self
.pre_pass
.heading_id_by_location(ev.span.start())
.heading_id_by_location(pos)
.unwrap_or_default()
.to_string()
.into(),
@ -957,10 +961,10 @@ impl<'s> Parser<'s> {
}
Container::TableRow { head }
}
block::Container::Section => Container::Section {
block::Container::Section { pos } => Container::Section {
id: self
.pre_pass
.heading_id_by_location(ev.span.start())
.heading_id_by_location(pos)
.unwrap_or_default()
.to_string()
.into(),