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
use crate::{
traits::{AsFooter, MarkdownElement},
types::{header::Header, link::Link, list::List, paragraph::Paragraph},
PRELIMINARY_REMARK,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::fmt;
use tousize::ToUsize;
#[derive(Default)]
pub struct Markdown {
pub elements: Vec<Box<dyn MarkdownElement>>,
pub footers: Vec<Box<dyn MarkdownElement>>,
}
impl<'a> Markdown {
pub fn new() -> Self {
Self::default()
}
pub fn with(
elements: Vec<Box<dyn MarkdownElement>>,
footers: Vec<Box<dyn MarkdownElement>>,
) -> Self {
Self { elements, footers }
}
pub fn with_remark() -> Self {
let elements = (&*PRELIMINARY_REMARK).clone();
Self {
elements: elements.to_vec(),
..Default::default()
}
}
pub fn header(&mut self, text: impl Into<String>, level: impl ToUsize) -> &mut Self {
let header = Header::from(text, level);
self.elements.push(Box::new(header));
self
}
pub fn header1(&mut self, text: impl Into<String>) -> &mut Self {
self.header(text, 1usize);
self
}
pub fn header2(&mut self, text: impl Into<String>) -> &mut Self {
self.header(text, 2usize);
self
}
pub fn header3(&mut self, text: impl Into<String>) -> &mut Self {
self.header(text, 3usize);
self
}
pub fn header4(&mut self, text: impl Into<String>) -> &mut Self {
self.header(text, 4usize);
self
}
pub fn header5(&mut self, text: impl Into<String>) -> &mut Self {
self.header(text, 5usize);
self
}
pub fn header6(&mut self, text: impl Into<String>) -> &mut Self {
self.header(text, 6usize);
self
}
pub fn list(&mut self, list: List) -> &mut Self {
self.elements.push(Box::new(list));
self
}
pub fn link(&mut self, link: Link) -> &mut Self {
if link.footer {
self.footers.push(link.as_footer());
}
self.elements.push(Box::new(link));
self
}
pub fn paragraph(&mut self, text: impl Into<String>) -> &mut Self {
self.elements.push(Box::new(Paragraph::from(text)));
self
}
pub fn render(&self) -> String {
self.to_string()
}
}
impl fmt::Display for Markdown {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for element in &self.elements {
writeln!(f, "{}", element.render())?;
}
for footer in &self.footers {
writeln!(f, "{}", footer.render())?;
}
Ok(())
}
}