docx_rs/reader/
run_property.rs1use 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}