avv2word 1.1.18 → 1.1.20

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.
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