/ src / markdown_line_element.rs
markdown_line_element.rs
 1  use crate::markdown_inline_element::{process_inline_markdown_text, MarkdownToken};
 2  use serde::{Deserialize, Serialize};
 3  
 4  #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
 5  pub enum MarkdownLineElementType {
 6      H1,
 7      H2,
 8      H3,
 9      H4,
10      H5,
11      H6,
12      Paragraph,
13      Divider,
14      OrderedList,
15      UnorderedList,
16      ConfigVariable,
17  }
18  impl MarkdownLineElementType {
19      fn get_header_by_int(number: usize) -> MarkdownLineElementType {
20          return match number {
21              1 => MarkdownLineElementType::H1,
22              2 => MarkdownLineElementType::H2,
23              3 => MarkdownLineElementType::H3,
24              4 => MarkdownLineElementType::H4,
25              5 => MarkdownLineElementType::H5,
26              _ => MarkdownLineElementType::H6,
27          };
28      }
29  }
30  
31  #[derive(Debug, Clone, Serialize, Deserialize)]
32  pub struct MarkdownLineElement {
33      pub indent: usize,
34      pub line_type: MarkdownLineElementType,
35      pub markdown: Vec<MarkdownToken>,
36  }
37  
38  impl MarkdownLineElement {
39      pub fn new(line: &str) -> Self {
40          let indent = line.chars().take_while(|&c| c == ' ').count() / 2;
41          if indent * 2 != line.chars().take_while(|&c| c == ' ').count() {
42              panic!("Indentation error: Indentation must be a multiple of 2 spaces\nline that fugged ub: {}", &line);
43          }
44  
45          let trimmed = line.trim_start();
46          let (line_type, content): (MarkdownLineElementType, &str) = if trimmed.starts_with("#") {
47              let level = trimmed.chars().take_while(|&c| c == '#').count();
48              let line_type = MarkdownLineElementType::get_header_by_int(level);
49              (line_type, &trimmed[level..].trim())
50          } else if trimmed.starts_with("---") {
51              (MarkdownLineElementType::Divider, "")
52          } else if trimmed.starts_with("- ") {
53              (MarkdownLineElementType::UnorderedList, &trimmed[2..].trim())
54          } else if trimmed.starts_with("* ") {
55              (MarkdownLineElementType::OrderedList, &trimmed[2..].trim())
56          } else if trimmed.starts_with("@@") {
57              (
58                  MarkdownLineElementType::ConfigVariable,
59                  &trimmed[2..].trim(),
60              )
61          } else {
62              (MarkdownLineElementType::Paragraph, trimmed)
63          };
64  
65          MarkdownLineElement {
66              indent,
67              line_type,
68              markdown: process_inline_markdown_text(&content),
69          }
70      }
71  
72      pub fn parse_markdown(md_content: &str) -> Vec<MarkdownLineElement> {
73          md_content.lines().map(MarkdownLineElement::new).collect()
74      }
75  }