docx_templater 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/docx_templater.rb +114 -0
  2. metadata +79 -0
@@ -0,0 +1,114 @@
1
+ require 'zip/zipfilesystem'
2
+ require 'htmlentities'
3
+
4
+ # Use .docx as reusable templates
5
+ #
6
+ # Example:
7
+ # buffer = DocxTemplater.replace_file_with_content('path/to/mydocument.docx',
8
+ # {
9
+ # :client_email1 => 'test@example.com',
10
+ # :client_phone1 => '555-555-5555',
11
+ # })
12
+ # # In Rails you can send a word document via send_data
13
+ # send_data buffer.string, :filename => 'REPC.docx'
14
+ # # Or save the output to a word file
15
+ # File.open("path/to/mydocument.docx", "wb") {|f| f.write(buffer.string) }
16
+ class DocxTemplater
17
+ def initialize(opts = {})
18
+ @options = opts
19
+ end
20
+
21
+ def replace_file_with_content(file_path, data_provider)
22
+ # Rubyzip doesn't save it right unless saved like this: https://gist.github.com/e7d2855435654e1ebc52
23
+ zf = Zip::ZipFile.new(file_path) # Put original file name here
24
+
25
+ buffer = Zip::ZipOutputStream.write_buffer do |out|
26
+ zf.entries.each do |e|
27
+ process_entry(e, out, data_provider)
28
+ end
29
+ end
30
+ # You can save this buffer or send it with rails via send_data
31
+ return buffer
32
+ end
33
+
34
+ def generate_tags_for(*args)
35
+ attributes = {}
36
+ args.flatten!
37
+ # Prefixes the model name or custom prefix. Makes it so we don't having naming clashes when used with records from multiple m
38
+ args.each do |arg|
39
+ if arg.is_a?(Hash) && arg.has_key?(:data) && arg.has_key?(:prefix)
40
+ template_attributes = (arg[:data].respond_to?(:template_attributes) && :template_attributes) || :attributes
41
+ arg[:data].send(template_attributes).each_key do |key|
42
+ attributes["#{arg[:prefix]}_#{key.to_s}".to_sym] = arg[:data].send(template_attributes)[key]
43
+ end
44
+ elsif arg.is_a?(Hash)
45
+ attributes.merge!(arg)
46
+ else
47
+ template_attributes = (arg.respond_to?(:template_attributes) && :template_attributes) || :attributes
48
+ arg.send(template_attributes).each_key do |key|
49
+ attributes["#{arg.class.name.underscore}_#{key.to_s}".to_sym] = arg.send(template_attributes)[key]
50
+ end
51
+ end
52
+ end
53
+ attributes
54
+ end
55
+
56
+ private
57
+ def all_tags_regex
58
+ /\|\|\<*.+?\>*\|\|/
59
+ end
60
+
61
+ def malformed_tag_regex
62
+ /(?<=>)\w{3,}(?=<)/
63
+ end
64
+
65
+ def well_formed_tag_regex
66
+ /(?<=\|\|)\w{3,}(?=\|\|)/
67
+ end
68
+
69
+ def just_label_regex
70
+ /(?<=>)(\w{3,})/
71
+ end
72
+
73
+ def entry_requires_replacement?(entry)
74
+ entry.ftype != :directory && entry.name =~ /document|header|footer/
75
+ end
76
+
77
+ def get_entry_content(entry, data_provider)
78
+ if entry_requires_replacement?(entry)
79
+ replace_entry_content(entry.get_input_stream.read, data_provider)
80
+ else
81
+ entry.get_input_stream.read
82
+ end
83
+ end
84
+
85
+ def process_entry(entry, output, data_provider)
86
+ output.put_next_entry(entry.name)
87
+ output.write get_entry_content(entry, data_provider) if entry.ftype != :directory
88
+ end
89
+
90
+ def replace_entry_content(str, data_provider)
91
+ possible_tags = str.scan(all_tags_regex)
92
+ # Loops through what looks like are tags. Anything with ||name|| even if they are not in the available tags list
93
+ possible_tags.each do |tag|
94
+ #extracts just the tag name
95
+ tag_name = malformed_tag_regex.match(tag)
96
+ tag_name ||= well_formed_tag_regex.match(tag)
97
+ tag_name ||= ''
98
+ # This will handle instances where someone edits just part of a tag and Word wraps that part in more XML
99
+ words = tag.scan(just_label_regex).flatten!
100
+ if words.respond_to?(:size) && words.size > 1
101
+ #Then the tag was split by word
102
+ tag_name = words.join('')
103
+ end
104
+ tag_name = tag_name.to_s.to_sym
105
+ # if in the available tag list, replace with the new value
106
+ if data_provider.has_key?(tag_name)
107
+ encoder = HTMLEntities.new
108
+ content = encoder.encode("#{data_provider[tag_name]}")
109
+ str.gsub!(tag, content)
110
+ end
111
+ end
112
+ str
113
+ end
114
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: docx_templater
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.7
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Paul Smith
9
+ - Michael Ries
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-08-03 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rubyzip
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.9.9
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: 0.9.9
31
+ - !ruby/object:Gem::Dependency
32
+ name: htmlentities
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 4.3.1
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: 4.3.1
47
+ description: Uses a .docx file with keyword tags within '||' as a template. This gem
48
+ will then open the .docx and replace those tags with dynamically defined content.
49
+ email: pauls@basecampops.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - lib/docx_templater.rb
55
+ homepage: http://rubygems.org/gems/docx_templater
56
+ licenses: []
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 1.8.24
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Uses a .docx as a template and replaces 'tags' within || with other content
79
+ test_files: []