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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/README.md +83 -2
  4. data/lib/ruby_pptx/action.rb +12 -4
  5. data/lib/ruby_pptx/autoshape_spec.rb +6 -2
  6. data/lib/ruby_pptx/builder.rb +3 -1
  7. data/lib/ruby_pptx/chart/categories.rb +45 -15
  8. data/lib/ruby_pptx/chart/chart.rb +77 -27
  9. data/lib/ruby_pptx/chart/combo.rb +9 -3
  10. data/lib/ruby_pptx/chart/data.rb +45 -15
  11. data/lib/ruby_pptx/chart/format.rb +229 -76
  12. data/lib/ruby_pptx/chart/workbook_writer.rb +9 -3
  13. data/lib/ruby_pptx/chart/xml_writer.rb +54 -18
  14. data/lib/ruby_pptx/chart/xy_data.rb +68 -22
  15. data/lib/ruby_pptx/dml/color.rb +27 -9
  16. data/lib/ruby_pptx/dml/effect.rb +6 -2
  17. data/lib/ruby_pptx/dml/fill.rb +42 -14
  18. data/lib/ruby_pptx/element_proxy.rb +12 -4
  19. data/lib/ruby_pptx/enum/base.rb +30 -10
  20. data/lib/ruby_pptx/enum/prog_id.rb +3 -1
  21. data/lib/ruby_pptx/geometry.rb +32 -10
  22. data/lib/ruby_pptx/image.rb +27 -9
  23. data/lib/ruby_pptx/length.rb +94 -27
  24. data/lib/ruby_pptx/media.rb +12 -4
  25. data/lib/ruby_pptx/numeric_lengths.rb +34 -9
  26. data/lib/ruby_pptx/opc/oxml.rb +7 -5
  27. data/lib/ruby_pptx/opc/pack_uri.rb +15 -5
  28. data/lib/ruby_pptx/opc/package.rb +97 -31
  29. data/lib/ruby_pptx/opc/serialized.rb +15 -5
  30. data/lib/ruby_pptx/oxml/backend.rb +585 -0
  31. data/lib/ruby_pptx/oxml/chart.rb +112 -42
  32. data/lib/ruby_pptx/oxml/content_model.rb +6 -2
  33. data/lib/ruby_pptx/oxml/dml/color.rb +6 -2
  34. data/lib/ruby_pptx/oxml/dml/fill.rb +6 -2
  35. data/lib/ruby_pptx/oxml/element.rb +138 -101
  36. data/lib/ruby_pptx/oxml/ns.rb +7 -7
  37. data/lib/ruby_pptx/oxml/presentation.rb +9 -3
  38. data/lib/ruby_pptx/oxml/section.rb +3 -1
  39. data/lib/ruby_pptx/oxml/shapes/autoshape.rb +39 -13
  40. data/lib/ruby_pptx/oxml/shapes/groupshape.rb +15 -7
  41. data/lib/ruby_pptx/oxml/shapes/other.rb +47 -16
  42. data/lib/ruby_pptx/oxml/shapes/shared.rb +96 -30
  43. data/lib/ruby_pptx/oxml/simple_types.rb +169 -52
  44. data/lib/ruby_pptx/oxml/slide.rb +24 -8
  45. data/lib/ruby_pptx/oxml/table.rb +39 -13
  46. data/lib/ruby_pptx/oxml/text.rb +37 -15
  47. data/lib/ruby_pptx/oxml/theme.rb +13 -4
  48. data/lib/ruby_pptx/package.rb +9 -3
  49. data/lib/ruby_pptx/parts/chart.rb +6 -2
  50. data/lib/ruby_pptx/parts/image.rb +12 -4
  51. data/lib/ruby_pptx/parts/media.rb +3 -1
  52. data/lib/ruby_pptx/parts/presentation.rb +15 -5
  53. data/lib/ruby_pptx/parts/slide.rb +33 -11
  54. data/lib/ruby_pptx/parts/theme.rb +3 -1
  55. data/lib/ruby_pptx/pattern_matching.rb +6 -2
  56. data/lib/ruby_pptx/presentation.rb +24 -8
  57. data/lib/ruby_pptx/section.rb +30 -10
  58. data/lib/ruby_pptx/shapes/adjustments.rb +9 -3
  59. data/lib/ruby_pptx/shapes/authoring.rb +3 -1
  60. data/lib/ruby_pptx/shapes/base.rb +74 -24
  61. data/lib/ruby_pptx/shapes/freeform.rb +36 -12
  62. data/lib/ruby_pptx/shapes/placeholder.rb +44 -15
  63. data/lib/ruby_pptx/shapes/shape.rb +91 -30
  64. data/lib/ruby_pptx/shapes/shape_tree.rb +66 -22
  65. data/lib/ruby_pptx/slide.rb +123 -41
  66. data/lib/ruby_pptx/table.rb +105 -35
  67. data/lib/ruby_pptx/text/font_metrics.rb +30 -9
  68. data/lib/ruby_pptx/text/text.rb +108 -36
  69. data/lib/ruby_pptx/theme.rb +30 -10
  70. data/lib/ruby_pptx/version.rb +1 -1
  71. data/lib/ruby_pptx.rb +8 -1
  72. metadata +22 -1
@@ -12,23 +12,33 @@ module Pptx
12
12
  #
13
13
  # Reached through the `format` of whatever it belongs to.
14
14
  class ChartFormat < ElementProxy
15
- def fill = @fill ||= FillFormat.from_fill_parent(@element.get_or_add_spPr)
15
+ def fill
16
+ @fill ||= FillFormat.from_fill_parent(@element.get_or_add_spPr)
17
+ end
16
18
 
17
- def line = @line ||= LineFormat.new(@element.get_or_add_spPr)
19
+ def line
20
+ @line ||= LineFormat.new(@element.get_or_add_spPr)
21
+ end
18
22
 
19
- def inspect = "#<Pptx::ChartFormat #{fill.type&.name}>"
23
+ def inspect
24
+ "#<Pptx::ChartFormat #{fill.type&.name}>"
25
+ end
20
26
  end
21
27
 
22
28
  # A chart's legend.
23
29
  class ChartLegend < ElementProxy
24
30
  # The legend's font, created on first use.
25
- def font = @font ||= Font.new(@element.defRPr)
31
+ def font
32
+ @font ||= Font.new(@element.defRPr)
33
+ end
26
34
 
27
35
  # Where the legend sits. Absent from the file means PowerPoint's default,
28
36
  # which is the right-hand side.
29
37
  #
30
38
  # @return [Pptx::Enum::Member] a member of XL_LEGEND_POSITION
31
- def position = @element.legendPos&.val || Enum::XL_LEGEND_POSITION::RIGHT
39
+ def position
40
+ @element.legendPos&.val || Enum::XL_LEGEND_POSITION::RIGHT
41
+ end
32
42
 
33
43
  def position=(value)
34
44
  @element.get_or_add_legendPos.val = Enum::XL_LEGEND_POSITION.fetch(value)
@@ -36,7 +46,9 @@ module Pptx
36
46
 
37
47
  # How far the legend is shifted sideways, as a fraction of the chart
38
48
  # width: -1.0 to 1.0, with 0.0 meaning PowerPoint places it.
39
- def horz_offset = @element.horz_offset
49
+ def horz_offset
50
+ @element.horz_offset
51
+ end
40
52
 
41
53
  def horz_offset=(value)
42
54
  @element.horz_offset = value
@@ -44,7 +56,9 @@ module Pptx
44
56
 
45
57
  # True when the legend sits inside the plot area, overlapping it, rather
46
58
  # than having space made for it. An absent `c:overlay` reads as true.
47
- def include_in_layout? = @element.overlay.nil? || @element.overlay.val
59
+ def include_in_layout?
60
+ @element.overlay.nil? || @element.overlay.val
61
+ end
48
62
 
49
63
  # nil removes the setting and returns to the default.
50
64
  def include_in_layout=(value)
@@ -55,7 +69,9 @@ module Pptx
55
69
  end
56
70
  end
57
71
 
58
- def inspect = "#<Pptx::ChartLegend #{position.name}>"
72
+ def inspect
73
+ "#<Pptx::ChartLegend #{position.name}>"
74
+ end
59
75
  end
60
76
 
61
77
  # A chart or axis title.
@@ -64,37 +80,55 @@ module Pptx
64
80
  # same way.
65
81
  class ChartTitle < ElementProxy
66
82
  # The title box's fill and outline.
67
- def format = @format ||= ChartFormat.new(@element)
83
+ def format
84
+ @format ||= ChartFormat.new(@element)
85
+ end
68
86
 
69
87
  # True when the title has text of its own rather than being generated.
70
- def text_frame? = !@element.rich.nil?
88
+ def text_frame?
89
+ !@element.rich.nil?
90
+ end
71
91
 
72
92
  # The title's text, created on first use.
73
- def text_frame = TextFrame.new(@element.get_or_add_rich, self)
93
+ def text_frame
94
+ TextFrame.new(@element.get_or_add_rich, self)
95
+ end
74
96
 
75
97
  # Titles are formatting, not content; there is no part to reach for.
76
- def part = nil
98
+ def part
99
+ nil
100
+ end
77
101
 
78
- def text = text_frame? ? text_frame.text : ""
102
+ def text
103
+ text_frame? ? text_frame.text : ""
104
+ end
79
105
 
80
106
  def text=(value)
81
107
  text_frame.text = value
82
108
  end
83
109
 
84
- def inspect = "#<Pptx::ChartTitle #{text.inspect}>"
110
+ def inspect
111
+ "#<Pptx::ChartTitle #{text.inspect}>"
112
+ end
85
113
  end
86
114
 
87
115
  # The major gridlines of an axis.
88
116
  class Gridlines < ElementProxy
89
- def format = @format ||= ChartFormat.new(@element.get_or_add_majorGridlines)
117
+ def format
118
+ @format ||= ChartFormat.new(@element.get_or_add_majorGridlines)
119
+ end
90
120
  end
91
121
 
92
122
  # The labels along an axis: their font, number format and spacing.
93
123
  class TickLabels < ElementProxy
94
- def font = @font ||= Font.new(@element.defRPr)
124
+ def font
125
+ @font ||= Font.new(@element.defRPr)
126
+ end
95
127
 
96
128
  # The Excel number format, "General" when none is set.
97
- def number_format = @element.numFmt&.formatCode || "General"
129
+ def number_format
130
+ @element.numFmt&.formatCode || "General"
131
+ end
98
132
 
99
133
  # Setting a format stops it following the source data's format.
100
134
  def number_format=(value)
@@ -116,7 +150,9 @@ module Pptx
116
150
 
117
151
  # Distance of the labels from the axis as a percentage of the default;
118
152
  # 100 is the default. Only a category axis has one.
119
- def offset = @element.respond_to?(:lblOffset) ? (@element.lblOffset&.val || 100) : 100
153
+ def offset
154
+ @element.respond_to?(:lblOffset) ? (@element.lblOffset&.val || 100) : 100
155
+ end
120
156
 
121
157
  def offset=(value)
122
158
  raise Error, "only a category axis has a label offset" unless @element.nsptag == "c:catAx"
@@ -132,13 +168,17 @@ module Pptx
132
168
  # only they have.
133
169
  class ChartAxis < ElementProxy
134
170
  # The axis line and its fill.
135
- def format = @format ||= ChartFormat.new(@element)
171
+ def format
172
+ @format ||= ChartFormat.new(@element)
173
+ end
136
174
 
137
175
  # Whether the axis is drawn. A `c:delete` of true hides it.
138
176
  #
139
177
  # An axis with no `c:delete` at all is drawn, which is what the schema and
140
178
  # PowerPoint say. python-pptx reports it as hidden; see PORTING.md.
141
- def visible? = @element.delete.nil? || !@element.delete.val
179
+ def visible?
180
+ @element.delete.nil? || !@element.delete.val
181
+ end
142
182
 
143
183
  def visible=(value)
144
184
  unless [true, false].include?(value)
@@ -148,50 +188,66 @@ module Pptx
148
188
  @element.get_or_add_delete.val = !value
149
189
  end
150
190
 
151
- def major_gridlines? = !@element.majorGridlines.nil?
191
+ def major_gridlines?
192
+ !@element.majorGridlines.nil?
193
+ end
152
194
 
153
195
  def major_gridlines=(value)
154
196
  value ? @element.get_or_add_majorGridlines : @element.remove_majorGridlines
155
197
  end
156
198
 
157
199
  # The major gridlines, for formatting. Asking for them switches them on.
158
- def major_gridlines = @major_gridlines ||= Gridlines.new(@element)
200
+ def major_gridlines
201
+ @major_gridlines ||= Gridlines.new(@element)
202
+ end
159
203
 
160
- def minor_gridlines? = !@element.minorGridlines.nil?
204
+ def minor_gridlines?
205
+ !@element.minorGridlines.nil?
206
+ end
161
207
 
162
208
  def minor_gridlines=(value)
163
209
  value ? @element.get_or_add_minorGridlines : @element.remove_minorGridlines
164
210
  end
165
211
 
166
212
  # @return [Pptx::Enum::Member] a member of XL_TICK_MARK
167
- def major_tick_mark = @element.majorTickMark&.val || Enum::XL_TICK_MARK::CROSS
213
+ def major_tick_mark
214
+ @element.majorTickMark&.val || Enum::XL_TICK_MARK::CROSS
215
+ end
168
216
 
169
217
  # The default, cross, is written by leaving the element out.
170
218
  def major_tick_mark=(value)
171
219
  set_tick_mark(:majorTickMark, value)
172
220
  end
173
221
 
174
- def minor_tick_mark = @element.minorTickMark&.val || Enum::XL_TICK_MARK::CROSS
222
+ def minor_tick_mark
223
+ @element.minorTickMark&.val || Enum::XL_TICK_MARK::CROSS
224
+ end
175
225
 
176
226
  def minor_tick_mark=(value)
177
227
  set_tick_mark(:minorTickMark, value)
178
228
  end
179
229
 
180
230
  # The fixed end of the scale, or nil when PowerPoint scales automatically.
181
- def maximum_scale = @element.scaling.maximum
231
+ def maximum_scale
232
+ @element.scaling.maximum
233
+ end
182
234
 
183
235
  def maximum_scale=(value)
184
236
  @element.scaling.maximum = value
185
237
  end
186
238
 
187
- def minimum_scale = @element.scaling.minimum
239
+ def minimum_scale
240
+ @element.scaling.minimum
241
+ end
188
242
 
189
243
  def minimum_scale=(value)
190
244
  @element.scaling.minimum = value
191
245
  end
192
246
 
193
247
  # True when the axis runs from its maximum to its minimum.
194
- def reverse_order? = @element.orientation == Oxml::SimpleTypes::ST_Orientation::MAX_MIN
248
+ def reverse_order?
249
+ @element.orientation == Oxml::SimpleTypes::ST_Orientation::MAX_MIN
250
+ end
195
251
 
196
252
  def reverse_order=(value)
197
253
  @element.orientation = if value
@@ -211,17 +267,23 @@ module Pptx
211
267
  end
212
268
 
213
269
  # The labels along the axis.
214
- def tick_labels = @tick_labels ||= TickLabels.new(@element)
270
+ def tick_labels
271
+ @tick_labels ||= TickLabels.new(@element)
272
+ end
215
273
 
216
274
  # Shortcuts for the tick-label number format, the setting most often
217
275
  # wanted from an axis.
218
- def number_format = tick_labels.number_format
276
+ def number_format
277
+ tick_labels.number_format
278
+ end
219
279
 
220
280
  def number_format=(value)
221
281
  tick_labels.number_format = value
222
282
  end
223
283
 
224
- def title? = !@element.title.nil?
284
+ def title?
285
+ !@element.title.nil?
286
+ end
225
287
 
226
288
  # @return [ChartTitle, nil] nil when the axis has no title
227
289
  def title
@@ -239,7 +301,9 @@ module Pptx
239
301
  end
240
302
  end
241
303
 
242
- def inspect = "#<#{self.class.name} visible=#{visible?}>"
304
+ def inspect
305
+ "#<#{self.class.name} visible=#{visible?}>"
306
+ end
243
307
 
244
308
  private
245
309
 
@@ -254,12 +318,16 @@ module Pptx
254
318
 
255
319
  # The horizontal axis of most charts: one label per category.
256
320
  class CategoryAxis < ChartAxis
257
- def category_type = Enum::XL_CATEGORY_TYPE::CATEGORY_SCALE
321
+ def category_type
322
+ Enum::XL_CATEGORY_TYPE::CATEGORY_SCALE
323
+ end
258
324
  end
259
325
 
260
326
  # A category axis whose categories are dates.
261
327
  class DateAxis < ChartAxis
262
- def category_type = Enum::XL_CATEGORY_TYPE::TIME_SCALE
328
+ def category_type
329
+ Enum::XL_CATEGORY_TYPE::TIME_SCALE
330
+ end
263
331
  end
264
332
 
265
333
  # An axis measuring values. An XY or bubble chart has two.
@@ -270,7 +338,9 @@ module Pptx
270
338
  #
271
339
  # @return [Pptx::Enum::Member] a member of XL_AXIS_CROSSES; CUSTOM when a
272
340
  # specific value is set through {#crosses_at}
273
- def crosses = cross_axis.crosses&.val || Enum::XL_AXIS_CROSSES::CUSTOM
341
+ def crosses
342
+ cross_axis.crosses&.val || Enum::XL_AXIS_CROSSES::CUSTOM
343
+ end
274
344
 
275
345
  def crosses=(value)
276
346
  member = Enum::XL_AXIS_CROSSES.fetch(value)
@@ -287,7 +357,9 @@ module Pptx
287
357
  end
288
358
 
289
359
  # The value on this axis at which the other crosses, or nil.
290
- def crosses_at = cross_axis.crossesAt&.val
360
+ def crosses_at
361
+ cross_axis.crossesAt&.val
362
+ end
291
363
 
292
364
  def crosses_at=(value)
293
365
  axis = cross_axis
@@ -297,14 +369,18 @@ module Pptx
297
369
  end
298
370
 
299
371
  # The distance between major tick marks, or nil when automatic.
300
- def major_unit = @element.majorUnit&.val
372
+ def major_unit
373
+ @element.majorUnit&.val
374
+ end
301
375
 
302
376
  def major_unit=(value)
303
377
  @element.remove_majorUnit
304
378
  @element.get_or_add_majorUnit.val = value unless value.nil?
305
379
  end
306
380
 
307
- def minor_unit = @element.minorUnit&.val
381
+ def minor_unit
382
+ @element.minorUnit&.val
383
+ end
308
384
 
309
385
  def minor_unit=(value)
310
386
  @element.remove_minorUnit
@@ -316,7 +392,10 @@ module Pptx
316
392
  # The axis whose `c:axId` this one names in its `c:crossAx`.
317
393
  def cross_axis
318
394
  id = @element.crossAx.val
319
- @element.xpath("(../c:catAx | ../c:valAx | ../c:dateAx)/c:axId[@val=\"#{id}\"]").first.parent
395
+ # A union of whole paths rather than `(a | b)/c`: the same query, but
396
+ # REXML's XPath does not accept a union as a path step.
397
+ query = %w[c:catAx c:valAx c:dateAx].map { |axis| "../#{axis}/c:axId[@val=\"#{id}\"]" }.join(" | ")
398
+ @element.xpath(query).first.parent
320
399
  end
321
400
  end
322
401
 
@@ -344,10 +423,14 @@ module Pptx
344
423
  end
345
424
  end
346
425
 
347
- def font = @font ||= Font.new(@element.defRPr)
426
+ def font
427
+ @font ||= Font.new(@element.defRPr)
428
+ end
348
429
 
349
430
  # The Excel number format, "General" when none is set.
350
- def number_format = @element.numFmt&.formatCode || "General"
431
+ def number_format
432
+ @element.numFmt&.formatCode || "General"
433
+ end
351
434
 
352
435
  def number_format=(value)
353
436
  @element.get_or_add_numFmt.formatCode = value
@@ -366,7 +449,9 @@ module Pptx
366
449
  end
367
450
 
368
451
  # @return [Pptx::Enum::Member, nil] a member of XL_DATA_LABEL_POSITION
369
- def position = @element.dLblPos&.val
452
+ def position
453
+ @element.dLblPos&.val
454
+ end
370
455
 
371
456
  def position=(value)
372
457
  if value.nil?
@@ -376,7 +461,9 @@ module Pptx
376
461
  end
377
462
  end
378
463
 
379
- def inspect = "#<Pptx::ChartDataLabels value=#{show_value?}>"
464
+ def inspect
465
+ "#<Pptx::ChartDataLabels value=#{show_value?}>"
466
+ end
380
467
  end
381
468
 
382
469
  # The label of a single data point, overriding the series' labels for it.
@@ -386,19 +473,29 @@ module Pptx
386
473
  @idx = idx
387
474
  end
388
475
 
389
- def font = @font ||= TextFrame.new(label_element.get_or_add_txPr, self).paragraphs[0].font
476
+ def font
477
+ @font ||= TextFrame.new(label_element.get_or_add_txPr, self).paragraphs[0].font
478
+ end
390
479
 
391
480
  # True when the label has text of its own rather than a generated value.
392
- def text_frame? = !@ser.dLbl_for_point(@idx)&.rich.nil?
481
+ def text_frame?
482
+ !@ser.dLbl_for_point(@idx)&.rich.nil?
483
+ end
393
484
 
394
485
  # The label's own text, replacing the generated value. Created on use.
395
- def text_frame = TextFrame.new(label_element.get_or_add_rich, self)
486
+ def text_frame
487
+ TextFrame.new(label_element.get_or_add_rich, self)
488
+ end
396
489
 
397
490
  # Labels are formatting, not content; there is no part to reach for.
398
- def part = nil
491
+ def part
492
+ nil
493
+ end
399
494
 
400
495
  # @return [Pptx::Enum::Member, nil] a member of XL_DATA_LABEL_POSITION
401
- def position = @ser.dLbl_for_point(@idx)&.dLblPos&.val
496
+ def position
497
+ @ser.dLbl_for_point(@idx)&.dLblPos&.val
498
+ end
402
499
 
403
500
  def position=(value)
404
501
  if value.nil?
@@ -408,21 +505,29 @@ module Pptx
408
505
  end
409
506
  end
410
507
 
411
- def inspect = "#<Pptx::DataLabel point=#{@idx}>"
508
+ def inspect
509
+ "#<Pptx::DataLabel point=#{@idx}>"
510
+ end
412
511
 
413
512
  private
414
513
 
415
514
  # This point's `c:dLbl`, created on first use.
416
- def label_element = @ser.get_or_add_dLbl_for_point(@idx)
515
+ def label_element
516
+ @ser.get_or_add_dLbl_for_point(@idx)
517
+ end
417
518
  end
418
519
 
419
520
  # The symbol drawn at each point of a line, radar or XY series, or at one
420
521
  # point.
421
522
  class Marker < ElementProxy
422
- def format = @format ||= ChartFormat.new(@element.get_or_add_marker)
523
+ def format
524
+ @format ||= ChartFormat.new(@element.get_or_add_marker)
525
+ end
423
526
 
424
527
  # Size in points, 2 to 72, or nil when inherited.
425
- def size = @element.marker&.size&.val
528
+ def size
529
+ @element.marker&.size&.val
530
+ end
426
531
 
427
532
  def size=(value)
428
533
  marker = @element.get_or_add_marker
@@ -431,7 +536,9 @@ module Pptx
431
536
  end
432
537
 
433
538
  # @return [Pptx::Enum::Member, nil] a member of XL_MARKER_STYLE
434
- def style = @element.marker&.symbol&.val
539
+ def style
540
+ @element.marker&.symbol&.val
541
+ end
435
542
 
436
543
  def style=(value)
437
544
  marker = @element.get_or_add_marker
@@ -447,13 +554,21 @@ module Pptx
447
554
  @idx = idx
448
555
  end
449
556
 
450
- def data_label = @data_label ||= DataLabel.new(@ser, @idx)
557
+ def data_label
558
+ @data_label ||= DataLabel.new(@ser, @idx)
559
+ end
451
560
 
452
- def format = @format ||= ChartFormat.new(@ser.get_or_add_dPt_for_point(@idx))
561
+ def format
562
+ @format ||= ChartFormat.new(@ser.get_or_add_dPt_for_point(@idx))
563
+ end
453
564
 
454
- def marker = @marker ||= Marker.new(@ser.get_or_add_dPt_for_point(@idx))
565
+ def marker
566
+ @marker ||= Marker.new(@ser.get_or_add_dPt_for_point(@idx))
567
+ end
455
568
 
456
- def inspect = "#<Pptx::ChartPoint #{@idx}>"
569
+ def inspect
570
+ "#<Pptx::ChartPoint #{@idx}>"
571
+ end
457
572
  end
458
573
 
459
574
  # The points of a series, indexed from 0.
@@ -466,7 +581,9 @@ module Pptx
466
581
  @count = count
467
582
  end
468
583
 
469
- def size = @count
584
+ def size
585
+ @count
586
+ end
470
587
  alias length size
471
588
 
472
589
  def [](index, length = nil)
@@ -480,7 +597,9 @@ module Pptx
480
597
  self
481
598
  end
482
599
 
483
- def inspect = "#<Pptx::ChartPoints size=#{size}>"
600
+ def inspect
601
+ "#<Pptx::ChartPoints size=#{size}>"
602
+ end
484
603
  end
485
604
 
486
605
  # One plot -- a "chart group" in the MS API -- within a chart.
@@ -496,13 +615,19 @@ module Pptx
496
615
  end
497
616
 
498
617
  # The categories this plot's series are plotted against.
499
- def categories = ChartCategories.new(@element)
618
+ def categories
619
+ ChartCategories.new(@element)
620
+ end
500
621
 
501
622
  # This plot's series, in the order the chart draws them.
502
- def series = @element.sers.map { |ser| ChartSeriesView.for(ser, @chart) }
623
+ def series
624
+ @element.sers.map { |ser| ChartSeriesView.for(ser, @chart) }
625
+ end
503
626
 
504
627
  # The space between bars, as a percentage of bar width.
505
- def gap_width = @element.gapWidth&.val || 150
628
+ def gap_width
629
+ @element.gapWidth&.val || 150
630
+ end
506
631
 
507
632
  def gap_width=(value)
508
633
  @element.get_or_add_gapWidth.val = value
@@ -510,7 +635,9 @@ module Pptx
510
635
 
511
636
  # How far bars in a group overlap, -100 to 100. Zero is written by
512
637
  # leaving the element out.
513
- def overlap = @element.overlap&.val || 0
638
+ def overlap
639
+ @element.overlap&.val || 0
640
+ end
514
641
 
515
642
  def overlap=(value)
516
643
  if value.zero?
@@ -521,7 +648,9 @@ module Pptx
521
648
  end
522
649
 
523
650
  # The bubble size as a percentage of the default, 0 to 300.
524
- def bubble_scale = @element.bubbleScale&.val || 100
651
+ def bubble_scale
652
+ @element.bubbleScale&.val || 100
653
+ end
525
654
 
526
655
  # nil returns to the default.
527
656
  def bubble_scale=(value)
@@ -531,14 +660,18 @@ module Pptx
531
660
 
532
661
  # Whether each data point gets its own colour, as a pie does. An absent
533
662
  # `c:varyColors` reads as true, the schema default.
534
- def vary_by_categories? = @element.varyColors.nil? || @element.varyColors.val
663
+ def vary_by_categories?
664
+ @element.varyColors.nil? || @element.varyColors.val
665
+ end
535
666
 
536
667
  def vary_by_categories=(value)
537
668
  @element.get_or_add_varyColors.val = value ? true : false
538
669
  end
539
670
 
540
671
  # Whether this plot shows data labels at all.
541
- def data_labels? = !@element.dLbls.nil?
672
+ def data_labels?
673
+ !@element.dLbls.nil?
674
+ end
542
675
 
543
676
  # Switching labels on shows values, as PowerPoint's default does.
544
677
  def data_labels=(value)
@@ -553,9 +686,13 @@ module Pptx
553
686
  # The data-label settings, switched on with PowerPoint's defaults if the
554
687
  # plot has none yet. python-pptx makes you set `has_data_labels` first;
555
688
  # asking for them is enough here.
556
- def data_labels = @data_labels ||= ChartDataLabels.new(@element.get_or_add_default_dLbls)
689
+ def data_labels
690
+ @data_labels ||= ChartDataLabels.new(@element.get_or_add_default_dLbls)
691
+ end
557
692
 
558
- def inspect = "#<Pptx::ChartPlot #{@element.nsptag}>"
693
+ def inspect
694
+ "#<Pptx::ChartPlot #{@element.nsptag}>"
695
+ end
559
696
  end
560
697
 
561
698
  # The categories of a plot, read back from the chart's cached values.
@@ -577,9 +714,13 @@ module Pptx
577
714
  self
578
715
  end
579
716
 
580
- def [](index) = to_a[index]
717
+ def [](index)
718
+ to_a[index]
719
+ end
581
720
 
582
- def size = @plot.cat_pt_count
721
+ def size
722
+ @plot.cat_pt_count
723
+ end
583
724
  alias length size
584
725
 
585
726
  # How many levels of labels there are: 0 with no categories, 1 for a
@@ -610,7 +751,9 @@ module Pptx
610
751
  leaf.map { |category| lineage(category, parents).reverse.map(&:label) }
611
752
  end
612
753
 
613
- def inspect = "#<Pptx::ChartCategories #{map(&:label).inspect}>"
754
+ def inspect
755
+ "#<Pptx::ChartCategories #{map(&:label).inspect}>"
756
+ end
614
757
 
615
758
  private
616
759
 
@@ -633,15 +776,25 @@ module Pptx
633
776
  end
634
777
 
635
778
  # The label, "" for an empty category.
636
- def label = @point.nil? ? "" : @point.v.text
779
+ def label
780
+ @point.nil? ? "" : @point.v.text
781
+ end
637
782
 
638
- def idx = @point.nil? ? @idx : @point.idx
783
+ def idx
784
+ @point.nil? ? @idx : @point.idx
785
+ end
639
786
 
640
- def to_s = label
787
+ def to_s
788
+ label
789
+ end
641
790
  alias to_str to_s
642
791
 
643
- def ==(other) = other.is_a?(ChartCategory) ? label == other.label && idx == other.idx : label == other
792
+ def ==(other)
793
+ other.is_a?(ChartCategory) ? label == other.label && idx == other.idx : label == other
794
+ end
644
795
 
645
- def inspect = "#<Pptx::ChartCategory #{idx}:#{label.inspect}>"
796
+ def inspect
797
+ "#<Pptx::ChartCategory #{idx}:#{label.inspect}>"
798
+ end
646
799
  end
647
800
  end
@@ -64,9 +64,13 @@ module Pptx
64
64
  # Only date categories need a cell style -- a number format that makes
65
65
  # the serial numbers read as dates -- so only they get a styles part.
66
66
  # XY and bubble data have no categories, so never dates.
67
- def dates? = @chart_data.respond_to?(:categories) && @chart_data.categories.dates?
67
+ def dates?
68
+ @chart_data.respond_to?(:categories) && @chart_data.categories.dates?
69
+ end
68
70
 
69
- def declaration = %(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n)
71
+ def declaration
72
+ %(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n)
73
+ end
70
74
 
71
75
  def content_types_xml
72
76
  <<~XML
@@ -132,7 +136,9 @@ module Pptx
132
136
  end.join
133
137
  end
134
138
 
135
- def depth = @chart_data.categories.depth
139
+ def depth
140
+ @chart_data.categories.depth
141
+ end
136
142
 
137
143
  def category_cells(rows)
138
144
  @chart_data.categories.levels.each_with_index do |level, level_index|