prepass: fix referenced headings with e.g. spaces
headings that did not exactly match their ids were previously not matched with their reference
This commit is contained in:
		
					parent
					
						
							
								45c86da274
							
						
					
				
			
			
				commit
				
					
						9efd4e4448
					
				
			
		
					 1 changed files with 59 additions and 2 deletions
				
			
		
							
								
								
									
										61
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										61
									
								
								src/lib.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -579,6 +579,8 @@ struct Heading {
 | 
			
		|||
    location: usize,
 | 
			
		||||
    /// Automatically generated id from heading text.
 | 
			
		||||
    id_auto: String,
 | 
			
		||||
    /// Text of heading, formatting stripped.
 | 
			
		||||
    text: String,
 | 
			
		||||
    /// Overriding id from an explicit attribute on the heading.
 | 
			
		||||
    id_override: Option<String>,
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -630,6 +632,7 @@ impl<'s> PrePass<'s> {
 | 
			
		|||
                        .map(ToString::to_string);
 | 
			
		||||
 | 
			
		||||
                    let mut id_auto = String::new();
 | 
			
		||||
                    let mut text = String::new();
 | 
			
		||||
                    let mut last_whitespace = true;
 | 
			
		||||
                    let inlines = tree.take_inlines().collect::<Vec<_>>();
 | 
			
		||||
                    inline_parser.reset();
 | 
			
		||||
| 
						 | 
				
			
			@ -637,6 +640,7 @@ impl<'s> PrePass<'s> {
 | 
			
		|||
                        inline_parser.feed_line(*sp, i == inlines.len() - 1);
 | 
			
		||||
                        inline_parser.for_each(|ev| match ev.kind {
 | 
			
		||||
                            inline::EventKind::Str => {
 | 
			
		||||
                                text.push_str(ev.span.of(src));
 | 
			
		||||
                                let mut chars = ev.span.of(src).chars().peekable();
 | 
			
		||||
                                while let Some(c) = chars.next() {
 | 
			
		||||
                                    if c.is_whitespace() {
 | 
			
		||||
| 
						 | 
				
			
			@ -654,6 +658,7 @@ impl<'s> PrePass<'s> {
 | 
			
		|||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            inline::EventKind::Atom(inline::Atom::Softbreak) => {
 | 
			
		||||
                                text.push(' ');
 | 
			
		||||
                                id_auto.push('-');
 | 
			
		||||
                            }
 | 
			
		||||
                            _ => {}
 | 
			
		||||
| 
						 | 
				
			
			@ -686,6 +691,7 @@ impl<'s> PrePass<'s> {
 | 
			
		|||
                    headings.push(Heading {
 | 
			
		||||
                        location: e.span.start(),
 | 
			
		||||
                        id_auto,
 | 
			
		||||
                        text,
 | 
			
		||||
                        id_override,
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -703,7 +709,7 @@ impl<'s> PrePass<'s> {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        let mut headings_lex = (0..headings.len()).collect::<Vec<_>>();
 | 
			
		||||
        headings_lex.sort_by_key(|i| &headings[*i].id_auto);
 | 
			
		||||
        headings_lex.sort_by_key(|i| &headings[*i].text);
 | 
			
		||||
 | 
			
		||||
        Self {
 | 
			
		||||
            link_definitions,
 | 
			
		||||
| 
						 | 
				
			
			@ -726,7 +732,7 @@ impl<'s> PrePass<'s> {
 | 
			
		|||
 | 
			
		||||
    fn heading_id_by_tag(&self, tag: &str) -> Option<&str> {
 | 
			
		||||
        self.headings_lex
 | 
			
		||||
            .binary_search_by_key(&tag, |i| &self.headings[*i].id_auto)
 | 
			
		||||
            .binary_search_by_key(&tag, |i| &self.headings[*i].text)
 | 
			
		||||
            .ok()
 | 
			
		||||
            .map(|i| self.heading_id(i))
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1149,6 +1155,57 @@ mod test {
 | 
			
		|||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn heading_ref() {
 | 
			
		||||
        test_parse!(
 | 
			
		||||
            concat!(
 | 
			
		||||
                "A [link][Some Section] to another section.\n", //
 | 
			
		||||
                "\n",                                           //
 | 
			
		||||
                "# Some Section",                               //
 | 
			
		||||
            ),
 | 
			
		||||
            Start(Paragraph, Attributes::new()),
 | 
			
		||||
            Str("A ".into()),
 | 
			
		||||
            Start(
 | 
			
		||||
                Link(
 | 
			
		||||
                    "#Some-Section".into(),
 | 
			
		||||
                    LinkType::Span(SpanLinkType::Reference)
 | 
			
		||||
                ),
 | 
			
		||||
                Attributes::new()
 | 
			
		||||
            ),
 | 
			
		||||
            Str("link".into()),
 | 
			
		||||
            End(Link(
 | 
			
		||||
                "#Some-Section".into(),
 | 
			
		||||
                LinkType::Span(SpanLinkType::Reference)
 | 
			
		||||
            )),
 | 
			
		||||
            Str(" to another section.".into()),
 | 
			
		||||
            End(Paragraph),
 | 
			
		||||
            Blankline,
 | 
			
		||||
            Start(
 | 
			
		||||
                Section {
 | 
			
		||||
                    id: "Some-Section".into()
 | 
			
		||||
                },
 | 
			
		||||
                Attributes::new()
 | 
			
		||||
            ),
 | 
			
		||||
            Start(
 | 
			
		||||
                Heading {
 | 
			
		||||
                    level: 1,
 | 
			
		||||
                    has_section: true,
 | 
			
		||||
                    id: "Some-Section".into(),
 | 
			
		||||
                },
 | 
			
		||||
                Attributes::new(),
 | 
			
		||||
            ),
 | 
			
		||||
            Str("Some Section".into()),
 | 
			
		||||
            End(Heading {
 | 
			
		||||
                level: 1,
 | 
			
		||||
                has_section: true,
 | 
			
		||||
                id: "Some-Section".into(),
 | 
			
		||||
            }),
 | 
			
		||||
            End(Section {
 | 
			
		||||
                id: "Some-Section".into()
 | 
			
		||||
            }),
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn blockquote() {
 | 
			
		||||
        test_parse!(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue