1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
mod code_block;
mod command;
mod header;
mod link;
mod list;
mod literal;
mod range;
mod table;
pub use crate::ast::{code_block::CodeBlock, command::Command, header::Header, list::ListView, table::TableView};
pub use command::CommandKind;
pub use link::SmartLink;
pub use range::TextRange;
use std::{
collections::HashMap,
fmt::{self, Display, Formatter},
};
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ASTNode {
pub kind: ASTKind<ASTNode>,
pub range: TextRange,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ASTKind<T> {
None,
Statements(Vec<T>),
Header(Box<Header<T>>),
HorizontalRule,
Paragraph(Vec<T>),
CodeBlock(Box<CodeBlock>),
MathBlock(Box<String>),
TableView(Box<TableView<T>>),
ListView(Box<ListView<T>>),
Normal(Box<String>),
Raw(Box<String>),
Code(Box<String>),
Italic(Vec<T>),
Bold(Vec<T>),
Emphasis(Vec<T>),
Underline(Vec<T>),
Strikethrough(Vec<T>),
Undercover(Vec<T>),
MathInline(Box<String>),
MathDisplay(Box<String>),
Escaped(char),
Link(Box<SmartLink>),
Command(Box<Command<T>>),
String(Box<String>),
Number(Box<String>),
Boolean(bool),
Array,
Object,
}
impl<T> Default for ASTKind<T> {
fn default() -> Self {
Self::None
}
}
impl Default for ASTNode {
fn default() -> Self {
Self { kind: ASTKind::None, range: Default::default() }
}
}
impl<T> ASTKind<T> {
pub fn statements(children: Vec<T>) -> Self {
Self::Statements(children)
}
pub fn paragraph(children: Vec<T>) -> Self {
Self::Paragraph(children)
}
pub fn header(children: Vec<T>, level: usize) -> Self {
let header = Header { level, children };
Self::Header(Box::new(header))
}
pub fn code(code: CodeBlock) -> Self {
Self::CodeBlock(Box::new(code))
}
pub fn command(cmd: Command<T>) -> Self {
Self::Command(Box::new(cmd))
}
pub fn hr() -> ASTKind<T> {
Self::HorizontalRule
}
pub fn math(text: String, style: &str) -> Self {
match style {
"inline" => Self::MathInline(Box::new(text)),
"display" => Self::MathDisplay(Box::new(text)),
_ => Self::MathBlock(Box::new(text)),
}
}
pub fn style(children: Vec<T>, style: &str) -> Self {
match style {
"*" | "i" | "italic" => Self::Italic(children),
"**" | "b" | "bold" => Self::Bold(children),
"***" | "em" => Self::Emphasis(children),
"~" | "u" | "underline" => Self::Underline(children),
"~~" | "s" => Self::Strikethrough(children),
"~~~" => Self::Undercover(children),
_ => unreachable!(),
}
}
pub fn text(text: String, style: &str) -> Self {
match style {
"raw" => Self::Raw(Box::new(text)),
_ => Self::Normal(Box::new(text)),
}
}
pub fn escaped(char: char) -> Self {
Self::Escaped(char)
}
}