diff --git a/src/block.rs b/src/block.rs index af1ca7f..d5b35f3 100644 --- a/src/block.rs +++ b/src/block.rs @@ -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, })), "##" ), diff --git a/src/lib.rs b/src/lib.rs index 516ccf0..0051486 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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(),