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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
/// A Gemtext AST node.
///
/// Each Gemtext line is a `Node`, and some lines can even be grouped together,
/// such as the `Node::List` `Node`!
///
/// # Gemtext Resources
///
/// - [Gemtext Documentation](https://gemini.circumlunar.space/docs/gemtext.gmi)
/// - [Gemtext Cheatsheet](https://gemini.circumlunar.space/docs/cheatsheet.gmi).
/// - [Gemini Specification](https://gemini.circumlunar.space/docs/specification.gmi).
#[derive(Debug, PartialEq, Clone, Eq)]
pub enum Node {
/// A text line
///
/// # Example
///
/// ```gemini
/// This is a text line
/// ```
Text(String),
/// A link line
///
/// # Examples
///
/// ```gemini
/// => /this-is-the-to This is the text
///
/// => gemini://to.somewhere.link
/// ```
Link {
/// The location that a link line is pointing to
///
/// # Examples
///
/// ```gemini
/// => /this-is-the-to This is the text
///
/// => gemini://to.somewhere.link
/// ```
to: String,
/// The text a link line *may* have
///
/// # Examples
///
/// ```gemini
/// => /this-is-the-to This line has text, unlike the next one.
///
/// => gemini://to.somewhere.link
/// ```
text: Option<String>,
},
/// A heading line
///
/// # Examples
///
/// ```gemini
/// # This is a heading
///
/// ## This is a sub-heading
///
/// ### This is a sub-sub-heading
/// ```
Heading {
/// The level of a heading
///
/// # Examples
///
/// ```gemini
/// # This is a level 1 heading
///
/// ## This is a level 2 sub-heading
///
/// ### This is a level 3 sub-sub-heading
/// ```
level: usize,
/// The text of a heading
///
/// # Examples
///
/// ```gemini
/// # This is the headings text
///
/// # This is also the headings text
/// ```
text: String,
},
/// A collection of sequential list item lines
///
/// # Examples
///
/// ```gemini
/// * These are
/// * sequential list
/// * items.
/// ```
List(Vec<String>),
/// A blockquote line
///
/// # Examples
///
/// ```gemini
/// > This is a blockquote line
///
/// > This is also a blockquote line
/// ```
Blockquote(String),
/// A preformatted block
///
/// # Examples
///
/// Try to ignore the leading backslash in-front of the triple backticks,
/// they are there to not confuse the Markdown engine.
///
/// ```gemini
/// \```This is the alt-text
/// This is the preformatted block
///
/// This is the rest of the preformatted block
/// \```
/// ```
PreformattedText {
/// A preformatted blocks alt-text
///
/// # Examples
///
/// Try to ignore the leading backslash in-front of the triple backticks,
/// they are there to not confuse the Markdown engine.
///
/// ```gemini
/// \```This is the alt-text
/// This is the preformatted block
///
/// This is the rest of the preformatted block
/// \```
/// ```
alt_text: Option<String>,
/// A preformatted blocks content
///
/// # Examples
///
/// Try to ignore the leading backslash in-front of the triple backticks,
/// they are there to not confuse the Markdown engine.
///
/// ```gemini
/// \```This is the alt-text
/// This is the preformatted blocks content
///
/// This is the rest of the preformatted blocks content
/// \```
/// ```
text: String,
},
/// A whitespace line, a line which contains nothing but whitespace.
Whitespace,
}
impl Node {
/// Convert a single [`Node`] of any node type to a Gemtext [`String`]
#[must_use]
pub fn to_gemtext(&self) -> String {
super::Ast::from_nodes(vec![self.to_owned()]).to_gemtext()
}
}
|