standard-procedure-consolidate 0.3.9 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/checksums/standard-procedure-consolidate-0.4.0.gem.sha512 +1 -0
- data/lib/consolidate/docx/image.rb +11 -3
- data/lib/consolidate/docx/image_reference_node_builder.rb +64 -62
- data/lib/consolidate/docx/merge.rb +138 -48
- data/lib/consolidate/image.rb +4 -1
- data/lib/consolidate/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39e8b33a8f43ddb4a3bff6ccfb91ee9608d741dc9dff3759ea7c45b1c3cf3d3c
|
4
|
+
data.tar.gz: 71d357d9e60a98f199c7d67ab3f6a0b5ee8999218162fabf43a4fc4283f04a85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e68a557b00ecb43feb93cdc9a5c9a4c09edd93f8421206be3372e617809bc9ce01cb9ad4928e6f97f49b6db64fd9a329dd2ff7360d5d7b618ce455d0f080c6b1
|
7
|
+
data.tar.gz: 94417403770d855c0df0d1927b3de00235a668503790e06388de83cadb3b3d2b533f394fab3ddcda5ace164bbe7394810c8ad6b00092eb553552f74fabaa2e5e
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
58d1597374e775340c60e3e49b9d65437909b482f7be3040fb9fdca5d8d4b4d3020508a9ee01e3521b2c552e1b853d0475335d1ca1c092b4172c1e9ac86df640
|
@@ -13,12 +13,20 @@ module Consolidate
|
|
13
13
|
def storage_path = "word/#{media_path}"
|
14
14
|
|
15
15
|
# Convert width from pixels to EMU
|
16
|
-
def width = super *
|
16
|
+
def width = super * emu_per_width_pixel
|
17
17
|
|
18
18
|
# Convert height from pixels to EMU
|
19
|
-
def height = super *
|
19
|
+
def height = super * emu_per_height_pixel
|
20
20
|
|
21
|
-
|
21
|
+
# Get the width of this image in EMU up to a maximum page width (also in EMU)
|
22
|
+
def clamped_width(maximum = 7_772_400) = [width, maximum].min
|
23
|
+
|
24
|
+
# Get the height of this image in EMU adjusted for a maximum page width (also in EMU)
|
25
|
+
def clamped_height(maximum = 7_772_400) = (height * clamped_width(maximum).to_f / width.to_f).to_i
|
26
|
+
|
27
|
+
def emu_per_width_pixel = 914_400 / dpi[:x]
|
28
|
+
|
29
|
+
def emu_per_height_pixel = 914_400 / dpi[:y]
|
22
30
|
end
|
23
31
|
end
|
24
32
|
end
|
@@ -5,74 +5,67 @@ require "nokogiri"
|
|
5
5
|
|
6
6
|
module Consolidate
|
7
7
|
module Docx
|
8
|
-
class ImageReferenceNodeBuilder < Data.define(:field_name, :image, :node_id, :document)
|
8
|
+
class ImageReferenceNodeBuilder < Data.define(:field_name, :image, :node_id, :image_number, :document)
|
9
9
|
def call
|
10
|
-
Nokogiri::XML::Node.new("w:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
graphic_frame_locks["noChangeAspect"] = "1"
|
31
|
-
end
|
10
|
+
Nokogiri::XML::Node.new("w:drawing", document).tap do |drawing|
|
11
|
+
drawing["xmlns:a"] = "http://schemas.openxmlformats.org/drawingml/2006/main"
|
12
|
+
drawing << Nokogiri::XML::Node.new("wp:inline", document).tap do |inline|
|
13
|
+
inline["distT"] = "0"
|
14
|
+
inline["distB"] = "0"
|
15
|
+
inline["distL"] = "0"
|
16
|
+
inline["distR"] = "0"
|
17
|
+
inline << Nokogiri::XML::Node.new("wp:extent", document).tap do |extent|
|
18
|
+
extent["cx"] = image.clamped_width(max_width_from(document))
|
19
|
+
extent["cy"] = image.clamped_height(max_width_from(document))
|
20
|
+
end
|
21
|
+
inline << Nokogiri::XML::Node.new("wp:effectExtent", document).tap do |effect_extent|
|
22
|
+
effect_extent["l"] = "0"
|
23
|
+
effect_extent["t"] = "0"
|
24
|
+
effect_extent["r"] = "0"
|
25
|
+
effect_extent["b"] = "0"
|
26
|
+
end
|
27
|
+
inline << Nokogiri::XML::Node.new("wp:cNvGraphicFramePr", document).tap do |c_nv_graphic_frame_pr|
|
28
|
+
c_nv_graphic_frame_pr << Nokogiri::XML::Node.new("a:graphicFrameLocks", document).tap do |graphic_frame_locks|
|
29
|
+
graphic_frame_locks["noChangeAspect"] = true
|
32
30
|
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
31
|
+
end
|
32
|
+
inline << Nokogiri::XML::Node.new("a:graphic", document).tap do |graphic|
|
33
|
+
graphic["xmlns:a"] = "http://schemas.openxmlformats.org/drawingml/2006/main"
|
34
|
+
graphic << Nokogiri::XML::Node.new("a:graphicData", document).tap do |graphic_data|
|
35
|
+
graphic_data["uri"] = "http://schemas.openxmlformats.org/drawingml/2006/picture"
|
36
|
+
graphic_data << Nokogiri::XML::Node.new("pic:pic", document).tap do |pic|
|
37
|
+
pic["xmlns:pic"] = "http://schemas.openxmlformats.org/drawingml/2006/picture"
|
38
|
+
pic << Nokogiri::XML::Node.new("pic:nvPicPr", document).tap do |nv_pic_pr|
|
39
|
+
nv_pic_pr << Nokogiri::XML::Node.new("pic:cNvPr", document).tap do |c_nv_pr|
|
40
|
+
c_nv_pr["id"] = image_number
|
41
|
+
c_nv_pr["name"] = image.name
|
42
|
+
c_nv_pr["descr"] = image.name
|
43
|
+
c_nv_pr["hidden"] = false
|
44
|
+
c_nv_pr << Nokogiri::XML::Node.new("pic:cNvPicPr", document)
|
49
45
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
blip << Nokogiri::XML::Node.new("a:extLst", document)
|
55
|
-
end
|
56
|
-
blip_fill << Nokogiri::XML::Node.new("a:stretch", document).tap do |stretch|
|
57
|
-
stretch << Nokogiri::XML::Node.new("a:fillRect", document)
|
58
|
-
end
|
46
|
+
end
|
47
|
+
pic << Nokogiri::XML::Node.new("pic:blipFill", document).tap do |blip_fill|
|
48
|
+
blip_fill << Nokogiri::XML::Node.new("a:blip", document).tap do |blip|
|
49
|
+
blip["r:embed"] = node_id
|
59
50
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
51
|
+
blip_fill << Nokogiri::XML::Node.new("a:stretch", document).tap do |stretch|
|
52
|
+
stretch << Nokogiri::XML::Node.new("a:fillRect", document)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
pic << Nokogiri::XML::Node.new("pic:spPr", document).tap do |sp_pr|
|
56
|
+
sp_pr << Nokogiri::XML::Node.new("a:xfrm", document).tap do |xfrm|
|
57
|
+
xfrm << Nokogiri::XML::Node.new("a:off", document).tap do |off|
|
58
|
+
off["x"] = "0"
|
59
|
+
off["y"] = "0"
|
70
60
|
end
|
71
|
-
|
72
|
-
|
73
|
-
|
61
|
+
xfrm << Nokogiri::XML::Node.new("a:ext", document).tap do |ext|
|
62
|
+
ext["cx"] = image.clamped_width(max_width_from(document))
|
63
|
+
ext["cy"] = image.clamped_height(max_width_from(document))
|
74
64
|
end
|
75
|
-
|
65
|
+
end
|
66
|
+
sp_pr << Nokogiri::XML::Node.new("a:prstGeom", document).tap do |prst_geom|
|
67
|
+
prst_geom["prst"] = "rect"
|
68
|
+
prst_geom << Nokogiri::XML::Node.new("a:avLst", document)
|
76
69
|
end
|
77
70
|
end
|
78
71
|
end
|
@@ -81,6 +74,15 @@ module Consolidate
|
|
81
74
|
end
|
82
75
|
end
|
83
76
|
end
|
77
|
+
|
78
|
+
DEFAULT_PAGE_WIDTH = 12_240
|
79
|
+
TWENTIETHS_OF_A_POINT_TO_EMU = 635
|
80
|
+
DEFAULT_PAGE_WIDTH_IN_EMU = DEFAULT_PAGE_WIDTH * TWENTIETHS_OF_A_POINT_TO_EMU
|
81
|
+
|
82
|
+
private def max_width_from document
|
83
|
+
page_width = (document.at_xpath("//w:sectPr/w:pgSz/@w:w")&.value || DEFAULT_PAGE_WIDTH).to_i
|
84
|
+
page_width * TWENTIETHS_OF_A_POINT_TO_EMU
|
85
|
+
end
|
84
86
|
end
|
85
87
|
end
|
86
88
|
end
|
@@ -20,13 +20,16 @@ module Consolidate
|
|
20
20
|
@zip = Zip::File.open(path)
|
21
21
|
@documents = load_documents
|
22
22
|
@relations = load_relations
|
23
|
+
@contents_xml = load_and_update_contents_xml
|
23
24
|
@output = {}
|
24
25
|
@images = {}
|
26
|
+
@mapping = {}
|
25
27
|
end
|
26
28
|
|
27
29
|
# Helper method to display the contents of the document and the merge fields from the CLI
|
28
30
|
def examine
|
29
31
|
puts "Documents: #{document_names.join(", ")}"
|
32
|
+
puts "Content documents: #{content_document_names.join(", ")}"
|
30
33
|
puts "Merge fields: #{text_field_names.join(", ")}"
|
31
34
|
puts "Image fields: #{image_field_names.join(", ")}"
|
32
35
|
end
|
@@ -38,29 +41,47 @@ module Consolidate
|
|
38
41
|
def image_field_names = @image_field_names ||= tag_nodes.collect { |tag_node| image_field_names_from tag_node }.flatten.compact.uniq
|
39
42
|
|
40
43
|
# List the documents stored within this docx
|
41
|
-
def document_names = @zip.entries.
|
44
|
+
def document_names = @zip.entries.map(&:name)
|
45
|
+
|
46
|
+
# List the content within this docx
|
47
|
+
def content_document_names = @documents.keys
|
48
|
+
|
49
|
+
# List the field names that are present in the merge data
|
50
|
+
def merge_field_names = @mapping.keys
|
42
51
|
|
43
52
|
# 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
|
44
53
|
def data mapping = {}
|
45
|
-
mapping = mapping.transform_keys(&:to_s)
|
46
|
-
|
54
|
+
@mapping = mapping.transform_keys(&:to_s)
|
55
|
+
if verbose
|
56
|
+
puts "...mapping data"
|
57
|
+
puts @mapping.keys.select { |field_name| text_field_names.include?(field_name) }.map { |field_name| "... #{field_name} => #{@mapping[field_name]}" }.join("\n")
|
58
|
+
end
|
47
59
|
|
48
|
-
@images =
|
60
|
+
@images = load_images_and_link_relations
|
49
61
|
|
50
62
|
@documents.each do |name, document|
|
51
|
-
@output[name] = substitute(document.dup,
|
63
|
+
@output[name] = substitute(document.dup, document_name: name).serialize save_with: 0
|
52
64
|
end
|
53
65
|
end
|
54
66
|
|
55
67
|
def write_to path
|
56
68
|
puts "...writing to #{path}" if verbose
|
57
69
|
Zip::File.open(path, Zip::File::CREATE) do |out|
|
70
|
+
@output[contents_xml] = @contents_xml.serialize save_with: 0
|
71
|
+
|
58
72
|
@images.each do |field_name, image|
|
59
|
-
puts "... writing #{field_name} to #{image.storage_path}" if verbose
|
73
|
+
puts "... writing image #{field_name} to #{image.storage_path}" if verbose
|
60
74
|
out.get_output_stream(image.storage_path) { |o| o.write image.contents }
|
61
75
|
end
|
62
76
|
|
63
|
-
@
|
77
|
+
@relations.each do |relation_name, relations|
|
78
|
+
puts "... writing relations #{relation_name}" if verbose
|
79
|
+
out.get_output_stream(relation_name) { |o| o.write relations }
|
80
|
+
end
|
81
|
+
|
82
|
+
@zip.reject do |entry|
|
83
|
+
@relations.key? entry.name
|
84
|
+
end.each do |entry|
|
64
85
|
puts "... writing updated document to #{entry.name}" if verbose
|
65
86
|
out.get_output_stream(entry.name) { |o| o.write(@output[entry.name] || @relations[entry.name] || @zip.read(entry.name)) }
|
66
87
|
end
|
@@ -71,25 +92,7 @@ module Consolidate
|
|
71
92
|
|
72
93
|
attr_reader :verbose
|
73
94
|
|
74
|
-
def
|
75
|
-
@zip.entries.each_with_object({}) do |entry, results|
|
76
|
-
next unless entry.name.match?(/word\/(document|header|footer|footnotes|endnotes).?\.xml/)
|
77
|
-
puts "...reading document #{entry.name}" if verbose
|
78
|
-
contents = @zip.get_input_stream entry
|
79
|
-
results[entry.name] = Nokogiri::XML(contents) { |x| x.noent }
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def load_relations
|
84
|
-
@zip.entries.each_with_object({}) do |entry, results|
|
85
|
-
next unless entry.name.match?(/word\/_rels\/.*.rels/)
|
86
|
-
puts "...reading relation #{entry.name}" if verbose
|
87
|
-
contents = @zip.get_input_stream entry
|
88
|
-
results[entry.name] = Nokogiri::XML(contents) { |x| x.noent }
|
89
|
-
end
|
90
|
-
ensure
|
91
|
-
@zip.close
|
92
|
-
end
|
95
|
+
def contents_xml = "[Content_Types].xml"
|
93
96
|
|
94
97
|
# Regex to find merge fields that contain text
|
95
98
|
def text_tag = /\{\{\s*(?!.*_image\b)(\S+)\s*\}\}/i
|
@@ -113,30 +116,59 @@ module Consolidate
|
|
113
116
|
# Extract the image field name(s) from the paragraph
|
114
117
|
def image_field_names_from(tag_node) = (matches = tag_node.content.scan(image_tag)).empty? ? nil : matches.flatten.map(&:strip)
|
115
118
|
|
119
|
+
# Unique number for each image field
|
120
|
+
def relation_number_for(field_name) = @mapping.keys.index(field_name) + 1000
|
121
|
+
|
116
122
|
# Identifier to use when linking a merge field to the actual image file contents
|
117
|
-
def relation_id_for(field_name) = "rId#{field_name}"
|
123
|
+
def relation_id_for(field_name) = "rId#{relation_number_for(field_name)}"
|
124
|
+
|
125
|
+
# Empty elations document for documents that do not already have one
|
126
|
+
def default_relations_document = %(<?xml version="1.0" encoding="UTF-8"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>)
|
127
|
+
|
128
|
+
def load_documents
|
129
|
+
@zip.entries.each_with_object({}) do |entry, results|
|
130
|
+
next unless entry.name.match?(/word\/(document|header|footer|footnotes|endnotes).?\.xml/)
|
131
|
+
puts "...reading document #{entry.name}" if verbose
|
132
|
+
contents = @zip.get_input_stream entry
|
133
|
+
results[entry.name] = Nokogiri::XML(contents) { |x| x.noent }
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def load_relations
|
138
|
+
@zip.entries.each_with_object({}) do |entry, results|
|
139
|
+
next unless entry.name.match?(/word\/(document|header|footer|footnotes|endnotes).?\.xml/)
|
140
|
+
relation_document = entry.name.gsub("word/", "word/_rels/").gsub(".xml", ".xml.rels")
|
141
|
+
puts "...reading or building relations for #{relation_document}" if verbose
|
142
|
+
contents = @zip.find_entry(relation_document) ? @zip.get_input_stream(relation_document) : default_relations_document
|
143
|
+
results[relation_document] = Nokogiri::XML(contents) { |x| x.noent }
|
144
|
+
end
|
145
|
+
ensure
|
146
|
+
@zip.close
|
147
|
+
end
|
118
148
|
|
119
149
|
# Create relation links for each image field and store the image data
|
120
|
-
def
|
121
|
-
|
150
|
+
def load_images_and_link_relations
|
151
|
+
load_images.tap do |images|
|
122
152
|
link_relations_to images
|
123
153
|
end
|
124
154
|
end
|
125
155
|
|
126
156
|
# Build a mapping of image paths to the image data so that the image data can be stored in the output docx
|
127
|
-
def
|
157
|
+
def load_images
|
128
158
|
image_field_names.each_with_object({}) do |field_name, result|
|
129
|
-
result[field_name] = Consolidate::Docx::Image.new(mapping[field_name])
|
159
|
+
result[field_name] = Consolidate::Docx::Image.new(@mapping[field_name])
|
160
|
+
puts "... #{field_name} => #{result[field_name].media_path}" if verbose
|
130
161
|
end
|
131
162
|
end
|
132
163
|
|
133
164
|
# Update all relation documents to include a relationship for each image field and its stored image path
|
134
165
|
def link_relations_to images
|
135
166
|
@relations.each do |name, xml|
|
167
|
+
puts "... linking images in #{name}" if verbose
|
136
168
|
images.each do |field_name, image|
|
137
169
|
# Is this image already referenced in this relationship document?
|
138
|
-
next unless xml.at_xpath("//Relationship[@Target
|
139
|
-
puts "...
|
170
|
+
next unless xml.at_xpath("//Relationship[@Target=\"#{image.media_path}\"]").nil?
|
171
|
+
puts "... #{relation_id_for(field_name)} => #{image.media_path}" if verbose
|
140
172
|
xml.root << Nokogiri::XML::Node.new("Relationship", xml).tap do |relation|
|
141
173
|
relation["Id"] = relation_id_for(field_name)
|
142
174
|
relation["Type"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
|
@@ -146,32 +178,38 @@ module Consolidate
|
|
146
178
|
end
|
147
179
|
end
|
148
180
|
|
181
|
+
def load_and_update_contents_xml
|
182
|
+
puts "...reading and updating #{contents_xml}" if verbose
|
183
|
+
content = @zip.get_input_stream(contents_xml)
|
184
|
+
Nokogiri::XML(content) { |x| x.noent }.tap do |document|
|
185
|
+
add_content_relations_to document
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
149
189
|
# Go through the given document, replacing any merge fields with the values provided
|
150
190
|
# and storing the results in a new document
|
151
|
-
def substitute document, document_name
|
191
|
+
def substitute document, document_name:
|
192
|
+
puts "...substituting fields in #{document_name}" if verbose && tag_nodes_for(document).any?
|
193
|
+
substitute_text document, document_name: document_name
|
194
|
+
substitute_images document, document_name: document_name
|
195
|
+
end
|
196
|
+
|
197
|
+
def substitute_text document, document_name:
|
152
198
|
tag_nodes_for(document).each do |tag_node|
|
153
|
-
|
154
|
-
image_field_names = image_field_names_from(tag_node) || []
|
199
|
+
field_names = text_field_names_from(tag_node) || []
|
155
200
|
|
156
201
|
# Extract the properties (formatting) nodes if they exist
|
157
202
|
paragraph_properties = tag_node.search ".//w:pPr"
|
158
203
|
run_properties = tag_node.at_xpath ".//w:rPr"
|
159
204
|
|
160
|
-
# Get the current contents, then substitute any text fields
|
205
|
+
# Get the current contents, then substitute any text fields
|
161
206
|
text = tag_node.content
|
162
207
|
|
163
|
-
|
164
|
-
field_value = mapping[field_name].to_s
|
165
|
-
puts "...substituting #{field_name} with #{field_value}
|
208
|
+
field_names.each do |field_name|
|
209
|
+
field_value = @mapping[field_name].to_s
|
210
|
+
puts "... substituting '#{field_name}' with '#{field_value}'" if verbose
|
166
211
|
text = text.gsub(tag_for(field_name), field_value)
|
167
212
|
end
|
168
|
-
image_nodes = image_field_names.collect do |field_name|
|
169
|
-
image = @images[field_name]
|
170
|
-
puts "...substituting #{field_name} in #{document_name}" if verbose
|
171
|
-
# Remove the merge tag and create an image reference node to be added to this node
|
172
|
-
text = text.gsub(tag_for(field_name), "")
|
173
|
-
ImageReferenceNodeBuilder.new(field_name: field_name, image: image, node_id: relation_id_for(field_name), document: document).call
|
174
|
-
end
|
175
213
|
|
176
214
|
# Create a new text node with the substituted text
|
177
215
|
text_node = Nokogiri::XML::Node.new("w:t", tag_node.document)
|
@@ -182,7 +220,39 @@ module Consolidate
|
|
182
220
|
run_node << run_properties unless run_properties.nil?
|
183
221
|
run_node << text_node
|
184
222
|
# Add the paragraph properties and the run node to the tag node
|
185
|
-
tag_node.children = Nokogiri::XML::NodeSet.new(document, paragraph_properties.to_a + [run_node]
|
223
|
+
tag_node.children = Nokogiri::XML::NodeSet.new(document, paragraph_properties.to_a + [run_node])
|
224
|
+
rescue => ex
|
225
|
+
# Have to mangle the exception message otherwise it outputs the entire document
|
226
|
+
puts ex.message.to_s[0..255]
|
227
|
+
puts ex.backtrace.first
|
228
|
+
end
|
229
|
+
document
|
230
|
+
end
|
231
|
+
|
232
|
+
# Go through the given document, replacing any merge fields with the values provided
|
233
|
+
# and storing the results in a new document
|
234
|
+
def substitute_images document, document_name:
|
235
|
+
tag_nodes_for(document).each do |tag_node|
|
236
|
+
field_names = image_field_names_from(tag_node) || []
|
237
|
+
# Extract the properties (formatting) nodes if they exist
|
238
|
+
paragraph_properties = tag_node.search ".//w:pPr"
|
239
|
+
run_properties = tag_node.at_xpath ".//w:rPr"
|
240
|
+
|
241
|
+
pieces = tag_node.content.split(image_tag)
|
242
|
+
# Split the content into pieces - either text or an image merge field
|
243
|
+
# Then replace the text with text nodes or the image merge fields with drawing nodes
|
244
|
+
replacement_nodes = pieces.collect do |piece|
|
245
|
+
field_name = piece.strip
|
246
|
+
if field_names.include? field_name
|
247
|
+
image = @images[field_name]
|
248
|
+
puts "... substituting '#{field_name}' with '<#{relation_id_for(field_name)}/>'" if verbose
|
249
|
+
ImageReferenceNodeBuilder.new(field_name: field_name, image: image, node_id: relation_id_for(field_name), image_number: relation_number_for(field_name), document: document).call
|
250
|
+
else
|
251
|
+
Nokogiri::XML::Node.new("w:t", document) { |t| t.content = piece }
|
252
|
+
end
|
253
|
+
end
|
254
|
+
run_nodes = (replacement_nodes.map { |node| Nokogiri::XML::Node.new("w:r", document) { |run_node| run_node.children = node } } + [run_properties]).compact
|
255
|
+
tag_node.children = Nokogiri::XML::NodeSet.new(document, paragraph_properties.to_a + run_nodes)
|
186
256
|
rescue => ex
|
187
257
|
# Have to mangle the exception message otherwise it outputs the entire document
|
188
258
|
puts ex.message.to_s[0..255]
|
@@ -190,6 +260,26 @@ module Consolidate
|
|
190
260
|
end
|
191
261
|
document
|
192
262
|
end
|
263
|
+
|
264
|
+
CONTENT_RELATIONS = {
|
265
|
+
jpeg: "image/jpg",
|
266
|
+
png: "image/png",
|
267
|
+
bmp: "image/bmp",
|
268
|
+
gif: "image/gif",
|
269
|
+
tif: "image/tif",
|
270
|
+
pdf: "application/pdf",
|
271
|
+
mov: "application/movie"
|
272
|
+
}.freeze
|
273
|
+
|
274
|
+
def add_content_relations_to document
|
275
|
+
CONTENT_RELATIONS.each do |file_type, content_type|
|
276
|
+
next unless document.at_xpath("//Default[@Extension=\"#{file_type}\"]").nil?
|
277
|
+
document.root << Nokogiri::XML::Node.new("Default", document).tap do |relation|
|
278
|
+
relation["Extension"] = file_type
|
279
|
+
relation["ContentType"] = content_type
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
193
283
|
end
|
194
284
|
end
|
195
285
|
end
|
data/lib/consolidate/image.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Consolidate
|
4
4
|
class Image
|
5
|
-
attr_reader :name, :width, :height
|
5
|
+
attr_reader :name, :width, :height, :aspect_ratio, :dpi
|
6
6
|
|
7
7
|
def initialize name:, width:, height:, path: nil, url: nil, contents: nil
|
8
8
|
@name = name
|
@@ -11,6 +11,9 @@ module Consolidate
|
|
11
11
|
@path = path
|
12
12
|
@url = url
|
13
13
|
@contents = contents
|
14
|
+
@aspect_ratio = width.to_f / height.to_f
|
15
|
+
# TODO: Read this from the contents
|
16
|
+
@dpi = {x: 72, y: 72}
|
14
17
|
end
|
15
18
|
|
16
19
|
def to_s = name
|
data/lib/consolidate/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: standard-procedure-consolidate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rahoul Baruah
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- checksums/standard-procedure-consolidate-0.3.0.gem.sha512
|
65
65
|
- checksums/standard-procedure-consolidate-0.3.1.gem.sha512
|
66
66
|
- checksums/standard-procedure-consolidate-0.3.9.gem.sha512
|
67
|
+
- checksums/standard-procedure-consolidate-0.4.0.gem.sha512
|
67
68
|
- exe/consolidate
|
68
69
|
- exe/examine
|
69
70
|
- lib/consolidate.rb
|