Class: Consolidate::Docx::Merge

Inherits:
Object
  • Object
show all
Defined in:
lib/consolidate/docx/merge.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, verbose: false) ⇒ Merge



18
19
20
21
22
23
24
25
26
27
# File 'lib/consolidate/docx/merge.rb', line 18

def initialize(path, verbose: false)
  @verbose = verbose
  @zip = Zip::File.open(path)
  @documents = load_documents
  @relations = load_relations
  @contents_xml = load_and_update_contents_xml
  @output = {}
  @images = {}
  @mapping = {}
end

Class Method Details

.open(path, verbose: false, &block) ⇒ Object



11
12
13
14
15
16
# File 'lib/consolidate/docx/merge.rb', line 11

def self.open(path, verbose: false, &block)
  new(path, verbose: verbose, &block).tap do |merge|
    block&.call merge
  end
  path
end

Instance Method Details

#content_document_namesObject

List the content within this docx



47
# File 'lib/consolidate/docx/merge.rb', line 47

def content_document_names = @documents.keys

#data(mapping = {}) ⇒ Object

Set the merge data and erform the substitution - creating copies of any documents that contain merge tags and replacing the tags with the supplied data



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/consolidate/docx/merge.rb', line 53

def data mapping = {}
  @mapping = mapping.transform_keys(&:to_s)
  if verbose
    puts "...mapping data"
    puts @mapping.keys.select { |field_name| text_field_names.include?(field_name) }.map { |field_name| "...   #{field_name} => #{@mapping[field_name]}" }.join("\n")
  end

  @images = load_images_and_link_relations

  @documents.each do |name, document|
    @output[name] = substitute(document.dup, document_name: name).serialize save_with: 0
  end
end

#document_namesObject

List the documents stored within this docx



44
# File 'lib/consolidate/docx/merge.rb', line 44

def document_names = @zip.entries.map(&:name)

#examineObject

Helper method to display the contents of the document and the merge fields from the CLI



30
31
32
33
34
35
# File 'lib/consolidate/docx/merge.rb', line 30

def examine
  puts "Documents: #{document_names.join(", ")}"
  puts "Content documents: #{content_document_names.join(", ")}"
  puts "Merge fields: #{text_field_names.join(", ")}"
  puts "Image fields: #{image_field_names.join(", ")}"
end

#image_field_namesObject

Read all documents within the docx and extract any image fields



41
# File 'lib/consolidate/docx/merge.rb', line 41

def image_field_names = @image_field_names ||= tag_nodes.collect { |tag_node| image_field_names_from tag_node }.flatten.compact.uniq

#merge_field_namesObject

List the field names that are present in the merge data



50
# File 'lib/consolidate/docx/merge.rb', line 50

def merge_field_names = @mapping.keys

#text_field_namesObject

Read all documents within the docx and extract any merge fields



38
# File 'lib/consolidate/docx/merge.rb', line 38

def text_field_names = @text_field_names ||= tag_nodes.collect { |tag_node| text_field_names_from tag_node }.flatten.compact.uniq

#write_to(path) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/consolidate/docx/merge.rb', line 67

def write_to path
  puts "...writing to #{path}" if verbose
  Zip::File.open(path, create: true) do |out|
    @output[contents_xml] = @contents_xml.serialize save_with: 0

    @images.each do |field_name, image|
      next if image.nil?
      puts "...  writing image #{field_name} to #{image.storage_path}" if verbose
      out.get_output_stream(image.storage_path) { |o| o.write image.contents }
    end

    @relations.each do |relation_name, relations|
      puts "...  writing relations #{relation_name}" if verbose
      out.get_output_stream(relation_name) { |o| o.write relations }
    end

    @zip.reject do |entry|
      @relations.key? entry.name
    end.each do |entry|
      puts "...  writing updated document to #{entry.name}" if verbose
      out.get_output_stream(entry.name) { |o| o.write(@output[entry.name] || @relations[entry.name] || @zip.read(entry.name)) }
    end
  end
end