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.
 | 
			
		||||
    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!(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								src/lib.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue