diff options
Diffstat (limited to 'src/parse')
| -rw-r--r-- | src/parse/mod.rs | 30 | ||||
| -rw-r--r-- | src/parse/tokens.rs | 31 |
2 files changed, 48 insertions, 13 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs index a997421e..0737d4ca 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -175,18 +175,24 @@ fn markup_indented(p: &mut Parser, min_indent: usize) { _ => false, }); + let marker = p.marker(); let mut at_start = false; - p.perform(NodeKind::Markup { min_indent }, |p| { - while !p.eof() { - if let Some(NodeKind::Space { newlines: (1 ..) }) = p.peek() { - if p.column(p.current_end()) < min_indent { - break; - } - } - markup_node(p, &mut at_start); + while !p.eof() { + match p.peek() { + Some(NodeKind::Space { newlines: (1 ..) }) + if p.column(p.current_end()) < min_indent => + { + break; + } + Some(NodeKind::Label(_)) => break, + _ => {} } - }); + + markup_node(p, &mut at_start); + } + + marker.end(p, NodeKind::Markup { min_indent }); } /// Parse a markup node. @@ -212,16 +218,18 @@ fn markup_node(p: &mut Parser, at_start: &mut bool) { // Text and markup. NodeKind::Text(_) + | NodeKind::Linebreak { .. } | NodeKind::NonBreakingSpace | NodeKind::Shy | NodeKind::EnDash | NodeKind::EmDash | NodeKind::Ellipsis | NodeKind::Quote { .. } - | NodeKind::Linebreak { .. } + | NodeKind::Escape(_) | NodeKind::Raw(_) | NodeKind::Math(_) - | NodeKind::Escape(_) => { + | NodeKind::Label(_) + | NodeKind::Ref(_) => { p.eat(); } diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index be107f3c..e004dd37 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -148,8 +148,10 @@ impl<'s> Tokens<'s> { '*' if !self.in_word() => NodeKind::Star, '_' if !self.in_word() => NodeKind::Underscore, '`' => self.raw(), - '$' => self.math(), '=' => NodeKind::Eq, + '$' => self.math(), + '<' => self.label(), + '@' => self.reference(), c if c == '.' || c.is_ascii_digit() => self.numbering(start, c), // Plain text. @@ -277,7 +279,9 @@ impl<'s> Tokens<'s> { // Parenthesis and hashtag. '[' | ']' | '{' | '}' | '#' | // Markup. - '~' | '\'' | '"' | '*' | '_' | '`' | '$' | '=' | '-' | '.' => { + '~' | '-' | '.' | ':' | + '\'' | '"' | '*' | '_' | '`' | '$' | '=' | + '<' | '>' | '@' => { self.s.expect(c); NodeKind::Escape(c) } @@ -453,6 +457,29 @@ impl<'s> Tokens<'s> { } } + fn label(&mut self) -> NodeKind { + let label = self.s.eat_while(is_id_continue); + if self.s.eat_if('>') { + if !label.is_empty() { + NodeKind::Label(label.into()) + } else { + NodeKind::Error(SpanPos::Full, "label cannot be empty".into()) + } + } else { + self.terminated = false; + NodeKind::Error(SpanPos::End, "expected closing angle bracket".into()) + } + } + + fn reference(&mut self) -> NodeKind { + let label = self.s.eat_while(is_id_continue); + if !label.is_empty() { + NodeKind::Ref(label.into()) + } else { + NodeKind::Error(SpanPos::Full, "label cannot be empty".into()) + } + } + fn ident(&mut self, start: usize) -> NodeKind { self.s.eat_while(is_id_continue); match self.s.from(start) { |
