docx_reader/reader/
run.rs

1use std::io::Read;
2use std::str::FromStr;
3use xml::attribute::OwnedAttribute;
4use xml::reader::{EventReader, XmlEvent};
5
6use crate::escape::replace_escaped;
7use crate::types::BreakType;
8use crate::{reader::*, FieldCharType};
9
10use super::Run;
11
12#[derive(PartialEq, Debug)]
13enum TextState {
14	Idle,
15	Text,
16	Delete,
17}
18
19fn read_field_char(attributes: &[OwnedAttribute]) -> Result<FieldChar, ReaderError> {
20	let mut t: Option<FieldCharType> = None;
21	let mut dirty = false;
22	for a in attributes {
23		let local_name = &a.name.local_name;
24		match local_name.as_str() {
25			"fldCharType" => {
26				if let Ok(ty) = FieldCharType::from_str(&a.value) {
27					t = Some(ty);
28				}
29			}
30			"dirty" => {
31				dirty = !is_false(&a.value);
32			}
33			_ => {}
34		}
35	}
36
37	if let Some(t) = t {
38		let mut f = FieldChar::new(t);
39		if dirty {
40			f = f.dirty();
41		}
42		Ok(f)
43	} else {
44		Err(ReaderError::XMLReadError)
45	}
46}
47
48impl ElementReader for Run {
49	fn read<R: Read>(
50		r: &mut EventReader<R>,
51		_attrs: &[OwnedAttribute],
52	) -> Result<Self, ReaderError> {
53		let mut run = Run::new();
54		let mut text_state = TextState::Idle;
55		loop {
56			let e = r.next();
57			match e {
58				Ok(XmlEvent::StartElement {
59					attributes, name, ..
60				}) => {
61					match name.prefix.as_deref() {
62						Some("w") => {
63							let e = XMLElement::from_str(&name.local_name).unwrap();
64
65							ignore::ignore_element(e.clone(), XMLElement::RunPropertyChange, r);
66
67							match e {
68								XMLElement::Tab => {
69									run = run.add_tab();
70								}
71								XMLElement::Sym => {
72									if let Some(font) = read(&attributes, "font") {
73										if let Some(char) = read(&attributes, "char") {
74											let sym = Sym::new(font, char);
75											run = run.add_sym(sym);
76										}
77									}
78								}
79								XMLElement::RunProperty => {
80									let p = RunProperty::read(r, &attributes)?;
81									run = run.set_property(p);
82								}
83								XMLElement::Text => text_state = TextState::Text,
84								XMLElement::DeleteText => text_state = TextState::Delete,
85								XMLElement::Break => {
86									if let Some(a) = &attributes.get(0) {
87										run = run.add_break(BreakType::from_str(&a.value)?)
88									} else {
89										run = run.add_break(BreakType::TextWrapping)
90									}
91								}
92								XMLElement::Drawing => {
93									if let Ok(drawing) = Drawing::read(r, &attributes) {
94										run = run.add_drawing(drawing);
95									}
96								}
97								XMLElement::FieldChar => {
98									if let Ok(f) = read_field_char(&attributes) {
99										run.children.push(RunChild::FieldChar(f));
100									}
101								}
102								XMLElement::InstrText => loop {
103									let e = r.next();
104									match e {
105										Ok(XmlEvent::Characters(c)) => {
106											run.children.push(RunChild::InstrTextString(c));
107											break;
108										}
109										Ok(XmlEvent::EndElement { name, .. }) => {
110											let e = XMLElement::from_str(&name.local_name).unwrap();
111											match e {
112												XMLElement::Run => {
113													return Ok(run);
114												}
115												_ => {}
116											}
117										}
118										Err(_) => return Err(ReaderError::XMLReadError),
119										_ => {}
120									}
121								},
122								_ => {}
123							}
124						}
125						Some("mc") => {
126							let e = McXMLElement::from_str(&name.local_name).unwrap();
127							match e {
128								McXMLElement::Fallback => {
129									let _ = McFallback::read(r, &attributes)?;
130								}
131								_ => {}
132							}
133						}
134						Some("v") => {
135							let e = VXMLElement::from_str(&name.local_name).unwrap();
136							match e {
137								// Experimental For now support only imageData in shape
138								VXMLElement::Shape => {
139									if let Ok(shape) = Shape::read(r, &attributes) {
140										run.children.push(RunChild::Shape(Box::new(shape)));
141									}
142								}
143								_ => {}
144							}
145						}
146						_ => {}
147					};
148				}
149				Ok(XmlEvent::Characters(c)) => match text_state {
150					TextState::Delete => {
151						run = run.add_delete_text_without_escape(replace_escaped(&c));
152					}
153					TextState::Text => {
154						run = run.add_text_without_escape(replace_escaped(&c));
155					}
156					_ => {}
157				},
158				Ok(XmlEvent::Whitespace(c)) => match text_state {
159					TextState::Delete => {
160						run = run.add_delete_text_without_escape(replace_escaped(&c));
161					}
162					TextState::Text => {
163						run = run.add_text_without_escape(replace_escaped(&c));
164					}
165					_ => {}
166				},
167				Ok(XmlEvent::EndElement { name, .. }) => {
168					let e = XMLElement::from_str(&name.local_name).unwrap();
169					match e {
170						XMLElement::Run => {
171							return Ok(run);
172						}
173						XMLElement::DeleteText | XMLElement::Text => text_state = TextState::Idle,
174						_ => {}
175					}
176				}
177				Err(_) => return Err(ReaderError::XMLReadError),
178				_ => {}
179			}
180		}
181	}
182}