typst_syntax/
kind.rs

1/// A syntactical building block of a Typst file.
2///
3/// Can be created by the lexer or by the parser.
4#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
5#[repr(u8)]
6pub enum SyntaxKind {
7    /// The end of token stream.
8    End,
9    /// An invalid sequence of characters.
10    Error,
11
12    /// A shebang: `#! ...`
13    Shebang,
14    /// A line comment: `// ...`.
15    LineComment,
16    /// A block comment: `/* ... */`.
17    BlockComment,
18
19    /// The contents of a file or content block.
20    Markup,
21    /// Plain text without markup.
22    Text,
23    /// Whitespace. Contains at most one newline in markup, as more indicate a
24    /// paragraph break.
25    Space,
26    /// A forced line break: `\`.
27    Linebreak,
28    /// A paragraph break, indicated by one or multiple blank lines.
29    Parbreak,
30    /// An escape sequence: `\#`, `\u{1F5FA}`.
31    Escape,
32    /// A shorthand for a unicode codepoint. For example, `~` for non-breaking
33    /// space or `-?` for a soft hyphen.
34    Shorthand,
35    /// A smart quote: `'` or `"`.
36    SmartQuote,
37    /// Strong content: `*Strong*`.
38    Strong,
39    /// Emphasized content: `_Emphasized_`.
40    Emph,
41    /// Raw text with optional syntax highlighting: `` `...` ``.
42    Raw,
43    /// A language tag at the start of raw text: ``typ ``.
44    RawLang,
45    /// A raw delimiter consisting of 1 or 3+ backticks: `` ` ``.
46    RawDelim,
47    /// A sequence of whitespace to ignore in a raw text: `    `.
48    RawTrimmed,
49    /// A hyperlink: `https://typst.org`.
50    Link,
51    /// A label: `<intro>`.
52    Label,
53    /// A reference: `@target`, `@target[..]`.
54    Ref,
55    /// Introduces a reference: `@target`.
56    RefMarker,
57    /// A section heading: `= Introduction`.
58    Heading,
59    /// Introduces a section heading: `=`, `==`, ...
60    HeadingMarker,
61    /// An item in a bullet list: `- ...`.
62    ListItem,
63    /// Introduces a list item: `-`.
64    ListMarker,
65    /// An item in an enumeration (numbered list): `+ ...` or `1. ...`.
66    EnumItem,
67    /// Introduces an enumeration item: `+`, `1.`.
68    EnumMarker,
69    /// An item in a term list: `/ Term: Details`.
70    TermItem,
71    /// Introduces a term item: `/`.
72    TermMarker,
73    /// A mathematical equation: `$x$`, `$ x^2 $`.
74    Equation,
75
76    /// The contents of a mathematical equation: `x^2 + 1`.
77    Math,
78    /// A lone text fragment in math: `x`, `25`, `3.1415`, `=`, `|`, `[`.
79    MathText,
80    /// An identifier in math: `pi`.
81    MathIdent,
82    /// A shorthand for a unicode codepoint in math: `a <= b`.
83    MathShorthand,
84    /// An alignment point in math: `&`.
85    MathAlignPoint,
86    /// Matched delimiters in math: `[x + y]`.
87    MathDelimited,
88    /// A base with optional attachments in math: `a_1^2`.
89    MathAttach,
90    /// Grouped primes in math: `a'''`.
91    MathPrimes,
92    /// A fraction in math: `x/2`.
93    MathFrac,
94    /// A root in math: `√x`, `∛x` or `∜x`.
95    MathRoot,
96
97    /// A hash that switches into code mode: `#`.
98    Hash,
99    /// A left curly brace, starting a code block: `{`.
100    LeftBrace,
101    /// A right curly brace, terminating a code block: `}`.
102    RightBrace,
103    /// A left square bracket, starting a content block: `[`.
104    LeftBracket,
105    /// A right square bracket, terminating a content block: `]`.
106    RightBracket,
107    /// A left round parenthesis, starting a grouped expression, collection,
108    /// argument or parameter list: `(`.
109    LeftParen,
110    /// A right round parenthesis, terminating a grouped expression, collection,
111    /// argument or parameter list: `)`.
112    RightParen,
113    /// A comma separator in a sequence: `,`.
114    Comma,
115    /// A semicolon terminating an expression: `;`.
116    Semicolon,
117    /// A colon between name/key and value in a dictionary, argument or
118    /// parameter list, or between the term and body of a term list term: `:`.
119    Colon,
120    /// The strong text toggle, multiplication operator, and wildcard import
121    /// symbol: `*`.
122    Star,
123    /// Toggles emphasized text and indicates a subscript in math: `_`.
124    Underscore,
125    /// Starts and ends a mathematical equation: `$`.
126    Dollar,
127    /// The unary plus and binary addition operator: `+`.
128    Plus,
129    /// The unary negation and binary subtraction operator: `-`.
130    Minus,
131    /// The division operator and fraction operator in math: `/`.
132    Slash,
133    /// The superscript operator in math: `^`.
134    Hat,
135    /// The prime in math: `'`.
136    Prime,
137    /// The field access and method call operator: `.`.
138    Dot,
139    /// The assignment operator: `=`.
140    Eq,
141    /// The equality operator: `==`.
142    EqEq,
143    /// The inequality operator: `!=`.
144    ExclEq,
145    /// The less-than operator: `<`.
146    Lt,
147    /// The less-than or equal operator: `<=`.
148    LtEq,
149    /// The greater-than operator: `>`.
150    Gt,
151    /// The greater-than or equal operator: `>=`.
152    GtEq,
153    /// The add-assign operator: `+=`.
154    PlusEq,
155    /// The subtract-assign operator: `-=`.
156    HyphEq,
157    /// The multiply-assign operator: `*=`.
158    StarEq,
159    /// The divide-assign operator: `/=`.
160    SlashEq,
161    /// Indicates a spread or sink: `..`.
162    Dots,
163    /// An arrow between a closure's parameters and body: `=>`.
164    Arrow,
165    /// A root: `√`, `∛` or `∜`.
166    Root,
167
168    /// The `not` operator.
169    Not,
170    /// The `and` operator.
171    And,
172    /// The `or` operator.
173    Or,
174    /// The `none` literal.
175    None,
176    /// The `auto` literal.
177    Auto,
178    /// The `let` keyword.
179    Let,
180    /// The `set` keyword.
181    Set,
182    /// The `show` keyword.
183    Show,
184    /// The `context` keyword.
185    Context,
186    /// The `if` keyword.
187    If,
188    /// The `else` keyword.
189    Else,
190    /// The `for` keyword.
191    For,
192    /// The `in` keyword.
193    In,
194    /// The `while` keyword.
195    While,
196    /// The `break` keyword.
197    Break,
198    /// The `continue` keyword.
199    Continue,
200    /// The `return` keyword.
201    Return,
202    /// The `import` keyword.
203    Import,
204    /// The `include` keyword.
205    Include,
206    /// The `as` keyword.
207    As,
208
209    /// The contents of a code block.
210    Code,
211    /// An identifier: `it`.
212    Ident,
213    /// A boolean: `true`, `false`.
214    Bool,
215    /// An integer: `120`.
216    Int,
217    /// A floating-point number: `1.2`, `10e-4`.
218    Float,
219    /// A numeric value with a unit: `12pt`, `3cm`, `2em`, `90deg`, `50%`.
220    Numeric,
221    /// A quoted string: `"..."`.
222    Str,
223    /// A code block: `{ let x = 1; x + 2 }`.
224    CodeBlock,
225    /// A content block: `[*Hi* there!]`.
226    ContentBlock,
227    /// A grouped expression: `(1 + 2)`.
228    Parenthesized,
229    /// An array: `(1, "hi", 12cm)`.
230    Array,
231    /// A dictionary: `(thickness: 3pt, dash: "solid")`.
232    Dict,
233    /// A named pair: `thickness: 3pt`.
234    Named,
235    /// A keyed pair: `"spacy key": true`.
236    Keyed,
237    /// A unary operation: `-x`.
238    Unary,
239    /// A binary operation: `a + b`.
240    Binary,
241    /// A field access: `properties.age`.
242    FieldAccess,
243    /// An invocation of a function or method: `f(x, y)`.
244    FuncCall,
245    /// A function call's argument list: `(12pt, y)`.
246    Args,
247    /// Spread arguments or an argument sink: `..x`.
248    Spread,
249    /// A closure: `(x, y) => z`.
250    Closure,
251    /// A closure's parameters: `(x, y)`.
252    Params,
253    /// A let binding: `let x = 1`.
254    LetBinding,
255    /// A set rule: `set text(...)`.
256    SetRule,
257    /// A show rule: `show heading: it => emph(it.body)`.
258    ShowRule,
259    /// A contextual expression: `context text.lang`.
260    Contextual,
261    /// An if-else conditional: `if x { y } else { z }`.
262    Conditional,
263    /// A while loop: `while x { y }`.
264    WhileLoop,
265    /// A for loop: `for x in y { z }`.
266    ForLoop,
267    /// A module import: `import "utils.typ": a, b, c`.
268    ModuleImport,
269    /// Items to import from a module: `a, b, c`.
270    ImportItems,
271    /// A path to an imported name from a submodule: `a.b.c`.
272    ImportItemPath,
273    /// A renamed import item: `a as d`.
274    RenamedImportItem,
275    /// A module include: `include "chapter1.typ"`.
276    ModuleInclude,
277    /// A break from a loop: `break`.
278    LoopBreak,
279    /// A continue in a loop: `continue`.
280    LoopContinue,
281    /// A return from a function: `return`, `return x + 1`.
282    FuncReturn,
283    /// A destructuring pattern: `(x, _, ..y)`.
284    Destructuring,
285    /// A destructuring assignment expression: `(x, y) = (1, 2)`.
286    DestructAssignment,
287}
288
289impl SyntaxKind {
290    /// Is this a bracket, brace, or parenthesis?
291    pub fn is_grouping(self) -> bool {
292        matches!(
293            self,
294            Self::LeftBracket
295                | Self::LeftBrace
296                | Self::LeftParen
297                | Self::RightBracket
298                | Self::RightBrace
299                | Self::RightParen
300        )
301    }
302
303    /// Does this node terminate a preceding expression?
304    pub fn is_terminator(self) -> bool {
305        matches!(
306            self,
307            Self::End
308                | Self::Semicolon
309                | Self::RightBrace
310                | Self::RightParen
311                | Self::RightBracket
312        )
313    }
314
315    /// Is this a code or content block.
316    pub fn is_block(self) -> bool {
317        matches!(self, Self::CodeBlock | Self::ContentBlock)
318    }
319
320    /// Does this node need termination through a semicolon or linebreak?
321    pub fn is_stmt(self) -> bool {
322        matches!(
323            self,
324            Self::LetBinding
325                | Self::SetRule
326                | Self::ShowRule
327                | Self::ModuleImport
328                | Self::ModuleInclude
329        )
330    }
331
332    /// Is this node is a keyword.
333    pub fn is_keyword(self) -> bool {
334        matches!(
335            self,
336            Self::Not
337                | Self::And
338                | Self::Or
339                | Self::None
340                | Self::Auto
341                | Self::Let
342                | Self::Set
343                | Self::Show
344                | Self::Context
345                | Self::If
346                | Self::Else
347                | Self::For
348                | Self::In
349                | Self::While
350                | Self::Break
351                | Self::Continue
352                | Self::Return
353                | Self::Import
354                | Self::Include
355                | Self::As
356        )
357    }
358
359    /// Whether this kind of node is automatically skipped by the parser in
360    /// code and math mode.
361    pub fn is_trivia(self) -> bool {
362        matches!(
363            self,
364            Self::Shebang
365                | Self::LineComment
366                | Self::BlockComment
367                | Self::Space
368                | Self::Parbreak
369        )
370    }
371
372    /// Whether this is an error.
373    pub fn is_error(self) -> bool {
374        self == Self::Error
375    }
376
377    /// A human-readable name for the kind.
378    pub fn name(self) -> &'static str {
379        match self {
380            Self::End => "end of tokens",
381            Self::Error => "syntax error",
382            Self::Shebang => "shebang",
383            Self::LineComment => "line comment",
384            Self::BlockComment => "block comment",
385            Self::Markup => "markup",
386            Self::Text => "text",
387            Self::Space => "space",
388            Self::Linebreak => "line break",
389            Self::Parbreak => "paragraph break",
390            Self::Escape => "escape sequence",
391            Self::Shorthand => "shorthand",
392            Self::SmartQuote => "smart quote",
393            Self::Strong => "strong content",
394            Self::Emph => "emphasized content",
395            Self::Raw => "raw block",
396            Self::RawLang => "raw language tag",
397            Self::RawTrimmed => "raw trimmed",
398            Self::RawDelim => "raw delimiter",
399            Self::Link => "link",
400            Self::Label => "label",
401            Self::Ref => "reference",
402            Self::RefMarker => "reference marker",
403            Self::Heading => "heading",
404            Self::HeadingMarker => "heading marker",
405            Self::ListItem => "list item",
406            Self::ListMarker => "list marker",
407            Self::EnumItem => "enum item",
408            Self::EnumMarker => "enum marker",
409            Self::TermItem => "term list item",
410            Self::TermMarker => "term marker",
411            Self::Equation => "equation",
412            Self::Math => "math",
413            Self::MathText => "math text",
414            Self::MathIdent => "math identifier",
415            Self::MathShorthand => "math shorthand",
416            Self::MathAlignPoint => "math alignment point",
417            Self::MathDelimited => "delimited math",
418            Self::MathAttach => "math attachments",
419            Self::MathFrac => "math fraction",
420            Self::MathRoot => "math root",
421            Self::MathPrimes => "math primes",
422            Self::Hash => "hash",
423            Self::LeftBrace => "opening brace",
424            Self::RightBrace => "closing brace",
425            Self::LeftBracket => "opening bracket",
426            Self::RightBracket => "closing bracket",
427            Self::LeftParen => "opening paren",
428            Self::RightParen => "closing paren",
429            Self::Comma => "comma",
430            Self::Semicolon => "semicolon",
431            Self::Colon => "colon",
432            Self::Star => "star",
433            Self::Underscore => "underscore",
434            Self::Dollar => "dollar sign",
435            Self::Plus => "plus",
436            Self::Minus => "minus",
437            Self::Slash => "slash",
438            Self::Hat => "hat",
439            Self::Prime => "prime",
440            Self::Dot => "dot",
441            Self::Eq => "equals sign",
442            Self::EqEq => "equality operator",
443            Self::ExclEq => "inequality operator",
444            Self::Lt => "less-than operator",
445            Self::LtEq => "less-than or equal operator",
446            Self::Gt => "greater-than operator",
447            Self::GtEq => "greater-than or equal operator",
448            Self::PlusEq => "add-assign operator",
449            Self::HyphEq => "subtract-assign operator",
450            Self::StarEq => "multiply-assign operator",
451            Self::SlashEq => "divide-assign operator",
452            Self::Dots => "dots",
453            Self::Arrow => "arrow",
454            Self::Root => "root",
455            Self::Not => "operator `not`",
456            Self::And => "operator `and`",
457            Self::Or => "operator `or`",
458            Self::None => "`none`",
459            Self::Auto => "`auto`",
460            Self::Let => "keyword `let`",
461            Self::Set => "keyword `set`",
462            Self::Show => "keyword `show`",
463            Self::Context => "keyword `context`",
464            Self::If => "keyword `if`",
465            Self::Else => "keyword `else`",
466            Self::For => "keyword `for`",
467            Self::In => "keyword `in`",
468            Self::While => "keyword `while`",
469            Self::Break => "keyword `break`",
470            Self::Continue => "keyword `continue`",
471            Self::Return => "keyword `return`",
472            Self::Import => "keyword `import`",
473            Self::Include => "keyword `include`",
474            Self::As => "keyword `as`",
475            Self::Code => "code",
476            Self::Ident => "identifier",
477            Self::Bool => "boolean",
478            Self::Int => "integer",
479            Self::Float => "float",
480            Self::Numeric => "numeric value",
481            Self::Str => "string",
482            Self::CodeBlock => "code block",
483            Self::ContentBlock => "content block",
484            Self::Parenthesized => "group",
485            Self::Array => "array",
486            Self::Dict => "dictionary",
487            Self::Named => "named pair",
488            Self::Keyed => "keyed pair",
489            Self::Unary => "unary expression",
490            Self::Binary => "binary expression",
491            Self::FieldAccess => "field access",
492            Self::FuncCall => "function call",
493            Self::Args => "call arguments",
494            Self::Spread => "spread",
495            Self::Closure => "closure",
496            Self::Params => "closure parameters",
497            Self::LetBinding => "`let` expression",
498            Self::SetRule => "`set` expression",
499            Self::ShowRule => "`show` expression",
500            Self::Contextual => "`context` expression",
501            Self::Conditional => "`if` expression",
502            Self::WhileLoop => "while-loop expression",
503            Self::ForLoop => "for-loop expression",
504            Self::ModuleImport => "`import` expression",
505            Self::ImportItems => "import items",
506            Self::ImportItemPath => "imported item path",
507            Self::RenamedImportItem => "renamed import item",
508            Self::ModuleInclude => "`include` expression",
509            Self::LoopBreak => "`break` expression",
510            Self::LoopContinue => "`continue` expression",
511            Self::FuncReturn => "`return` expression",
512            Self::Destructuring => "destructuring pattern",
513            Self::DestructAssignment => "destructuring assignment expression",
514        }
515    }
516}