diff options
Diffstat (limited to 'src/syntax')
| -rw-r--r-- | src/syntax/node.rs | 110 | ||||
| -rw-r--r-- | src/syntax/token.rs | 14 | ||||
| -rw-r--r-- | src/syntax/visit.rs | 15 |
3 files changed, 42 insertions, 97 deletions
diff --git a/src/syntax/node.rs b/src/syntax/node.rs index 5f76b56a..b4684d0b 100644 --- a/src/syntax/node.rs +++ b/src/syntax/node.rs @@ -17,70 +17,16 @@ pub enum Node { Strong(Span), /// Emphasized text was enabled / disabled: `_`. Emph(Span), - /// A section heading: `= Introduction`. - Heading(HeadingNode), /// A raw block with optional syntax highlighting: `` `...` ``. Raw(RawNode), + /// A section heading: `= Introduction`. + Heading(HeadingNode), + /// A single list item: `- ...`. + List(ListNode), /// An expression. Expr(Expr), } -impl Node { - // The names of the corresponding library functions. - pub const LINEBREAK: &'static str = "linebreak"; - pub const PARBREAK: &'static str = "parbreak"; - pub const STRONG: &'static str = "strong"; - pub const EMPH: &'static str = "emph"; - pub const HEADING: &'static str = "heading"; - pub const RAW: &'static str = "raw"; - - /// Desugar markup into a function call. - pub fn desugar(&self) -> Option<CallExpr> { - match *self { - Self::Text(_) => None, - Self::Space => None, - Self::Linebreak(span) => Some(call(span, Self::LINEBREAK)), - Self::Parbreak(span) => Some(call(span, Self::PARBREAK)), - Self::Strong(span) => Some(call(span, Self::STRONG)), - Self::Emph(span) => Some(call(span, Self::EMPH)), - Self::Heading(ref heading) => Some(heading.desugar()), - Self::Raw(ref raw) => Some(raw.desugar()), - Self::Expr(_) => None, - } - } -} - -/// A section heading: `= Introduction`. -#[derive(Debug, Clone, PartialEq)] -pub struct HeadingNode { - /// The source code location. - pub span: Span, - /// The section depth (numer of equals signs). - pub level: usize, - /// The contents of the heading. - pub contents: Rc<Tree>, -} - -impl HeadingNode { - pub const LEVEL: &'static str = "level"; - pub const BODY: &'static str = "body"; - - /// Desugar into a function call. - pub fn desugar(&self) -> CallExpr { - let Self { span, level, ref contents } = *self; - let mut call = call(span, Node::HEADING); - call.args.items.push(CallArg::Named(Named { - name: ident(span, Self::LEVEL), - expr: Expr::Int(span, level as i64), - })); - call.args.items.push(CallArg::Pos(Expr::Template(TemplateExpr { - span, - tree: Rc::clone(&contents), - }))); - call - } -} - /// A raw block with optional syntax highlighting: `` `...` ``. /// /// Raw blocks start with 1 or 3+ backticks and end with the same number of @@ -158,38 +104,22 @@ pub struct RawNode { pub block: bool, } -impl RawNode { - pub const LANG: &'static str = "lang"; - pub const BLOCK: &'static str = "block"; - pub const TEXT: &'static str = "text"; - - /// Desugar into a function call. - pub fn desugar(&self) -> CallExpr { - let Self { span, ref lang, ref text, block } = *self; - let mut call = call(span, Node::RAW); - if let Some(lang) = lang { - call.args.items.push(CallArg::Named(Named { - name: ident(span, Self::LANG), - expr: Expr::Str(span, lang.string.clone()), - })); - } - call.args.items.push(CallArg::Named(Named { - name: ident(span, Self::BLOCK), - expr: Expr::Bool(span, block), - })); - call.args.items.push(CallArg::Pos(Expr::Str(span, text.clone()))); - call - } -} - -fn call(span: Span, name: &str) -> CallExpr { - CallExpr { - span, - callee: Box::new(Expr::Ident(Ident { span, string: name.into() })), - args: CallArgs { span, items: vec![] }, - } +/// A section heading: `= Introduction`. +#[derive(Debug, Clone, PartialEq)] +pub struct HeadingNode { + /// The source code location. + pub span: Span, + /// The section depth (numer of equals signs). + pub level: usize, + /// The contents of the heading. + pub body: Rc<Tree>, } -fn ident(span: Span, string: &str) -> Ident { - Ident { span, string: string.into() } +/// A single list item: `- ...`. +#[derive(Debug, Clone, PartialEq)] +pub struct ListNode { + /// The source code location. + pub span: Span, + /// The contents of the list item. + pub body: Tree, } diff --git a/src/syntax/token.rs b/src/syntax/token.rs index 538d81b7..9098f176 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -24,6 +24,10 @@ pub enum Token<'s> { Hashtag, /// A tilde: `~`. Tilde, + /// Two hyphens: `--`. + HyphHyph, + /// Three hyphens: `---`. + HyphHyphHyph, /// A backslash followed by nothing or whitespace: `\`. Backslash, /// A comma: `,`. @@ -103,15 +107,15 @@ pub enum Token<'s> { Space(usize), /// A consecutive non-markup string. Text(&'s str), + /// A slash and the letter "u" followed by a hexadecimal unicode entity + /// enclosed in curly braces: `\u{1F5FA}`. + UnicodeEscape(UnicodeEscapeToken<'s>), /// An arbitrary number of backticks followed by inner contents, terminated /// with the same number of backticks: `` `...` ``. Raw(RawToken<'s>), /// One or two dollar signs followed by inner contents, terminated with the /// same number of dollar signs. Math(MathToken<'s>), - /// A slash and the letter "u" followed by a hexadecimal unicode entity - /// enclosed in curly braces: `\u{1F5FA}`. - UnicodeEscape(UnicodeEscapeToken<'s>), /// An identifier: `center`. Ident(&'s str), /// A boolean: `true`, `false`. @@ -204,6 +208,8 @@ impl<'s> Token<'s> { Self::Underscore => "underscore", Self::Hashtag => "hashtag", Self::Tilde => "tilde", + Self::HyphHyph => "en dash", + Self::HyphHyphHyph => "em dash", Self::Backslash => "backslash", Self::Comma => "comma", Self::Semicolon => "semicolon", @@ -242,9 +248,9 @@ impl<'s> Token<'s> { Self::Using => "keyword `using`", Self::Space(_) => "space", Self::Text(_) => "text", + Self::UnicodeEscape(_) => "unicode escape sequence", Self::Raw(_) => "raw block", Self::Math(_) => "math formula", - Self::UnicodeEscape(_) => "unicode escape sequence", Self::Ident(_) => "identifier", Self::Bool(_) => "boolean", Self::Int(_) => "integer", diff --git a/src/syntax/visit.rs b/src/syntax/visit.rs index 40d8e664..86481d4e 100644 --- a/src/syntax/visit.rs +++ b/src/syntax/visit.rs @@ -52,16 +52,25 @@ visit! { match node { Node::Text(_) => {} Node::Space => {} - Node::Strong(_) => {} Node::Linebreak(_) => {} Node::Parbreak(_) => {} + Node::Strong(_) => {} Node::Emph(_) => {} - Node::Heading(heading) => v.visit_tree(&heading.contents), Node::Raw(_) => {} - Node::Expr(expr) => v.visit_expr(expr), + Node::Heading(n) => v.visit_heading(n), + Node::List(n) => v.visit_list(n), + Node::Expr(n) => v.visit_expr(n), } } + fn visit_heading(v, node: &HeadingNode) { + v.visit_tree(&node.body); + } + + fn visit_list(v, node: &ListNode) { + v.visit_tree(&node.body); + } + fn visit_expr(v, node: &Expr) { match node { Expr::None(_) => {} |
