docx_manipulator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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