tex_rs/
element.rs

1use crate::Convert;
2// Type aliases //
3type Body = String;
4type Meta = String;
5type Pkg = String;
6/// User-Defined Tuple for Body, Meta and Pkg levels
7pub type UDTuple = (Body, Meta, Pkg);
8/// Item for Environment and List
9pub type Item = String;
10// Structs //
11/// Part struct, contains text and a vec for elements
12#[derive(Debug, Clone)]
13pub struct Part(pub String, pub Vec<Element>);
14/// Chapter struct, contains text and a vec for elements
15#[derive(Debug, Clone)]
16pub struct Chapter(pub String, pub Vec<Element>);
17/// Section struct, contains text and a vec for elements
18#[derive(Debug, Clone)]
19pub struct Section(pub String, pub Vec<Element>);
20/// Paragraph struct, contains text and a vec for elements
21#[derive(Debug, Clone)]
22pub struct Paragraph(pub String, pub Option<Vec<Element>>);
23/// Text struct with text and specifid text type
24#[derive(Debug, Clone)]
25pub struct Text(pub String, pub TextType);
26/// Input struct with text for filename
27#[derive(Debug, Clone)]
28pub struct Input(pub String);
29/// Environment struct with text for name, and vec for items (String)
30#[derive(Debug, Clone)]
31pub struct Environment(pub String, pub Vec<Item>);
32/// User-defined command with string and level for it to be in
33/// - Meta: In the metadata level, just before packages
34/// - Package: In the level where packages are
35/// - Body: Inside the document environment
36#[derive(Debug, Clone)]
37pub struct UserDefined(pub String, pub Level);
38/// List struct with ListMode (enumerate or itemize) and vec for items (String)
39#[derive(Debug, Clone)]
40pub struct List(pub ListMode, pub Vec<Item>);
41
42pub type Comment = UserDefined;
43
44// Enums //
45
46/// Elements enum that contains all elements
47/// - Part
48/// - Chapter
49/// - Section (Headers)
50/// - Paragraph
51/// - Text (Italic, bold, verbatim, etc.)
52/// - Input
53/// - Environment `(\begin{}...\end{})`
54/// - UserDefiend (any kind of custom code)
55/// - List (enumerate or itemize)
56#[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/// TextType enum that contains the different kind
70/// of text like;
71/// - Normal `(\par ...)`
72/// - Bold `(\textbf{...})`
73/// - Italic `(\textit{...})`
74/// - Underline `(\underline{...})`
75/// - Verbatim `(\verb!...!)`
76/// - Roman `(\textrm{...})`
77#[derive(Debug, Clone)]
78pub enum TextType {
79    Normal,
80    Bold,
81    Italic,
82    Underline,
83    Verbatim,
84    Roman,
85}
86/// ListMode enum that contains the two different lists
87/// - Itemize `(\begin{itemize}...\end{itemize})`
88/// - Enumerate `(\begin{enumerate}...\end{enumerate})`
89#[derive(Debug, Clone)]
90pub enum ListMode {
91    Itemize,
92    Enumerate,
93}
94/// Level determines where the userdefined command goes
95/// - Meta: Where metadata goes
96/// - Package: Where packages goes
97/// - Body: Inside the document environment
98#[derive(Debug, Clone)]
99pub enum Level {
100    Meta,
101    Body,
102    Package,
103}
104
105// Implementations //
106impl Element {
107    /// Determines Prioirty rank
108    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    /// Gets the Vec element inside the struct
122    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    /// Recursive function to get latex string for all elements inside struct
136    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    /// Parallel version of loop_through using rayon
153    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    /// Attach string to environment, alternative to attach which requires an Element
208    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    /// Evaluates a userdefined, and puts it's string in the appropriate level
224    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// Macros
237#[macro_export]
238/// Creates a vector of elements instead of creating `vec![Element::from(foo)]`
239macro_rules! elements {
240   ($($x:expr),+) => ({
241       let mut v = Vec::new();
242       $( v.push(Element::from($x)); )+
243       v
244   });
245}
246
247// Trait Implementations //
248impl Convert for Part {
249    fn to_latex_string(&self) -> String {
250        format!("\\part{{{}}}", &self.0)
251    }
252    /*fn to_matex_string(&self) -> String {
253        format!("part: {}", &self.0)
254    } */
255}
256
257impl Convert for Chapter {
258    fn to_latex_string(&self) -> String {
259        format!("\\chapter{{{}}}", &self.0)
260    }
261    /* fn to_matex_string(&self) -> String {
262        format!("chapter: {}", &self.0)
263    } */
264}
265
266impl Convert for Section {
267    fn to_latex_string(&self) -> String {
268        format!("\\section{{{}}}", &self.0)
269    }
270    /* fn to_matex_string(&self) -> String {
271        format!("section: {}", &self.0)
272    } */
273}
274
275impl Convert for Paragraph {
276    fn to_latex_string(&self) -> String {
277        format!("\\paragraph{{{}}}", &self.0)
278    }
279    /* fn to_matex_string(&self) -> String {
280        format!("paragraph: {}", &self.0)
281    } */
282}
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    /* fn to_matex_string(&self) -> String {
308        match &self.1{
309            TextType::Normal => {format!("par: {}", &self.0)}
310            TextType::Bold => {format!("textbf: {}", &self.0)}
311            TextType::Italic => {format!("textit: {}", &self.0)}
312            TextType::Underline => {format!("underline: {}", &self.0)}
313            TextType::Verbatim => {format!("verb: {}", &self.0)}
314            TextType::Roman => {format!("textrm: {}", &self.0)}
315        }
316    } */
317}
318
319impl Convert for Input {
320    fn to_latex_string(&self) -> String {
321        format!("\\input{{{}}}", &self.0)
322    }
323    /* fn to_matex_string(&self) -> String {
324        format!("import: {}", &self.0)
325    } */
326}
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    /* fn to_matex_string(&self) -> String {
341        let begin = format!("{} > begin", &self.0);
342        let end = format!("{} > end", &self.0);
343        let mut s = Vec::new();
344        s.push(begin);
345        for i in &self.1{
346            s.push(i.to_owned());
347        }
348        s.push(end);
349        s.join("\n")
350    } */
351}
352
353impl Convert for UserDefined {
354    fn to_latex_string(&self) -> String {
355        self.0.clone()
356    }
357    /* fn to_matex_string(&self) -> String {
358        self.0.clone()
359    } */
360}
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}