open_xml_package 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: 4810bfc241d1304a49265a41d83d1001dfc82b98
4
- data.tar.gz: f79a5e20f1fff7efde22611227989c10a1c3c172
3
+ metadata.gz: 2b72f5c67d5a18d27b73e969c287d3901d5180ae
4
+ data.tar.gz: 3136fa54c21681c6f1d7025480befbf286313ddf
5
5
  SHA512:
6
- metadata.gz: ad48be06ceb26837ae2666f56ec8b58ba5bd8cdbe9d58ca9708c5f9a24db0ee9ce589edb02746581a66f84d01b5ac56e43ac68a3e40a95a714627b98a0a67d12
7
- data.tar.gz: 965b5eb3ba83acb311bae0589ebd0d56483a17bb379cc7f812a2420a871a239fa1ccad65f82c3bff6ff7e0bc44561620d35d66416f8aaa2a71adbeb582d8e12e
6
+ metadata.gz: 5fe55147d26a022c6be62eae2cfb5b292198999cd4f0cfa8438c8bcb0019d6af798b7889597b544d92149c44081335425a9076a2716d73a0461180b8f4c0ec27
7
+ data.tar.gz: 227b72c1f194c1bdba20b656522b7d6c4c2dd6f742d7b1e2b47e019286f9a5956b3b932b2d80185ba3faff2e39f44ca5ca04d597440cb9bb2e00f52e6974a461
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # OpenXmlPackage
2
2
 
3
- TODO: Write a gem description
3
+ A Ruby implementation of [DocumentFormat.OpenXml.Packaging.OpenXmlPackage](http://msdn.microsoft.com/en-us/library/documentformat.openxml.packaging.openxmlpackage_members(v=office.14).aspx) from Microsoft's Open XML SDK.
4
+
5
+
6
+
4
7
 
5
8
  ## Installation
6
9
 
@@ -16,9 +19,34 @@ Or install it yourself as:
16
19
 
17
20
  $ gem install open_xml_package
18
21
 
22
+
23
+
24
+
19
25
  ## Usage
20
26
 
21
- TODO: Write usage instructions here
27
+ #### Writing
28
+
29
+ You can assemble an Open XML Package in-memory and then write it to disk:
30
+
31
+ ```ruby
32
+ package = OpenXmlPackage.new
33
+ package.add_part "content/document.xml", "<document></document>"
34
+ package.add_part "media/image.png", File.open(image_path, "rb", &:read)
35
+ package.write_to "~/Desktop/output.zip"
36
+ ```
37
+
38
+
39
+ #### Reading
40
+
41
+ You can read the contents of an Open XML Package:
42
+
43
+ ```ruby
44
+ OpenXmlPackage.open("~/Desktop/output.zip") do |package|
45
+ package.parts.map(&:path) # => ["content/document.xml", "media/image.png"]
46
+ end
47
+ ```
48
+
49
+
22
50
 
23
51
  ## Contributing
24
52
 
@@ -27,3 +55,10 @@ TODO: Write usage instructions here
27
55
  3. Commit your changes (`git commit -am 'Add some feature'`)
28
56
  4. Push to the branch (`git push origin my-new-feature`)
29
57
  5. Create a new Pull Request
58
+
59
+ #### Reference
60
+
61
+ - [DocumentFormat.OpenXml.Packaging.OpenXmlPackage](http://msdn.microsoft.com/en-us/library/documentformat.openxml.packaging.openxmlpackage_members(v=office.14).aspx)
62
+ - [DocumentFormat.OpenXml.Packaging.OpenXmlPartContainer](http://msdn.microsoft.com/en-us/library/documentformat.openxml.packaging.openxmlpartcontainer_members(v=office.14).aspx)
63
+ - [DocumentFormat.OpenXml.Packaging.OpenXmlPart](http://msdn.microsoft.com/en-us/library/documentformat.openxml.packaging.openxmlpart_members(v=office.14).aspx)
64
+ - [System.IO.Packaging.Package](http://msdn.microsoft.com/en-us/library/system.io.packaging.package.aspx)
@@ -0,0 +1,14 @@
1
+ class OpenXmlPackage
2
+ class Part < Struct.new(:path, :content)
3
+
4
+ def content
5
+ self[:content] = self[:content].get_input_stream.read if promise?
6
+ super
7
+ end
8
+
9
+ def promise?
10
+ self[:content].respond_to?(:get_input_stream)
11
+ end
12
+
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
1
  class OpenXmlPackage
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,3 +1,4 @@
1
+ require "open_xml_package/part"
1
2
  require "open_xml_package/version"
2
3
  require "zip"
3
4
 
@@ -5,21 +6,65 @@ require "zip"
5
6
  class OpenXmlPackage
6
7
  attr_reader :parts
7
8
 
8
- def initialize
9
- @parts = {}
9
+ def self.open(path)
10
+ if block_given?
11
+ Zip::File.open(path) do |zipfile|
12
+ yield new(zipfile)
13
+ end
14
+ else
15
+ new Zip::File.open(path)
16
+ end
17
+ end
18
+
19
+ def initialize(zipfile=nil)
20
+ @zipfile = zipfile
21
+ @parts = []
22
+ read_zipfile! if zipfile
23
+ end
24
+
25
+
26
+
27
+ def add_part(path_or_part, content=nil)
28
+ path = path_or_part
29
+ path = path_or_part.path if path_or_part.respond_to?(:path)
30
+ content = path_or_part.read if path_or_part.respond_to?(:read)
31
+
32
+ @parts << Part.new(path, content)
10
33
  end
11
34
 
12
- def add_part(path, part)
13
- parts[path] = part
35
+ def get_part(path)
36
+ @parts.detect { |part| part.path == path }
37
+ end
38
+
39
+
40
+
41
+ def close
42
+ zipfile.close if zipfile
14
43
  end
15
44
 
16
45
  def write_to(path)
17
- Zip::OutputStream.open(path) do |io|
18
- parts.each do |path, part|
19
- io.put_next_entry path
20
- io.write part.read
46
+ File.open(path, "w") do |file|
47
+ file.write to_stream.string
48
+ end
49
+ end
50
+
51
+ def to_stream
52
+ Zip::OutputStream.write_buffer do |io|
53
+ parts.each do |part|
54
+ io.put_next_entry part.path
55
+ io.write part.content
21
56
  end
22
57
  end
23
58
  end
24
59
 
60
+ private
61
+
62
+ attr_reader :zipfile
63
+
64
+ def read_zipfile!
65
+ zipfile.entries.each do |entry|
66
+ @parts << Part.new(entry.name, entry)
67
+ end
68
+ end
69
+
25
70
  end
@@ -1,11 +1,29 @@
1
1
  require "test_helper"
2
2
  require "fileutils"
3
- require "digest"
3
+ require "set"
4
4
 
5
5
 
6
6
  class OpenXmlPackageTest < ActiveSupport::TestCase
7
7
  attr_reader :package, :temp_file
8
8
 
9
+
10
+
11
+ context "#add_part" do
12
+ should "accept a path and content" do
13
+ package = OpenXmlPackage.new
14
+ package.add_part "PATH", "CONTENT"
15
+ assert_equal 1, package.parts.count
16
+ end
17
+
18
+ should "accept a part that responds to :path and :read" do
19
+ package = OpenXmlPackage.new
20
+ package.add_part OpenXmlPackage::Part.new("PATH", "CONTENT")
21
+ assert_equal 1, package.parts.count
22
+ end
23
+ end
24
+
25
+
26
+
9
27
  context "Writing" do
10
28
  setup do
11
29
  @temp_file = expand_path "../tmp/test.zip"
@@ -15,10 +33,10 @@ class OpenXmlPackageTest < ActiveSupport::TestCase
15
33
  context "Given a simple part" do
16
34
  setup do
17
35
  @package = OpenXmlPackage.new
18
- package.add_part "content/document.xml", some_content
36
+ package.add_part "content/document.xml", document_content
19
37
  end
20
38
 
21
- should "write the expected file" do
39
+ should "write a valid zip file with the expected parts" do
22
40
  package.write_to temp_file
23
41
  assert File.exists?(temp_file), "Expected the file #{temp_file.inspect} to have been created"
24
42
  assert_equal %w{content/document.xml}, Zip::File.open(temp_file).entries.map(&:name)
@@ -28,16 +46,58 @@ class OpenXmlPackageTest < ActiveSupport::TestCase
28
46
 
29
47
 
30
48
 
49
+ context "Reading" do
50
+ context "Given a sample Word document" do
51
+ setup do
52
+ @temp_file = expand_path "./support/sample.docx"
53
+ @package = OpenXmlPackage.open(temp_file)
54
+ @expected_contents = Set[
55
+ "[Content_Types].xml",
56
+ "_rels/.rels",
57
+ "docProps/app.xml",
58
+ "docProps/core.xml",
59
+ "docProps/thumbnail.jpeg",
60
+ "word/_rels/document.xml.rels",
61
+ "word/document.xml",
62
+ "word/fontTable.xml",
63
+ "word/media/image1.png",
64
+ "word/settings.xml",
65
+ "word/styles.xml",
66
+ "word/stylesWithEffects.xml",
67
+ "word/theme/theme1.xml",
68
+ "word/webSettings.xml" ]
69
+ end
70
+
71
+ teardown do
72
+ package.close
73
+ end
74
+
75
+ should "discover the expected parts" do
76
+ assert_equal @expected_contents, package.parts.map(&:path).to_set
77
+ end
78
+
79
+ should "read their content on-demand" do
80
+ assert_equal web_settings_content, package.get_part("word/webSettings.xml").content
81
+ end
82
+ end
83
+ end
84
+
85
+
86
+
31
87
  private
32
88
 
33
- def some_content
34
- StringIO.new(<<-STR)
89
+ def document_content
90
+ <<-STR
35
91
  <document>
36
92
  <body>Works!</body>
37
93
  </document>
38
94
  STR
39
95
  end
40
96
 
97
+ def web_settings_content
98
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n<w:webSettings xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:w14=\"http://schemas.microsoft.com/office/word/2010/wordml\" mc:Ignorable=\"w14\"><w:allowPNG/><w:doNotSaveAsSingleFile/></w:webSettings>"
99
+ end
100
+
41
101
  def expand_path(path)
42
102
  File.expand_path(File.join(File.dirname(__FILE__), path))
43
103
  end
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: open_xml_package
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Lail
@@ -155,9 +155,11 @@ files:
155
155
  - README.md
156
156
  - Rakefile
157
157
  - lib/open_xml_package.rb
158
+ - lib/open_xml_package/part.rb
158
159
  - lib/open_xml_package/version.rb
159
160
  - open_xml_package.gemspec
160
161
  - test/open_xml_package_test.rb
162
+ - test/support/sample.docx
161
163
  - test/test_helper.rb
162
164
  homepage: ''
163
165
  licenses:
@@ -185,4 +187,5 @@ specification_version: 4
185
187
  summary: A Ruby implementation of OpenXmlPackage
186
188
  test_files:
187
189
  - test/open_xml_package_test.rb
190
+ - test/support/sample.docx
188
191
  - test/test_helper.rb