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}