ruby_pptx 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/README.md +83 -2
- data/lib/ruby_pptx/action.rb +12 -4
- data/lib/ruby_pptx/autoshape_spec.rb +6 -2
- data/lib/ruby_pptx/builder.rb +3 -1
- data/lib/ruby_pptx/chart/categories.rb +45 -15
- data/lib/ruby_pptx/chart/chart.rb +77 -27
- data/lib/ruby_pptx/chart/combo.rb +9 -3
- data/lib/ruby_pptx/chart/data.rb +45 -15
- data/lib/ruby_pptx/chart/format.rb +229 -76
- data/lib/ruby_pptx/chart/workbook_writer.rb +9 -3
- data/lib/ruby_pptx/chart/xml_writer.rb +54 -18
- data/lib/ruby_pptx/chart/xy_data.rb +68 -22
- data/lib/ruby_pptx/dml/color.rb +27 -9
- data/lib/ruby_pptx/dml/effect.rb +6 -2
- data/lib/ruby_pptx/dml/fill.rb +42 -14
- data/lib/ruby_pptx/element_proxy.rb +12 -4
- data/lib/ruby_pptx/enum/base.rb +30 -10
- data/lib/ruby_pptx/enum/prog_id.rb +3 -1
- data/lib/ruby_pptx/geometry.rb +32 -10
- data/lib/ruby_pptx/image.rb +27 -9
- data/lib/ruby_pptx/length.rb +94 -27
- data/lib/ruby_pptx/media.rb +12 -4
- data/lib/ruby_pptx/numeric_lengths.rb +34 -9
- data/lib/ruby_pptx/opc/oxml.rb +7 -5
- data/lib/ruby_pptx/opc/pack_uri.rb +15 -5
- data/lib/ruby_pptx/opc/package.rb +97 -31
- data/lib/ruby_pptx/opc/serialized.rb +15 -5
- data/lib/ruby_pptx/oxml/backend.rb +585 -0
- data/lib/ruby_pptx/oxml/chart.rb +112 -42
- data/lib/ruby_pptx/oxml/content_model.rb +6 -2
- data/lib/ruby_pptx/oxml/dml/color.rb +6 -2
- data/lib/ruby_pptx/oxml/dml/fill.rb +6 -2
- data/lib/ruby_pptx/oxml/element.rb +138 -101
- data/lib/ruby_pptx/oxml/ns.rb +7 -7
- data/lib/ruby_pptx/oxml/presentation.rb +9 -3
- data/lib/ruby_pptx/oxml/section.rb +3 -1
- data/lib/ruby_pptx/oxml/shapes/autoshape.rb +39 -13
- data/lib/ruby_pptx/oxml/shapes/groupshape.rb +15 -7
- data/lib/ruby_pptx/oxml/shapes/other.rb +47 -16
- data/lib/ruby_pptx/oxml/shapes/shared.rb +96 -30
- data/lib/ruby_pptx/oxml/simple_types.rb +169 -52
- data/lib/ruby_pptx/oxml/slide.rb +24 -8
- data/lib/ruby_pptx/oxml/table.rb +39 -13
- data/lib/ruby_pptx/oxml/text.rb +37 -15
- data/lib/ruby_pptx/oxml/theme.rb +13 -4
- data/lib/ruby_pptx/package.rb +9 -3
- data/lib/ruby_pptx/parts/chart.rb +6 -2
- data/lib/ruby_pptx/parts/image.rb +12 -4
- data/lib/ruby_pptx/parts/media.rb +3 -1
- data/lib/ruby_pptx/parts/presentation.rb +15 -5
- data/lib/ruby_pptx/parts/slide.rb +33 -11
- data/lib/ruby_pptx/parts/theme.rb +3 -1
- data/lib/ruby_pptx/pattern_matching.rb +6 -2
- data/lib/ruby_pptx/presentation.rb +24 -8
- data/lib/ruby_pptx/section.rb +30 -10
- data/lib/ruby_pptx/shapes/adjustments.rb +9 -3
- data/lib/ruby_pptx/shapes/authoring.rb +3 -1
- data/lib/ruby_pptx/shapes/base.rb +74 -24
- data/lib/ruby_pptx/shapes/freeform.rb +36 -12
- data/lib/ruby_pptx/shapes/placeholder.rb +44 -15
- data/lib/ruby_pptx/shapes/shape.rb +91 -30
- data/lib/ruby_pptx/shapes/shape_tree.rb +66 -22
- data/lib/ruby_pptx/slide.rb +123 -41
- data/lib/ruby_pptx/table.rb +105 -35
- data/lib/ruby_pptx/text/font_metrics.rb +30 -9
- data/lib/ruby_pptx/text/text.rb +108 -36
- data/lib/ruby_pptx/theme.rb +30 -10
- data/lib/ruby_pptx/version.rb +1 -1
- data/lib/ruby_pptx.rb +8 -1
- metadata +22 -1
data/lib/ruby_pptx/oxml/text.rb
CHANGED
|
@@ -24,7 +24,9 @@ module Pptx
|
|
|
24
24
|
zero_or_one "a:rPr", successors: %w[a:t]
|
|
25
25
|
one_and_only_one "a:t"
|
|
26
26
|
|
|
27
|
-
def text
|
|
27
|
+
def text
|
|
28
|
+
t.text
|
|
29
|
+
end
|
|
28
30
|
|
|
29
31
|
def text=(value)
|
|
30
32
|
t.text = CT_RegularTextRun.escape_control_chars(value.to_s)
|
|
@@ -46,7 +48,9 @@ module Pptx
|
|
|
46
48
|
# A break carries no text of its own; it *is* the line feed, which we
|
|
47
49
|
# report as a vertical tab to match how PowerPoint puts it on the
|
|
48
50
|
# clipboard.
|
|
49
|
-
def text
|
|
51
|
+
def text
|
|
52
|
+
"\v"
|
|
53
|
+
end
|
|
50
54
|
end
|
|
51
55
|
|
|
52
56
|
# `a:fld`, a slide-number or date field.
|
|
@@ -55,7 +59,9 @@ module Pptx
|
|
|
55
59
|
zero_or_one "a:rPr", successors: %w[a:pPr a:t]
|
|
56
60
|
zero_or_one "a:t", successors: []
|
|
57
61
|
|
|
58
|
-
def text
|
|
62
|
+
def text
|
|
63
|
+
t&.text.to_s
|
|
64
|
+
end
|
|
59
65
|
end
|
|
60
66
|
|
|
61
67
|
# `a:latin`, `a:ea`, `a:cs` and `a:sym`: a typeface reference.
|
|
@@ -84,7 +90,9 @@ module Pptx
|
|
|
84
90
|
optional_attr "i", type: SimpleTypes::XsdBoolean
|
|
85
91
|
optional_attr "u", type: Enum::MSO_TEXT_UNDERLINE_TYPE
|
|
86
92
|
|
|
87
|
-
def new_gradFill
|
|
93
|
+
def new_gradFill
|
|
94
|
+
CT_GradientFillProperties.new_grad_fill(self)
|
|
95
|
+
end
|
|
88
96
|
end
|
|
89
97
|
|
|
90
98
|
# `a:bodyPr`, the properties of a text body: margins, anchoring, autofit.
|
|
@@ -197,14 +205,18 @@ module Pptx
|
|
|
197
205
|
value.is_a?(Pptx::Length) ? spacing.set_spc_pts(value) : spacing.set_spc_pct(value)
|
|
198
206
|
end
|
|
199
207
|
|
|
200
|
-
def space_before
|
|
208
|
+
def space_before
|
|
209
|
+
spcBef&.spcPts&.val
|
|
210
|
+
end
|
|
201
211
|
|
|
202
212
|
def space_before=(value)
|
|
203
213
|
remove_spcBef
|
|
204
214
|
get_or_add_spcBef.set_spc_pts(value) unless value.nil?
|
|
205
215
|
end
|
|
206
216
|
|
|
207
|
-
def space_after
|
|
217
|
+
def space_after
|
|
218
|
+
spcAft&.spcPts&.val
|
|
219
|
+
end
|
|
208
220
|
|
|
209
221
|
def space_after=(value)
|
|
210
222
|
remove_spcAft
|
|
@@ -223,7 +235,9 @@ module Pptx
|
|
|
223
235
|
CONTENT_TAGS = %w[a:r a:br a:fld].freeze
|
|
224
236
|
|
|
225
237
|
# A run is created with its required `a:t` already in place.
|
|
226
|
-
def new_r
|
|
238
|
+
def new_r
|
|
239
|
+
build_from_xml(%(<a:r #{Ns.nsdecls("a")}><a:t/></a:r>))
|
|
240
|
+
end
|
|
227
241
|
|
|
228
242
|
def add_run(text = nil)
|
|
229
243
|
run = add_r
|
|
@@ -231,7 +245,9 @@ module Pptx
|
|
|
231
245
|
run
|
|
232
246
|
end
|
|
233
247
|
|
|
234
|
-
def add_line_break
|
|
248
|
+
def add_line_break
|
|
249
|
+
add_br
|
|
250
|
+
end
|
|
235
251
|
|
|
236
252
|
# Append +text+ as runs, turning each "\n" or "\v" into a line break.
|
|
237
253
|
#
|
|
@@ -248,12 +264,12 @@ module Pptx
|
|
|
248
264
|
# The `a:r`, `a:br` and `a:fld` children, in document order.
|
|
249
265
|
def content_children
|
|
250
266
|
tags = CONTENT_TAGS.map { |t| Ns.qn(t) }
|
|
251
|
-
|
|
252
|
-
.select { |c| tags.include?(Ns.clark_name_of(c)) }
|
|
253
|
-
.map { |c| Element.wrap(c) }
|
|
267
|
+
element_children.select { |c| tags.include?(c.clark_name) }
|
|
254
268
|
end
|
|
255
269
|
|
|
256
|
-
def text
|
|
270
|
+
def text
|
|
271
|
+
content_children.map(&:text).join
|
|
272
|
+
end
|
|
257
273
|
end
|
|
258
274
|
|
|
259
275
|
# `p:txBody`, `a:txBody` and `c:txPr`: a body of text.
|
|
@@ -267,7 +283,9 @@ module Pptx
|
|
|
267
283
|
# A chart's `c:txPr` holds a paragraph for its formatting alone; the
|
|
268
284
|
# default run properties of that first paragraph are where a chart,
|
|
269
285
|
# axis, legend or data-label font lives.
|
|
270
|
-
def defRPr
|
|
286
|
+
def defRPr
|
|
287
|
+
p_list.first.get_or_add_pPr.get_or_add_defRPr
|
|
288
|
+
end
|
|
271
289
|
|
|
272
290
|
# The `c:txPr` a chart element gains when its font is first set.
|
|
273
291
|
TXPR_XML = <<~XML.freeze
|
|
@@ -284,10 +302,14 @@ module Pptx
|
|
|
284
302
|
|
|
285
303
|
class << self
|
|
286
304
|
# A `p:txBody` with one empty paragraph, built in +context+'s document.
|
|
287
|
-
def new_element(context)
|
|
305
|
+
def new_element(context)
|
|
306
|
+
context.build_from_xml(txbody_xml)
|
|
307
|
+
end
|
|
288
308
|
|
|
289
309
|
# A standalone `p:txBody`, for callers with no element to build from.
|
|
290
|
-
def parse_new
|
|
310
|
+
def parse_new
|
|
311
|
+
Element.parse(txbody_xml)
|
|
312
|
+
end
|
|
291
313
|
|
|
292
314
|
def txbody_xml
|
|
293
315
|
<<~XML
|
data/lib/ruby_pptx/oxml/theme.rb
CHANGED
|
@@ -20,10 +20,17 @@ module Pptx
|
|
|
20
20
|
one_and_only_one "a:themeElements"
|
|
21
21
|
required_attr "name", type: SimpleTypes::XsdString
|
|
22
22
|
|
|
23
|
-
def self.new_default
|
|
23
|
+
def self.new_default
|
|
24
|
+
Oxml.parse_from_template("theme")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def clrScheme
|
|
28
|
+
themeElements.clrScheme
|
|
29
|
+
end
|
|
24
30
|
|
|
25
|
-
def
|
|
26
|
-
|
|
31
|
+
def fontScheme
|
|
32
|
+
themeElements.fontScheme
|
|
33
|
+
end
|
|
27
34
|
end
|
|
28
35
|
|
|
29
36
|
# `a:themeElements`, the four schemes that make up a theme.
|
|
@@ -83,7 +90,9 @@ module Pptx
|
|
|
83
90
|
one_and_only_one "a:ea"
|
|
84
91
|
one_and_only_one "a:cs"
|
|
85
92
|
|
|
86
|
-
def typeface
|
|
93
|
+
def typeface
|
|
94
|
+
latin.typeface
|
|
95
|
+
end
|
|
87
96
|
|
|
88
97
|
def typeface=(value)
|
|
89
98
|
latin.typeface = value
|
data/lib/ruby_pptx/package.rb
CHANGED
|
@@ -22,7 +22,9 @@ module Pptx
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def presentation_part
|
|
25
|
+
def presentation_part
|
|
26
|
+
main_document_part
|
|
27
|
+
end
|
|
26
28
|
|
|
27
29
|
# The media part holding +video+, created if the package has no part with
|
|
28
30
|
# the same content. Matched by SHA-1, as images are.
|
|
@@ -41,10 +43,14 @@ module Pptx
|
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
# The next free `/ppt/media/imageN.<ext>` partname, reusing gaps.
|
|
44
|
-
def next_image_partname(ext)
|
|
46
|
+
def next_image_partname(ext)
|
|
47
|
+
next_media_like_partname("image", ext)
|
|
48
|
+
end
|
|
45
49
|
|
|
46
50
|
# The next free `/ppt/media/mediaN.<ext>` partname, reusing gaps.
|
|
47
|
-
def next_media_partname(ext)
|
|
51
|
+
def next_media_partname(ext)
|
|
52
|
+
next_media_like_partname("media", ext)
|
|
53
|
+
end
|
|
48
54
|
|
|
49
55
|
private
|
|
50
56
|
|
|
@@ -39,9 +39,13 @@ module Pptx
|
|
|
39
39
|
part
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def chart
|
|
42
|
+
def chart
|
|
43
|
+
@chart ||= Chart.new(element, self)
|
|
44
|
+
end
|
|
43
45
|
|
|
44
|
-
def workbook
|
|
46
|
+
def workbook
|
|
47
|
+
@workbook ||= ChartWorkbook.new(element, self)
|
|
48
|
+
end
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
# The embedded workbook behind a chart.
|
|
@@ -20,15 +20,23 @@ module Pptx
|
|
|
20
20
|
@source_filename = source_filename
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def image
|
|
23
|
+
def image
|
|
24
|
+
@image ||= Image.from_blob(blob, @source_filename)
|
|
25
|
+
end
|
|
24
26
|
|
|
25
|
-
def ext
|
|
27
|
+
def ext
|
|
28
|
+
partname.ext
|
|
29
|
+
end
|
|
26
30
|
|
|
27
31
|
# The name PowerPoint shows in the alt-text/description field: the file
|
|
28
32
|
# the image came from, or a generic name when it came from a stream.
|
|
29
|
-
def desc
|
|
33
|
+
def desc
|
|
34
|
+
@source_filename || "image.#{ext}"
|
|
35
|
+
end
|
|
30
36
|
|
|
31
|
-
def sha1
|
|
37
|
+
def sha1
|
|
38
|
+
image.sha1
|
|
39
|
+
end
|
|
32
40
|
|
|
33
41
|
# Resolve a requested size against the image's native size.
|
|
34
42
|
#
|
|
@@ -11,7 +11,9 @@ module Pptx
|
|
|
11
11
|
# The presentation part, `/ppt/presentation.xml`; the package's main
|
|
12
12
|
# document part.
|
|
13
13
|
class PresentationPart < Opc::XmlPart
|
|
14
|
-
def presentation
|
|
14
|
+
def presentation
|
|
15
|
+
@presentation ||= Presentation.new(element, self)
|
|
16
|
+
end
|
|
15
17
|
|
|
16
18
|
# Create a blank slide part inheriting from +slide_layout+.
|
|
17
19
|
#
|
|
@@ -22,7 +24,9 @@ module Pptx
|
|
|
22
24
|
[r_id, slide_part.slide]
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
def core_properties
|
|
27
|
+
def core_properties
|
|
28
|
+
package.core_properties
|
|
29
|
+
end
|
|
26
30
|
|
|
27
31
|
# The presentation's notes master, created from the default template on
|
|
28
32
|
# first use.
|
|
@@ -38,9 +42,13 @@ module Pptx
|
|
|
38
42
|
part
|
|
39
43
|
end
|
|
40
44
|
|
|
41
|
-
def related_slide(r_id)
|
|
45
|
+
def related_slide(r_id)
|
|
46
|
+
related_part(r_id).slide
|
|
47
|
+
end
|
|
42
48
|
|
|
43
|
-
def related_slide_master(r_id)
|
|
49
|
+
def related_slide_master(r_id)
|
|
50
|
+
related_part(r_id).slide_master
|
|
51
|
+
end
|
|
44
52
|
|
|
45
53
|
# The slide with presentation-wide id +slide_id+.
|
|
46
54
|
#
|
|
@@ -73,7 +81,9 @@ module Pptx
|
|
|
73
81
|
Opc::PackURI.new("/ppt/slides/slide#{count + 1}.xml")
|
|
74
82
|
end
|
|
75
83
|
|
|
76
|
-
def save(path_or_stream)
|
|
84
|
+
def save(path_or_stream)
|
|
85
|
+
package.save(path_or_stream)
|
|
86
|
+
end
|
|
77
87
|
end
|
|
78
88
|
end
|
|
79
89
|
end
|
|
@@ -12,7 +12,9 @@ module Pptx
|
|
|
12
12
|
# and the notes master.
|
|
13
13
|
class BaseSlidePart < Opc::XmlPart
|
|
14
14
|
# The internal name of this slide.
|
|
15
|
-
def name
|
|
15
|
+
def name
|
|
16
|
+
element.cSld.name
|
|
17
|
+
end
|
|
16
18
|
|
|
17
19
|
# Create a chart part for +chart_data+ and relate this slide to it.
|
|
18
20
|
#
|
|
@@ -81,7 +83,9 @@ module Pptx
|
|
|
81
83
|
part
|
|
82
84
|
end
|
|
83
85
|
|
|
84
|
-
def slide
|
|
86
|
+
def slide
|
|
87
|
+
@slide ||= Slide.new(element, self)
|
|
88
|
+
end
|
|
85
89
|
|
|
86
90
|
# The layout part this slide inherits from.
|
|
87
91
|
def slide_layout
|
|
@@ -89,9 +93,13 @@ module Pptx
|
|
|
89
93
|
end
|
|
90
94
|
|
|
91
95
|
# The presentation-wide id of this slide.
|
|
92
|
-
def slide_id
|
|
96
|
+
def slide_id
|
|
97
|
+
package.presentation_part.slide_id_for(self)
|
|
98
|
+
end
|
|
93
99
|
|
|
94
|
-
def notes_slide?
|
|
100
|
+
def notes_slide?
|
|
101
|
+
rels.any? { |r| r.reltype == Opc::RELATIONSHIP_TYPE::NOTES_SLIDE }
|
|
102
|
+
end
|
|
95
103
|
|
|
96
104
|
# This slide's notes slide, created on first use.
|
|
97
105
|
def notes_slide
|
|
@@ -117,7 +125,9 @@ module Pptx
|
|
|
117
125
|
part
|
|
118
126
|
end
|
|
119
127
|
|
|
120
|
-
def slide_layout
|
|
128
|
+
def slide_layout
|
|
129
|
+
@slide_layout ||= SlideLayout.new(element, self)
|
|
130
|
+
end
|
|
121
131
|
|
|
122
132
|
def slide_master
|
|
123
133
|
part_related_by(Opc::RELATIONSHIP_TYPE::SLIDE_MASTER).slide_master
|
|
@@ -143,10 +153,14 @@ module Pptx
|
|
|
143
153
|
part
|
|
144
154
|
end
|
|
145
155
|
|
|
146
|
-
def slide_master
|
|
156
|
+
def slide_master
|
|
157
|
+
@slide_master ||= SlideMaster.new(element, self)
|
|
158
|
+
end
|
|
147
159
|
|
|
148
160
|
# The theme this master draws its colours and fonts from.
|
|
149
|
-
def theme_part
|
|
161
|
+
def theme_part
|
|
162
|
+
part_related_by(Opc::RELATIONSHIP_TYPE::THEME)
|
|
163
|
+
end
|
|
150
164
|
|
|
151
165
|
# Add +slide_layout_part+ to this master's layout list.
|
|
152
166
|
#
|
|
@@ -159,7 +173,9 @@ module Pptx
|
|
|
159
173
|
r_id
|
|
160
174
|
end
|
|
161
175
|
|
|
162
|
-
def related_slide_layout(r_id)
|
|
176
|
+
def related_slide_layout(r_id)
|
|
177
|
+
related_part(r_id).slide_layout
|
|
178
|
+
end
|
|
163
179
|
|
|
164
180
|
private
|
|
165
181
|
|
|
@@ -192,7 +208,9 @@ module Pptx
|
|
|
192
208
|
part
|
|
193
209
|
end
|
|
194
210
|
|
|
195
|
-
def notes_master
|
|
211
|
+
def notes_master
|
|
212
|
+
@notes_master ||= NotesMaster.new(element, self)
|
|
213
|
+
end
|
|
196
214
|
end
|
|
197
215
|
|
|
198
216
|
# A notes-slide part, `/ppt/notesSlides/notesSlideN.xml`.
|
|
@@ -213,9 +231,13 @@ module Pptx
|
|
|
213
231
|
part
|
|
214
232
|
end
|
|
215
233
|
|
|
216
|
-
def notes_slide
|
|
234
|
+
def notes_slide
|
|
235
|
+
@notes_slide ||= NotesSlide.new(element, self)
|
|
236
|
+
end
|
|
217
237
|
|
|
218
|
-
def notes_master
|
|
238
|
+
def notes_master
|
|
239
|
+
part_related_by(Opc::RELATIONSHIP_TYPE::NOTES_MASTER).notes_master
|
|
240
|
+
end
|
|
219
241
|
end
|
|
220
242
|
end
|
|
221
243
|
end
|
|
@@ -20,7 +20,9 @@ module Pptx
|
|
|
20
20
|
# Only the keys a pattern actually asks for are computed, so matching on a
|
|
21
21
|
# shape's name does not walk its text.
|
|
22
22
|
module PatternMatching
|
|
23
|
-
def self.included(base)
|
|
23
|
+
def self.included(base)
|
|
24
|
+
base.extend(ClassMethods)
|
|
25
|
+
end
|
|
24
26
|
|
|
25
27
|
# A member reads as its name; anything else is passed through.
|
|
26
28
|
def self.for_pattern(value)
|
|
@@ -45,6 +47,8 @@ module Pptx
|
|
|
45
47
|
# means enumerating all of it, which is the opposite of the lazy wrapping
|
|
46
48
|
# everything else here does. Use it where the whole list is wanted anyway.
|
|
47
49
|
module DeconstructToArray
|
|
48
|
-
def deconstruct
|
|
50
|
+
def deconstruct
|
|
51
|
+
to_a
|
|
52
|
+
end
|
|
49
53
|
end
|
|
50
54
|
end
|
|
@@ -42,7 +42,9 @@ module Pptx
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# A new presentation based on the built-in default template.
|
|
45
|
-
def new_default
|
|
45
|
+
def new_default
|
|
46
|
+
Presentation.open(nil)
|
|
47
|
+
end
|
|
46
48
|
|
|
47
49
|
def default_template_path
|
|
48
50
|
File.expand_path("templates/default.pptx", __dir__)
|
|
@@ -55,7 +57,9 @@ module Pptx
|
|
|
55
57
|
].freeze
|
|
56
58
|
|
|
57
59
|
# The Dublin Core metadata for this presentation.
|
|
58
|
-
def core_properties
|
|
60
|
+
def core_properties
|
|
61
|
+
part.core_properties
|
|
62
|
+
end
|
|
59
63
|
|
|
60
64
|
# The slides in this presentation.
|
|
61
65
|
def slides
|
|
@@ -74,32 +78,44 @@ module Pptx
|
|
|
74
78
|
# The notes master, created from the default template on first use.
|
|
75
79
|
#
|
|
76
80
|
# @return [NotesMaster]
|
|
77
|
-
def notes_master
|
|
81
|
+
def notes_master
|
|
82
|
+
part.notes_master_part.notes_master
|
|
83
|
+
end
|
|
78
84
|
|
|
79
85
|
# The first slide master, which is the only one in most presentations.
|
|
80
|
-
def slide_master
|
|
86
|
+
def slide_master
|
|
87
|
+
slide_masters[0]
|
|
88
|
+
end
|
|
81
89
|
|
|
82
90
|
# The layouts of the first slide master.
|
|
83
91
|
#
|
|
84
92
|
# A presentation may have several masters, each with its own layouts; this
|
|
85
93
|
# is a convenience for the common case of one.
|
|
86
|
-
def slide_layouts
|
|
94
|
+
def slide_layouts
|
|
95
|
+
slide_master.slide_layouts
|
|
96
|
+
end
|
|
87
97
|
|
|
88
98
|
# The sections grouping this presentation's slides.
|
|
89
99
|
#
|
|
90
100
|
# Sections are a PowerPoint 2010 extension; a presentation with none has
|
|
91
101
|
# an empty collection and writes no extension element.
|
|
92
|
-
def sections
|
|
102
|
+
def sections
|
|
103
|
+
@sections ||= Sections.new(self)
|
|
104
|
+
end
|
|
93
105
|
|
|
94
106
|
# @return [Length, nil] nil when the presentation defines no slide size
|
|
95
|
-
def slide_width
|
|
107
|
+
def slide_width
|
|
108
|
+
@element.sldSz&.cx
|
|
109
|
+
end
|
|
96
110
|
|
|
97
111
|
def slide_width=(width)
|
|
98
112
|
@element.get_or_add_sldSz.cx = width
|
|
99
113
|
end
|
|
100
114
|
|
|
101
115
|
# @return [Length, nil]
|
|
102
|
-
def slide_height
|
|
116
|
+
def slide_height
|
|
117
|
+
@element.sldSz&.cy
|
|
118
|
+
end
|
|
103
119
|
|
|
104
120
|
def slide_height=(height)
|
|
105
121
|
@element.get_or_add_sldSz.cy = height
|
data/lib/ruby_pptx/section.rb
CHANGED
|
@@ -32,10 +32,14 @@ module Pptx
|
|
|
32
32
|
self
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def size
|
|
35
|
+
def size
|
|
36
|
+
section_elements.size
|
|
37
|
+
end
|
|
36
38
|
alias length size
|
|
37
39
|
|
|
38
|
-
def empty?
|
|
40
|
+
def empty?
|
|
41
|
+
size.zero?
|
|
42
|
+
end
|
|
39
43
|
|
|
40
44
|
# Indexed by position, or looked up by name.
|
|
41
45
|
def [](key, length = nil)
|
|
@@ -45,7 +49,9 @@ module Pptx
|
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
# @return [Section, nil]
|
|
48
|
-
def by_name(name)
|
|
52
|
+
def by_name(name)
|
|
53
|
+
find { |section| section.name == name }
|
|
54
|
+
end
|
|
49
55
|
|
|
50
56
|
# Add a section, optionally containing +slides+.
|
|
51
57
|
#
|
|
@@ -69,11 +75,15 @@ module Pptx
|
|
|
69
75
|
section
|
|
70
76
|
end
|
|
71
77
|
|
|
72
|
-
def inspect
|
|
78
|
+
def inspect
|
|
79
|
+
"#<Pptx::Sections #{map(&:name).inspect}>"
|
|
80
|
+
end
|
|
73
81
|
|
|
74
82
|
private
|
|
75
83
|
|
|
76
|
-
def section_elements
|
|
84
|
+
def section_elements
|
|
85
|
+
@presentation.element.section_list&.section_list || []
|
|
86
|
+
end
|
|
77
87
|
end
|
|
78
88
|
|
|
79
89
|
# One named section of a presentation.
|
|
@@ -87,14 +97,18 @@ module Pptx
|
|
|
87
97
|
@presentation = presentation
|
|
88
98
|
end
|
|
89
99
|
|
|
90
|
-
def name
|
|
100
|
+
def name
|
|
101
|
+
@element.name
|
|
102
|
+
end
|
|
91
103
|
|
|
92
104
|
def name=(value)
|
|
93
105
|
@element.name = value.to_s
|
|
94
106
|
end
|
|
95
107
|
|
|
96
108
|
# The GUID PowerPoint uses to identify this section.
|
|
97
|
-
def id
|
|
109
|
+
def id
|
|
110
|
+
@element.id
|
|
111
|
+
end
|
|
98
112
|
|
|
99
113
|
# The slides in this section, in section order.
|
|
100
114
|
#
|
|
@@ -104,7 +118,9 @@ module Pptx
|
|
|
104
118
|
slide_ids.filter_map { |slide_id| @presentation.slides.by_id(slide_id) }
|
|
105
119
|
end
|
|
106
120
|
|
|
107
|
-
def slide_ids
|
|
121
|
+
def slide_ids
|
|
122
|
+
@element.sldIdLst.sldId_list.map(&:id)
|
|
123
|
+
end
|
|
108
124
|
|
|
109
125
|
# Put +slide+ in this section. A slide belongs to at most one section, so
|
|
110
126
|
# it is removed from any other first.
|
|
@@ -123,8 +139,12 @@ module Pptx
|
|
|
123
139
|
slide
|
|
124
140
|
end
|
|
125
141
|
|
|
126
|
-
def include?(slide)
|
|
142
|
+
def include?(slide)
|
|
143
|
+
slide_ids.include?(slide.slide_id)
|
|
144
|
+
end
|
|
127
145
|
|
|
128
|
-
def inspect
|
|
146
|
+
def inspect
|
|
147
|
+
"#<Pptx::Section #{name.inspect} slides=#{slide_ids.size}>"
|
|
148
|
+
end
|
|
129
149
|
end
|
|
130
150
|
end
|
|
@@ -21,7 +21,9 @@ module Pptx
|
|
|
21
21
|
SCALE = 100_000.0
|
|
22
22
|
|
|
23
23
|
Adjustment = Struct.new(:name, :default, :actual) do
|
|
24
|
-
def raw
|
|
24
|
+
def raw
|
|
25
|
+
actual || default
|
|
26
|
+
end
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
# @param preset_geometry [Pptx::Oxml::Element, nil] the shape's
|
|
@@ -57,10 +59,14 @@ module Pptx
|
|
|
57
59
|
self
|
|
58
60
|
end
|
|
59
61
|
|
|
60
|
-
def size
|
|
62
|
+
def size
|
|
63
|
+
@adjustments.size
|
|
64
|
+
end
|
|
61
65
|
alias length size
|
|
62
66
|
|
|
63
|
-
def inspect
|
|
67
|
+
def inspect
|
|
68
|
+
"#<Pptx::Adjustments #{to_a.inspect}>"
|
|
69
|
+
end
|
|
64
70
|
|
|
65
71
|
private
|
|
66
72
|
|