avv2word 1.1.18 → 1.1.20

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95e387833887863cebe3143db7017ab686644701424caa5b49343c51300ad310
4
- data.tar.gz: 7c24d2050e2a38d43347b520262a4a1c8214a84e6e0e3888f7a24285df44b4cc
3
+ metadata.gz: 8c2007bdd078951c37ebd73c35daf9a6a6022b23b366e28335c1f482a6da18b0
4
+ data.tar.gz: 42af443d0dce033451ebd545115fe2db68438b338287cb8b6713f91a8de87fb2
5
5
  SHA512:
6
- metadata.gz: 5b511db218b1df2be1e85e663c0ddd0479d5bc3b3ad463b096b382adcc285d383688aa37d1ed74388cd7979f8dbba97fe15841caf23bdc6a6c6f4781f265bfb4
7
- data.tar.gz: fd00d1831daca0f1a8b1d7fc882b2af026d5c709122c1e5ef3560eb0822f9c591655f67f91a16f73edc37831b8a208ec17caff08578ad3479b57e262fcdcf106
6
+ metadata.gz: 6bedab9f56d9134974c78f20ab3b500102c281bae9d69c8f0c0c0c56e28be74b650421f7ed3730e13a5c32ed293d99cd415681346964dc0cbe72171a9d37a5f5
7
+ data.tar.gz: ac2849c81b0dfd36a327b6b86673c936aa2d035777477093f9bd178a3a9375fa5a4d977ff3bd14e2d172109925c29b3ee19e6c50da0218ba71207d8ef243ffac
@@ -11,13 +11,15 @@ module Avv2word
11
11
 
12
12
  # create working dir
13
13
  FileUtils.mkdir_p("tmp_imgs")
14
- resize = 1 # for testing purposes; half size: 0.5
14
+ resize = 1 # future feature; half size: 0.5
15
15
 
16
16
  doc = Nokogiri::HTML.fragment(html)
17
17
  doc.css("img").each_with_index do |img_elm,i|
18
18
  mime_type, img_data = img_elm.attributes["src"].value.split(",")
19
19
  # ^--data:image/jpeg;base64
20
- img_path = "tmp_imgs/image_#{i}.jpg"
20
+ ext = mime_type.match(/image\/(\w+?);base64/)[1]
21
+ ext = "jpg" if ext == "jpeg"
22
+ img_path = "tmp_imgs/image#{i+1}.#{ext}"
21
23
  File.open(img_path,"wb"){|f| f.write Base64.decode64(img_data)}
22
24
  img_elm.attributes["src"].value = img_path
23
25
  match_dimensions = %x( file #{img_path} ).match(/, (?<x>\d+) ?x ?(?<y>\d+),/)
@@ -29,8 +31,20 @@ module Avv2word
29
31
  doc.to_html
30
32
  end
31
33
 
34
+ def escape_footnotes(html)
35
+ doc = Nokogiri::HTML.fragment(html)
36
+ nodes_with_footnotes = doc.css("footnote")
37
+ nodes_with_footnotes.each do |node|
38
+ node.name = "footnote"
39
+ node.content = node.attributes["data-value"]
40
+ node.attributes.map{|k,v| node.attributes[k].remove }
41
+ end
42
+ doc.to_html
43
+ end
44
+
32
45
  def create(content, template_name = nil, extras = false)
33
46
  content = extract_images_html(content)
47
+ content = escape_footnotes(content)
34
48
  template_name += extension if template_name && !template_name.end_with?(extension)
35
49
  document = new(template_file(template_name))
36
50
  document.replace_files(content, extras)
@@ -44,6 +58,7 @@ module Avv2word
44
58
  end
45
59
 
46
60
  def create_with_content(template, content, extras = false)
61
+ content = extract_images_html(content)
47
62
  template += extension unless template.end_with?(extension)
48
63
  document = new(template_file(template))
49
64
  document.replace_files(content, extras)
@@ -109,7 +124,6 @@ module Avv2word
109
124
  elsif entry.name == Document.content_types_xml_file
110
125
  raw_file = entry.get_input_stream.read
111
126
  content_types = @image_files.empty? ? raw_file : inject_image_content_types(raw_file)
112
-
113
127
  out.write(content_types)
114
128
  else
115
129
  out.write(template_zip.read(entry.name))
@@ -124,6 +138,18 @@ module Avv2word
124
138
  end
125
139
  end
126
140
  end
141
+
142
+ %w( word/_rels/header.xml.rels
143
+ word/_rels/footer.xml.rels
144
+ word/footnotes.xml
145
+ word/endnotes.xml
146
+ ).each do |f|
147
+ if @replaceable_files[f]
148
+ out.put_next_entry f
149
+ out.write(@replaceable_files[f])
150
+ end
151
+ end
152
+
127
153
  end
128
154
  buffer.string
129
155
  end
@@ -143,9 +169,15 @@ module Avv2word
143
169
  transform_and_replace(footer, xslt_path('footer'), Document.footer_xml_file)
144
170
  transform_and_replace(original_source, xslt_path('relations'), Document.relations_xml_file)
145
171
  source = xslt(stylesheet_name: 'cleanup').transform(original_source)
172
+
173
+ add_footnotes(source.css("footnote").map{ |footnote| footnote.text })
174
+
146
175
  transform_and_replace(source, xslt_path('numbering'), Document.numbering_xml_file)
147
176
  transform_doc_xml(source, extras)
177
+
148
178
  local_images(source)
179
+ local_images(footer, :footer) if @footer
180
+ local_images(header, :header) if @header
149
181
  end
150
182
 
151
183
  def transform_doc_xml(source, extras = false)
@@ -156,13 +188,40 @@ module Avv2word
156
188
 
157
189
  private
158
190
 
191
+ def add_footnotes(footnotes)
192
+ if footnotes.empty?
193
+ @replaceable_files["word/footnotes.xml"] = ""
194
+ return
195
+ end
196
+ doc = Nokogiri::XML.parse(File.read("templates/default/word/footnotes.xml"))
197
+ fn_node = doc.xpath("//w:footnote").last
198
+ footnotes.each_with_index do |footnote,i|
199
+ fn_node2 = fn_node.clone
200
+ fn_node2.parent = fn_node.parent
201
+ fn_node2["w:id"] = (fn_node["w:id"].to_i + i).to_s
202
+ fn_node2.xpath("w:p/w:r/w:t").first.content = " " + footnote
203
+ end
204
+ fn_node.remove
205
+
206
+ @replaceable_files["word/footnotes.xml"] = doc.to_xml
207
+ # add relation
208
+ rels = Nokogiri::XML(@replaceable_files["word/_rels/document.xml.rels"])
209
+ new_rel = '<Relationship Id="rIdXXXXX" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/>'
210
+ new_rel.sub!(/XXXXX/, (rels.xpath("//xmlns:Relationship").size+1).to_s )
211
+ new_rel = Nokogiri::XML.parse(new_rel).child
212
+ rels.children.first << new_rel
213
+ @replaceable_files["word/_rels/document.xml.rels"] = rels.to_xml
214
+ end
215
+
159
216
  def inject_image_relations(relations, noko_html_source)
160
217
  rel_doc = Nokogiri::XML(relations)
161
218
  relations_root = rel_doc.css("Relationships").first
162
219
 
220
+ relations_size = relations_root.css("Relationship").size
221
+
163
222
  noko_html_source.css("img").each_with_index do |img,i|
164
223
  new_relation = relations_root.css("Relationship").last.clone
165
- new_relation["Id"] = "rId#{i+10}"
224
+ new_relation["Id"] = "rId#{i + 10}" # use relations_size for dynamic relations create, todo
166
225
  new_relation["Type"] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
167
226
  new_relation["Target"] = "media/image#{i+1}#{File.extname(img[:src])}"
168
227
  relations_root.add_child new_relation
@@ -176,18 +235,30 @@ module Avv2word
176
235
  content.gsub!(/\s*xmlns:(\w+)="(.*?)\s*"/, '') if remove_ns
177
236
  if ( file =~ /document\.xml\.rels/ ) && ( source.css("img").size > 0 )
178
237
  content = inject_image_relations(content, source)
238
+ elsif file =~ /header/i
239
+ @replaceable_files["word/_rels/header.xml.rels"] = %(<?xml version="1.0" encoding="UTF-8"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\n</Relationships>)
240
+ source.css("img").each_with_index do |noko_img,i|
241
+ # <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image3.png"/>
242
+ new_head_rel = %Q(<Relationship Id="rId#{i+10}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/#{File.basename(noko_img["src"])}"/>)
243
+ @replaceable_files["word/_rels/header.xml.rels"].sub!(/<\/Relationships>/, new_head_rel + "</Relationships>")
244
+ end
245
+ elsif file =~ /footer/i
246
+ @replaceable_files["word/_rels/footer.xml.rels"] = %(<?xml version="1.0" encoding="UTF-8"?>\n<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">\n</Relationships>)
247
+ source.css("img").each_with_index do |noko_img,i|
248
+ new_foot_rel = %Q(<Relationship Id="rId#{i+10}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/#{File.basename(noko_img["src"])}"/>)
249
+ @replaceable_files["word/_rels/footer.xml.rels"].sub!(/<\/Relationships>/, new_foot_rel + "</Relationships>")
250
+ end
179
251
  end
180
252
  @replaceable_files[file] = content
181
253
  end
182
254
 
183
255
  #generates an array of hashes with filename and full url
184
256
  #for all images to be embeded in the word document
185
- def local_images(source)
186
- source.css('img').each_with_index do |image,i|
257
+ def local_images(source, type = nil)
258
+ source.css('img').sort_by{|e| e.attributes['src'].value}.each_with_index do |image,i|
187
259
  filename = image['data-filename'] ? image['data-filename'] : image['src'].split("/").last
188
260
  ext = File.extname(filename).delete(".").downcase
189
-
190
- @image_files << { filename: "image#{i+1}.#{ext}", url: image['src'], ext: ext }
261
+ @image_files << { filename: "image#{@image_files.size+1}.#{ext}", url: image['src'], ext: ext }
191
262
  end
192
263
  end
193
264
 
Binary file
@@ -1,3 +1,3 @@
1
1
  module Avv2word
2
- VERSION = '1.1.18'
2
+ VERSION = '1.1.20'
3
3
  end
@@ -20,6 +20,7 @@
20
20
  <xsl:include href="./tables.xslt"/>
21
21
  <xsl:include href="./links.xslt"/>
22
22
  <xsl:include href="./images.xslt"/>
23
+ <xsl:include href="./footnote.xslt"/>
23
24
  <xsl:template match="/">
24
25
  <xsl:apply-templates />
25
26
  </xsl:template>
@@ -0,0 +1,29 @@
1
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
2
+ xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
3
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
4
+ xmlns:o="urn:schemas-microsoft-com:office:office"
5
+ xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
6
+ xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
7
+ xmlns:v="urn:schemas-microsoft-com:vml"
8
+ xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"
9
+ xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
10
+ xmlns:w10="urn:schemas-microsoft-com:office:word"
11
+ xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
12
+ xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
13
+ xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"
14
+ xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"
15
+ xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
16
+ xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape"
17
+ mc:Ignorable="w14 wp14">
18
+
19
+ <xsl:template match="footnote">
20
+ <xsl:number level="any" count="footnote" format="1"/>
21
+ <w:r>
22
+ <w:rPr>
23
+ <w:rStyle w:val="FootnoteReference"/>
24
+ </w:rPr>
25
+ <w:footnoteReference w:id="{format-number(count(preceding::footnote)+1,'0')}"/>
26
+ <xsl:apply-templates select="@*|node()"/>
27
+ </w:r>
28
+ </xsl:template>
29
+ </xsl:stylesheet>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: avv2word
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.18
4
+ version: 1.1.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marián Bilas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-11 00:00:00.000000000 Z
11
+ date: 2019-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -146,6 +146,7 @@ files:
146
146
  - lib/avv2word/xslt/cleanup.xslt
147
147
  - lib/avv2word/xslt/extras.xslt
148
148
  - lib/avv2word/xslt/footer.xslt
149
+ - lib/avv2word/xslt/footnote.xslt
149
150
  - lib/avv2word/xslt/functions.xslt
150
151
  - lib/avv2word/xslt/header.xslt
151
152
  - lib/avv2word/xslt/htmltoword.xslt