summaryrefslogtreecommitdiff
path: root/src/parse
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse')
-rw-r--r--src/parse/mod.rs3
-rw-r--r--src/parse/tokens.rs78
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));