block: parse div fences
This commit is contained in:
		
					parent
					
						
							
								dc2647910c
							
						
					
				
			
			
				commit
				
					
						fee50d36fb
					
				
			
		
					 1 changed files with 56 additions and 46 deletions
				
			
		
							
								
								
									
										62
									
								
								src/block.rs
									
										
									
									
									
								
							
							
						
						
									
										62
									
								
								src/block.rs
									
										
									
									
									
								
							| 
						 | 
					@ -187,12 +187,10 @@ impl<'s> TreeParser<'s> {
 | 
				
			||||||
                    lines[0] = lines[0].skip(2);
 | 
					                    lines[0] = lines[0].skip(2);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // skip closing fence of code blocks / divs
 | 
					                // skip fences of code blocks / divs
 | 
				
			||||||
                let lines = if !truncated
 | 
					                let lines = if matches!(kind, Block::Leaf(CodeBlock) | Block::Container(Div)) {
 | 
				
			||||||
                    && matches!(kind, Block::Leaf(CodeBlock) | Block::Container(Div))
 | 
					                    let l = lines.len() - usize::from(!truncated);
 | 
				
			||||||
                {
 | 
					                    &mut lines[1..l]
 | 
				
			||||||
                    let l = lines.len();
 | 
					 | 
				
			||||||
                    &mut lines[..l - 1]
 | 
					 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    lines
 | 
					                    lines
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
| 
						 | 
					@ -270,26 +268,13 @@ impl<'s> TreeParser<'s> {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // skip first inline if empty (e.g. code block)
 | 
					 | 
				
			||||||
        let lines = if lines[0].is_empty() {
 | 
					 | 
				
			||||||
            &mut lines[1..]
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            lines
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        lines.iter().for_each(|line| self.tree.inline(*line));
 | 
					        lines.iter().for_each(|line| self.tree.inline(*line));
 | 
				
			||||||
        self.tree.exit();
 | 
					        self.tree.exit();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_container(&mut self, c: Container, lines: &mut [Span], span: Span, indent: usize) {
 | 
					    fn parse_container(&mut self, c: Container, lines: &mut [Span], span: Span, indent: usize) {
 | 
				
			||||||
        let line_count_inner = lines.len() - usize::from(matches!(c, Div));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // update spans, remove indentation / container prefix
 | 
					        // update spans, remove indentation / container prefix
 | 
				
			||||||
        lines
 | 
					        lines.iter_mut().skip(1).for_each(|sp| {
 | 
				
			||||||
            .iter_mut()
 | 
					 | 
				
			||||||
            .skip(1)
 | 
					 | 
				
			||||||
            .take(line_count_inner)
 | 
					 | 
				
			||||||
            .for_each(|sp| {
 | 
					 | 
				
			||||||
            let src = sp.of(self.src);
 | 
					            let src = sp.of(self.src);
 | 
				
			||||||
            let src_t = src.trim();
 | 
					            let src_t = src.trim();
 | 
				
			||||||
            let spaces = src.len() - src.trim_start().len();
 | 
					            let spaces = src.len() - src.trim_start().len();
 | 
				
			||||||
| 
						 | 
					@ -334,8 +319,8 @@ impl<'s> TreeParser<'s> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.tree.enter(Node::Container(c), span);
 | 
					        self.tree.enter(Node::Container(c), span);
 | 
				
			||||||
        let mut l = 0;
 | 
					        let mut l = 0;
 | 
				
			||||||
        while l < line_count_inner {
 | 
					        while l < lines.len() {
 | 
				
			||||||
            l += self.parse_block(&mut lines[l..line_count_inner]);
 | 
					            l += self.parse_block(&mut lines[l..]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if let Some(OpenList { depth, .. }) = self.open_lists.last() {
 | 
					        if let Some(OpenList { depth, .. }) = self.open_lists.last() {
 | 
				
			||||||
| 
						 | 
					@ -657,10 +642,11 @@ impl BlockParser {
 | 
				
			||||||
                empty || spaces > self.indent
 | 
					                empty || spaces > self.indent
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Block::Container(Div) | Block::Leaf(CodeBlock) => {
 | 
					            Block::Container(Div) | Block::Leaf(CodeBlock) => {
 | 
				
			||||||
                let (fence, fence_length) = self.fence.unwrap();
 | 
					                let (fence_char, l0) = self.fence.unwrap();
 | 
				
			||||||
                let mut c = line.chars();
 | 
					                let l1 = line_t.len();
 | 
				
			||||||
                !((&mut c).take(fence_length).all(|c| c == fence)
 | 
					                let is_end_fence = line_t.chars().all(|c| c == fence_char)
 | 
				
			||||||
                    && c.next().map_or(true, char::is_whitespace))
 | 
					                    && (l0 == l1 || (l0 < l1 && matches!(self.kind, Block::Container(..))));
 | 
				
			||||||
 | 
					                !is_end_fence
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Block::Container(Table) if self.caption => !empty,
 | 
					            Block::Container(Table) if self.caption => !empty,
 | 
				
			||||||
            Block::Container(Table) => {
 | 
					            Block::Container(Table) => {
 | 
				
			||||||
| 
						 | 
					@ -1577,6 +1563,30 @@ mod test {
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn parse_div() {
 | 
				
			||||||
 | 
					        test_parse!(
 | 
				
			||||||
 | 
					            concat!("::: cls\n", "abc\n", ":::\n",),
 | 
				
			||||||
 | 
					            (Enter(Container(Div)), "cls"),
 | 
				
			||||||
 | 
					            (Enter(Leaf(Paragraph)), ""),
 | 
				
			||||||
 | 
					            (Inline, "abc"),
 | 
				
			||||||
 | 
					            (Exit(Leaf(Paragraph)), ""),
 | 
				
			||||||
 | 
					            (Exit(Container(Div)), "cls"),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn parse_div_no_class() {
 | 
				
			||||||
 | 
					        test_parse!(
 | 
				
			||||||
 | 
					            concat!(":::\n", "abc\n", ":::\n",),
 | 
				
			||||||
 | 
					            (Enter(Container(Div)), ""),
 | 
				
			||||||
 | 
					            (Enter(Leaf(Paragraph)), ""),
 | 
				
			||||||
 | 
					            (Inline, "abc"),
 | 
				
			||||||
 | 
					            (Exit(Leaf(Paragraph)), ""),
 | 
				
			||||||
 | 
					            (Exit(Container(Div)), ""),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    macro_rules! test_block {
 | 
					    macro_rules! test_block {
 | 
				
			||||||
        ($src:expr, $kind:expr, $str:expr, $len:expr $(,)?) => {
 | 
					        ($src:expr, $kind:expr, $str:expr, $len:expr $(,)?) => {
 | 
				
			||||||
            let lines = super::lines($src).map(|sp| sp.of($src));
 | 
					            let lines = super::lines($src).map(|sp| sp.of($src));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue