mrml/mj_table/
render.rs

1use super::{MjTable, NAME};
2use crate::helper::size::Pixel;
3use crate::mj_section::WithMjSectionBackground;
4use crate::prelude::render::*;
5
6impl<'root> WithMjSectionBackground<'root> for Renderer<'root, MjTable, ()> {}
7
8impl<'root> Renderer<'root, MjTable, ()> {
9    fn set_style_table<'a, 't>(&'a self, tag: Tag<'t>) -> Tag<'t>
10    where
11        'root: 'a,
12        'a: 't,
13    {
14        tag.maybe_add_style("color", self.attribute("color"))
15            .maybe_add_style("font-family", self.attribute("font-family"))
16            .maybe_add_style("font-size", self.attribute("font-size"))
17            .maybe_add_style("line-height", self.attribute("line-height"))
18            .maybe_add_style("table-layout", self.attribute("table-layout"))
19            .maybe_add_style("width", self.attribute("width"))
20            .maybe_add_style("border", self.attribute("border"))
21    }
22}
23
24impl<'root> Render<'root> for Renderer<'root, MjTable, ()> {
25    fn default_attribute(&self, name: &str) -> Option<&'static str> {
26        match name {
27            "align" => Some("left"),
28            "border" => Some("none"),
29            "cellpadding" => Some("0"),
30            "cellspacing" => Some("0"),
31            "color" => Some("#000000"),
32            "font-family" => Some("Ubuntu, Helvetica, Arial, sans-serif"),
33            "font-size" => Some("13px"),
34            "line-height" => Some("22px"),
35            "padding" => Some("10px 25px"),
36            "table-layout" => Some("auto"),
37            "width" => Some("100%"),
38            _ => None,
39        }
40    }
41
42    fn raw_attribute(&self, key: &str) -> Option<&'root str> {
43        match self.element.attributes.get(key) {
44            Some(Some(inner)) => Some(inner),
45            _ => None,
46        }
47    }
48
49    fn tag(&self) -> Option<&str> {
50        Some(NAME)
51    }
52
53    fn context(&self) -> &'root RenderContext<'root> {
54        self.context
55    }
56
57    fn set_container_width(&mut self, width: Option<Pixel>) {
58        self.container_width = width;
59    }
60
61    fn render(&self, cursor: &mut RenderCursor) -> Result<(), Error> {
62        let font_family = self.attribute("font-family");
63        cursor.header.maybe_add_font_families(font_family);
64
65        let table = self
66            .set_style_table(Tag::table())
67            .add_attribute("border", "0")
68            .maybe_add_attribute("cellpadding", self.attribute("cellpadding"))
69            .maybe_add_attribute("cellspacing", self.attribute("cellspacing"))
70            .maybe_add_attribute("width", self.attribute("width"));
71        table.render_open(&mut cursor.buffer)?;
72        for (index, child) in self.element.children.iter().enumerate() {
73            let mut renderer = child.renderer(self.context());
74            renderer.set_index(index);
75            renderer.render(cursor)?;
76        }
77        table.render_close(&mut cursor.buffer);
78        Ok(())
79    }
80}
81
82impl<'render, 'root: 'render> Renderable<'render, 'root> for MjTable {
83    fn renderer(
84        &'root self,
85        context: &'root RenderContext<'root>,
86    ) -> Box<dyn Render<'root> + 'render> {
87        Box::new(Renderer::new(context, self, ()))
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    crate::should_render!(basic, "mj-table");
94    crate::should_render!(table, "mj-table-table");
95    crate::should_render!(text, "mj-table-text");
96    crate::should_render!(other, "mj-table-other");
97}