rubypoint 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/GPL-LICENSE +674 -0
- data/README.textile +21 -0
- data/Rakefile +96 -0
- data/lib/rubypoint.rb +107 -0
- data/lib/rubypoint/content_types_xml.rb +48 -0
- data/lib/rubypoint/core.rb +13 -0
- data/lib/rubypoint/docProps/app.rb +47 -0
- data/lib/rubypoint/element.rb +33 -0
- data/lib/rubypoint/file.rb +20 -0
- data/lib/rubypoint/ppt/presentation.rb +42 -0
- data/lib/rubypoint/ppt/rels/presentation_rel.rb +73 -0
- data/lib/rubypoint/presentation.rb +89 -0
- data/lib/rubypoint/relationship.rb +25 -0
- data/lib/rubypoint/slide/rel.rb +16 -0
- data/lib/rubypoint/slide/slide.rb +34 -0
- data/lib/rubypoint/textfield.rb +19 -0
- metadata +89 -0
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
|