diff options
Diffstat (limited to 'src/parse')
| -rw-r--r-- | src/parse/mod.rs | 3 | ||||
| -rw-r--r-- | src/parse/tokens.rs | 78 |
2 files changed, 48 insertions, 33 deletions
diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 92e86450..47cba111 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -213,10 +213,11 @@ fn markup_node(p: &mut Parser, at_start: &mut bool) { // Text and markup. NodeKind::Text(_) | NodeKind::NonBreakingSpace + | NodeKind::Shy | NodeKind::EnDash | NodeKind::EmDash | NodeKind::Quote(_) - | NodeKind::Linebreak + | NodeKind::Linebreak(_) | NodeKind::Raw(_) | NodeKind::Math(_) | NodeKind::Escape(_) => { diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index a98ef264..053a7f61 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -264,42 +264,52 @@ impl<'s> Tokens<'s> { } fn backslash(&mut self) -> NodeKind { - match self.s.peek() { - Some(c) => match c { - // Backslash and comments. - '\\' | '/' | - // Parenthesis and hashtag. - '[' | ']' | '{' | '}' | '#' | - // Markup. - '~' | '\'' | '"' | '*' | '_' | '`' | '$' | '=' | '-' | '.' => { - self.s.eat_assert(c) ; - NodeKind::Escape(c) - } - 'u' if self.s.rest().starts_with("u{") => { - self.s.eat_assert('u'); - self.s.eat_assert('{'); - let sequence = self.s.eat_while(|c| c.is_ascii_alphanumeric()); - if self.s.eat_if('}') { - if let Some(c) = resolve_hex(sequence) { - NodeKind::Escape(c) - } else { - NodeKind::Error( - ErrorPos::Full, - "invalid unicode escape sequence".into(), - ) - } + let c = match self.s.peek() { + Some(c) => c, + None => return NodeKind::Linebreak(false), + }; + + match c { + // Backslash and comments. + '\\' | '/' | + // Parenthesis and hashtag. + '[' | ']' | '{' | '}' | '#' | + // Markup. + '~' | '\'' | '"' | '*' | '_' | '`' | '$' | '=' | '-' | '.' => { + self.s.eat_assert(c) ; + NodeKind::Escape(c) + } + 'u' if self.s.rest().starts_with("u{") => { + self.s.eat_assert('u'); + self.s.eat_assert('{'); + let sequence = self.s.eat_while(|c| c.is_ascii_alphanumeric()); + if self.s.eat_if('}') { + if let Some(c) = resolve_hex(sequence) { + NodeKind::Escape(c) } else { - self.terminated = false; NodeKind::Error( - ErrorPos::End, - "expected closing brace".into(), + ErrorPos::Full, + "invalid unicode escape sequence".into(), ) } + } else { + self.terminated = false; + NodeKind::Error( + ErrorPos::End, + "expected closing brace".into(), + ) } - c if c.is_whitespace() => NodeKind::Linebreak, - _ => NodeKind::Text('\\'.into()), - }, - None => NodeKind::Linebreak, + } + + // Linebreaks. + c if c.is_whitespace() => NodeKind::Linebreak(false), + '+' => { + self.s.eat_assert(c); + NodeKind::Linebreak(true) + } + + // Just the backslash. + _ => NodeKind::Text('\\'.into()), } } @@ -323,6 +333,8 @@ impl<'s> Tokens<'s> { } else { NodeKind::EnDash } + } else if self.s.eat_if('?') { + NodeKind::Shy } else { NodeKind::Minus } @@ -845,8 +857,10 @@ mod tests { t!(Markup: "_" => Underscore); t!(Markup[""]: "===" => Eq, Eq, Eq); t!(Markup["a1/"]: "= " => Eq, Space(0)); + t!(Markup[" "]: r"\" => Linebreak(false)); + t!(Markup[" "]: r"\+" => Linebreak(true)); t!(Markup: "~" => NonBreakingSpace); - t!(Markup[" "]: r"\" => Linebreak); + t!(Markup["a1/"]: "-?" => Shy); t!(Markup["a "]: r"a--" => Text("a"), EnDash); t!(Markup["a1/"]: "- " => Minus, Space(0)); t!(Markup[" "]: "." => EnumNumbering(None)); |
