Skip to content

Commit 92fed2d

Browse files
committed
Implement substitute method on TextRun class
Enables substituting text in multi-line paragraphs, preserving formatting and text styles. Example usage: ``` doc.paragraphs.each do |p| p.each_text_run do |tr| tr.substitute('_placeholder_', 'replacement value') end end ```
1 parent 3e67745 commit 92fed2d

4 files changed

Lines changed: 32 additions & 0 deletions

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ doc.paragraphs.each do |p|
8989
p.remove! if p.to_s =~ /TODO/
9090
end
9191

92+
# Substitute text, preserving formatting
93+
doc.paragraphs.each do |p|
94+
p.each_text_run do |tr|
95+
tr.substitute('_placeholder_', 'replacement value')
96+
end
97+
end
98+
9299
# Save document to specified path
93100
doc.save('example-edited.docx')
94101
```

lib/docx/containers/text_run.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ def parse_text
4545
@text_nodes.map(&:content).join('')
4646
end
4747

48+
# Substitute text in text @text_nodes
49+
def substitute(match, replacement)
50+
@text_nodes.each do |text_node|
51+
text_node.content = text_node.content.gsub(match, replacement)
52+
end
53+
end
54+
4855
def parse_formatting
4956
{
5057
italic: !@node.xpath('.//w:i').empty?,

spec/docx/document_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,24 @@
166166
end
167167
end
168168

169+
describe 'format-preserving substitution' do
170+
before do
171+
@doc = Docx::Document.open(@fixtures_path + '/substitution.docx')
172+
end
173+
174+
it 'should replace placeholder in any line of a paragraph' do
175+
expect(@doc.paragraphs[0].text).to eq('Page title')
176+
expect(@doc.paragraphs[1].text).to eq('Multi-line paragraph line 1_placeholder2_ line 2_placeholder3_ line3 ')
177+
178+
@doc.paragraphs[1].each_text_run do |text_run|
179+
text_run.substitute('_placeholder2_', 'same paragraph')
180+
text_run.substitute('_placeholder3_', 'yet the same paragraph')
181+
end
182+
183+
expect(@doc.paragraphs[1].text).to eq('Multi-line paragraph line 1same paragraph line 2yet the same paragraph line3 ')
184+
end
185+
end
186+
169187
describe 'read formatting' do
170188
before do
171189
@doc = Docx::Document.open(@fixtures_path + '/formatting.docx')

spec/fixtures/substitution.docx

6.08 KB
Binary file not shown.

0 commit comments

Comments
 (0)