docx_reader/reader/
section_property.rs1use std::io::Read;
2use std::str::FromStr;
3use xml::attribute::OwnedAttribute;
4use xml::reader::{EventReader, XmlEvent};
5
6use crate::SectionType;
7
8use super::*;
9
10fn read_page_size(attributes: &[OwnedAttribute]) -> Result<PageSize, ReaderError> {
11 let mut size = PageSize::new();
12 for a in attributes {
13 let local_name = &a.name.local_name;
14 match local_name.as_str() {
15 "w" => {
16 size = size.width(value_to_dax(&a.value)? as u32);
17 }
18 "h" => {
19 size = size.height(value_to_dax(&a.value)? as u32);
20 }
21 _ => {}
22 }
23 }
24 Ok(size)
25}
26
27fn read_page_margin(
28 attributes: &[OwnedAttribute],
29) -> Result<crate::types::PageMargin, ReaderError> {
30 let mut margin = crate::types::PageMargin::new();
31 for a in attributes {
32 let local_name = &a.name.local_name;
33 match local_name.as_str() {
34 "top" => {
35 margin = margin.top(value_to_dax(&a.value)? as i32);
36 }
37 "right" => {
38 margin = margin.right(value_to_dax(&a.value)? as i32);
39 }
40 "bottom" => {
41 margin = margin.bottom(value_to_dax(&a.value)? as i32);
42 }
43 "left" => {
44 margin = margin.left(value_to_dax(&a.value)? as i32);
45 }
46 "header" => {
47 margin = margin.header(value_to_dax(&a.value)? as i32);
48 }
49 "footer" => {
50 margin = margin.footer(value_to_dax(&a.value)? as i32);
51 }
52 "gutter" => {
53 margin = margin.gutter(value_to_dax(&a.value)? as i32);
54 }
55 _ => {}
56 }
57 }
58 Ok(margin)
59}
60
61fn read_header_or_footer_reference(
62 attributes: &[OwnedAttribute],
63) -> Result<(String, String), ReaderError> {
64 let mut rid = "".to_owned();
65 let mut header_type = "default".to_owned();
66 for a in attributes {
67 let local_name = &a.name.local_name;
68 match local_name.as_str() {
69 "type" => {
70 header_type = a.value.to_owned();
71 }
72 "id" => {
73 rid = a.value.to_owned();
74 }
75 _ => {}
76 }
77 }
78 Ok((rid, header_type))
79}
80
81impl ElementReader for SectionProperty {
82 fn read<R: Read>(
83 r: &mut EventReader<R>,
84 _attrs: &[OwnedAttribute],
85 ) -> Result<Self, ReaderError> {
86 let mut sp = SectionProperty::new();
87 loop {
88 let e = r.next();
89 match e {
90 Ok(XmlEvent::StartElement {
91 attributes, name, ..
92 }) => {
93 let e = XMLElement::from_str(&name.local_name).unwrap();
94 match e {
95 XMLElement::PageMargin => {
96 let margin = read_page_margin(&attributes)?;
97 sp = sp.page_margin(margin);
98 }
99 XMLElement::PageSize => {
100 let size = read_page_size(&attributes)?;
101 sp = sp.page_size(size);
102 }
103 XMLElement::DocGrid => {
104 if let Ok(doc_grid) = DocGrid::read(r, &attributes) {
105 sp = sp.doc_grid(doc_grid);
106 }
107 }
108 XMLElement::HeaderReference => {
109 if let Ok((rid, header_type)) =
110 read_header_or_footer_reference(&attributes)
111 {
112 match header_type.as_str() {
113 "default" => {
114 sp.header_reference =
115 Some(HeaderReference::new(header_type, rid));
116 }
117 "first" => {
118 sp.first_header_reference =
119 Some(HeaderReference::new(header_type, rid));
120 }
121 "even" => {
122 sp.even_header_reference =
123 Some(HeaderReference::new(header_type, rid));
124 }
125 _ => {}
126 }
127 }
128 }
129 XMLElement::FooterReference => {
130 if let Ok((rid, footer_type)) =
131 read_header_or_footer_reference(&attributes)
132 {
133 match footer_type.as_str() {
134 "default" => {
135 sp.footer_reference =
136 Some(FooterReference::new(footer_type, rid));
137 }
138 "first" => {
139 sp.first_footer_reference =
140 Some(FooterReference::new(footer_type, rid));
141 }
142 "even" => {
143 sp.even_footer_reference =
144 Some(FooterReference::new(footer_type, rid));
145 }
146 _ => {}
147 }
148 }
149 }
150 XMLElement::Type => {
151 if let Some(val) = read_val(&attributes) {
152 if let Ok(val) = SectionType::from_str(&val) {
153 sp.section_type = Some(val);
154 }
155 }
156 }
157 XMLElement::TitlePg => sp = sp.title_pg(),
158 _ => {}
159 }
160 }
161 Ok(XmlEvent::EndElement { name, .. }) => {
162 let e = XMLElement::from_str(&name.local_name).unwrap();
163 if e == XMLElement::SectionProperty {
164 return Ok(sp);
165 }
166 }
167 Err(_) => return Err(ReaderError::XMLReadError),
168 _ => {}
169 }
170 }
171 }
172}