implement symbols
e.g. :some-sym:
This commit is contained in:
		
					parent
					
						
							
								61f0d6281e
							
						
					
				
			
			
				commit
				
					
						0420aad0a5
					
				
			
		
					 4 changed files with 51 additions and 0 deletions
				
			
		| 
						 | 
					@ -402,6 +402,7 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> {
 | 
				
			||||||
                            number, number, number
 | 
					                            number, number, number
 | 
				
			||||||
                        )?;
 | 
					                        )?;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    Atom::Symbol(sym) => write!(self.out, ":{}:", sym)?,
 | 
				
			||||||
                    Atom::LeftSingleQuote => self.out.write_str("‘")?,
 | 
					                    Atom::LeftSingleQuote => self.out.write_str("‘")?,
 | 
				
			||||||
                    Atom::RightSingleQuote => self.out.write_str("’")?,
 | 
					                    Atom::RightSingleQuote => self.out.write_str("’")?,
 | 
				
			||||||
                    Atom::LeftDoubleQuote => self.out.write_str("“")?,
 | 
					                    Atom::LeftDoubleQuote => self.out.write_str("“")?,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ use Container::*;
 | 
				
			||||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
					#[derive(Debug, Clone, PartialEq, Eq)]
 | 
				
			||||||
pub enum Atom {
 | 
					pub enum Atom {
 | 
				
			||||||
    FootnoteReference,
 | 
					    FootnoteReference,
 | 
				
			||||||
 | 
					    Symbol,
 | 
				
			||||||
    Softbreak,
 | 
					    Softbreak,
 | 
				
			||||||
    Hardbreak,
 | 
					    Hardbreak,
 | 
				
			||||||
    Escape,
 | 
					    Escape,
 | 
				
			||||||
| 
						 | 
					@ -115,6 +116,7 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
 | 
				
			||||||
            self.parse_verbatim(&first)
 | 
					            self.parse_verbatim(&first)
 | 
				
			||||||
                .or_else(|| self.parse_attributes(&first))
 | 
					                .or_else(|| self.parse_attributes(&first))
 | 
				
			||||||
                .or_else(|| self.parse_autolink(&first))
 | 
					                .or_else(|| self.parse_autolink(&first))
 | 
				
			||||||
 | 
					                .or_else(|| self.parse_symbol(&first))
 | 
				
			||||||
                .or_else(|| self.parse_footnote_reference(&first))
 | 
					                .or_else(|| self.parse_footnote_reference(&first))
 | 
				
			||||||
                .or_else(|| self.parse_container(&first))
 | 
					                .or_else(|| self.parse_container(&first))
 | 
				
			||||||
                .or_else(|| self.parse_atom(&first))
 | 
					                .or_else(|| self.parse_atom(&first))
 | 
				
			||||||
| 
						 | 
					@ -351,6 +353,37 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn parse_symbol(&mut self, first: &lex::Token) -> Option<Event> {
 | 
				
			||||||
 | 
					        if first.kind == lex::Kind::Sym(Symbol::Colon) {
 | 
				
			||||||
 | 
					            let mut ahead = self.lexer.chars();
 | 
				
			||||||
 | 
					            let mut end = false;
 | 
				
			||||||
 | 
					            let mut valid = true;
 | 
				
			||||||
 | 
					            let len = (&mut ahead)
 | 
				
			||||||
 | 
					                .take_while(|c| {
 | 
				
			||||||
 | 
					                    if *c == ':' {
 | 
				
			||||||
 | 
					                        end = true;
 | 
				
			||||||
 | 
					                    } else if !c.is_ascii_alphanumeric() && !matches!(c, '-' | '+' | '_') {
 | 
				
			||||||
 | 
					                        valid = false;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    !end && !c.is_whitespace()
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .map(char::len_utf8)
 | 
				
			||||||
 | 
					                .sum();
 | 
				
			||||||
 | 
					            (end && valid).then(|| {
 | 
				
			||||||
 | 
					                self.lexer = lex::Lexer::new(ahead);
 | 
				
			||||||
 | 
					                self.span = self.span.after(len);
 | 
				
			||||||
 | 
					                let span = self.span;
 | 
				
			||||||
 | 
					                self.span = self.span.after(1);
 | 
				
			||||||
 | 
					                Event {
 | 
				
			||||||
 | 
					                    kind: EventKind::Atom(Symbol),
 | 
				
			||||||
 | 
					                    span,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            None
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_footnote_reference(&mut self, first: &lex::Token) -> Option<Event> {
 | 
					    fn parse_footnote_reference(&mut self, first: &lex::Token) -> Option<Event> {
 | 
				
			||||||
        if first.kind == lex::Kind::Open(Delimiter::Bracket)
 | 
					        if first.kind == lex::Kind::Open(Delimiter::Bracket)
 | 
				
			||||||
            && matches!(
 | 
					            && matches!(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,7 @@ pub enum Symbol {
 | 
				
			||||||
    Quote2,
 | 
					    Quote2,
 | 
				
			||||||
    Tilde,
 | 
					    Tilde,
 | 
				
			||||||
    Underscore,
 | 
					    Underscore,
 | 
				
			||||||
 | 
					    Colon,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
					#[derive(Debug, Clone, Copy, PartialEq, Eq)]
 | 
				
			||||||
| 
						 | 
					@ -232,6 +233,7 @@ impl<I: Iterator<Item = char> + Clone> Lexer<I> {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            '<' => Sym(Lt),
 | 
					            '<' => Sym(Lt),
 | 
				
			||||||
            '|' => Sym(Pipe),
 | 
					            '|' => Sym(Pipe),
 | 
				
			||||||
 | 
					            ':' => Sym(Colon),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            '`' => self.eat_seq(Backtick),
 | 
					            '`' => self.eat_seq(Backtick),
 | 
				
			||||||
            '$' => self.eat_seq(Dollar),
 | 
					            '$' => self.eat_seq(Dollar),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								src/lib.rs
									
										
									
									
									
								
							| 
						 | 
					@ -236,6 +236,8 @@ pub enum OrderedListStyle {
 | 
				
			||||||
pub enum Atom<'s> {
 | 
					pub enum Atom<'s> {
 | 
				
			||||||
    /// A footnote reference.
 | 
					    /// A footnote reference.
 | 
				
			||||||
    FootnoteReference(&'s str, usize),
 | 
					    FootnoteReference(&'s str, usize),
 | 
				
			||||||
 | 
					    /// A symbol, by default rendered literally but may be treated specially.
 | 
				
			||||||
 | 
					    Symbol(CowStr<'s>),
 | 
				
			||||||
    /// Left single quotation mark.
 | 
					    /// Left single quotation mark.
 | 
				
			||||||
    LeftSingleQuote,
 | 
					    LeftSingleQuote,
 | 
				
			||||||
    /// Right double quotation mark.
 | 
					    /// Right double quotation mark.
 | 
				
			||||||
| 
						 | 
					@ -654,6 +656,7 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                            number,
 | 
					                            number,
 | 
				
			||||||
                        )
 | 
					                        )
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    inline::Atom::Symbol => Atom::Symbol(self.inlines.src(inline.span)),
 | 
				
			||||||
                    inline::Atom::Quote { ty, left } => match (ty, left) {
 | 
					                    inline::Atom::Quote { ty, left } => match (ty, left) {
 | 
				
			||||||
                        (inline::QuoteType::Single, true) => Atom::LeftSingleQuote,
 | 
					                        (inline::QuoteType::Single, true) => Atom::LeftSingleQuote,
 | 
				
			||||||
                        (inline::QuoteType::Single, false) => Atom::RightSingleQuote,
 | 
					                        (inline::QuoteType::Single, false) => Atom::RightSingleQuote,
 | 
				
			||||||
| 
						 | 
					@ -1088,6 +1091,18 @@ mod test {
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn symbol() {
 | 
				
			||||||
 | 
					        test_parse!(
 | 
				
			||||||
 | 
					            "abc :+1: def",
 | 
				
			||||||
 | 
					            Start(Paragraph, Attributes::new()),
 | 
				
			||||||
 | 
					            Str("abc ".into()),
 | 
				
			||||||
 | 
					            Atom(Symbol("+1".into())),
 | 
				
			||||||
 | 
					            Str(" def".into()),
 | 
				
			||||||
 | 
					            End(Paragraph),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn link_inline() {
 | 
					    fn link_inline() {
 | 
				
			||||||
        test_parse!(
 | 
					        test_parse!(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue