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,
 | 
					    location: usize,
 | 
				
			||||||
    /// Automatically generated id from heading text.
 | 
					    /// Automatically generated id from heading text.
 | 
				
			||||||
    id_auto: String,
 | 
					    id_auto: String,
 | 
				
			||||||
 | 
					    /// Text of heading, formatting stripped.
 | 
				
			||||||
 | 
					    text: String,
 | 
				
			||||||
    /// Overriding id from an explicit attribute on the heading.
 | 
					    /// Overriding id from an explicit attribute on the heading.
 | 
				
			||||||
    id_override: Option<String>,
 | 
					    id_override: Option<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -630,6 +632,7 @@ impl<'s> PrePass<'s> {
 | 
				
			||||||
                        .map(ToString::to_string);
 | 
					                        .map(ToString::to_string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    let mut id_auto = String::new();
 | 
					                    let mut id_auto = String::new();
 | 
				
			||||||
 | 
					                    let mut text = String::new();
 | 
				
			||||||
                    let mut last_whitespace = true;
 | 
					                    let mut last_whitespace = true;
 | 
				
			||||||
                    let inlines = tree.take_inlines().collect::<Vec<_>>();
 | 
					                    let inlines = tree.take_inlines().collect::<Vec<_>>();
 | 
				
			||||||
                    inline_parser.reset();
 | 
					                    inline_parser.reset();
 | 
				
			||||||
| 
						 | 
					@ -637,6 +640,7 @@ impl<'s> PrePass<'s> {
 | 
				
			||||||
                        inline_parser.feed_line(*sp, i == inlines.len() - 1);
 | 
					                        inline_parser.feed_line(*sp, i == inlines.len() - 1);
 | 
				
			||||||
                        inline_parser.for_each(|ev| match ev.kind {
 | 
					                        inline_parser.for_each(|ev| match ev.kind {
 | 
				
			||||||
                            inline::EventKind::Str => {
 | 
					                            inline::EventKind::Str => {
 | 
				
			||||||
 | 
					                                text.push_str(ev.span.of(src));
 | 
				
			||||||
                                let mut chars = ev.span.of(src).chars().peekable();
 | 
					                                let mut chars = ev.span.of(src).chars().peekable();
 | 
				
			||||||
                                while let Some(c) = chars.next() {
 | 
					                                while let Some(c) = chars.next() {
 | 
				
			||||||
                                    if c.is_whitespace() {
 | 
					                                    if c.is_whitespace() {
 | 
				
			||||||
| 
						 | 
					@ -654,6 +658,7 @@ impl<'s> PrePass<'s> {
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            inline::EventKind::Atom(inline::Atom::Softbreak) => {
 | 
					                            inline::EventKind::Atom(inline::Atom::Softbreak) => {
 | 
				
			||||||
 | 
					                                text.push(' ');
 | 
				
			||||||
                                id_auto.push('-');
 | 
					                                id_auto.push('-');
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            _ => {}
 | 
					                            _ => {}
 | 
				
			||||||
| 
						 | 
					@ -686,6 +691,7 @@ impl<'s> PrePass<'s> {
 | 
				
			||||||
                    headings.push(Heading {
 | 
					                    headings.push(Heading {
 | 
				
			||||||
                        location: e.span.start(),
 | 
					                        location: e.span.start(),
 | 
				
			||||||
                        id_auto,
 | 
					                        id_auto,
 | 
				
			||||||
 | 
					                        text,
 | 
				
			||||||
                        id_override,
 | 
					                        id_override,
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					@ -703,7 +709,7 @@ impl<'s> PrePass<'s> {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut headings_lex = (0..headings.len()).collect::<Vec<_>>();
 | 
					        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 {
 | 
					        Self {
 | 
				
			||||||
            link_definitions,
 | 
					            link_definitions,
 | 
				
			||||||
| 
						 | 
					@ -726,7 +732,7 @@ impl<'s> PrePass<'s> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn heading_id_by_tag(&self, tag: &str) -> Option<&str> {
 | 
					    fn heading_id_by_tag(&self, tag: &str) -> Option<&str> {
 | 
				
			||||||
        self.headings_lex
 | 
					        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()
 | 
					            .ok()
 | 
				
			||||||
            .map(|i| self.heading_id(i))
 | 
					            .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]
 | 
					    #[test]
 | 
				
			||||||
    fn blockquote() {
 | 
					    fn blockquote() {
 | 
				
			||||||
        test_parse!(
 | 
					        test_parse!(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue