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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use writedown::{ast, Render};

//TODO: implement by macro

// ast::Node -> html::Node
// html::Node(v).render();

#[derive(Debug)]
pub enum Node {
    Section(Section),
    Paragraph(Paragraph),
    Block(Block),
    Unknown,
}

impl Render for Node {
    fn render(&self) -> String {
        match &self {
            Node::Section(s) => s.render(),
            Node::Paragraph(p) => p.render(),
            Node::Block(b) => b.render(),
            _ => unimplemented!(),
        }
    }
}

impl From<ast::Node> for Node {
    fn from(node: ast::Node) -> Self {
        match node {
            ast::Node::Section(v) => Node::Section(v.into()),
            ast::Node::Paragraph(v) => Node::Paragraph(v.into()),
            ast::Node::Block(v) => Node::Block(v.into()),
            _ => unimplemented!(),
        }
    }
}

#[derive(Debug)]
pub struct Section {
    pub level: usize,
    pub title: String,
    pub child: Vec<Node>,
}
#[derive(Debug)]
pub struct Paragraph {
    pub child: Vec<ParagraphChild>,
}
#[derive(Debug)]
pub enum ParagraphChild {
    Sentence(String),
    Func(ast::Func),
}

#[derive(Debug)]
pub enum Block {
    Code(String),
}

impl From<ast::Section> for Section {
    fn from(v: ast::Section) -> Section {
        let mut child: Vec<Node> = Vec::new();
        for c in v.child {
            child.push(c.into());
        }
        Section {
            level: v.level,
            title: v.title,
            child,
        }
    }
}
impl From<ast::Paragraph> for Paragraph {
    fn from(v: ast::Paragraph) -> Paragraph {
        let mut child = Vec::new();
        for c in v.child {
            child.push(c.into());
        }
        Paragraph { child }
    }
}
impl From<ast::ParagraphChild> for ParagraphChild {
    fn from(v: ast::ParagraphChild) -> ParagraphChild {
        match v {
            ast::ParagraphChild::Sentence(s) => ParagraphChild::Sentence(s),
            ast::ParagraphChild::Func(f) => ParagraphChild::Func(f),
        }
    }
}
impl From<ast::Block> for Block {
    fn from(v: ast::Block) -> Block {
        match v {
            ast::Block::Code(b) => Block::Code(b),
            _ => unimplemented!(),
        }
    }
}

impl Render for Section {
    fn render(&self) -> String {
        let l = format!("{}", self.level + 1);
        let mut cs = String::new();
        for c in &self.child {
            cs += &c.render();
        }

        format!("<h{}>{}</h{}>\n{}", l, self.title, l, cs)
    }
}
impl Render for Paragraph {
    fn render(&self) -> String {
        let mut cs = String::new();
        for c in &self.child {
            //eprintln!("{:?}", &c);
            cs += &c.render();
        }
        format!("<p>{}</p>\n", cs)
    }
}
impl Render for ParagraphChild {
    fn render(&self) -> String {
        match &self {
            ParagraphChild::Sentence(s) => s.to_string(),
            ParagraphChild::Func(_f) => unimplemented!(),
        }
    }
}

impl Render for Block {
    fn render(&self) -> String {
        match &self {
            Block::Code(code) => format!("\n<pre><code>{}</code></pre>", str2html(code)),
        }
    }
}

pub fn str2html(s: &str) -> String {
    s.replace("<", "&lt;").replace(">", "&gt;")
}