linch_docx_rs/document/
text_ops.rs1use crate::document::{BlockContent, Document, Paragraph, ParagraphContent, RunContent};
4
5#[derive(Clone, Debug)]
7pub struct TextLocation {
8 pub paragraph_index: usize,
9 pub char_offset: usize,
10}
11
12impl Document {
13 pub fn replace_text(&mut self, find: &str, replace: &str) -> usize {
15 let mut count = 0;
16 for content in &mut self.body.content {
17 if let BlockContent::Paragraph(para) = content {
18 count += replace_text_in_paragraph(para, find, replace);
19 }
20 }
21 count
22 }
23
24 pub fn find_text(&self, needle: &str) -> Vec<TextLocation> {
26 let mut results = Vec::new();
27 for (para_idx, para) in self.body.paragraphs().enumerate() {
28 let text = para.text();
29 let mut start = 0;
30 while let Some(pos) = text[start..].find(needle) {
31 results.push(TextLocation {
32 paragraph_index: para_idx,
33 char_offset: start + pos,
34 });
35 start += pos + needle.len();
36 }
37 }
38 results
39 }
40}
41
42fn replace_text_in_paragraph(para: &mut Paragraph, find: &str, replace: &str) -> usize {
44 let mut count = 0;
45 for content in &mut para.content {
46 if let ParagraphContent::Run(run) = content {
47 for rc in &mut run.content {
48 if let RunContent::Text(ref mut text) = rc {
49 let matches = text.matches(find).count();
50 if matches > 0 {
51 *text = text.replace(find, replace);
52 count += matches;
53 }
54 }
55 }
56 }
57 }
58 count
59}