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
|
@@ -17,7 +17,9 @@ module Pptx
|
|
|
17
17
|
# the Python original exactly.
|
|
18
18
|
class BaseSimpleType
|
|
19
19
|
class << self
|
|
20
|
-
def from_xml(xml_value)
|
|
20
|
+
def from_xml(xml_value)
|
|
21
|
+
convert_from_xml(xml_value)
|
|
22
|
+
end
|
|
21
23
|
|
|
22
24
|
def to_xml(value)
|
|
23
25
|
value = normalize(value)
|
|
@@ -29,12 +31,16 @@ module Pptx
|
|
|
29
31
|
# passed anywhere an integer was expected. Our {Pptx::Length} is a
|
|
30
32
|
# separate class, so unwrap it here and every type gains the same
|
|
31
33
|
# affordance: `shape.width = Pptx.inches(1)` works.
|
|
32
|
-
def normalize(value)
|
|
34
|
+
def normalize(value)
|
|
35
|
+
value.is_a?(Pptx::Length) ? value.emu : value
|
|
36
|
+
end
|
|
33
37
|
|
|
34
38
|
# Python's `round()` is round-half-to-even; Ruby's `Float#round`
|
|
35
39
|
# defaults to half-up. Every rounding conversion here goes through
|
|
36
40
|
# this helper so values landing exactly on .5 match python-pptx.
|
|
37
|
-
def round_half_even(value)
|
|
41
|
+
def round_half_even(value)
|
|
42
|
+
value.round(half: :even)
|
|
43
|
+
end
|
|
38
44
|
|
|
39
45
|
def validate_float(value)
|
|
40
46
|
return if value.is_a?(Numeric) && !value.is_a?(Complex)
|
|
@@ -76,26 +82,53 @@ module Pptx
|
|
|
76
82
|
|
|
77
83
|
class BaseFloatType < BaseSimpleType
|
|
78
84
|
class << self
|
|
79
|
-
def convert_from_xml(str_value)
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
def convert_from_xml(str_value)
|
|
86
|
+
Float(str_value)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def convert_to_xml(value)
|
|
90
|
+
Float(value).to_s
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def validate(value)
|
|
94
|
+
validate_float(value)
|
|
95
|
+
end
|
|
82
96
|
end
|
|
83
97
|
end
|
|
84
98
|
|
|
85
99
|
class BaseIntType < BaseSimpleType
|
|
86
100
|
class << self
|
|
87
|
-
def convert_from_percent_literal(str_value)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
101
|
+
def convert_from_percent_literal(str_value)
|
|
102
|
+
Integer(str_value.delete("%"), 10)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def convert_from_xml(str_value)
|
|
106
|
+
Integer(str_value, 10)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def convert_to_xml(value)
|
|
110
|
+
value.to_i.to_s
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def validate(value)
|
|
114
|
+
validate_int(value)
|
|
115
|
+
end
|
|
91
116
|
end
|
|
92
117
|
end
|
|
93
118
|
|
|
94
119
|
class BaseStringType < BaseSimpleType
|
|
95
120
|
class << self
|
|
96
|
-
def convert_from_xml(str_value)
|
|
97
|
-
|
|
98
|
-
|
|
121
|
+
def convert_from_xml(str_value)
|
|
122
|
+
str_value
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def convert_to_xml(value)
|
|
126
|
+
value
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def validate(value)
|
|
130
|
+
validate_string(value)
|
|
131
|
+
end
|
|
99
132
|
end
|
|
100
133
|
end
|
|
101
134
|
|
|
@@ -110,7 +143,9 @@ module Pptx
|
|
|
110
143
|
@members = mapping.values.freeze
|
|
111
144
|
end
|
|
112
145
|
|
|
113
|
-
def members
|
|
146
|
+
def members
|
|
147
|
+
@members || superclass.members
|
|
148
|
+
end
|
|
114
149
|
|
|
115
150
|
def validate(value)
|
|
116
151
|
validate_string(value)
|
|
@@ -137,7 +172,9 @@ module Pptx
|
|
|
137
172
|
%w[1 true].include?(str_value)
|
|
138
173
|
end
|
|
139
174
|
|
|
140
|
-
def convert_to_xml(value)
|
|
175
|
+
def convert_to_xml(value)
|
|
176
|
+
value ? "1" : "0"
|
|
177
|
+
end
|
|
141
178
|
|
|
142
179
|
def validate(value)
|
|
143
180
|
return if [true, false].include?(value)
|
|
@@ -154,7 +191,9 @@ module Pptx
|
|
|
154
191
|
class XsdId < BaseStringType; end
|
|
155
192
|
|
|
156
193
|
class XsdInt < BaseIntType
|
|
157
|
-
def self.validate(value)
|
|
194
|
+
def self.validate(value)
|
|
195
|
+
validate_int_in_range(value, -2_147_483_648, 2_147_483_647)
|
|
196
|
+
end
|
|
158
197
|
end
|
|
159
198
|
|
|
160
199
|
class XsdLong < BaseIntType
|
|
@@ -171,15 +210,21 @@ module Pptx
|
|
|
171
210
|
class XsdTokenEnumeration < BaseStringEnumerationType; end
|
|
172
211
|
|
|
173
212
|
class XsdUnsignedByte < BaseIntType
|
|
174
|
-
def self.validate(value)
|
|
213
|
+
def self.validate(value)
|
|
214
|
+
validate_int_in_range(value, 0, 255)
|
|
215
|
+
end
|
|
175
216
|
end
|
|
176
217
|
|
|
177
218
|
class XsdUnsignedInt < BaseIntType
|
|
178
|
-
def self.validate(value)
|
|
219
|
+
def self.validate(value)
|
|
220
|
+
validate_int_in_range(value, 0, 4_294_967_295)
|
|
221
|
+
end
|
|
179
222
|
end
|
|
180
223
|
|
|
181
224
|
class XsdUnsignedShort < BaseIntType
|
|
182
|
-
def self.validate(value)
|
|
225
|
+
def self.validate(value)
|
|
226
|
+
validate_int_in_range(value, 0, 65_535)
|
|
227
|
+
end
|
|
183
228
|
end
|
|
184
229
|
|
|
185
230
|
# -- ST_* types from the ECMA-376 schema ------------------------------
|
|
@@ -200,7 +245,9 @@ module Pptx
|
|
|
200
245
|
(round_half_even(value * DEGREE_INCREMENTS) % THREE_SIXTY).to_s
|
|
201
246
|
end
|
|
202
247
|
|
|
203
|
-
def validate(value)
|
|
248
|
+
def validate(value)
|
|
249
|
+
BaseFloatType.validate(value)
|
|
250
|
+
end
|
|
204
251
|
end
|
|
205
252
|
end
|
|
206
253
|
|
|
@@ -223,7 +270,9 @@ module Pptx
|
|
|
223
270
|
str_value.include?("%") ? convert_from_percent_literal(str_value) : super
|
|
224
271
|
end
|
|
225
272
|
|
|
226
|
-
def validate(value)
|
|
273
|
+
def validate(value)
|
|
274
|
+
validate_int_in_range(value, 0, 300)
|
|
275
|
+
end
|
|
227
276
|
end
|
|
228
277
|
end
|
|
229
278
|
|
|
@@ -242,8 +291,13 @@ module Pptx
|
|
|
242
291
|
end
|
|
243
292
|
end
|
|
244
293
|
|
|
245
|
-
def convert_to_xml(value)
|
|
246
|
-
|
|
294
|
+
def convert_to_xml(value)
|
|
295
|
+
value.to_i.to_s
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def validate(value)
|
|
299
|
+
ST_CoordinateUnqualified.validate(value)
|
|
300
|
+
end
|
|
247
301
|
end
|
|
248
302
|
end
|
|
249
303
|
|
|
@@ -258,17 +312,26 @@ module Pptx
|
|
|
258
312
|
end
|
|
259
313
|
end
|
|
260
314
|
|
|
261
|
-
def convert_to_xml(value)
|
|
262
|
-
|
|
315
|
+
def convert_to_xml(value)
|
|
316
|
+
ST_Coordinate32Unqualified.convert_to_xml(value)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def validate(value)
|
|
320
|
+
ST_Coordinate32Unqualified.validate(value)
|
|
321
|
+
end
|
|
263
322
|
end
|
|
264
323
|
end
|
|
265
324
|
|
|
266
325
|
class ST_Coordinate32Unqualified < XsdInt
|
|
267
|
-
def self.convert_from_xml(str_value)
|
|
326
|
+
def self.convert_from_xml(str_value)
|
|
327
|
+
Pptx::Length.emu(Integer(str_value, 10))
|
|
328
|
+
end
|
|
268
329
|
end
|
|
269
330
|
|
|
270
331
|
class ST_CoordinateUnqualified < XsdLong
|
|
271
|
-
def self.validate(value)
|
|
332
|
+
def self.validate(value)
|
|
333
|
+
validate_int_in_range(value, -27_273_042_329_600, 27_273_042_316_900)
|
|
334
|
+
end
|
|
272
335
|
end
|
|
273
336
|
|
|
274
337
|
# `orient` on `<p:ph>`.
|
|
@@ -287,7 +350,9 @@ module Pptx
|
|
|
287
350
|
str_value.include?("%") ? convert_from_percent_literal(str_value) : super
|
|
288
351
|
end
|
|
289
352
|
|
|
290
|
-
def validate(value)
|
|
353
|
+
def validate(value)
|
|
354
|
+
validate_int_in_range(value, 0, 500)
|
|
355
|
+
end
|
|
291
356
|
end
|
|
292
357
|
end
|
|
293
358
|
|
|
@@ -300,7 +365,9 @@ module Pptx
|
|
|
300
365
|
class ST_HexColorRGB < BaseStringType
|
|
301
366
|
class << self
|
|
302
367
|
# Upper-cased purely for consistency of output.
|
|
303
|
-
def convert_to_xml(value)
|
|
368
|
+
def convert_to_xml(value)
|
|
369
|
+
value.upcase
|
|
370
|
+
end
|
|
304
371
|
|
|
305
372
|
def validate(value)
|
|
306
373
|
str_value = validate_string(value)
|
|
@@ -326,13 +393,17 @@ module Pptx
|
|
|
326
393
|
str_value.end_with?("%") ? convert_from_percent_literal(str_value) : Integer(str_value, 10)
|
|
327
394
|
end
|
|
328
395
|
|
|
329
|
-
def validate(value)
|
|
396
|
+
def validate(value)
|
|
397
|
+
validate_int_in_range(value, 0, 1000)
|
|
398
|
+
end
|
|
330
399
|
end
|
|
331
400
|
end
|
|
332
401
|
|
|
333
402
|
class ST_LineWidth < XsdInt
|
|
334
403
|
class << self
|
|
335
|
-
def convert_from_xml(str_value)
|
|
404
|
+
def convert_from_xml(str_value)
|
|
405
|
+
Pptx::Length.emu(Integer(str_value, 10))
|
|
406
|
+
end
|
|
336
407
|
|
|
337
408
|
def validate(value)
|
|
338
409
|
super
|
|
@@ -345,7 +416,9 @@ module Pptx
|
|
|
345
416
|
end
|
|
346
417
|
|
|
347
418
|
class ST_MarkerSize < XsdUnsignedByte
|
|
348
|
-
def self.validate(value)
|
|
419
|
+
def self.validate(value)
|
|
420
|
+
validate_int_in_range(value, 2, 72)
|
|
421
|
+
end
|
|
349
422
|
end
|
|
350
423
|
|
|
351
424
|
# `val` on c:orientation (CT_Orientation).
|
|
@@ -360,7 +433,9 @@ module Pptx
|
|
|
360
433
|
str_value.include?("%") ? convert_from_percent_literal(str_value) : super
|
|
361
434
|
end
|
|
362
435
|
|
|
363
|
-
def validate(value)
|
|
436
|
+
def validate(value)
|
|
437
|
+
validate_int_in_range(value, -100, 100)
|
|
438
|
+
end
|
|
364
439
|
end
|
|
365
440
|
end
|
|
366
441
|
|
|
@@ -374,9 +449,13 @@ module Pptx
|
|
|
374
449
|
Integer(str_value, 10) / 100_000.0
|
|
375
450
|
end
|
|
376
451
|
|
|
377
|
-
def convert_to_xml(value)
|
|
452
|
+
def convert_to_xml(value)
|
|
453
|
+
round_half_even(value * 100_000.0).to_s
|
|
454
|
+
end
|
|
378
455
|
|
|
379
|
-
def validate(value)
|
|
456
|
+
def validate(value)
|
|
457
|
+
validate_float_in_range(value, -21_474.83648, 21_474.83647)
|
|
458
|
+
end
|
|
380
459
|
|
|
381
460
|
def convert_from_percent_literal_float(str_value)
|
|
382
461
|
Float(str_value.delete_suffix("%")) / 100.0
|
|
@@ -391,8 +470,13 @@ module Pptx
|
|
|
391
470
|
|
|
392
471
|
class ST_PositiveCoordinate < XsdLong
|
|
393
472
|
class << self
|
|
394
|
-
def convert_from_xml(str_value)
|
|
395
|
-
|
|
473
|
+
def convert_from_xml(str_value)
|
|
474
|
+
Pptx::Length.emu(super)
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def validate(value)
|
|
478
|
+
validate_int_in_range(value, 0, 27_273_042_316_900)
|
|
479
|
+
end
|
|
396
480
|
end
|
|
397
481
|
end
|
|
398
482
|
|
|
@@ -410,13 +494,17 @@ module Pptx
|
|
|
410
494
|
|
|
411
495
|
# ST_Percentage constrained to 0.0..1.0.
|
|
412
496
|
class ST_PositiveFixedPercentage < ST_Percentage
|
|
413
|
-
def self.validate(value)
|
|
497
|
+
def self.validate(value)
|
|
498
|
+
validate_float_in_range(value, 0.0, 1.0)
|
|
499
|
+
end
|
|
414
500
|
end
|
|
415
501
|
|
|
416
502
|
class ST_RelationshipId < XsdString; end
|
|
417
503
|
|
|
418
504
|
class ST_SlideId < XsdUnsignedInt
|
|
419
|
-
def self.validate(value)
|
|
505
|
+
def self.validate(value)
|
|
506
|
+
validate_int_in_range(value, 256, 2_147_483_647)
|
|
507
|
+
end
|
|
420
508
|
end
|
|
421
509
|
|
|
422
510
|
# The 36 layout kinds ST_SlideLayoutType allows. PowerPoint uses this to
|
|
@@ -443,14 +531,18 @@ module Pptx
|
|
|
443
531
|
# the signed 32-bit maximum -- PowerPoint numbers them from 2147483648
|
|
444
532
|
# upwards precisely so they cannot be confused with slide ids.
|
|
445
533
|
class ST_SlideMasterId < XsdUnsignedInt
|
|
446
|
-
def self.validate(value)
|
|
534
|
+
def self.validate(value)
|
|
535
|
+
validate_int_in_range(value, 2_147_483_648, 4_294_967_295)
|
|
536
|
+
end
|
|
447
537
|
end
|
|
448
538
|
|
|
449
539
|
class ST_SlideLayoutId < ST_SlideMasterId; end
|
|
450
540
|
|
|
451
541
|
class ST_SlideSizeCoordinate < BaseIntType
|
|
452
542
|
class << self
|
|
453
|
-
def convert_from_xml(str_value)
|
|
543
|
+
def convert_from_xml(str_value)
|
|
544
|
+
Pptx::Length.emu(Integer(str_value, 10))
|
|
545
|
+
end
|
|
454
546
|
|
|
455
547
|
def validate(value)
|
|
456
548
|
validate_int(value)
|
|
@@ -463,7 +555,9 @@ module Pptx
|
|
|
463
555
|
end
|
|
464
556
|
|
|
465
557
|
class ST_Style < XsdUnsignedByte
|
|
466
|
-
def self.validate(value)
|
|
558
|
+
def self.validate(value)
|
|
559
|
+
validate_int_in_range(value, 1, 48)
|
|
560
|
+
end
|
|
467
561
|
end
|
|
468
562
|
|
|
469
563
|
# `TargetMode` on a Relationship element.
|
|
@@ -488,7 +582,9 @@ module Pptx
|
|
|
488
582
|
Integer(str_value, 10) / 1000.0
|
|
489
583
|
end
|
|
490
584
|
|
|
491
|
-
def convert_to_xml(value)
|
|
585
|
+
def convert_to_xml(value)
|
|
586
|
+
(value * 1000.0).to_i.to_s
|
|
587
|
+
end
|
|
492
588
|
|
|
493
589
|
def validate(value)
|
|
494
590
|
BaseFloatType.validate(value)
|
|
@@ -500,11 +596,15 @@ module Pptx
|
|
|
500
596
|
end
|
|
501
597
|
|
|
502
598
|
class ST_TextFontSize < BaseIntType
|
|
503
|
-
def self.validate(value)
|
|
599
|
+
def self.validate(value)
|
|
600
|
+
validate_int_in_range(value, 100, 400_000)
|
|
601
|
+
end
|
|
504
602
|
end
|
|
505
603
|
|
|
506
604
|
class ST_TextIndentLevelType < BaseIntType
|
|
507
|
-
def self.validate(value)
|
|
605
|
+
def self.validate(value)
|
|
606
|
+
validate_int_in_range(value, 0, 8)
|
|
607
|
+
end
|
|
508
608
|
end
|
|
509
609
|
|
|
510
610
|
# Line spacing as a multiple of line height, so 1.75 <-> "175000".
|
|
@@ -516,18 +616,30 @@ module Pptx
|
|
|
516
616
|
Integer(str_value, 10) / 100_000.0
|
|
517
617
|
end
|
|
518
618
|
|
|
519
|
-
def convert_to_xml(value)
|
|
619
|
+
def convert_to_xml(value)
|
|
620
|
+
round_half_even(value * 100_000.0).to_s
|
|
621
|
+
end
|
|
520
622
|
|
|
521
|
-
def validate(value)
|
|
623
|
+
def validate(value)
|
|
624
|
+
validate_float_in_range(value, 0.0, 132.0)
|
|
625
|
+
end
|
|
522
626
|
end
|
|
523
627
|
end
|
|
524
628
|
|
|
525
629
|
# Reads centipoints, exposes a {Pptx::Length}.
|
|
526
630
|
class ST_TextSpacingPoint < BaseIntType
|
|
527
631
|
class << self
|
|
528
|
-
def convert_from_xml(str_value)
|
|
529
|
-
|
|
530
|
-
|
|
632
|
+
def convert_from_xml(str_value)
|
|
633
|
+
Pptx::Length.centipoints(Integer(str_value, 10))
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
def convert_to_xml(value)
|
|
637
|
+
Pptx::Length.emu(value).centipoints.to_s
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
def validate(value)
|
|
641
|
+
validate_int_in_range(value, 0, 20_116_800)
|
|
642
|
+
end
|
|
531
643
|
end
|
|
532
644
|
end
|
|
533
645
|
|
|
@@ -554,8 +666,13 @@ module Pptx
|
|
|
554
666
|
Pptx::Length.emu(round_half_even(Float(str_value[0...-2]) * multiplier))
|
|
555
667
|
end
|
|
556
668
|
|
|
557
|
-
def convert_to_xml(value)
|
|
558
|
-
|
|
669
|
+
def convert_to_xml(value)
|
|
670
|
+
value.to_i.to_s
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
def validate(value)
|
|
674
|
+
validate_int(value)
|
|
675
|
+
end
|
|
559
676
|
end
|
|
560
677
|
end
|
|
561
678
|
end
|
data/lib/ruby_pptx/oxml/slide.rb
CHANGED
|
@@ -16,7 +16,9 @@ module Pptx
|
|
|
16
16
|
# Behaviour common to the six slide-like root elements.
|
|
17
17
|
module BaseSlideElement
|
|
18
18
|
# The `p:cSld/p:spTree` grandchild every slide type has.
|
|
19
|
-
def spTree
|
|
19
|
+
def spTree
|
|
20
|
+
cSld.spTree
|
|
21
|
+
end
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
# `p:cSld`, the common slide data holding the shape tree.
|
|
@@ -74,7 +76,9 @@ module Pptx
|
|
|
74
76
|
|
|
75
77
|
# A new gradient starts from PowerPoint's default rather than empty; an
|
|
76
78
|
# `a:gradFill` with no stops draws nothing.
|
|
77
|
-
def new_gradFill
|
|
79
|
+
def new_gradFill
|
|
80
|
+
CT_GradientFillProperties.new_grad_fill(self)
|
|
81
|
+
end
|
|
78
82
|
end
|
|
79
83
|
|
|
80
84
|
# `p:sld`, the root of a slide part.
|
|
@@ -87,9 +91,13 @@ module Pptx
|
|
|
87
91
|
zero_or_one "p:timing", successors: %w[p:extLst]
|
|
88
92
|
|
|
89
93
|
# A new, empty `p:sld` with the minimum structure PowerPoint requires.
|
|
90
|
-
def self.new_element
|
|
94
|
+
def self.new_element
|
|
95
|
+
Element.parse(SLD_XML)
|
|
96
|
+
end
|
|
91
97
|
|
|
92
|
-
def bg
|
|
98
|
+
def bg
|
|
99
|
+
cSld.bg
|
|
100
|
+
end
|
|
93
101
|
|
|
94
102
|
# The node list a `p:video` entry hangs off, which is what makes
|
|
95
103
|
# PowerPoint show play controls under a movie.
|
|
@@ -191,7 +199,9 @@ module Pptx
|
|
|
191
199
|
|
|
192
200
|
# A new `p:sldMaster` carrying the colour map and text styles a master
|
|
193
201
|
# cannot do without, an empty shape tree and no layouts.
|
|
194
|
-
def self.new_element
|
|
202
|
+
def self.new_element
|
|
203
|
+
Oxml.parse_from_template("slideMaster")
|
|
204
|
+
end
|
|
195
205
|
end
|
|
196
206
|
|
|
197
207
|
# `p:clrMap`, which binds each of a slide's colour roles to a theme colour.
|
|
@@ -215,7 +225,9 @@ module Pptx
|
|
|
215
225
|
tag "p:sldLayoutIdLst"
|
|
216
226
|
zero_or_more "p:sldLayoutId", as: :sldLayoutId
|
|
217
227
|
|
|
218
|
-
def size
|
|
228
|
+
def size
|
|
229
|
+
sldLayoutId_list.size
|
|
230
|
+
end
|
|
219
231
|
end
|
|
220
232
|
|
|
221
233
|
# `p:sldLayoutId`, a reference to one slide layout.
|
|
@@ -232,7 +244,9 @@ module Pptx
|
|
|
232
244
|
tag "p:notesMaster"
|
|
233
245
|
one_and_only_one "p:cSld"
|
|
234
246
|
|
|
235
|
-
def self.new_default
|
|
247
|
+
def self.new_default
|
|
248
|
+
Oxml.parse_from_template("notesMaster")
|
|
249
|
+
end
|
|
236
250
|
end
|
|
237
251
|
|
|
238
252
|
# `p:notes`, the root of a notes-slide part.
|
|
@@ -245,7 +259,9 @@ module Pptx
|
|
|
245
259
|
tag "p:notes"
|
|
246
260
|
one_and_only_one "p:cSld"
|
|
247
261
|
|
|
248
|
-
def self.new_element
|
|
262
|
+
def self.new_element
|
|
263
|
+
Oxml.parse_from_template("notes")
|
|
264
|
+
end
|
|
249
265
|
end
|
|
250
266
|
|
|
251
267
|
# `p:timing`, animation and timing information.
|
data/lib/ruby_pptx/oxml/table.rb
CHANGED
|
@@ -19,7 +19,9 @@ module Pptx
|
|
|
19
19
|
tag "a:tblGrid"
|
|
20
20
|
zero_or_more "a:gridCol", as: :gridCol
|
|
21
21
|
|
|
22
|
-
def add_grid_col(width)
|
|
22
|
+
def add_grid_col(width)
|
|
23
|
+
add_gridCol(w: width)
|
|
24
|
+
end
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
# `a:tblPr`, whole-table properties such as banding and header rows.
|
|
@@ -45,7 +47,9 @@ module Pptx
|
|
|
45
47
|
|
|
46
48
|
# A new gradient starts from PowerPoint's default rather than empty; an
|
|
47
49
|
# `a:gradFill` with no stops draws nothing.
|
|
48
|
-
def new_gradFill
|
|
50
|
+
def new_gradFill
|
|
51
|
+
CT_GradientFillProperties.new_grad_fill(self)
|
|
52
|
+
end
|
|
49
53
|
end
|
|
50
54
|
|
|
51
55
|
# `a:tc`, one cell of a table.
|
|
@@ -71,17 +75,27 @@ module Pptx
|
|
|
71
75
|
|
|
72
76
|
# A cell always has a text body, so a new one is created with it rather
|
|
73
77
|
# than empty.
|
|
74
|
-
def self.new_cell(context)
|
|
78
|
+
def self.new_cell(context)
|
|
79
|
+
context.build_from_xml(CELL_XML)
|
|
80
|
+
end
|
|
75
81
|
|
|
76
82
|
# The `a:tr` this cell sits in.
|
|
77
|
-
def tr
|
|
83
|
+
def tr
|
|
84
|
+
parent
|
|
85
|
+
end
|
|
78
86
|
|
|
79
87
|
# The `a:tbl` this cell belongs to.
|
|
80
|
-
def tbl
|
|
88
|
+
def tbl
|
|
89
|
+
tr.parent
|
|
90
|
+
end
|
|
81
91
|
|
|
82
|
-
def col_idx
|
|
92
|
+
def col_idx
|
|
93
|
+
tr.tc_list.index(self)
|
|
94
|
+
end
|
|
83
95
|
|
|
84
|
-
def row_idx
|
|
96
|
+
def row_idx
|
|
97
|
+
tbl.tr_list.index(tr)
|
|
98
|
+
end
|
|
85
99
|
|
|
86
100
|
# True when this is the top-left cell of a merged range.
|
|
87
101
|
#
|
|
@@ -94,7 +108,9 @@ module Pptx
|
|
|
94
108
|
end
|
|
95
109
|
|
|
96
110
|
# True when this cell is covered by a merge rather than being its origin.
|
|
97
|
-
def spanned?
|
|
111
|
+
def spanned?
|
|
112
|
+
hMerge || vMerge
|
|
113
|
+
end
|
|
98
114
|
|
|
99
115
|
# Take the paragraphs from +other+ into this cell's text body.
|
|
100
116
|
#
|
|
@@ -119,9 +135,13 @@ module Pptx
|
|
|
119
135
|
zero_or_more "a:tc", successors: %w[a:extLst], as: :tc
|
|
120
136
|
required_attr "h", type: SimpleTypes::ST_Coordinate
|
|
121
137
|
|
|
122
|
-
def new_tc
|
|
138
|
+
def new_tc
|
|
139
|
+
CT_TableCell.new_cell(self)
|
|
140
|
+
end
|
|
123
141
|
|
|
124
|
-
def add_cell
|
|
142
|
+
def add_cell
|
|
143
|
+
add_tc
|
|
144
|
+
end
|
|
125
145
|
end
|
|
126
146
|
|
|
127
147
|
# `a:tbl`, a table.
|
|
@@ -172,7 +192,9 @@ module Pptx
|
|
|
172
192
|
end
|
|
173
193
|
|
|
174
194
|
# The cell at +row_idx+, +col_idx+.
|
|
175
|
-
def tc(row_idx, col_idx)
|
|
195
|
+
def tc(row_idx, col_idx)
|
|
196
|
+
tr_list[row_idx].tc_list[col_idx]
|
|
197
|
+
end
|
|
176
198
|
|
|
177
199
|
# The rectangle of cells spanned by the two opposite corners +a+ and +b+.
|
|
178
200
|
#
|
|
@@ -222,9 +244,13 @@ module Pptx
|
|
|
222
244
|
(@top..@bottom).flat_map { |row| (@left..@right).map { |col| @tbl.tc(row, col) } }
|
|
223
245
|
end
|
|
224
246
|
|
|
225
|
-
def top_row_cells
|
|
247
|
+
def top_row_cells
|
|
248
|
+
(@left..@right).map { |col| @tbl.tc(@top, col) }
|
|
249
|
+
end
|
|
226
250
|
|
|
227
|
-
def left_column_cells
|
|
251
|
+
def left_column_cells
|
|
252
|
+
(@top..@bottom).map { |row| @tbl.tc(row, @left) }
|
|
253
|
+
end
|
|
228
254
|
|
|
229
255
|
def cells_except_left_column
|
|
230
256
|
(@top..@bottom).flat_map { |row| ((@left + 1)..@right).map { |col| @tbl.tc(row, col) } }
|