open_xml_package 0.0.1 → 0.0.2

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