writedown_html/
html.rs

1use writedown::{ast, Render};
2
3//TODO: implement by macro
4
5// ast::Node -> html::Node
6// html::Node(v).render();
7
8#[derive(Debug)]
9pub enum Node {
10    Section(Section),
11    Paragraph(Paragraph),
12    Block(Block),
13    Unknown,
14}
15
16impl Render for Node {
17    fn render(&self) -> String {
18        match &self {
19            Node::Section(s) => s.render(),
20            Node::Paragraph(p) => p.render(),
21            Node::Block(b) => b.render(),
22            _ => unimplemented!(),
23        }
24    }
25}
26
27impl From<ast::Node> for Node {
28    fn from(node: ast::Node) -> Self {
29        match node {
30            ast::Node::Section(v) => Node::Section(v.into()),
31            ast::Node::Paragraph(v) => Node::Paragraph(v.into()),
32            ast::Node::Block(v) => Node::Block(v.into()),
33            _ => unimplemented!(),
34        }
35    }
36}
37
38#[derive(Debug)]
39pub struct Section {
40    pub level: usize,
41    pub title: String,
42    pub child: Vec<Node>,
43}
44#[derive(Debug)]
45pub struct Paragraph {
46    pub child: Vec<ParagraphChild>,
47}
48#[derive(Debug)]
49pub enum ParagraphChild {
50    Sentence(String),
51    Func(ast::Func),
52}
53
54#[derive(Debug)]
55pub enum Block {
56    Code(String),
57}
58
59impl From<ast::Section> for Section {
60    fn from(v: ast::Section) -> Section {
61        let mut child: Vec<Node> = Vec::new();
62        for c in v.child {
63            child.push(c.into());
64        }
65        Section {
66            level: v.level,
67            title: v.title,
68            child,
69        }
70    }
71}
72impl From<ast::Paragraph> for Paragraph {
73    fn from(v: ast::Paragraph) -> Paragraph {
74        let mut child = Vec::new();
75        for c in v.child {
76            child.push(c.into());
77        }
78        Paragraph { child }
79    }
80}
81impl From<ast::ParagraphChild> for ParagraphChild {
82    fn from(v: ast::ParagraphChild) -> ParagraphChild {
83        match v {
84            ast::ParagraphChild::Sentence(s) => ParagraphChild::Sentence(s),
85            ast::ParagraphChild::Func(f) => ParagraphChild::Func(f),
86        }
87    }
88}
89impl From<ast::Block> for Block {
90    fn from(v: ast::Block) -> Block {
91        match v {
92            ast::Block::Code(b) => Block::Code(b),
93            _ => unimplemented!(),
94        }
95    }
96}
97
98impl Render for Section {
99    fn render(&self) -> String {
100        let l = format!("{}", self.level + 1);
101        let mut cs = String::new();
102        for c in &self.child {
103            cs += &c.render();
104        }
105
106        format!("<h{}>{}</h{}>\n{}", l, self.title, l, cs)
107    }
108}
109impl Render for Paragraph {
110    fn render(&self) -> String {
111        let mut cs = String::new();
112        for c in &self.child {
113            //eprintln!("{:?}", &c);
114            cs += &c.render();
115        }
116        format!("<p>{}</p>\n", cs)
117    }
118}
119impl Render for ParagraphChild {
120    fn render(&self) -> String {
121        match &self {
122            ParagraphChild::Sentence(s) => s.to_string(),
123            ParagraphChild::Func(_f) => unimplemented!(),
124        }
125    }
126}
127
128impl Render for Block {
129    fn render(&self) -> String {
130        match &self {
131            Block::Code(code) => format!("\n<pre><code>{}</code></pre>", str2html(code)),
132        }
133    }
134}
135
136pub fn str2html(s: &str) -> String {
137    s.replace("<", "&lt;").replace(">", "&gt;")
138}