rubypoint 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/README.textile ADDED
@@ -0,0 +1,21 @@
1
+ h1. RubyPoint
2
+
3
+ This project it still a work in progress, and doesn't do much right now...
4
+
5
+ h2. Licence
6
+
7
+ Copyright (C) 2009 James Pozdena
8
+
9
+ This program is free software: you can redistribute it and/or modify
10
+ it under the terms of the GNU General Public License as published by
11
+ the Free Software Foundation, either version 3 of the License, or
12
+ (at your option) any later version.
13
+
14
+ This program is distributed in the hope that it will be useful,
15
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ GNU General Public License for more details.
18
+
19
+ You should have received a copy of the GNU General Public License
20
+ along with this program. If not, see http://www.gnu.org/licenses/.
21
+
data/Rakefile ADDED
@@ -0,0 +1,96 @@
1
+ gem "rspec", "1.2.9"
2
+ require 'rubygems'
3
+ require 'spec'
4
+ require 'spec/rake/spectask'
5
+ require 'rake/gempackagetask'
6
+ require 'rubygems/specification'
7
+ require 'date'
8
+
9
+ autoload :RubyPoint, 'lib/rubypoint'
10
+
11
+ desc "Run dhem speccczzz"
12
+ Spec::Rake::SpecTask.new do |t|
13
+ t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
14
+ t.spec_files = FileList['spec/**/*_spec.rb']
15
+ end
16
+
17
+ task :default => :spec
18
+
19
+ GEM = 'rubypoint'
20
+ GEM_NAME = 'rubypoint'
21
+ GEM_VERSION = '0.0.1'
22
+ AUTHORS = ['James Pozdena']
23
+ EMAIL = "jpoz@jpoz.net"
24
+ HOMEPAGE = "http://github.com/jpoz/rubypoint"
25
+ SUMMARY = "Make pptx files with Ruby."
26
+
27
+ spec = Gem::Specification.new do |s|
28
+ s.name = GEM
29
+ s.version = GEM_VERSION
30
+ s.platform = Gem::Platform::RUBY
31
+ s.has_rdoc = true
32
+ s.extra_rdoc_files = ["GPL-LICENSE"]
33
+ s.summary = SUMMARY
34
+ s.description = s.summary
35
+ s.authors = AUTHORS
36
+ s.email = EMAIL
37
+ s.homepage = HOMEPAGE
38
+ s.require_path = 'lib'
39
+ s.autorequire = GEM
40
+ s.add_dependency('zipruby', '>= 0.3.2')
41
+ s.add_dependency('hpricot', '>= 0.8.1')
42
+ s.files = %w(GPL-LICENSE README.textile Rakefile) + Dir.glob("{lib}/**/*")
43
+ end
44
+
45
+ Rake::GemPackageTask.new(spec) do |pkg|
46
+ pkg.gem_spec = spec
47
+ end
48
+
49
+ desc "install the gem locally"
50
+ task :install => [:package] do
51
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
52
+ end
53
+
54
+ desc "create a gemspec file"
55
+ task :make_spec do
56
+ File.open("#{GEM}.gemspec", "w") do |file|
57
+ file.puts spec.to_ruby
58
+ end
59
+ end
60
+
61
+
62
+ # RubyPoint specific
63
+
64
+ desc "Decompress a pptx into a folder in tmp/"
65
+ task :decompress, :file_path do |t, args|
66
+ file_name = args.file_path.split('/').last
67
+ puts "Decompressing #{args.file_path} into tmp/#{file_name}/"
68
+ RubyPoint.open_doc(args.file_path, "tmp/#{file_name}")
69
+ end
70
+
71
+ desc "Recompress a folder into a pptx"
72
+ task :recompress, :folder_path, :save_path do |t, args|
73
+ puts "Recompressing #{args.folder_path} into #{args.save_path}"
74
+ RubyPoint.compress_folder(args.folder_path, args.save_path)
75
+ end
76
+
77
+ desc "Diff two pptxs"
78
+ task :diff, :file1, :file2 do |t, args|
79
+ puts "Diff of #{args.file1} and #{args.file2}"
80
+ results = RubyPoint.diff(args.file1, args.file2)
81
+ results.each do |r|
82
+ puts r[:path]
83
+ r[:errors].each do |e|
84
+ puts " #{e}"
85
+ end
86
+ end
87
+ end
88
+
89
+ desc "show two pptxs files"
90
+ task :show, :file1, :file2, :path do |t, args|
91
+ puts "Showing #{args.file1} and #{args.file2}"
92
+ puts RubyPoint.show(args.file1, args.file2, args.path)
93
+ end
94
+
95
+
96
+
data/lib/rubypoint.rb ADDED
@@ -0,0 +1,107 @@
1
+ require "rubygems"
2
+ require 'ftools'
3
+
4
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
5
+
6
+ class RubyPoint
7
+ def self.working_directory
8
+ 'tmp/'
9
+ end
10
+
11
+ def self.open_doc(file_path, save_path)
12
+ file_name = file_path.split('/').last
13
+ save_path = file_name.split('.').first unless save_path
14
+ tmp_file = "#{save_path}/#{file_name}"
15
+ system("mkdir #{save_path}")
16
+ system("cp #{file_path} #{tmp_file}")
17
+ system("unzip -q #{tmp_file} -d #{save_path}/")
18
+ system("rm #{tmp_file}")
19
+ end
20
+
21
+ def self.compress_folder(folder_path, file_path)
22
+ Zip::Archive.open(file_path, Zip::CREATE) do |zip_file|
23
+ Dir.glob("#{folder_path}/**/*", ::File::FNM_DOTMATCH).each do |path|
24
+ zip_path = path.gsub("#{folder_path}/","")
25
+ next if zip_path == "." || zip_path == ".." || zip_path.match(/DS_Store/)
26
+ if ::File.directory?(path)
27
+ zip_file.add_dir(zip_path)
28
+ else
29
+ zip_file.add_file(zip_path, path)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.clear_working_directory
36
+ system("rm -rf #{self.working_directory}*")
37
+ end
38
+
39
+ def self.diff(doc1, doc2)
40
+ doc_id = Time.now.to_i
41
+ open_doc(doc1, "tmp/TEST#{doc_id}_1")
42
+ open_doc(doc2, "tmp/BASE#{doc_id}_2")
43
+ `mate tmp/TEST#{doc_id}_1`
44
+ `mate tmp/BASE#{doc_id}_2`
45
+ end
46
+
47
+ def self.show(doc1, doc2, path)
48
+ require 'xmlsimple'
49
+ doc_id = Time.now.to_i
50
+ open_doc(doc1, "tmp/#{doc_id}_1")
51
+ open_doc(doc2, "tmp/#{doc_id}_2")
52
+ puts "tmp/#{doc_id}_1/#{path}"
53
+ return Dir.glob("tmp/#{doc_id}_1/**/*", ::File::FNM_DOTMATCH).inspect unless ::File.exists?("tmp/#{doc_id}_1/#{path}") && ::File.exists?("tmp/#{doc_id}_2/#{path}")
54
+ file1 = `xmllint --format tmp/#{doc_id}_1/#{path}`
55
+ file2 = `xmllint --format tmp/#{doc_id}_2/#{path}`
56
+ sizes_array = []
57
+ file1_array = []
58
+ file2_array = []
59
+ file1.each_line { |line| file1_array << line }
60
+ file2.each_line { |line| file2_array << line}
61
+ max = 200
62
+ results = ""
63
+ file1_array.each_with_index do |line,i|
64
+ disp = line
65
+ disp += file2_array[i]
66
+ results += disp
67
+ end
68
+ results
69
+ end
70
+
71
+ private
72
+
73
+ def self.diff_unpacked(folder_path1, folder_path2)
74
+ results = []
75
+ Dir.glob("#{folder_path1}/**/*", ::File::FNM_DOTMATCH).each do |path|
76
+ path2 = path.gsub(folder_path1,folder_path2)
77
+ result = {:path => path, :path2 => path2, :errors => []}
78
+ result[:errors] << 'File Does Not exist' unless ::File.exists?(path2)
79
+ next unless ::File.file?(path) && ::File.file?(path2)
80
+ file_diff = diff_files(path, path2)
81
+ result[:errors] << file_diff unless file_diff.nil?
82
+ result[:errors].flatten!
83
+ results << result unless result[:errors].empty?
84
+ end
85
+ results
86
+ end
87
+
88
+ def self.diff_files(path1, path2)
89
+ require 'xmlsimple'
90
+ filename1 = path1.split('/').last
91
+ file_type = path1.split('.').last
92
+ return nil unless %w{xml rels}.include?(file_type)
93
+ file1 = ::File.read(path1)
94
+ file2 = ::File.read(path2)
95
+ return nil if file1 == file2
96
+ begin
97
+ doc1 = y(XmlSimple.xml_in(file1))
98
+ doc2 = y(XmlSimple.xml_in(file2))
99
+ rescue
100
+ return "Error reading doc"
101
+ end
102
+ "#{doc1} \n #{doc2}"
103
+ end
104
+
105
+ end
106
+
107
+ require "rubypoint/core"
@@ -0,0 +1,48 @@
1
+ class RubyPoint::ContentTypes
2
+ class XML < RubyPoint::File
3
+
4
+ def initialize(presentation)
5
+ @presentation = presentation
6
+ @file_path = presentation.file_directory + "/[Content_Types].xml"
7
+ end
8
+
9
+ def before_write
10
+ self.slides.each do |s|
11
+ self << Slide.new(s)
12
+ end
13
+ end
14
+
15
+ def slides
16
+ @presentation.slides
17
+ end
18
+
19
+ def doc
20
+ @doc ||= Hpricot::XML(raw)
21
+ end
22
+
23
+ def raw
24
+ raw = <<EOF
25
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
26
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Override PartName="/ppt/slideLayouts/slideLayout8.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout9.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout11.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout4.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/ppt/slideLayouts/slideLayout2.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/tableStyles.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/ppt/viewProps.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml"/><Override PartName="/ppt/slideLayouts/slideLayout1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/><Override PartName="/ppt/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/ppt/slideLayouts/slideLayout6.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Default Extension="bin" ContentType="application/vnd.openxmlformats-officedocument.presentationml.printerSettings"/><Override PartName="/ppt/presentation.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Override PartName="/ppt/slideLayouts/slideLayout7.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/presProps.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presProps+xml"/><Default Extension="jpeg" ContentType="image/jpeg"/><Override PartName="/ppt/slideLayouts/slideLayout3.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout5.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/><Override PartName="/ppt/slideLayouts/slideLayout10.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/></Types>
27
+ EOF
28
+ end
29
+
30
+ class Slide < RubyPoint::Element
31
+
32
+ attr_accessor :slide
33
+
34
+ def initialize(slide)
35
+ @slide = slide
36
+ end
37
+
38
+ def write
39
+ # TODO need a freaking better search that this!!!
40
+ @parent.doc.search("//Types").html += self.raw
41
+ end
42
+
43
+ def raw
44
+ %Q{<Override PartName="/ppt/slides/slide#{slide.slide_id}.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/>}
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,13 @@
1
+ gem 'hpricot', '>= 0.8.1'
2
+ require 'hpricot'
3
+ require 'rubypoint/presentation'
4
+ require 'rubypoint/element'
5
+ require 'rubypoint/file'
6
+ require 'rubypoint/relationship'
7
+ require 'rubypoint/textfield'
8
+ require 'rubypoint/slide/slide'
9
+ require 'rubypoint/slide/rel'
10
+ require 'rubypoint/docProps/app'
11
+ require 'rubypoint/content_types_xml'
12
+ require 'rubypoint/ppt/presentation'
13
+ require 'rubypoint/ppt/rels/presentation_rel'
@@ -0,0 +1,47 @@
1
+ class RubyPoint::App < RubyPoint::File
2
+
3
+ def initialize(presentation)
4
+ @presentation = presentation
5
+ @file_path = presentation.file_directory + "/docProps/app.xml"
6
+ end
7
+
8
+ def before_write
9
+ self.slides.each do |s|
10
+ self << Slide.new(s)
11
+ end
12
+ end
13
+
14
+ def slides
15
+ @presentation.slides
16
+ end
17
+
18
+ def doc
19
+ @doc ||= Hpricot::XML(raw)
20
+ end
21
+
22
+ def raw
23
+ raw = <<EOF
24
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
25
+ <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><TotalTime>2</TotalTime><Words>8</Words><Application>Microsoft Macintosh PowerPoint</Application><PresentationFormat>On-screen Show (4:3)</PresentationFormat><Paragraphs>2</Paragraphs><Slides>#{self.slides.size}</Slides><Notes>0</Notes><HiddenSlides>0</HiddenSlides><MMClips>0</MMClips><ScaleCrop>false</ScaleCrop><HeadingPairs><vt:vector size="4" baseType="variant"><vt:variant><vt:lpstr>Design Template</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant><vt:variant><vt:lpstr>Slide Titles</vt:lpstr></vt:variant><vt:variant><vt:i4>#{self.slides.size}</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size="#{self.slides.size + 1}" baseType="lpstr"><vt:lpstr>Office Theme</vt:lpstr></vt:vector></TitlesOfParts><Company>Revelation</Company><LinksUpToDate>false</LinksUpToDate><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>12.0000</AppVersion></Properties>
26
+ EOF
27
+ end
28
+
29
+ class Slide < RubyPoint::Element
30
+
31
+ attr_accessor :slide
32
+
33
+ def initialize(slide)
34
+ @slide = slide
35
+ end
36
+
37
+ def write
38
+ # TODO need a freaking better search that this!!!
39
+ @parent.doc.search("//vt:vector[@baseType='lpstr']").html += self.raw
40
+ end
41
+
42
+ def raw
43
+ %Q{<vt:lpstr>Slide #{slide.slide_id}</vt:lpstr>}
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,33 @@
1
+ class RubyPoint
2
+ class Element
3
+
4
+ attr_accessor :parent, :objects, :presentation
5
+
6
+ class << self
7
+ def class_attributes(*args)
8
+ args.each do |attribute|
9
+ script = <<EOF
10
+ attr_accessor :#{attribute}
11
+ def self.#{attribute}(value=false, &action)
12
+ value ? @#{attribute} = value : @#{attribute}_block = action
13
+ end
14
+ def self.#{attribute}_value_for(inst)
15
+ return @#{attribute} if @#{attribute}
16
+ @#{attribute}_block.call(inst)
17
+ end
18
+ def #{attribute}
19
+ return @#{attribute} if @#{attribute}
20
+ @#{attribute} = self.class.#{attribute}_value_for(self)
21
+ end
22
+ EOF
23
+ class_eval(script)
24
+ end
25
+ end
26
+ end
27
+
28
+ def objects
29
+ @objects ||= []
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,20 @@
1
+ class RubyPoint::File < RubyPoint::Element
2
+
3
+ attr_accessor :file_path, :doc
4
+
5
+ def write
6
+ self.before_write if self.respond_to?(:before_write)
7
+ self.objects.each do |o|
8
+ o.write
9
+ end
10
+ File.open(@file_path, "w") do |f|
11
+ f.puts self.doc
12
+ end
13
+ end
14
+
15
+ def <<(object)
16
+ object.parent = self
17
+ self.objects << object
18
+ end
19
+
20
+ end
@@ -0,0 +1,42 @@
1
+ class RubyPoint::Presentation::Presentation < RubyPoint::File
2
+
3
+ def initialize(presentation)
4
+ @presentation = presentation
5
+ @file_path = presentation.file_directory + "/ppt/presentation.xml"
6
+ end
7
+
8
+ def before_write
9
+ @presentation.slides.each do |s|
10
+ self << Slide.new(s)
11
+ end
12
+ end
13
+
14
+ def doc
15
+ @doc ||= Hpricot::XML(raw)
16
+ end
17
+
18
+ def raw
19
+ raw = <<EOF
20
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
21
+ <p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" mc:Ignorable="mv" mc:PreserveAttributes="mv:*" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" saveSubsetFonts="1" autoCompressPictures="0"><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rId1"/></p:sldMasterIdLst><p:sldIdLst></p:sldIdLst><p:sldSz cx="9144000" cy="6858000" type="screen4x3"/><p:notesSz cx="6858000" cy="9144000"/><p:defaultTextStyle><a:defPPr><a:defRPr lang="en-US"/></a:defPPr><a:lvl1pPr marL="0" algn="l" defTabSz="457200" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl1pPr><a:lvl2pPr marL="457200" algn="l" defTabSz="457200" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl2pPr><a:lvl3pPr marL="914400" algn="l" defTabSz="457200" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl3pPr><a:lvl4pPr marL="1371600" algn="l" defTabSz="457200" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl4pPr><a:lvl5pPr marL="1828800" algn="l" defTabSz="457200" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl5pPr><a:lvl6pPr marL="2286000" algn="l" defTabSz="457200" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl6pPr><a:lvl7pPr marL="2743200" algn="l" defTabSz="457200" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl7pPr><a:lvl8pPr marL="3200400" algn="l" defTabSz="457200" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl8pPr><a:lvl9pPr marL="3657600" algn="l" defTabSz="457200" rtl="0" eaLnBrk="1" latinLnBrk="0" hangingPunct="1"><a:defRPr sz="1800" kern="1200"><a:solidFill><a:schemeClr val="tx1"/></a:solidFill><a:latin typeface="+mn-lt"/><a:ea typeface="+mn-ea"/><a:cs typeface="+mn-cs"/></a:defRPr></a:lvl9pPr></p:defaultTextStyle></p:presentation>
22
+ EOF
23
+ end
24
+
25
+ class Slide < RubyPoint::Element
26
+
27
+ attr_accessor :slide
28
+
29
+ def initialize(slide)
30
+ @slide = slide
31
+ end
32
+
33
+ def write
34
+ @parent.doc.search('//p:sldIdLst').html += self.raw
35
+ end
36
+
37
+ def raw
38
+ %Q{<p:sldId id="#{255+slide.slide_id}" r:id="rId#{slide.rel_id.rel_id}"/>}
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,73 @@
1
+ class RubyPoint::PresentationRel < RubyPoint::File
2
+
3
+ def initialize(presentation)
4
+ @presentation = presentation
5
+ @file_path = presentation.file_directory + "/ppt/_rels/presentation.xml.rels"
6
+ @rel_id = 1
7
+ end
8
+
9
+ def before_write
10
+ self.objects << RubyPoint::PresentationRel::PrinterSettings.new(self)
11
+ self.objects << RubyPoint::PresentationRel::PresProps.new(self)
12
+ self.objects << RubyPoint::PresentationRel::ViewProps.new(self)
13
+ self.objects << RubyPoint::PresentationRel::Theme.new(self)
14
+ self.objects << RubyPoint::PresentationRel::TableStyles.new(self)
15
+ end
16
+
17
+ def next_rel_id
18
+ @rel_id += 1
19
+ end
20
+
21
+ def add_relationship_for(object)
22
+ slide_rel = RubyPoint::PresentationRel::Slide.new(self, object)
23
+ self.objects << slide_rel
24
+ slide_rel
25
+ end
26
+
27
+ def doc
28
+ @doc ||= Hpricot::XML(raw)
29
+ end
30
+
31
+ def raw
32
+ raw = <<EOF
33
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
34
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" Target="slideMasters/slideMaster1.xml"/></Relationships>
35
+ EOF
36
+ end
37
+
38
+ end
39
+
40
+ class RubyPoint::PresentationRel::Slide < RubyPoint::Relationship
41
+ target { |s| "slides/slide#{s.object.slide_id}.xml" } # s is the instance of the RubyPoint::PresentationRel::Slide
42
+ type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide"
43
+ end
44
+
45
+ class RubyPoint::PresentationRel::PresProps < RubyPoint::Relationship
46
+ target "presProps.xml"
47
+ type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps"
48
+ end
49
+
50
+ class RubyPoint::PresentationRel::ViewProps < RubyPoint::Relationship
51
+ target "viewProps.xml"
52
+ type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps"
53
+ end
54
+
55
+ class RubyPoint::PresentationRel::SlideMaster < RubyPoint::Relationship
56
+ target "slideMasters/slideMaster1.xml"
57
+ type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"
58
+ end
59
+
60
+ class RubyPoint::PresentationRel::TableStyles < RubyPoint::Relationship
61
+ target "tableStyles.xml"
62
+ type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles"
63
+ end
64
+
65
+ class RubyPoint::PresentationRel::PrinterSettings < RubyPoint::Relationship
66
+ target "printerSettings/printerSettings1.bin"
67
+ type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings"
68
+ end
69
+
70
+ class RubyPoint::PresentationRel::Theme < RubyPoint::Relationship
71
+ target "theme/theme1.xml"
72
+ type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"
73
+ end