block: parse description list

This commit is contained in:
Noah Hellman 2023-02-04 10:20:05 +01:00
parent 95bf52a31e
commit fbd8811c86
2 changed files with 73 additions and 11 deletions

View file

@ -60,6 +60,9 @@ pub enum Leaf {
/// Each inline is a line.
Heading { has_section: bool },
/// Span is empty.
DescriptionTerm,
/// Span is '|'.
/// Has zero or one inline for the cell contents.
TableCell(Alignment),
@ -354,12 +357,39 @@ impl<'s> TreeParser<'s> {
}
}
self.tree.enter(Node::Container(c), span);
let dt = if let ListItem(Description) = c {
let dt = self
.tree
.enter(Node::Leaf(DescriptionTerm), span.empty_after());
self.tree.exit();
Some(dt)
} else {
None
};
let node = self.tree.enter(Node::Container(c), span);
let mut l = 0;
while l < lines.len() {
l += self.parse_block(&mut lines[l..], false);
}
if let Some(node_dt) = dt {
let node_child = if let Some(node_child) = self.tree.children(node).next() {
if let tree::Element::Container(Node::Leaf(l @ Paragraph)) = node_child.elem {
*l = DescriptionTerm;
Some(node_child.index)
} else {
None
}
} else {
None
};
if let Some(node_child) = node_child {
self.tree.swap_prev(node_child);
self.tree.remove(node_dt);
}
}
if let Some(OpenList { depth, .. }) = self.open_lists.last() {
assert!(usize::from(*depth) <= self.tree.depth());
if self.tree.depth() == (*depth).into() {
@ -1684,6 +1714,40 @@ mod test {
);
}
#[test]
fn parse_description_list() {
test_parse!(
concat!(
": term\n", //
"\n", //
" description\n", //
),
(
Enter(Container(List {
ty: Description,
tight: false
})),
":"
),
(Enter(Leaf(DescriptionTerm)), ""),
(Inline, "term"),
(Exit(Leaf(DescriptionTerm)), ""),
(Enter(Container(ListItem(Description))), ":"),
(Atom(Blankline), "\n"),
(Enter(Leaf(Paragraph)), ""),
(Inline, "description"),
(Exit(Leaf(Paragraph)), ""),
(Exit(Container(ListItem(Description))), ":"),
(
Exit(Container(List {
ty: Description,
tight: false
})),
":"
),
);
}
#[test]
fn parse_table() {
test_parse!(

View file

@ -721,6 +721,7 @@ impl<'s> Parser<'s> {
.to_string()
.into(),
},
block::Leaf::DescriptionTerm => Container::DescriptionTerm,
block::Leaf::CodeBlock => {
if let Some(format) = content.strip_prefix('=') {
Container::RawBlock { format }
@ -771,16 +772,13 @@ impl<'s> Parser<'s> {
Container::List { kind, tight }
}
}
block::Container::ListItem(ty) => {
if matches!(ty, block::ListType::Task) {
let marker = ev.span.of(self.src);
Container::TaskListItem {
checked: marker.as_bytes()[3] != b' ',
}
} else {
Container::ListItem
}
}
block::Container::ListItem(ty) => match ty {
block::ListType::Task => Container::TaskListItem {
checked: content.as_bytes()[3] != b' ',
},
block::ListType::Description => Container::DescriptionDetails,
_ => Container::ListItem,
},
block::Container::Table => Container::Table,
block::Container::TableRow { head } => {
if enter {