docx_rs/reader/
table.rs

1use std::io::Read;
2use std::str::FromStr;
3
4use xml::attribute::OwnedAttribute;
5use xml::reader::{EventReader, XmlEvent};
6
7use super::*;
8use crate::types::*;
9
10impl ElementReader for Table {
11    fn read<R: Read>(r: &mut EventReader<R>, _: &[OwnedAttribute]) -> Result<Self, ReaderError> {
12        let mut t = Table::without_borders(vec![]);
13        let mut grid_col: Vec<usize> = vec![];
14        loop {
15            let e = r.next();
16            match e {
17                Ok(XmlEvent::StartElement {
18                    attributes, name, ..
19                }) => {
20                    let e = XMLElement::from_str(&name.local_name).unwrap();
21
22                    ignore::ignore_element(e.clone(), XMLElement::TablePropertyChange, r);
23                    ignore::ignore_element(e.clone(), XMLElement::TableGridChange, r);
24
25                    match e {
26                        XMLElement::TableRow => {
27                            t = t.add_row(TableRow::read(r, &attributes)?);
28                            continue;
29                        }
30                        XMLElement::TableWidth => {
31                            let (w, width_type) = read_width(&attributes)?;
32                            t = t.width(w as usize, width_type);
33                            continue;
34                        }
35                        XMLElement::TableProperty => {
36                            if let Ok(p) = TableProperty::read(r, &attributes) {
37                                t.property = p;
38                            }
39                        }
40                        XMLElement::Justification => {
41                            t = t.align(TableAlignmentType::from_str(&attributes[0].value)?);
42                        }
43                        XMLElement::TableIndent => {
44                            let (w, _) = read_width(&attributes)?;
45                            t = t.indent(w as i32);
46                            continue;
47                        }
48                        XMLElement::TableBorders => {
49                            if let Ok(borders) = TableBorders::read(r, &attributes) {
50                                t = t.set_borders(borders);
51                            }
52                        }
53                        XMLElement::TableStyle => {
54                            if let Some(s) = read_val(&attributes) {
55                                t = t.style(s);
56                            }
57                        }
58                        XMLElement::TableCellMargin => {
59                            if let Ok(margins) = TableCellMargins::read(r, &attributes) {
60                                t = t.margins(margins)
61                            }
62                        }
63                        XMLElement::GridCol => {
64                            let (w, _) = read_width(&attributes)?;
65                            grid_col.push(w as usize);
66                        }
67                        _ => {}
68                    }
69                }
70                Ok(XmlEvent::EndElement { name, .. }) => {
71                    let e = XMLElement::from_str(&name.local_name).unwrap();
72                    if e == XMLElement::Table {
73                        t = t.set_grid(grid_col);
74                        return Ok(t);
75                    }
76                }
77                Err(_) => return Err(ReaderError::XMLReadError),
78                _ => {}
79            }
80        }
81    }
82}
83
84#[cfg(test)]
85mod tests {
86
87    use super::*;
88    #[cfg(test)]
89    use pretty_assertions::assert_eq;
90
91    #[test]
92    fn test_read_table_with_width_prop() {
93        let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
94<w:tbl>
95    <w:tblPr>
96        <w:tblW w:w="9638" w:type="dxa"/>
97    </w:tblPr>
98    <w:tblGrid>
99        <w:gridCol w:w="3212"/>
100        <w:gridCol w:w="3213"/>
101        <w:gridCol w:w="3213"/>
102    </w:tblGrid>
103</w:tbl>
104</w:document>"#;
105        let mut parser = EventReader::new(c.as_bytes());
106        let t = Table::read(&mut parser, &[]).unwrap();
107        assert_eq!(
108            t,
109            Table::without_borders(vec![])
110                .set_grid(vec![3212, 3213, 3213])
111                .width(9638, WidthType::Dxa)
112        );
113    }
114
115    #[test]
116    fn test_read_table_with_layout() {
117        let c = r#"<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
118<w:tbl>
119    <w:tblPr>
120        <w:jc w:val="center"/>
121        <w:tblInd w:w="100" w:type="dxa"/>
122    </w:tblPr>
123</w:tbl>
124</w:document>"#;
125        let mut parser = EventReader::new(c.as_bytes());
126        let t = Table::read(&mut parser, &[]).unwrap();
127        assert_eq!(
128            t,
129            Table::without_borders(vec![])
130                .align(TableAlignmentType::Center)
131                .indent(100)
132        );
133    }
134}