diff --git a/src/block.rs b/src/block.rs index 8e52049..ffc4f86 100644 --- a/src/block.rs +++ b/src/block.rs @@ -293,6 +293,11 @@ impl<'s> TreeParser<'s> { self.open_sections.push(*level); self.tree.enter(Node::Container(Section), span); } + + // trim '#' characters + for line in lines[1..].iter_mut() { + *line = line.trim_start_matches(self.src, |c| c == '#' || c.is_whitespace()); + } } self.tree.enter(Node::Leaf(leaf), span); @@ -797,7 +802,10 @@ impl Kind { .. } => false, Self::Blockquote => matches!(next, Self::Blockquote | Self::Paragraph), - Self::Heading { .. } => matches!(next, Self::Paragraph), + Self::Heading { level } => { + matches!(next, Self::Paragraph) + || matches!(next, Self::Heading { level: l } if l == *level ) + } Self::Paragraph | Self::Table { caption: true } => { !matches!(next, Self::Atom(Blankline)) } @@ -964,6 +972,26 @@ mod test { ); } + #[test] + fn parse_heading() { + test_parse!( + concat!( + "# a\n", + "## b\n", // + ), + (Enter(Container(Section)), "#"), + (Enter(Leaf(Heading)), "#"), + (Inline, "a"), + (Exit(Leaf(Heading)), "#"), + (Enter(Container(Section)), "##"), + (Enter(Leaf(Heading)), "##"), + (Inline, "b"), + (Exit(Leaf(Heading)), "##"), + (Exit(Container(Section)), "##"), + (Exit(Container(Section)), "#"), + ); + } + #[test] fn parse_heading_multi() { test_parse!( @@ -990,6 +1018,24 @@ mod test { ); } + #[test] + fn parse_heading_multi_repeat() { + test_parse!( + concat!( + "# a\n", + "# b\n", + "c\n", // + ), + (Enter(Container(Section)), "#"), + (Enter(Leaf(Heading)), "#"), + (Inline, "a\n"), + (Inline, "b\n"), + (Inline, "c"), + (Exit(Leaf(Heading)), "#"), + (Exit(Container(Section)), "#"), + ); + } + #[test] fn parse_section() { test_parse!( diff --git a/src/span.rs b/src/span.rs index bf31c2b..3874063 100644 --- a/src/span.rs +++ b/src/span.rs @@ -89,6 +89,10 @@ impl Span { &s[self.start()..self.end()] } + pub fn trim_start_matches bool>(self, s: &str, pat: P) -> Self { + Self::from_slice(s, self.of(s).trim_start_matches(pat)) + } + pub fn trim_start(self, s: &str) -> Self { Self::from_slice(s, self.of(s).trim_start()) }