1use crate::Convert;
2type Body = String;
4type Meta = String;
5type Pkg = String;
6pub type UDTuple = (Body, Meta, Pkg);
8pub type Item = String;
10#[derive(Debug, Clone)]
13pub struct Part(pub String, pub Vec<Element>);
14#[derive(Debug, Clone)]
16pub struct Chapter(pub String, pub Vec<Element>);
17#[derive(Debug, Clone)]
19pub struct Section(pub String, pub Vec<Element>);
20#[derive(Debug, Clone)]
22pub struct Paragraph(pub String, pub Option<Vec<Element>>);
23#[derive(Debug, Clone)]
25pub struct Text(pub String, pub TextType);
26#[derive(Debug, Clone)]
28pub struct Input(pub String);
29#[derive(Debug, Clone)]
31pub struct Environment(pub String, pub Vec<Item>);
32#[derive(Debug, Clone)]
37pub struct UserDefined(pub String, pub Level);
38#[derive(Debug, Clone)]
40pub struct List(pub ListMode, pub Vec<Item>);
41
42pub type Comment = UserDefined;
43
44#[derive(Debug, Clone)]
57pub enum Element {
58 Part(Part),
59 Chapter(Chapter),
60 Section(Section),
61 Paragraph(Paragraph),
62 Text(Text),
63 Input(Input),
64 Environment(Environment),
65 UserDefined(UserDefined),
66 List(List),
67}
68
69#[derive(Debug, Clone)]
78pub enum TextType {
79 Normal,
80 Bold,
81 Italic,
82 Underline,
83 Verbatim,
84 Roman,
85}
86#[derive(Debug, Clone)]
90pub enum ListMode {
91 Itemize,
92 Enumerate,
93}
94#[derive(Debug, Clone)]
99pub enum Level {
100 Meta,
101 Body,
102 Package,
103}
104
105impl Element {
107 pub fn rank(&self) -> u8 {
109 match self {
110 Element::Part(_) => 0,
111 Element::Chapter(_) => 1,
112 Element::Section(_) => 2,
113 Element::Paragraph(_) => 3,
114 Element::UserDefined(_) => 4,
115 Element::Text(_) => 8,
116 Element::Input(_) => 7,
117 Element::Environment(_) => 6,
118 Element::List(_) => 5,
119 }
120 }
121 pub fn get_vec(&self) -> Option<Vec<Element>> {
123 match &self {
124 Element::Part(p) => Some(p.to_owned().1),
125 Element::Chapter(c) => Some(c.to_owned().1),
126 Element::Section(s) => Some(s.to_owned().1),
127 Element::Paragraph(p) => Some(p.to_owned().1.unwrap()),
128 Element::Text(_) => None,
129 Element::Input(_) => None,
130 Element::Environment(_) => None,
131 Element::UserDefined(_) => None,
132 Element::List(_) => None,
133 }
134 }
135 pub fn loop_through(&self) -> String {
137 let vec = match self.get_vec() {
138 Some(a) => a,
139 None => return "".to_string(),
140 };
141 let mut s = Vec::new();
142 if vec.is_empty() {
143 return "".to_string();
144 } else {
145 for i in &vec {
146 s.push(i.to_latex_string());
147 s.push(i.loop_through())
148 }
149 }
150 s.join(" ")
151 }
152 pub fn loop_through_parallel(&self) -> String {
154 let vec = match self.get_vec() {
155 Some(a) => a,
156 None => return "".to_string(),
157 };
158 let mut s = Vec::new();
159 if vec.is_empty() {
160 return "".to_string();
161 } else {
162 for i in &vec {
163 let r = rayon::join(|| i.clone().to_latex_string(), || i.clone().loop_through());
164 s.push(r.0);
165 s.push(r.1);
166 }
167 }
168 s.join(" ")
169 }
170}
171
172impl Part {
173 pub fn new(text: &str) -> Self {
174 Self(text.to_string(), Vec::new())
175 }
176}
177impl Chapter {
178 pub fn new(text: &str) -> Self {
179 Self(text.to_string(), Vec::new())
180 }
181}
182impl Section {
183 pub fn new(text: &str) -> Self {
184 Self(text.to_string(), Vec::new())
185 }
186}
187impl Paragraph {
188 pub fn new(text: &str) -> Self {
189 Self(text.to_string(), Some(Vec::new()))
190 }
191}
192impl Text {
193 pub fn new(text: &str, text_type: TextType) -> Self {
194 Self(text.to_string(), text_type)
195 }
196}
197impl Input {
198 pub fn new(text: &str) -> Self {
199 Self(text.to_string())
200 }
201}
202
203impl Environment {
204 pub fn new(text: &str) -> Self {
205 Self(text.to_string(), Vec::new())
206 }
207 pub fn attach_string(&mut self, item: Item) {
209 self.1.push(item);
210 }
211}
212
213impl List {
214 pub fn new(list_mode: ListMode, items: &Vec<Item>) -> Self {
215 Self(list_mode, items.to_owned())
216 }
217}
218
219impl UserDefined {
220 pub fn new(text: &str, level: Level) -> Self {
221 Self(text.to_string(), level)
222 }
223 pub fn evaluate(&self) -> UDTuple {
225 match &self.1 {
226 Level::Body => (self.0.clone(), "".to_owned(), "".to_owned()),
227 Level::Meta => ("".to_owned(), self.0.clone(), "".to_owned()),
228 Level::Package => ("".to_owned(), "".to_owned(), self.0.clone()),
229 }
230 }
231 pub fn new_comment(text: &str, level: Level) -> Self {
232 Self(format!("% {}", text), level)
233 }
234}
235
236#[macro_export]
238macro_rules! elements {
240 ($($x:expr),+) => ({
241 let mut v = Vec::new();
242 $( v.push(Element::from($x)); )+
243 v
244 });
245}
246
247impl Convert for Part {
249 fn to_latex_string(&self) -> String {
250 format!("\\part{{{}}}", &self.0)
251 }
252 }
256
257impl Convert for Chapter {
258 fn to_latex_string(&self) -> String {
259 format!("\\chapter{{{}}}", &self.0)
260 }
261 }
265
266impl Convert for Section {
267 fn to_latex_string(&self) -> String {
268 format!("\\section{{{}}}", &self.0)
269 }
270 }
274
275impl Convert for Paragraph {
276 fn to_latex_string(&self) -> String {
277 format!("\\paragraph{{{}}}", &self.0)
278 }
279 }
283
284impl Convert for Text {
285 fn to_latex_string(&self) -> String {
286 let text: String;
287 match &self.1 {
288 TextType::Normal => text = self.0.clone(),
289 TextType::Bold => {
290 text = format!("\\textbf{{{}}}", &self.0);
291 }
292 TextType::Italic => {
293 text = format!("\\textit{{{}}}", &self.0);
294 }
295 TextType::Roman => {
296 text = format!("\\textrm{{{}}}", &self.0);
297 }
298 TextType::Underline => {
299 text = format!("\\underline{{{}}}", &self.0);
300 }
301 TextType::Verbatim => {
302 text = format!("\\verb!{}!", &self.0);
303 }
304 }
305 format!("{}", &text)
306 }
307 }
318
319impl Convert for Input {
320 fn to_latex_string(&self) -> String {
321 format!("\\input{{{}}}", &self.0)
322 }
323 }
327
328impl Convert for Environment {
329 fn to_latex_string(&self) -> String {
330 let begin = format!("\\begin{{{}}}", &self.0);
331 let end = format!("\\end{{{}}}", &self.0);
332 let mut s = Vec::new();
333 s.push(begin);
334 for i in &self.1 {
335 s.push(i.to_owned());
336 }
337 s.push(end);
338 s.join("\n")
339 }
340 }
352
353impl Convert for UserDefined {
354 fn to_latex_string(&self) -> String {
355 self.0.clone()
356 }
357 }
361
362impl Convert for List {
363 fn to_latex_string(&self) -> String {
364 let mode: &str = match &self.0 {
365 ListMode::Enumerate => "enumerate",
366 ListMode::Itemize => "itemize",
367 };
368
369 let (begin, end) = (format!("\\begin{{{}}}", mode), format!("\\end{{{}}}", mode));
370 let mut s = Vec::new();
371 s.push(begin);
372 for i in &self.1 {
373 s.push(format!("\\item {}", &i));
374 }
375 s.push(end);
376 s.join("\n")
377 }
378}
379
380impl Convert for Element {
381 fn to_latex_string(&self) -> String {
382 match self {
383 Element::Part(e) => e.to_latex_string(),
384 Element::Chapter(e) => e.to_latex_string(),
385 Element::Section(e) => e.to_latex_string(),
386 Element::Paragraph(e) => e.to_latex_string(),
387 Element::Text(e) => e.to_latex_string(),
388 Element::Input(e) => e.to_latex_string(),
389 Element::Environment(e) => e.to_latex_string(),
390 Element::UserDefined(e) => e.to_latex_string(),
391 Element::List(e) => e.to_latex_string(),
392 }
393 }
394}
395
396impl From<Part> for Element {
397 fn from(p: Part) -> Self {
398 Element::Part(p)
399 }
400}
401
402impl From<Chapter> for Element {
403 fn from(c: Chapter) -> Self {
404 Element::Chapter(c)
405 }
406}
407
408impl From<Section> for Element {
409 fn from(s: Section) -> Self {
410 Element::Section(s)
411 }
412}
413
414impl From<Paragraph> for Element {
415 fn from(p: Paragraph) -> Self {
416 Element::Paragraph(p)
417 }
418}
419
420impl From<Text> for Element {
421 fn from(t: Text) -> Self {
422 Element::Text(t)
423 }
424}
425
426impl From<Input> for Element {
427 fn from(i: Input) -> Self {
428 Element::Input(i)
429 }
430}
431
432impl From<Environment> for Element {
433 fn from(e: Environment) -> Self {
434 Element::Environment(e)
435 }
436}
437
438impl From<UserDefined> for Element {
439 fn from(u: UserDefined) -> Self {
440 Element::UserDefined(u)
441 }
442}
443
444impl From<List> for Element {
445 fn from(l: List) -> Self {
446 Element::List(l)
447 }
448}
449
450impl From<Element> for String {
451 fn from(e: Element) -> Self {
452 e.to_latex_string()
453 }
454}