writedown-html 0.1.0

Writedown HTML backend
Documentation
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;")
}