diff options
Diffstat (limited to 'crates/typst-syntax/src')
| -rw-r--r-- | crates/typst-syntax/src/ast.rs | 17 | ||||
| -rw-r--r-- | crates/typst-syntax/src/highlight.rs | 2 | ||||
| -rw-r--r-- | crates/typst-syntax/src/kind.rs | 7 | ||||
| -rw-r--r-- | crates/typst-syntax/src/lexer.rs | 1 | ||||
| -rw-r--r-- | crates/typst-syntax/src/parser.rs | 9 | ||||
| -rw-r--r-- | crates/typst-syntax/src/set.rs | 1 |
6 files changed, 37 insertions, 0 deletions
diff --git a/crates/typst-syntax/src/ast.rs b/crates/typst-syntax/src/ast.rs index 6dd9b5f6..df9cef0c 100644 --- a/crates/typst-syntax/src/ast.rs +++ b/crates/typst-syntax/src/ast.rs @@ -187,6 +187,8 @@ pub enum Expr<'a> { Set(SetRule<'a>), /// A show rule: `show heading: it => emph(it.body)`. Show(ShowRule<'a>), + /// A contextual expression: `context text.lang`. + Contextual(Contextual<'a>), /// An if-else conditional: `if x { y } else { z }`. Conditional(Conditional<'a>), /// A while loop: `while x { y }`. @@ -264,6 +266,7 @@ impl<'a> AstNode<'a> for Expr<'a> { SyntaxKind::DestructAssignment => node.cast().map(Self::DestructAssign), SyntaxKind::SetRule => node.cast().map(Self::Set), SyntaxKind::ShowRule => node.cast().map(Self::Show), + SyntaxKind::Contextual => node.cast().map(Self::Contextual), SyntaxKind::Conditional => node.cast().map(Self::Conditional), SyntaxKind::WhileLoop => node.cast().map(Self::While), SyntaxKind::ForLoop => node.cast().map(Self::For), @@ -326,6 +329,7 @@ impl<'a> AstNode<'a> for Expr<'a> { Self::DestructAssign(v) => v.to_untyped(), Self::Set(v) => v.to_untyped(), Self::Show(v) => v.to_untyped(), + Self::Contextual(v) => v.to_untyped(), Self::Conditional(v) => v.to_untyped(), Self::While(v) => v.to_untyped(), Self::For(v) => v.to_untyped(), @@ -361,6 +365,7 @@ impl Expr<'_> { | Self::Let(_) | Self::Set(_) | Self::Show(_) + | Self::Contextual(_) | Self::Conditional(_) | Self::While(_) | Self::For(_) @@ -1947,6 +1952,18 @@ impl<'a> ShowRule<'a> { } node! { + /// A contextual expression: `context text.lang`. + Contextual +} + +impl<'a> Contextual<'a> { + /// The expression which depends on the context. + pub fn body(self) -> Expr<'a> { + self.0.cast_first_match().unwrap_or_default() + } +} + +node! { /// An if-else conditional: `if x { y } else { z }`. Conditional } diff --git a/crates/typst-syntax/src/highlight.rs b/crates/typst-syntax/src/highlight.rs index 99fbf4fe..19d35d0a 100644 --- a/crates/typst-syntax/src/highlight.rs +++ b/crates/typst-syntax/src/highlight.rs @@ -230,6 +230,7 @@ pub fn highlight(node: &LinkedNode) -> Option<Tag> { SyntaxKind::Let => Some(Tag::Keyword), SyntaxKind::Set => Some(Tag::Keyword), SyntaxKind::Show => Some(Tag::Keyword), + SyntaxKind::Context => Some(Tag::Keyword), SyntaxKind::If => Some(Tag::Keyword), SyntaxKind::Else => Some(Tag::Keyword), SyntaxKind::For => Some(Tag::Keyword), @@ -267,6 +268,7 @@ pub fn highlight(node: &LinkedNode) -> Option<Tag> { SyntaxKind::LetBinding => None, SyntaxKind::SetRule => None, SyntaxKind::ShowRule => None, + SyntaxKind::Contextual => None, SyntaxKind::Conditional => None, SyntaxKind::WhileLoop => None, SyntaxKind::ForLoop => None, diff --git a/crates/typst-syntax/src/kind.rs b/crates/typst-syntax/src/kind.rs index 536c9381..e5dd4e9b 100644 --- a/crates/typst-syntax/src/kind.rs +++ b/crates/typst-syntax/src/kind.rs @@ -159,6 +159,8 @@ pub enum SyntaxKind { Set, /// The `show` keyword. Show, + /// The `context` keyword. + Context, /// The `if` keyword. If, /// The `else` keyword. @@ -232,6 +234,8 @@ pub enum SyntaxKind { SetRule, /// A show rule: `show heading: it => emph(it.body)`. ShowRule, + /// A contextual expression: `context text.lang`. + Contextual, /// An if-else conditional: `if x { y } else { z }`. Conditional, /// A while loop: `while x { y }`. @@ -322,6 +326,7 @@ impl SyntaxKind { | Self::Let | Self::Set | Self::Show + | Self::Context | Self::If | Self::Else | Self::For @@ -426,6 +431,7 @@ impl SyntaxKind { Self::Let => "keyword `let`", Self::Set => "keyword `set`", Self::Show => "keyword `show`", + Self::Context => "keyword `context`", Self::If => "keyword `if`", Self::Else => "keyword `else`", Self::For => "keyword `for`", @@ -462,6 +468,7 @@ impl SyntaxKind { Self::LetBinding => "`let` expression", Self::SetRule => "`set` expression", Self::ShowRule => "`show` expression", + Self::Contextual => "`context` expression", Self::Conditional => "`if` expression", Self::WhileLoop => "while-loop expression", Self::ForLoop => "for-loop expression", diff --git a/crates/typst-syntax/src/lexer.rs b/crates/typst-syntax/src/lexer.rs index f0cf8846..cd1998a6 100644 --- a/crates/typst-syntax/src/lexer.rs +++ b/crates/typst-syntax/src/lexer.rs @@ -616,6 +616,7 @@ fn keyword(ident: &str) -> Option<SyntaxKind> { "let" => SyntaxKind::Let, "set" => SyntaxKind::Set, "show" => SyntaxKind::Show, + "context" => SyntaxKind::Context, "if" => SyntaxKind::If, "else" => SyntaxKind::Else, "for" => SyntaxKind::For, diff --git a/crates/typst-syntax/src/parser.rs b/crates/typst-syntax/src/parser.rs index 32e15cb7..567bcbd1 100644 --- a/crates/typst-syntax/src/parser.rs +++ b/crates/typst-syntax/src/parser.rs @@ -750,6 +750,7 @@ fn code_primary(p: &mut Parser, atomic: bool) { SyntaxKind::Let => let_binding(p), SyntaxKind::Set => set_rule(p), SyntaxKind::Show => show_rule(p), + SyntaxKind::Context => contextual(p, atomic), SyntaxKind::If => conditional(p), SyntaxKind::While => while_loop(p), SyntaxKind::For => for_loop(p), @@ -889,6 +890,14 @@ fn show_rule(p: &mut Parser) { p.wrap(m, SyntaxKind::ShowRule); } +/// Parses a contextual expression: `context text.lang`. +fn contextual(p: &mut Parser, atomic: bool) { + let m = p.marker(); + p.assert(SyntaxKind::Context); + code_expr_prec(p, atomic, 0); + p.wrap(m, SyntaxKind::Contextual); +} + /// Parses an if-else conditional: `if x { y } else { z }`. fn conditional(p: &mut Parser) { let m = p.marker(); diff --git a/crates/typst-syntax/src/set.rs b/crates/typst-syntax/src/set.rs index 88a9b18b..906d5fac 100644 --- a/crates/typst-syntax/src/set.rs +++ b/crates/typst-syntax/src/set.rs @@ -102,6 +102,7 @@ pub const ATOMIC_CODE_PRIMARY: SyntaxSet = SyntaxSet::new() .add(SyntaxKind::Let) .add(SyntaxKind::Set) .add(SyntaxKind::Show) + .add(SyntaxKind::Context) .add(SyntaxKind::If) .add(SyntaxKind::While) .add(SyntaxKind::For) |
