rubypoint 0.0.1

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