block: parse description list
This commit is contained in:
parent
95bf52a31e
commit
fbd8811c86
2 changed files with 73 additions and 11 deletions
66
src/block.rs
66
src/block.rs
|
@ -60,6 +60,9 @@ pub enum Leaf {
|
||||||
/// Each inline is a line.
|
/// Each inline is a line.
|
||||||
Heading { has_section: bool },
|
Heading { has_section: bool },
|
||||||
|
|
||||||
|
/// Span is empty.
|
||||||
|
DescriptionTerm,
|
||||||
|
|
||||||
/// Span is '|'.
|
/// Span is '|'.
|
||||||
/// Has zero or one inline for the cell contents.
|
/// Has zero or one inline for the cell contents.
|
||||||
TableCell(Alignment),
|
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;
|
let mut l = 0;
|
||||||
while l < lines.len() {
|
while l < lines.len() {
|
||||||
l += self.parse_block(&mut lines[l..], false);
|
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() {
|
if let Some(OpenList { depth, .. }) = self.open_lists.last() {
|
||||||
assert!(usize::from(*depth) <= self.tree.depth());
|
assert!(usize::from(*depth) <= self.tree.depth());
|
||||||
if self.tree.depth() == (*depth).into() {
|
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]
|
#[test]
|
||||||
fn parse_table() {
|
fn parse_table() {
|
||||||
test_parse!(
|
test_parse!(
|
||||||
|
|
18
src/lib.rs
18
src/lib.rs
|
@ -721,6 +721,7 @@ impl<'s> Parser<'s> {
|
||||||
.to_string()
|
.to_string()
|
||||||
.into(),
|
.into(),
|
||||||
},
|
},
|
||||||
|
block::Leaf::DescriptionTerm => Container::DescriptionTerm,
|
||||||
block::Leaf::CodeBlock => {
|
block::Leaf::CodeBlock => {
|
||||||
if let Some(format) = content.strip_prefix('=') {
|
if let Some(format) = content.strip_prefix('=') {
|
||||||
Container::RawBlock { format }
|
Container::RawBlock { format }
|
||||||
|
@ -771,16 +772,13 @@ impl<'s> Parser<'s> {
|
||||||
Container::List { kind, tight }
|
Container::List { kind, tight }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
block::Container::ListItem(ty) => {
|
block::Container::ListItem(ty) => match ty {
|
||||||
if matches!(ty, block::ListType::Task) {
|
block::ListType::Task => Container::TaskListItem {
|
||||||
let marker = ev.span.of(self.src);
|
checked: content.as_bytes()[3] != b' ',
|
||||||
Container::TaskListItem {
|
},
|
||||||
checked: marker.as_bytes()[3] != b' ',
|
block::ListType::Description => Container::DescriptionDetails,
|
||||||
}
|
_ => Container::ListItem,
|
||||||
} else {
|
},
|
||||||
Container::ListItem
|
|
||||||
}
|
|
||||||
}
|
|
||||||
block::Container::Table => Container::Table,
|
block::Container::Table => Container::Table,
|
||||||
block::Container::TableRow { head } => {
|
block::Container::TableRow { head } => {
|
||||||
if enter {
|
if enter {
|
||||||
|
|
Loading…
Reference in a new issue