Class: Ballmer::Presentation::Slides
- Inherits:
-
Object
- Object
- Ballmer::Presentation::Slides
- Includes:
- Enumerable
- Defined in:
- lib/ballmer/presentation/slides.rb
Overview
Manages concerns around keeping slide and notesSlides files in sync with an array of slides. These basically needs to trasnact the slided+ and slideNoted+ numbers to be in sync with an array. Its a big, ugly ass complicated beast. Send your thank you cards to Bill Gates.
Instance Method Summary collapse
-
#delete(slide) ⇒ Object
Removes a slide from the slides collection.
- #each(&block) ⇒ Object
-
#initialize(doc) ⇒ Slides
constructor
A new instance of Slides.
-
#push(slide) ⇒ Object
This method is crazy because it has to manipulate a ton of files within the PPTX.
- #size ⇒ Object (also: #length)
Constructor Details
#initialize(doc) ⇒ Slides
Returns a new instance of Slides.
10 11 12 |
# File 'lib/ballmer/presentation/slides.rb', line 10 def initialize(doc) @doc = doc end |
Instance Method Details
#delete(slide) ⇒ Object
Removes a slide from the slides collection
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/ballmer/presentation/slides.rb', line 111 def delete() # ./_rels/presentation.xml.rels # Update Relationship ids # Insert a new one slideRef @doc.edit_xml @doc.presentation.rels.path do |xml| # Calucate the next id # next_id = xml.xpath('//xmlns:Relationship[@Id]').map{ |n| n['Id'] }.sort.last.succ # TODO - Figure out how to make this more MS idiomatic up 9->10 instead of incrementing # the character.... # Insert that into the slide and crakc open the presentation.xml file target = .path.relative_path_from(@doc.presentation.path.dirname) relationship = xml.at_xpath("/xmlns:Relationships/xmlns:Relationship[@Type='#{Slide::REL_TYPE}' and @Target='#{target}']") # ./presentation.xml # Update attr # p:notesMasterId # Insert attr # p:sldId, increment, etc. @doc.edit_xml '/ppt/presentation.xml' do |xml| xml.at_xpath("/p:presentation/p:sldIdLst/p:sldId[@r:id='#{relationship['Id']}']").remove end relationship.remove end # Delete slide link and slideNotes link from ./[Content-Types].xml @doc.edit_xml @doc.content_types.path do |xml| xml.at_xpath("/xmlns:Types/xmlns:Override[@ContentType='#{Slide::CONTENT_TYPE}' and @PartName='#{.path}']").remove xml.at_xpath("/xmlns:Types/xmlns:Override[@ContentType='#{Notes::CONTENT_TYPE}' and @PartName='#{.notes.path}']").remove end # Update ./ppt # !!! DESTROY !!! # ./slides # Delete files # ./_rels/notesSlide(\d+).xml.rels @doc.delete .notes.rels.path # ./notesSlide(\d+).xml file @doc.delete .notes.path # ./_rels/slide(\d+).xml.rels @doc.delete .rels.path # ./slide(\d+).xml file @doc.delete .path # ./notesSlides # Delete files # Hooray! We're done! Ummm, what should we return though? can't be the slide since # its destroyed and there's no practical way to keep it around in memory. end |
#each(&block) ⇒ Object
14 15 16 17 |
# File 'lib/ballmer/presentation/slides.rb', line 14 def each(&block) # TODO - Do NOT read content-types, but read Rels instead (and move this type casting in there.) .each { |path| block.call path } end |
#push(slide) ⇒ Object
This method is crazy because it has to manipulate a ton of files within the PPTX. Most of what happens in here I figured out by diff-ing PPTX files that had copies of identical slides, but a different number of slides.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/ballmer/presentation/slides.rb', line 27 def push() n = to_a.size + 1 # Paths within the zip file of new files we have to write. = Pathname.new("/ppt/slides/slide#{n}.xml") = Pathname.new("/ppt/slides/_rels/slide#{n}.xml.rels") = Pathname.new("/ppt/notesSlides/notesSlide#{n}.xml") = Pathname.new("/ppt/notesSlides/_rels/notesSlide#{n}.xml.rels") # Update ./ppt # !!! CREATE !!! # ./slides # Create new files # ./slide(\d+).xml file @doc.copy , .path # ./_rels/slide(\d+).xml.rels @doc.copy , .rels.path # ./notesSlides # Create new files # ./notesSlide(\d+).xml file @doc.copy , .notes.path # ./_rels/notesSlide(\d+).xml.rels @doc.copy , .notes.rels.path # !!! UPDATES !!! # Update the notes in the new slide to point at the new notes @doc.edit_xml do |xml| # TODO - Move this rel logic into the parts so that we don't have to repeat ourselves when calculating this stuff out. xml.at_xpath("//xmlns:Relationship[@Type='#{Notes::REL_TYPE}']")['Target'] = .relative_path_from(.dirname) end # Update teh slideNotes reference to point at the new slide @doc.edit_xml do |xml| xml.at_xpath("//xmlns:Relationship[@Type='#{Slide::REL_TYPE}']")['Target'] = .relative_path_from(.dirname) end # ./_rels/presentation.xml.rels # Update Relationship ids # Insert a new one slideRef @doc.edit_xml @doc.presentation.rels.path do |xml| # Calucate the next id next_id = xml.xpath('//xmlns:Relationship[@Id]').map{ |n| n['Id'] }.sort.last.succ # TODO - Figure out how to make this more MS idiomatic up 9->10 instead of incrementing # the character.... # Insert that into the slide and crakc open the presentation.xml file types = xml.at_xpath('/xmlns:Relationships') types << Nokogiri::XML::Node.new("Relationship", xml).tap do |n| n['Id'] = next_id n['Type'] = Slide::REL_TYPE n['Target'] = .relative_path_from(@doc.presentation.path.dirname) end # ./presentation.xml # Update attr # p:notesMasterId # Insert attr # p:sldId, increment, etc. @doc.edit_xml '/ppt/presentation.xml' do |xml| = xml.at_xpath('/p:presentation/p:sldIdLst') = .xpath('//p:sldId[@id]').map{ |n| n['id'] }.sort.last.succ << Nokogiri::XML::Node.new("p:sldId", xml).tap do |n| # TODO - Fix the ID that's jacked up. n['id'] = n['r:id'] = next_id end end end # Update ./[Content-Types].xml with new slide link and slideNotes link @doc.edit_xml @doc.content_types.path do |xml| types = xml.at_xpath('/xmlns:Types') types << Nokogiri::XML::Node.new("Override", xml).tap do |n| n['PartName'] = n['ContentType'] = Slide::CONTENT_TYPE end types << Nokogiri::XML::Node.new("Override", xml).tap do |n| n['PartName'] = n['ContentType'] = Notes::CONTENT_TYPE end end # Great, that's all done, so lets return the slide eh? end |
#size ⇒ Object Also known as: length
19 20 21 |
# File 'lib/ballmer/presentation/slides.rb', line 19 def size .size end |