diff --git a/lib/docx_replace.rb b/lib/docx_replace.rb index 0e702df..a7d9795 100644 --- a/lib/docx_replace.rb +++ b/lib/docx_replace.rb @@ -6,25 +6,28 @@ module DocxReplace class Doc - attr_reader :document_content + attr_reader :document_contents def initialize(path, temp_dir=nil) @zip_file = Zip::File.new(path) + @document_file_paths = find_query_file_paths() @temp_dir = temp_dir - read_docx_file + read_docx_files end def replace(pattern, replacement, multiple_occurrences=false) replace = replacement.to_s.encode(xml: :text) - if multiple_occurrences - @document_content.force_encoding("UTF-8").gsub!(pattern, replace) - else - @document_content.force_encoding("UTF-8").sub!(pattern, replace) + @document_contents.each do |path, document| + if multiple_occurrences + document.force_encoding("UTF-8").gsub!(pattern, replace) + else + document.force_encoding("UTF-8").sub!(pattern, replace) + end end end def matches(pattern) - @document_content.scan(pattern).map{|match| match.first} + @document_contents.values.join.scan(pattern).map{|match| match.first} end def unique_matches(pattern) @@ -39,10 +42,18 @@ def commit(new_path=nil) end private - DOCUMENT_FILE_PATH = 'word/document.xml' - def read_docx_file - @document_content = @zip_file.read(DOCUMENT_FILE_PATH) + def find_query_file_paths + @zip_file.entries.map(&:name).select do |entry| + !(/^word\/(document|footer[0-9]+|header[0-9]+).xml$/ =~ entry).nil? + end + end + + def read_docx_files + @document_contents = {} + @document_file_paths.each do |path| + @document_contents[path] = @zip_file.read(path) + end end def write_back_to_file(new_path=nil) @@ -51,16 +62,19 @@ def write_back_to_file(new_path=nil) else temp_file = Tempfile.new('docxedit-', @temp_dir) end + Zip::OutputStream.open(temp_file.path) do |zos| @zip_file.entries.each do |e| - unless e.name == DOCUMENT_FILE_PATH + unless @document_file_paths.include?(e.name) zos.put_next_entry(e.name) zos.print e.get_input_stream.read end end - zos.put_next_entry(DOCUMENT_FILE_PATH) - zos.print @document_content + @document_contents.each do |path, document| + zos.put_next_entry(path) + zos.print document + end end if new_path.nil?