docx_templater 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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: []