Skip to main content

docx_rs/reader/
run_property.rs

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