block: specify heading pos in event
instead of using span
This commit is contained in:
		
					parent
					
						
							
								898ed90a24
							
						
					
				
			
			
				commit
				
					
						ee9ea2e023
					
				
			
		
					 2 changed files with 97 additions and 57 deletions
				
			
		
							
								
								
									
										136
									
								
								src/block.rs
									
										
									
									
									
								
							
							
						
						
									
										136
									
								
								src/block.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -58,7 +58,11 @@ pub enum Leaf<'s> {
 | 
			
		|||
 | 
			
		||||
    /// Span is `#` characters.
 | 
			
		||||
    /// Each inline is a line.
 | 
			
		||||
    Heading { level: u16, has_section: bool },
 | 
			
		||||
    Heading {
 | 
			
		||||
        level: u16,
 | 
			
		||||
        has_section: bool,
 | 
			
		||||
        pos: u32,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /// Span is empty.
 | 
			
		||||
    DescriptionTerm,
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +107,7 @@ pub enum Container<'s> {
 | 
			
		|||
    TableRow { head: bool },
 | 
			
		||||
 | 
			
		||||
    /// Span is '#' characters of heading.
 | 
			
		||||
    Section,
 | 
			
		||||
    Section { pos: u32 },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
			
		||||
| 
						 | 
				
			
			@ -259,6 +263,7 @@ impl<'s> TreeParser<'s> {
 | 
			
		|||
                Kind::Heading { level } => Block::Leaf(Heading {
 | 
			
		||||
                    level: level.try_into().unwrap(),
 | 
			
		||||
                    has_section: top_level,
 | 
			
		||||
                    pos: span.start() as u32,
 | 
			
		||||
                }),
 | 
			
		||||
                Kind::Fenced {
 | 
			
		||||
                    kind: FenceKind::CodeBlock(..),
 | 
			
		||||
| 
						 | 
				
			
			@ -343,7 +348,12 @@ impl<'s> TreeParser<'s> {
 | 
			
		|||
                    self.tree.exit(); // section
 | 
			
		||||
                });
 | 
			
		||||
                self.open_sections.push(*level);
 | 
			
		||||
                self.tree.enter(Node::Container(Section), span);
 | 
			
		||||
                self.tree.enter(
 | 
			
		||||
                    Node::Container(Section {
 | 
			
		||||
                        pos: span.start() as u32,
 | 
			
		||||
                    }),
 | 
			
		||||
                    span,
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // trim '#' characters
 | 
			
		||||
| 
						 | 
				
			
			@ -1110,11 +1120,12 @@ mod test {
 | 
			
		|||
                "# a\n",
 | 
			
		||||
                "## b\n", //
 | 
			
		||||
            ),
 | 
			
		||||
            (Enter(Container(Section)), "#"),
 | 
			
		||||
            (Enter(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1122,15 +1133,17 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
            (Enter(Container(Section)), "##"),
 | 
			
		||||
            (Enter(Container(Section { pos: 4 })), "##"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 2,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 4
 | 
			
		||||
                })),
 | 
			
		||||
                "##"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1138,12 +1151,13 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 2,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 4
 | 
			
		||||
                })),
 | 
			
		||||
                "##"
 | 
			
		||||
            ),
 | 
			
		||||
            (Exit(Container(Section)), "##"),
 | 
			
		||||
            (Exit(Container(Section)), "#"),
 | 
			
		||||
            (Exit(Container(Section { pos: 4 })), "##"),
 | 
			
		||||
            (Exit(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1154,11 +1168,12 @@ mod test {
 | 
			
		|||
                "#\n",
 | 
			
		||||
                "heading\n", //
 | 
			
		||||
            ),
 | 
			
		||||
            (Enter(Container(Section)), "#"),
 | 
			
		||||
            (Enter(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1166,11 +1181,12 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
            (Exit(Container(Section)), "#"),
 | 
			
		||||
            (Exit(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1184,11 +1200,12 @@ mod test {
 | 
			
		|||
                "  12\n",
 | 
			
		||||
                "15\n", //
 | 
			
		||||
            ),
 | 
			
		||||
            (Enter(Container(Section)), "#"),
 | 
			
		||||
            (Enter(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0,
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1196,17 +1213,19 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0,
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
            (Atom(Blankline), "\n"),
 | 
			
		||||
            (Exit(Container(Section)), "#"),
 | 
			
		||||
            (Enter(Container(Section)), "#"),
 | 
			
		||||
            (Exit(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
            (Enter(Container(Section { pos: 6 })), "#"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 6,
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1216,11 +1235,12 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 6,
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
            (Exit(Container(Section)), "#"),
 | 
			
		||||
            (Exit(Container(Section { pos: 6 })), "#"),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1232,11 +1252,12 @@ mod test {
 | 
			
		|||
                "# b\n",
 | 
			
		||||
                "c\n", //
 | 
			
		||||
            ),
 | 
			
		||||
            (Enter(Container(Section)), "#"),
 | 
			
		||||
            (Enter(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1246,11 +1267,12 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
            (Exit(Container(Section)), "#"),
 | 
			
		||||
            (Exit(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1270,11 +1292,12 @@ mod test {
 | 
			
		|||
                "\n",
 | 
			
		||||
                "# b\n",
 | 
			
		||||
            ),
 | 
			
		||||
            (Enter(Container(Section)), "#"),
 | 
			
		||||
            (Enter(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0,
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1282,16 +1305,18 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 0,
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
            (Atom(Blankline), "\n"),
 | 
			
		||||
            (Enter(Container(Section)), "##"),
 | 
			
		||||
            (Enter(Container(Section { pos: 5 })), "##"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 2,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 5,
 | 
			
		||||
                })),
 | 
			
		||||
                "##"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1299,16 +1324,18 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 2,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 5,
 | 
			
		||||
                })),
 | 
			
		||||
                "##"
 | 
			
		||||
            ),
 | 
			
		||||
            (Atom(Blankline), "\n"),
 | 
			
		||||
            (Enter(Container(Section)), "####"),
 | 
			
		||||
            (Enter(Container(Section { pos: 12 })), "####"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 4,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 12,
 | 
			
		||||
                })),
 | 
			
		||||
                "####"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1316,18 +1343,20 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 4,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 12,
 | 
			
		||||
                })),
 | 
			
		||||
                "####"
 | 
			
		||||
            ),
 | 
			
		||||
            (Atom(Blankline), "\n"),
 | 
			
		||||
            (Exit(Container(Section)), "####"),
 | 
			
		||||
            (Exit(Container(Section)), "##"),
 | 
			
		||||
            (Enter(Container(Section)), "##"),
 | 
			
		||||
            (Exit(Container(Section { pos: 12 })), "####"),
 | 
			
		||||
            (Exit(Container(Section { pos: 5 })), "##"),
 | 
			
		||||
            (Enter(Container(Section { pos: 23 })), "##"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 2,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 23,
 | 
			
		||||
                })),
 | 
			
		||||
                "##"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1335,16 +1364,18 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 2,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 23,
 | 
			
		||||
                })),
 | 
			
		||||
                "##"
 | 
			
		||||
            ),
 | 
			
		||||
            (Atom(Blankline), "\n"),
 | 
			
		||||
            (Enter(Container(Section)), "###"),
 | 
			
		||||
            (Enter(Container(Section { pos: 30 })), "###"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 3,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 30,
 | 
			
		||||
                })),
 | 
			
		||||
                "###"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1352,19 +1383,21 @@ mod test {
 | 
			
		|||
            (
 | 
			
		||||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 3,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 30,
 | 
			
		||||
                })),
 | 
			
		||||
                "###"
 | 
			
		||||
            ),
 | 
			
		||||
            (Atom(Blankline), "\n"),
 | 
			
		||||
            (Exit(Container(Section)), "###"),
 | 
			
		||||
            (Exit(Container(Section)), "##"),
 | 
			
		||||
            (Exit(Container(Section)), "#"),
 | 
			
		||||
            (Enter(Container(Section)), "#"),
 | 
			
		||||
            (Exit(Container(Section { pos: 30 })), "###"),
 | 
			
		||||
            (Exit(Container(Section { pos: 23 })), "##"),
 | 
			
		||||
            (Exit(Container(Section { pos: 0 })), "#"),
 | 
			
		||||
            (Enter(Container(Section { pos: 39 })), "#"),
 | 
			
		||||
            (
 | 
			
		||||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 39,
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1373,10 +1406,11 @@ mod test {
 | 
			
		|||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    pos: 39,
 | 
			
		||||
                })),
 | 
			
		||||
                "#"
 | 
			
		||||
            ),
 | 
			
		||||
            (Exit(Container(Section)), "#"),
 | 
			
		||||
            (Exit(Container(Section { pos: 39 })), "#"),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1417,6 +1451,7 @@ mod test {
 | 
			
		|||
                Enter(Leaf(Heading {
 | 
			
		||||
                    level: 2,
 | 
			
		||||
                    has_section: false,
 | 
			
		||||
                    pos: 8,
 | 
			
		||||
                })),
 | 
			
		||||
                "##"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			@ -1425,6 +1460,7 @@ mod test {
 | 
			
		|||
                Exit(Leaf(Heading {
 | 
			
		||||
                    level: 2,
 | 
			
		||||
                    has_section: false,
 | 
			
		||||
                    pos: 8,
 | 
			
		||||
                })),
 | 
			
		||||
                "##"
 | 
			
		||||
            ),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								src/lib.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -576,7 +576,7 @@ pub struct Parser<'s> {
 | 
			
		|||
#[derive(Clone)]
 | 
			
		||||
struct Heading {
 | 
			
		||||
    /// Location of heading in src.
 | 
			
		||||
    location: usize,
 | 
			
		||||
    location: u32,
 | 
			
		||||
    /// Automatically generated id from heading text.
 | 
			
		||||
    id_auto: String,
 | 
			
		||||
    /// Text of heading, formatting stripped.
 | 
			
		||||
| 
						 | 
				
			
			@ -694,7 +694,7 @@ impl<'s> PrePass<'s> {
 | 
			
		|||
                        std::mem::transmute::<&str, &'static str>(id_auto.as_ref())
 | 
			
		||||
                    });
 | 
			
		||||
                    headings.push(Heading {
 | 
			
		||||
                        location: e.span.start(),
 | 
			
		||||
                        location: e.span.start() as u32,
 | 
			
		||||
                        id_auto,
 | 
			
		||||
                        text,
 | 
			
		||||
                        id_override,
 | 
			
		||||
| 
						 | 
				
			
			@ -728,7 +728,7 @@ impl<'s> PrePass<'s> {
 | 
			
		|||
        h.id_override.as_ref().unwrap_or(&h.id_auto)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn heading_id_by_location(&self, location: usize) -> Option<&str> {
 | 
			
		||||
    fn heading_id_by_location(&self, location: u32) -> Option<&str> {
 | 
			
		||||
        self.headings
 | 
			
		||||
            .binary_search_by_key(&location, |h| h.location)
 | 
			
		||||
            .ok()
 | 
			
		||||
| 
						 | 
				
			
			@ -886,12 +886,16 @@ impl<'s> Parser<'s> {
 | 
			
		|||
                            self.inline_parser.reset();
 | 
			
		||||
                            match l {
 | 
			
		||||
                                block::Leaf::Paragraph => Container::Paragraph,
 | 
			
		||||
                                block::Leaf::Heading { level, has_section } => Container::Heading {
 | 
			
		||||
                                block::Leaf::Heading {
 | 
			
		||||
                                    level,
 | 
			
		||||
                                    has_section,
 | 
			
		||||
                                    pos,
 | 
			
		||||
                                } => Container::Heading {
 | 
			
		||||
                                    level,
 | 
			
		||||
                                    has_section,
 | 
			
		||||
                                    id: self
 | 
			
		||||
                                        .pre_pass
 | 
			
		||||
                                        .heading_id_by_location(ev.span.start())
 | 
			
		||||
                                        .heading_id_by_location(pos)
 | 
			
		||||
                                        .unwrap_or_default()
 | 
			
		||||
                                        .to_string()
 | 
			
		||||
                                        .into(),
 | 
			
		||||
| 
						 | 
				
			
			@ -957,10 +961,10 @@ impl<'s> Parser<'s> {
 | 
			
		|||
                                }
 | 
			
		||||
                                Container::TableRow { head }
 | 
			
		||||
                            }
 | 
			
		||||
                            block::Container::Section => Container::Section {
 | 
			
		||||
                            block::Container::Section { pos } => Container::Section {
 | 
			
		||||
                                id: self
 | 
			
		||||
                                    .pre_pass
 | 
			
		||||
                                    .heading_id_by_location(ev.span.start())
 | 
			
		||||
                                    .heading_id_by_location(pos)
 | 
			
		||||
                                    .unwrap_or_default()
 | 
			
		||||
                                    .to_string()
 | 
			
		||||
                                    .into(),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue