docx_rs/reader/
run_property.rs

1use std::io::Read;
2use std::str::FromStr;
3
4use xml::attribute::OwnedAttribute;
5use xml::reader::{EventReader, XmlEvent};
6
7use crate::VertAlignType;
8
9use super::*;
10
11fn read_run_fonts(attributes: &[OwnedAttribute]) -> Result<RunFonts, ReaderError> {
12    let mut f = RunFonts::new();
13    for a in attributes {
14        let local_name = &a.name.local_name;
15        match local_name.as_str() {
16            "asciiTheme" => {
17                f = f.ascii_theme(&a.value);
18            }
19            "eastAsiaTheme" => {
20                f = f.east_asia_theme(&a.value);
21            }
22            "hAnsiTheme" => {
23                f = f.hi_ansi_theme(&a.value);
24            }
25            "cstheme" => {
26                f = f.cs_theme(&a.value);
27            }
28            "ascii" => {
29                f = f.ascii(&a.value);
30            }
31            "eastAsia" => {
32                f = f.east_asia(&a.value);
33            }
34            "hAnsi" => {
35                f = f.hi_ansi(&a.value);
36            }
37            "cs" => {
38                f = f.cs(&a.value);
39            }
40            "hint" => {
41                f = f.hint(&a.value);
42            }
43            _ => {}
44        }
45    }
46    Ok(f)
47}
48
49impl ElementReader for RunProperty {
50    fn read<R: Read>(
51        r: &mut EventReader<R>,
52        _attrs: &[OwnedAttribute],
53    ) -> Result<Self, ReaderError> {
54        let mut rp = RunProperty::new();
55        loop {
56            let e = r.next();
57            match e {
58                Ok(XmlEvent::StartElement {
59                    attributes, name, ..
60                }) => {
61                    let e = XMLElement::from_str(&name.local_name).unwrap();
62
63                    ignore::ignore_element(e.clone(), XMLElement::RunPropertyChange, r);
64
65                    match e {
66                        XMLElement::RunStyle => {
67                            if let Some(v) = read_val(&attributes) {
68                                rp = rp.style(&v);
69                            }
70                        }
71                        XMLElement::Bold => {
72                            if !read_bool(&attributes) {
73                                rp = rp.disable_bold();
74                                continue;
75                            }
76                            rp = rp.bold();
77                        }
78                        XMLElement::Caps => {
79                            if !read_bool(&attributes) {
80                                rp.caps = Some(Caps::new().disable());
81                                continue;
82                            }
83                            rp = rp.caps();
84                        }
85                        XMLElement::PTab => {
86                            if let Ok(v) = PositionalTab::read(r, &attributes) {
87                                rp = rp.ptab(v)
88                            }
89                        }
90                        XMLElement::Highlight => rp = rp.highlight(attributes[0].value.clone()),
91                        XMLElement::Strike => {
92                            if !read_bool(&attributes) {
93                                rp.strike = Some(Strike::new().disable());
94                                continue;
95                            }
96                            rp = rp.strike();
97                        }
98                        XMLElement::Dstrike => {
99                            if !read_bool(&attributes) {
100                                rp.dstrike = Some(Dstrike::new().disable());
101                                continue;
102                            }
103                            rp = rp.dstrike();
104                        }
105                        XMLElement::VertAlign => {
106                            if let Ok(v) = VertAlignType::from_str(&attributes[0].value) {
107                                rp = rp.vert_align(v)
108                            }
109                        }
110                        XMLElement::Color => rp = rp.color(attributes[0].value.clone()),
111                        XMLElement::Size => {
112                            rp = rp.size(f64::from_str(&attributes[0].value)? as usize)
113                        }
114                        XMLElement::Spacing => {
115                            if let Some(v) = read_val(&attributes) {
116                                if let Ok(s) = f64::from_str(&v) {
117                                    rp = rp.spacing(s as i32)
118                                }
119                            }
120                        }
121                        XMLElement::RunFonts => {
122                            if let Ok(f) = read_run_fonts(&attributes) {
123                                rp = rp.fonts(f);
124                            }
125                        }
126                        XMLElement::Underline => rp = rp.underline(attributes[0].value.clone()),
127                        XMLElement::Italic => {
128                            if !read_bool(&attributes) {
129                                rp = rp.disable_italic();
130                                continue;
131                            }
132                            rp = rp.italic();
133                        }
134                        XMLElement::Shading => {
135                            if let Ok(shd) = Shading::read(r, &attributes) {
136                                rp = rp.shading(shd);
137                            }
138                        }
139                        XMLElement::Vanish => rp = rp.vanish(),
140                        XMLElement::SpecVanish => rp = rp.spec_vanish(),
141                        XMLElement::TextBorder => {
142                            if let Ok(attr) = read_border(&attributes) {
143                                let mut border = TextBorder::new()
144                                    .border_type(attr.border_type)
145                                    .color(attr.color);
146                                if let Some(size) = attr.size {
147                                    border = border.size(size as usize);
148                                };
149                                rp = rp.text_border(border);
150                                continue;
151                            }
152                        }
153                        XMLElement::Insert => {
154                            if let Ok(ins) = Insert::read(r, &attributes) {
155                                rp = rp.insert(ins);
156                            }
157                        }
158                        XMLElement::Delete => {
159                            if let Ok(del) = Delete::read(r, &attributes) {
160                                rp = rp.delete(del);
161                            }
162                        }
163                        _ => {}
164                    }
165                }
166                Ok(XmlEvent::EndElement { name, .. }) => {
167                    let e = XMLElement::from_str(&name.local_name).unwrap();
168                    if e == XMLElement::RunProperty {
169                        return Ok(rp);
170                    }
171                }
172                Err(_) => return Err(ReaderError::XMLReadError),
173                _ => {}
174            }
175        }
176    }
177}