docx_reader/documents/elements/
paragraph.rs

1use serde::ser::{SerializeStruct, Serializer};
2use serde::Serialize;
3
4use super::*;
5use crate::types::*;
6
7#[derive(Serialize, Debug, Clone, PartialEq)]
8#[serde(rename_all = "camelCase")]
9pub struct Paragraph {
10	pub id: String,
11	pub children: Vec<ParagraphChild>,
12	pub property: ParagraphProperty,
13	pub has_numbering: bool,
14}
15
16impl Default for Paragraph {
17	fn default() -> Self {
18		Self {
19			id: crate::generate_para_id(),
20			children: Vec::new(),
21			property: ParagraphProperty::new(),
22			has_numbering: false,
23		}
24	}
25}
26
27#[derive(Debug, Clone, PartialEq)]
28pub enum ParagraphChild {
29	Run(Box<Run>),
30	Insert(Insert),
31	Delete(Delete),
32	Hyperlink(Hyperlink),
33	StructuredDataTag(Box<StructuredDataTag>),
34}
35
36impl Serialize for ParagraphChild {
37	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
38	where
39		S: Serializer,
40	{
41		match *self {
42			ParagraphChild::Run(ref r) => {
43				let mut t = serializer.serialize_struct("Run", 2)?;
44				t.serialize_field("type", "run")?;
45				t.serialize_field("data", r)?;
46				t.end()
47			}
48			ParagraphChild::Insert(ref r) => {
49				let mut t = serializer.serialize_struct("Insert", 2)?;
50				t.serialize_field("type", "insert")?;
51				t.serialize_field("data", r)?;
52				t.end()
53			}
54			ParagraphChild::Delete(ref r) => {
55				let mut t = serializer.serialize_struct("Delete", 2)?;
56				t.serialize_field("type", "delete")?;
57				t.serialize_field("data", r)?;
58				t.end()
59			}
60			ParagraphChild::Hyperlink(ref r) => {
61				let mut t = serializer.serialize_struct("hyperlink", 2)?;
62				t.serialize_field("type", "hyperlink")?;
63				t.serialize_field("data", r)?;
64				t.end()
65			}
66			ParagraphChild::StructuredDataTag(ref r) => {
67				let mut t = serializer.serialize_struct("StructuredDataTag", 2)?;
68				t.serialize_field("type", "structuredDataTag")?;
69				t.serialize_field("data", r)?;
70				t.end()
71			}
72		}
73	}
74}
75
76impl Paragraph {
77	pub fn new() -> Paragraph {
78		Default::default()
79	}
80
81	pub fn id(mut self, id: impl Into<String>) -> Self {
82		self.id = id.into();
83		self
84	}
85
86	pub fn children(&self) -> &Vec<ParagraphChild> {
87		&self.children
88	}
89
90	pub fn add_run(mut self, run: Run) -> Paragraph {
91		self.children.push(ParagraphChild::Run(Box::new(run)));
92		self
93	}
94
95	pub fn add_hyperlink(mut self, link: Hyperlink) -> Self {
96		self.children.push(ParagraphChild::Hyperlink(link));
97		self
98	}
99
100	pub fn add_structured_data_tag(mut self, t: StructuredDataTag) -> Self {
101		self.children
102			.push(ParagraphChild::StructuredDataTag(Box::new(t)));
103		self
104	}
105
106	pub fn add_insert(mut self, insert: Insert) -> Paragraph {
107		self.children.push(ParagraphChild::Insert(insert));
108		self
109	}
110
111	pub fn add_delete(mut self, delete: Delete) -> Paragraph {
112		self.children.push(ParagraphChild::Delete(delete));
113		self
114	}
115
116	pub fn align(mut self, alignment_type: AlignmentType) -> Paragraph {
117		self.property = self.property.align(alignment_type);
118		self
119	}
120
121	pub fn style(mut self, style_id: &str) -> Paragraph {
122		self.property = self.property.style(style_id);
123		self
124	}
125
126	pub fn keep_next(mut self, v: bool) -> Self {
127		self.property = self.property.keep_next(v);
128		self
129	}
130
131	pub fn keep_lines(mut self, v: bool) -> Self {
132		self.property = self.property.keep_lines(v);
133		self
134	}
135
136	pub fn outline_lvl(mut self, v: usize) -> Self {
137		self.property = self.property.outline_lvl(v);
138		self
139	}
140
141	pub fn page_break_before(mut self, v: bool) -> Self {
142		self.property = self.property.page_break_before(v);
143		self
144	}
145
146	pub fn widow_control(mut self, v: bool) -> Self {
147		self.property = self.property.widow_control(v);
148		self
149	}
150
151	pub fn section_property(mut self, s: SectionProperty) -> Self {
152		self.property = self.property.section_property(s);
153		self
154	}
155
156	pub fn add_tab(mut self, t: Tab) -> Self {
157		self.property = self.property.add_tab(t);
158		self
159	}
160
161	pub fn indent(
162		mut self,
163		left: Option<i32>,
164		special_indent: Option<SpecialIndentType>,
165		end: Option<i32>,
166		start_chars: Option<i32>,
167	) -> Paragraph {
168		self.property = self.property.indent(left, special_indent, end, start_chars);
169		self
170	}
171
172	pub fn hanging_chars(mut self, chars: i32) -> Paragraph {
173		self.property = self.property.hanging_chars(chars);
174		self
175	}
176
177	pub fn first_line_chars(mut self, chars: i32) -> Paragraph {
178		self.property = self.property.first_line_chars(chars);
179		self
180	}
181
182	pub fn numbering(mut self, id: NumberingId, level: IndentLevel) -> Self {
183		self.property = self.property.numbering(id, level);
184		self.has_numbering = true;
185		self
186	}
187
188	pub fn size(mut self, size: usize) -> Self {
189		self.property.run_property = self.property.run_property.size(size);
190		self
191	}
192
193	pub fn bold(mut self) -> Self {
194		self.property.run_property = self.property.run_property.bold();
195		self
196	}
197
198	pub fn italic(mut self) -> Self {
199		self.property.run_property = self.property.run_property.italic();
200		self
201	}
202
203	pub fn fonts(mut self, f: RunFonts) -> Self {
204		self.property.run_property = self.property.run_property.fonts(f);
205		self
206	}
207
208	pub fn run_property(mut self, p: RunProperty) -> Self {
209		self.property.run_property = p;
210		self
211	}
212
213	pub fn line_spacing(mut self, spacing: LineSpacing) -> Self {
214		self.property = self.property.line_spacing(spacing);
215		self
216	}
217
218	pub fn character_spacing(mut self, spacing: i32) -> Self {
219		self.property = self.property.character_spacing(spacing);
220		self
221	}
222
223	pub fn delete(mut self, author: impl Into<String>, date: impl Into<String>) -> Self {
224		self.property.run_property.del = Some(Delete::new().author(author).date(date));
225		self
226	}
227
228	pub fn insert(mut self, author: impl Into<String>, date: impl Into<String>) -> Self {
229		self.property.run_property.ins = Some(Insert::new_with_empty().author(author).date(date));
230		self
231	}
232
233	pub fn paragraph_property_change(mut self, p: ParagraphPropertyChange) -> Self {
234		self.property = self.property.paragraph_property_change(p);
235		self
236	}
237
238	pub fn raw_text(&self) -> String {
239		let mut s = "".to_string();
240		// For now support only run and ins.
241		for c in self.children.iter() {
242			match c {
243				ParagraphChild::Insert(i) => {
244					for c in i.children.iter() {
245						if let InsertChild::Run(r) = c {
246							for c in r.children.iter() {
247								if let RunChild::Text(t) = c {
248									s.push_str(&t.text);
249								}
250							}
251						}
252					}
253				}
254				ParagraphChild::Run(run) => {
255					for c in run.children.iter() {
256						if let RunChild::Text(t) = c {
257							s.push_str(&t.text);
258						}
259					}
260				}
261				_ => {}
262			}
263		}
264		s
265	}
266}