block: allow repeating '#' in headings
This commit is contained in:
parent
451b2360f4
commit
bfa58dfc0d
2 changed files with 51 additions and 1 deletions
48
src/block.rs
48
src/block.rs
|
@ -293,6 +293,11 @@ impl<'s> TreeParser<'s> {
|
||||||
self.open_sections.push(*level);
|
self.open_sections.push(*level);
|
||||||
self.tree.enter(Node::Container(Section), span);
|
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);
|
self.tree.enter(Node::Leaf(leaf), span);
|
||||||
|
@ -797,7 +802,10 @@ impl Kind {
|
||||||
..
|
..
|
||||||
} => false,
|
} => false,
|
||||||
Self::Blockquote => matches!(next, Self::Blockquote | Self::Paragraph),
|
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 } => {
|
Self::Paragraph | Self::Table { caption: true } => {
|
||||||
!matches!(next, Self::Atom(Blankline))
|
!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]
|
#[test]
|
||||||
fn parse_heading_multi() {
|
fn parse_heading_multi() {
|
||||||
test_parse!(
|
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]
|
#[test]
|
||||||
fn parse_section() {
|
fn parse_section() {
|
||||||
test_parse!(
|
test_parse!(
|
||||||
|
|
|
@ -89,6 +89,10 @@ impl Span {
|
||||||
&s[self.start()..self.end()]
|
&s[self.start()..self.end()]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn trim_start_matches<P: FnMut(char) -> 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 {
|
pub fn trim_start(self, s: &str) -> Self {
|
||||||
Self::from_slice(s, self.of(s).trim_start())
|
Self::from_slice(s, self.of(s).trim_start())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue