docx_reader/reader/
run.rs1use 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 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}