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