Skip to main content

oxyl_parser/
ast.rs

1// AST types produced by the parser.
2//
3// Document is the top level container Node is the union
4// of every thing the parser knows how to recognise - rn 
5// the parser is very very dumb lol
6
7use oxyl_lexer::{Span};
8
9#[derive(Debug, Clone)]
10pub struct Document {
11    pub body: Vec<Node>,
12}
13
14#[derive(Debug, Clone)]
15pub enum Node {
16    Text(String, Span),
17    ParagraphBreak(Span),
18    Command { name: String , args: Vec<Arg>, span: Span, },
19    Group(Vec<Node>, Span),
20    /// Inline match: `$ ... $`. The span covers both `$` delimiters.
21    Math(Vec<Node>, Span),
22    /// Display math: `\[ ... \]`. The span covers both delimiters.
23    DisplayMath(Vec<Node>, Span),
24    /// A `% ...` line comment. THe string is the body without the leading 
25    /// `%` and without the trailing newline - the span covers the whole 
26    /// run, including both. Comments in AST since they can actually affect produced PDF.
27    Comment(String, Span),
28    /// A `&` column separator inside `tabular`/`array`/`align` and other environments.
29    AlignTab(Span),
30    /// A `~` - a non-breaking space. Acts like a regular space for layout
31    /// but forbids a line break at this point.
32    Tilde(Span),
33    /// `\begin{name} ... \end{name}`. `args` is everything after the 
34    /// environment name (optionals and additional mandatory groups). `body`
35    /// holds the parsed children; the span also covers the entire construct.
36    Environment {
37        name: String,
38        args: Vec<Arg>,
39        body: Vec<Node>,
40        span: Span,
41    },
42}
43
44impl Node {
45    pub fn span(&self) -> Span {
46        match self {
47            Node::Text(_, s) => *s,
48            Node::ParagraphBreak(s) => *s,
49            Node::Command { span, .. } => *span,
50            Node::Group(_, s) => *s,
51            Node::Math(_, s) => *s,
52            Node::DisplayMath(_, s) => *s,
53            Node::Comment(_, s) => *s,
54            Node::AlignTab(s) => *s,
55            Node::Tilde(s) => *s,
56            Node::Environment{ span, .. } => *span,
57        }
58    }
59}
60
61#[derive(Debug, Clone)]
62pub enum Arg {
63    Mandatory(Vec<Node>),
64    Optional(Vec<Node>),
65}