docx_manipulator 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ bin/
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create ruby-1.9.2-p180@docx_manipulator
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in docx_manipulator.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = Docx Manipulator
2
+
3
+ The purpose of this gem is to make the modification of the content of Microsoft Word documents easier.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # -*- coding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "docx_manipulator/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "docx_manipulator"
7
+ s.version = DocxManipulator::VERSION
8
+ s.authors = ["Michael Stämpfli"]
9
+ s.email = ["michael.staempfli@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Enables the modification of docx files.}
12
+ s.description = %q{This Gem enables you to modify the contents of docx files.}
13
+
14
+ s.rubyforge_project = "docx_manipulator"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- spec/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rspec"
23
+ s.add_runtime_dependency "rubyzip"
24
+ s.add_runtime_dependency "nokogiri"
25
+ end
@@ -0,0 +1,77 @@
1
+ require 'docx_manipulator/version'
2
+ require 'nokogiri'
3
+ require 'zip/zip'
4
+
5
+ class DocxManipulator
6
+
7
+ attr_reader :source, :target, :new_content, :new_relationships
8
+
9
+ def initialize(source, target)
10
+ @source = source
11
+ @target = target
12
+ @new_relationships = source_relationships
13
+ @images = {}
14
+ end
15
+
16
+ def source_content
17
+ content = ''
18
+ Zip::ZipFile.open(source) do |file|
19
+ content = file.read('word/document.xml')
20
+ end
21
+ content
22
+ end
23
+
24
+ def source_relationships
25
+ content = ''
26
+ Zip::ZipFile.open(source) do |file|
27
+ content = file.read('word/_rels/document.xml.rels')
28
+ end
29
+ Nokogiri::XML.parse(content)
30
+ end
31
+
32
+ def content(new_content, options = {})
33
+ new_content_string = case new_content
34
+ when File then new_content.read
35
+ else new_content
36
+ end
37
+ if options.include?(:xslt)
38
+ xslt = Nokogiri::XSLT.parse(options[:xslt])
39
+ data = Nokogiri::XML.parse(new_content_string)
40
+ @new_content = xslt.transform(data).to_s
41
+ else
42
+ @new_content = new_content_string
43
+ end
44
+ end
45
+
46
+ def add_image(id, path)
47
+ @images[id] = path
48
+ image_node = Nokogiri::XML::Node.new('Relationship', new_relationships)
49
+ image_node['Id'] = id
50
+ image_node['Type'] = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'
51
+ image_node['Target'] = "media/#{File.basename(path)}"
52
+ new_relationships.root << image_node
53
+ end
54
+
55
+ def process
56
+ Zip::ZipOutputStream.open(target) do |os|
57
+ Zip::ZipFile.foreach(source) do |entry|
58
+ os.put_next_entry entry.name
59
+ if entry.name == 'word/document.xml'
60
+ os.write @new_content
61
+ elsif entry.name == 'word/_rels/document.xml.rels'
62
+ os.write new_relationships.to_s
63
+ elsif entry.file?
64
+ os.write entry.get_input_stream.read
65
+ end
66
+ end
67
+
68
+ @images.each do |id, path|
69
+ os.put_next_entry "word/media/#{File.basename(path)}"
70
+ File.open(path) do |file|
71
+ IO.copy_stream file, os
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,3 @@
1
+ class DocxManipulator
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,100 @@
1
+ require 'docx_manipulator'
2
+ require 'zip/zip'
3
+
4
+ describe DocxManipulator do
5
+
6
+ subject { DocxManipulator.new('spec/files/movies.docx', 'spec/files/result.docx') }
7
+
8
+ describe "#source_content" do
9
+ it "returns the content of document.xml" do
10
+ subject.source_content.should =~ /w:document/
11
+ end
12
+ end
13
+
14
+ describe "#content" do
15
+ let(:xml_string) { <<-EOF
16
+ <?xml version="1.0" encoding="UTF-8"?>
17
+ <Movies>
18
+ <Genre name="Drama">
19
+ <Movie>
20
+ <Name>The Departed</Name>
21
+ <Released>2006</Released>
22
+ </Movie>
23
+ <Movie>
24
+ <Name>The Pursuit of Happyness</Name>
25
+ <Released>2006</Released>
26
+ </Movie>
27
+ </Genre>
28
+ </Movies>
29
+ EOF
30
+ }
31
+
32
+ it "transforms the data file with an xslt file" do
33
+ subject.content File.new('spec/files/data.xml'), :xslt => File.new('spec/files/document.xslt')
34
+ subject.new_content.should =~ /<w:t>The Departed<\/w:t>/
35
+ subject.new_content.should =~ /<w:t>The Pursuit of Happyness<\/w:t>/
36
+ end
37
+
38
+ it "transforms a string with an xslt file" do
39
+ subject.content xml_string, :xslt => File.new('spec/files/document.xslt')
40
+ subject.new_content.should =~ /<w:t>The Departed<\/w:t>/
41
+ subject.new_content.should =~ /<w:t>The Pursuit of Happyness<\/w:t>/
42
+ end
43
+
44
+ it "accepts a string" do
45
+ subject.content 'the new content'
46
+ subject.new_content.should == 'the new content'
47
+ end
48
+
49
+ it "accepts a file as input" do
50
+ subject.content File.new('spec/files/content.txt')
51
+ subject.new_content.should == 'this is the new content of the document'
52
+ end
53
+ end
54
+
55
+ describe '#add_image' do
56
+ it 'adds an image to the relations file' do
57
+ subject.add_image 'rId9', 'path/to/image.jpg'
58
+ subject.new_relationships.to_s.should =~ /<Relationship Id="rId9" Type="http:\/\/schemas.openxmlformats.org\/officeDocument\/2006\/relationships\/image" Target="media\/image.jpg"\/>/
59
+ end
60
+ end
61
+
62
+ describe "#process" do
63
+ after :each do
64
+ File.delete 'spec/files/result.docx'
65
+ end
66
+
67
+ it "generates the resulting document" do
68
+ subject.process
69
+ File.should exist('spec/files/result.docx')
70
+ end
71
+
72
+ it "replaces the content of the document" do
73
+ subject.content 'bla'
74
+ subject.process
75
+ Zip::ZipFile.open('spec/files/result.docx') do |file|
76
+ file.get_input_stream('word/document.xml').read.should == 'bla'
77
+ end
78
+ end
79
+
80
+ context 'with an image' do
81
+ it 'replaces the relations file' do
82
+ subject.add_image 'rId19', 'spec/files/duck.jpeg'
83
+ subject.process
84
+ Zip::ZipFile.open('spec/files/result.docx') do |file|
85
+ content = Nokogiri::XML.parse(file.get_input_stream('word/_rels/document.xml.rels').read)
86
+ content.xpath('//r:Relationship[@Id="rId19"]', 'r' => 'http://schemas.openxmlformats.org/package/2006/relationships').first['Target'].should == 'media/duck.jpeg'
87
+ end
88
+ end
89
+
90
+ it 'adds the image to the resulting file' do
91
+ subject.add_image 'rId19', 'spec/files/duck.jpeg'
92
+ subject.process
93
+ Zip::ZipFile.open('spec/files/result.docx') do |file|
94
+ file.find_entry('word/media/duck.jpeg').should_not be_nil
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ end
@@ -0,0 +1 @@
1
+ this is the new content of the document
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Movies>
3
+ <Genre name="Action">
4
+ <Movie>
5
+ <Name>Crash</Name>
6
+ <Released>2005</Released>
7
+ </Movie>
8
+ </Genre>
9
+ <Genre name="Drama">
10
+ <Movie>
11
+ <Name>The Departed</Name>
12
+ <Released>2006</Released>
13
+ </Movie>
14
+ <Movie>
15
+ <Name>The Pursuit of Happyness</Name>
16
+ <Released>2006</Released>
17
+ </Movie>
18
+ </Genre>
19
+ <Genre name="Comedy">
20
+ <Movie>
21
+ <Name>The Bucket List</Name>
22
+ <Released>2007</Released>
23
+ </Movie>
24
+ </Genre>
25
+ </Movies>
@@ -0,0 +1,23 @@
1
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
2
+ <xsl:template match="/">
3
+ <w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14">
4
+ <w:body>
5
+ <w:p w:rsidR="008E3083" w:rsidRPr="008E3083" w:rsidRDefault="008E3083"><w:pPr><w:rPr><w:b/><w:u w:val="single"/></w:rPr></w:pPr><w:r w:rsidRPr="008E3083"><w:rPr><w:b/><w:u w:val="single"/></w:rPr><w:t>Movies</w:t></w:r></w:p>
6
+
7
+ <xsl:for-each select="Movies/Genre">
8
+ <w:p w:rsidR="008E3083" w:rsidRDefault="008E3083"><w:r><w:t>
9
+ <xsl:value-of select="@name" />
10
+ </w:t></w:r></w:p>
11
+ <xsl:for-each select="Movie">
12
+ <w:p w:rsidR="008E3083" w:rsidRDefault="008E3083" w:rsidP="008E3083">
13
+ <w:pPr><w:pStyle w:val="ListParagraph"/><w:numPr><w:ilvl w:val="0"/><w:numId w:val="1"/></w:numPr></w:pPr>
14
+ <w:r><w:t><xsl:value-of select="Name" /></w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:t><xsl:value-of select="Released"/></w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:t>)</w:t></w:r>
15
+ <w:bookmarkStart w:id="0" w:name="_GoBack"/><w:bookmarkEnd w:id="0"/>
16
+ </w:p>
17
+ </xsl:for-each>
18
+ </xsl:for-each>
19
+ <w:sectPr w:rsidR="008E3083"><w:pgSz w:w="11906" w:h="16838"/><w:pgMar w:top="1417" w:right="1417" w:bottom="1134" w:left="1417" w:header="708" w:footer="708" w:gutter="0"/><w:cols w:space="708"/><w:docGrid w:linePitch="360"/></w:sectPr>
20
+ </w:body>
21
+ </w:document>
22
+ </xsl:template>
23
+ </xsl:stylesheet>
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: docx_manipulator
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - "Michael St\xC3\xA4mpfli"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-04-02 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rubyzip
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: nokogiri
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ description: This Gem enables you to modify the contents of docx files.
49
+ email:
50
+ - michael.staempfli@gmail.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - .rvmrc
60
+ - Gemfile
61
+ - README.rdoc
62
+ - Rakefile
63
+ - docx_manipulator.gemspec
64
+ - lib/docx_manipulator.rb
65
+ - lib/docx_manipulator/version.rb
66
+ - spec/docx_manipulator_spec.rb
67
+ - spec/files/content.txt
68
+ - spec/files/data.xml
69
+ - spec/files/document.xslt
70
+ - spec/files/duck.jpeg
71
+ - spec/files/movies.docx
72
+ homepage: ""
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project: docx_manipulator
95
+ rubygems_version: 1.8.11
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Enables the modification of docx files.
99
+ test_files:
100
+ - spec/docx_manipulator_spec.rb
101
+ - spec/files/content.txt
102
+ - spec/files/data.xml
103
+ - spec/files/document.xslt
104
+ - spec/files/duck.jpeg
105
+ - spec/files/movies.docx