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
|
@@ -267,11 +267,15 @@ module Pptx
|
|
|
267
267
|
XML
|
|
268
268
|
end
|
|
269
269
|
|
|
270
|
-
def dates?
|
|
270
|
+
def dates?
|
|
271
|
+
chart_data.categories.dates?
|
|
272
|
+
end
|
|
271
273
|
|
|
272
274
|
# A chart being written from scratch uses the 1900 date system;
|
|
273
275
|
# rewriting an existing chart's data honours the chart's own setting.
|
|
274
|
-
def date_1904?
|
|
276
|
+
def date_1904?
|
|
277
|
+
@date_1904 || false
|
|
278
|
+
end
|
|
275
279
|
|
|
276
280
|
def point_xml(index, value)
|
|
277
281
|
%(<c:pt idx="#{index}">\n <c:v>#{value}</c:v>\n</c:pt>\n)
|
|
@@ -279,7 +283,9 @@ module Pptx
|
|
|
279
283
|
|
|
280
284
|
# Floats keep their trailing ".0" here, unlike in the workbook, because
|
|
281
285
|
# that is what the reference implementation writes.
|
|
282
|
-
def format_value(value)
|
|
286
|
+
def format_value(value)
|
|
287
|
+
value.is_a?(String) ? escape(value) : value.to_s
|
|
288
|
+
end
|
|
283
289
|
|
|
284
290
|
def escape(text)
|
|
285
291
|
text.to_s.gsub("&", "&").gsub("<", "<").gsub(">", ">")
|
|
@@ -343,23 +349,35 @@ module Pptx
|
|
|
343
349
|
|
|
344
350
|
private
|
|
345
351
|
|
|
346
|
-
def bar?
|
|
352
|
+
def bar?
|
|
353
|
+
BAR_TYPES.include?(chart_type.name)
|
|
354
|
+
end
|
|
347
355
|
|
|
348
|
-
def bar_dir
|
|
356
|
+
def bar_dir
|
|
357
|
+
bar? ? "bar" : "col"
|
|
358
|
+
end
|
|
349
359
|
|
|
350
|
-
def grouping
|
|
360
|
+
def grouping
|
|
361
|
+
GROUPINGS.fetch(chart_type.name)
|
|
362
|
+
end
|
|
351
363
|
|
|
352
364
|
# A bar chart's category axis runs down the left; a column chart's runs
|
|
353
365
|
# along the bottom, and the value axis takes the other position.
|
|
354
|
-
def cat_ax_pos
|
|
366
|
+
def cat_ax_pos
|
|
367
|
+
bar? ? "l" : "b"
|
|
368
|
+
end
|
|
355
369
|
|
|
356
|
-
def val_ax_pos
|
|
370
|
+
def val_ax_pos
|
|
371
|
+
bar? ? "b" : "l"
|
|
372
|
+
end
|
|
357
373
|
|
|
358
374
|
def overlap
|
|
359
375
|
STACKED_TYPES.include?(chart_type.name) ? %( <c:overlap val="100"/>\n) : ""
|
|
360
376
|
end
|
|
361
377
|
|
|
362
|
-
def series_blocks
|
|
378
|
+
def series_blocks
|
|
379
|
+
all_series_xml { |series| series_xml(series) }
|
|
380
|
+
end
|
|
363
381
|
|
|
364
382
|
def cat_ax_xml
|
|
365
383
|
return date_ax_xml(CAT_AX_ID, VAL_AX_ID, cat_ax_pos) if dates?
|
|
@@ -442,9 +460,13 @@ module Pptx
|
|
|
442
460
|
|
|
443
461
|
private
|
|
444
462
|
|
|
445
|
-
def grouping
|
|
463
|
+
def grouping
|
|
464
|
+
GROUPINGS.fetch(chart_type.name)
|
|
465
|
+
end
|
|
446
466
|
|
|
447
|
-
def markers?
|
|
467
|
+
def markers?
|
|
468
|
+
MARKER_TYPES.include?(chart_type.name)
|
|
469
|
+
end
|
|
448
470
|
|
|
449
471
|
# A line chart without markers says so per series, by asking for the
|
|
450
472
|
# "none" marker symbol.
|
|
@@ -458,7 +480,9 @@ module Pptx
|
|
|
458
480
|
XML
|
|
459
481
|
end
|
|
460
482
|
|
|
461
|
-
def smooth_xml
|
|
483
|
+
def smooth_xml
|
|
484
|
+
%(<c:smooth val="0"/>\n)
|
|
485
|
+
end
|
|
462
486
|
|
|
463
487
|
def series_blocks
|
|
464
488
|
all_series_xml do |series|
|
|
@@ -516,7 +540,9 @@ module Pptx
|
|
|
516
540
|
|
|
517
541
|
# A pie plots one series only; any others live in the workbook but are
|
|
518
542
|
# not drawn.
|
|
519
|
-
def series_blocks
|
|
543
|
+
def series_blocks
|
|
544
|
+
series_xml(chart_data.series.first)
|
|
545
|
+
end
|
|
520
546
|
end
|
|
521
547
|
|
|
522
548
|
# Shared by the two families whose points carry their own x value rather
|
|
@@ -693,7 +719,9 @@ module Pptx
|
|
|
693
719
|
|
|
694
720
|
private
|
|
695
721
|
|
|
696
|
-
def three_d?
|
|
722
|
+
def three_d?
|
|
723
|
+
chart_type.name == :BUBBLE_THREE_D_EFFECT
|
|
724
|
+
end
|
|
697
725
|
|
|
698
726
|
def series_blocks
|
|
699
727
|
all_series_xml do |series|
|
|
@@ -770,9 +798,13 @@ module Pptx
|
|
|
770
798
|
|
|
771
799
|
private
|
|
772
800
|
|
|
773
|
-
def grouping
|
|
801
|
+
def grouping
|
|
802
|
+
GROUPINGS.fetch(chart_type.name)
|
|
803
|
+
end
|
|
774
804
|
|
|
775
|
-
def series_blocks
|
|
805
|
+
def series_blocks
|
|
806
|
+
all_series_xml { |series| series_xml(series) }
|
|
807
|
+
end
|
|
776
808
|
|
|
777
809
|
def cat_ax_xml
|
|
778
810
|
return date_ax_xml(CAT_AX_ID, VAL_AX_ID, "b") if dates?
|
|
@@ -884,7 +916,9 @@ module Pptx
|
|
|
884
916
|
|
|
885
917
|
private
|
|
886
918
|
|
|
887
|
-
def radar_style
|
|
919
|
+
def radar_style
|
|
920
|
+
chart_type.name == :RADAR_FILLED ? "filled" : "marker"
|
|
921
|
+
end
|
|
888
922
|
|
|
889
923
|
# A plain radar draws lines without markers, which is said per series by
|
|
890
924
|
# asking for the "none" symbol. The markers and filled variants do not.
|
|
@@ -947,7 +981,9 @@ module Pptx
|
|
|
947
981
|
private
|
|
948
982
|
|
|
949
983
|
# Unlike a pie, a doughnut draws every series as a concentric ring.
|
|
950
|
-
def series_blocks
|
|
984
|
+
def series_blocks
|
|
985
|
+
all_series_xml { |series| series_xml(series) }
|
|
986
|
+
end
|
|
951
987
|
end
|
|
952
988
|
end
|
|
953
989
|
end
|
|
@@ -42,9 +42,13 @@ module Pptx
|
|
|
42
42
|
series
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
def each(&)
|
|
45
|
+
def each(&)
|
|
46
|
+
@series.each(&)
|
|
47
|
+
end
|
|
46
48
|
|
|
47
|
-
def size
|
|
49
|
+
def size
|
|
50
|
+
@series.size
|
|
51
|
+
end
|
|
48
52
|
|
|
49
53
|
# The row a series' title sits on, counting the blocks before it.
|
|
50
54
|
#
|
|
@@ -55,13 +59,19 @@ module Pptx
|
|
|
55
59
|
end
|
|
56
60
|
|
|
57
61
|
# @api private
|
|
58
|
-
def series_name_ref(series)
|
|
62
|
+
def series_name_ref(series)
|
|
63
|
+
"#{WORKSHEET_NAME}!$B$#{title_row(series)}"
|
|
64
|
+
end
|
|
59
65
|
|
|
60
66
|
# @api private
|
|
61
|
-
def x_values_ref(series)
|
|
67
|
+
def x_values_ref(series)
|
|
68
|
+
column_ref(series, "A")
|
|
69
|
+
end
|
|
62
70
|
|
|
63
71
|
# @api private
|
|
64
|
-
def y_values_ref(series)
|
|
72
|
+
def y_values_ref(series)
|
|
73
|
+
column_ref(series, "B")
|
|
74
|
+
end
|
|
65
75
|
|
|
66
76
|
# @api private
|
|
67
77
|
def column_ref(series, column)
|
|
@@ -71,30 +81,44 @@ module Pptx
|
|
|
71
81
|
end
|
|
72
82
|
|
|
73
83
|
# @api private
|
|
74
|
-
def xlsx_blob
|
|
84
|
+
def xlsx_blob
|
|
85
|
+
XyWorkbookWriter.new(self).blob
|
|
86
|
+
end
|
|
75
87
|
|
|
76
88
|
# @api private
|
|
77
89
|
# Whether the worksheet carries a third column of bubble sizes.
|
|
78
|
-
def bubble?
|
|
90
|
+
def bubble?
|
|
91
|
+
false
|
|
92
|
+
end
|
|
79
93
|
|
|
80
|
-
def inspect
|
|
94
|
+
def inspect
|
|
95
|
+
"#<#{self.class.name} series=#{size}>"
|
|
96
|
+
end
|
|
81
97
|
|
|
82
98
|
private
|
|
83
99
|
|
|
84
|
-
def series_class
|
|
100
|
+
def series_class
|
|
101
|
+
XySeries
|
|
102
|
+
end
|
|
85
103
|
end
|
|
86
104
|
|
|
87
105
|
# Data for a bubble chart: series of (x, y, size) points.
|
|
88
106
|
class BubbleChartData < XyChartData
|
|
89
107
|
# @api private
|
|
90
|
-
def bubble_sizes_ref(series)
|
|
108
|
+
def bubble_sizes_ref(series)
|
|
109
|
+
column_ref(series, "C")
|
|
110
|
+
end
|
|
91
111
|
|
|
92
112
|
# @api private
|
|
93
|
-
def bubble?
|
|
113
|
+
def bubble?
|
|
114
|
+
true
|
|
115
|
+
end
|
|
94
116
|
|
|
95
117
|
private
|
|
96
118
|
|
|
97
|
-
def series_class
|
|
119
|
+
def series_class
|
|
120
|
+
BubbleSeries
|
|
121
|
+
end
|
|
98
122
|
end
|
|
99
123
|
|
|
100
124
|
# One series of a scatter chart.
|
|
@@ -117,19 +141,37 @@ module Pptx
|
|
|
117
141
|
self
|
|
118
142
|
end
|
|
119
143
|
|
|
120
|
-
def each(&)
|
|
144
|
+
def each(&)
|
|
145
|
+
@points.each(&)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def size
|
|
149
|
+
@points.size
|
|
150
|
+
end
|
|
121
151
|
|
|
122
|
-
def
|
|
152
|
+
def x_values
|
|
153
|
+
@points.map(&:first)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def y_values
|
|
157
|
+
@points.map { |point| point[1] }
|
|
158
|
+
end
|
|
123
159
|
|
|
124
|
-
def
|
|
160
|
+
def name_ref
|
|
161
|
+
@chart_data.series_name_ref(self)
|
|
162
|
+
end
|
|
125
163
|
|
|
126
|
-
def
|
|
164
|
+
def x_values_ref
|
|
165
|
+
@chart_data.x_values_ref(self)
|
|
166
|
+
end
|
|
127
167
|
|
|
128
|
-
def
|
|
129
|
-
|
|
130
|
-
|
|
168
|
+
def y_values_ref
|
|
169
|
+
@chart_data.y_values_ref(self)
|
|
170
|
+
end
|
|
131
171
|
|
|
132
|
-
def inspect
|
|
172
|
+
def inspect
|
|
173
|
+
"#<#{self.class.name} #{@name.inspect} #{size} points>"
|
|
174
|
+
end
|
|
133
175
|
end
|
|
134
176
|
|
|
135
177
|
# One series of a bubble chart, whose points carry a size as well.
|
|
@@ -139,9 +181,13 @@ module Pptx
|
|
|
139
181
|
self
|
|
140
182
|
end
|
|
141
183
|
|
|
142
|
-
def bubble_sizes
|
|
184
|
+
def bubble_sizes
|
|
185
|
+
@points.map { |point| point[2] }
|
|
186
|
+
end
|
|
143
187
|
|
|
144
|
-
def bubble_sizes_ref
|
|
188
|
+
def bubble_sizes_ref
|
|
189
|
+
@chart_data.bubble_sizes_ref(self)
|
|
190
|
+
end
|
|
145
191
|
end
|
|
146
192
|
|
|
147
193
|
# Writes the workbook behind a scatter or bubble chart.
|
data/lib/ruby_pptx/dml/color.rb
CHANGED
|
@@ -19,7 +19,9 @@ module Pptx
|
|
|
19
19
|
attr_reader :r, :g, :b
|
|
20
20
|
|
|
21
21
|
# Array patterns too: `in [r, g, b]`.
|
|
22
|
-
def deconstruct
|
|
22
|
+
def deconstruct
|
|
23
|
+
to_a
|
|
24
|
+
end
|
|
23
25
|
|
|
24
26
|
# Parse a hex string such as "3C2F80".
|
|
25
27
|
def self.from_string(hex)
|
|
@@ -46,17 +48,27 @@ module Pptx
|
|
|
46
48
|
freeze
|
|
47
49
|
end
|
|
48
50
|
|
|
49
|
-
def to_a
|
|
51
|
+
def to_a
|
|
52
|
+
[@r, @g, @b]
|
|
53
|
+
end
|
|
50
54
|
|
|
51
55
|
# The uppercase hex form OOXML uses, e.g. "3C2F80".
|
|
52
|
-
def to_s
|
|
56
|
+
def to_s
|
|
57
|
+
format("%02X%02X%02X", @r, @g, @b)
|
|
58
|
+
end
|
|
53
59
|
|
|
54
|
-
def ==(other)
|
|
60
|
+
def ==(other)
|
|
61
|
+
other.is_a?(RGBColor) && other.to_a == to_a
|
|
62
|
+
end
|
|
55
63
|
alias eql? ==
|
|
56
64
|
|
|
57
|
-
def hash
|
|
65
|
+
def hash
|
|
66
|
+
to_a.hash
|
|
67
|
+
end
|
|
58
68
|
|
|
59
|
-
def inspect
|
|
69
|
+
def inspect
|
|
70
|
+
"#<Pptx::RGBColor #{self}>"
|
|
71
|
+
end
|
|
60
72
|
end
|
|
61
73
|
|
|
62
74
|
# The colour of a font, fill or line.
|
|
@@ -66,7 +78,9 @@ module Pptx
|
|
|
66
78
|
class ColorFormat
|
|
67
79
|
# @param color_choice_parent [Pptx::Oxml::Element] the element holding the
|
|
68
80
|
# colour choice, e.g. `a:solidFill`
|
|
69
|
-
def self.from_color_choice_parent(color_choice_parent)
|
|
81
|
+
def self.from_color_choice_parent(color_choice_parent)
|
|
82
|
+
new(color_choice_parent)
|
|
83
|
+
end
|
|
70
84
|
|
|
71
85
|
def initialize(color_choice_parent)
|
|
72
86
|
@parent = color_choice_parent
|
|
@@ -146,10 +160,14 @@ module Pptx
|
|
|
146
160
|
end
|
|
147
161
|
end
|
|
148
162
|
|
|
149
|
-
def inspect
|
|
163
|
+
def inspect
|
|
164
|
+
"#<Pptx::ColorFormat type=#{type&.name.inspect} rgb=#{rgb&.to_s.inspect}>"
|
|
165
|
+
end
|
|
150
166
|
|
|
151
167
|
private
|
|
152
168
|
|
|
153
|
-
def color_element
|
|
169
|
+
def color_element
|
|
170
|
+
@parent.eg_colorChoice
|
|
171
|
+
end
|
|
154
172
|
end
|
|
155
173
|
end
|
data/lib/ruby_pptx/dml/effect.rb
CHANGED
|
@@ -16,7 +16,9 @@ module Pptx
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
# True when the shape takes its shadow from the style hierarchy.
|
|
19
|
-
def inherit?
|
|
19
|
+
def inherit?
|
|
20
|
+
@element.effectLst.nil?
|
|
21
|
+
end
|
|
20
22
|
|
|
21
23
|
alias inherit inherit?
|
|
22
24
|
|
|
@@ -28,6 +30,8 @@ module Pptx
|
|
|
28
30
|
value ? @element.remove_effectLst : @element.get_or_add_effectLst
|
|
29
31
|
end
|
|
30
32
|
|
|
31
|
-
def inspect
|
|
33
|
+
def inspect
|
|
34
|
+
"#<Pptx::ShadowFormat inherit=#{inherit?}>"
|
|
35
|
+
end
|
|
32
36
|
end
|
|
33
37
|
end
|
data/lib/ruby_pptx/dml/fill.rb
CHANGED
|
@@ -18,7 +18,9 @@ module Pptx
|
|
|
18
18
|
class FillFormat
|
|
19
19
|
# @param fill_parent [Pptx::Oxml::Element] the element carrying the fill
|
|
20
20
|
# choice group, e.g. `p:spPr` or `a:rPr`
|
|
21
|
-
def self.from_fill_parent(fill_parent)
|
|
21
|
+
def self.from_fill_parent(fill_parent)
|
|
22
|
+
new(fill_parent)
|
|
23
|
+
end
|
|
22
24
|
|
|
23
25
|
def initialize(fill_parent)
|
|
24
26
|
@parent = fill_parent
|
|
@@ -124,13 +126,19 @@ module Pptx
|
|
|
124
126
|
# The colour stops the gradient passes through, in order.
|
|
125
127
|
#
|
|
126
128
|
# @return [GradientStops]
|
|
127
|
-
def gradient_stops
|
|
129
|
+
def gradient_stops
|
|
130
|
+
GradientStops.new(require_gradient.get_or_add_gsLst)
|
|
131
|
+
end
|
|
128
132
|
|
|
129
|
-
def inspect
|
|
133
|
+
def inspect
|
|
134
|
+
"#<Pptx::FillFormat type=#{type&.name.inspect}>"
|
|
135
|
+
end
|
|
130
136
|
|
|
131
137
|
private
|
|
132
138
|
|
|
133
|
-
def fill_element
|
|
139
|
+
def fill_element
|
|
140
|
+
@parent.eg_fillProperties
|
|
141
|
+
end
|
|
134
142
|
|
|
135
143
|
def require_gradient
|
|
136
144
|
raise Error, "fill type #{type&.name.inspect} is not a gradient" unless type&.name == :GRADIENT
|
|
@@ -160,27 +168,39 @@ module Pptx
|
|
|
160
168
|
self
|
|
161
169
|
end
|
|
162
170
|
|
|
163
|
-
def size
|
|
171
|
+
def size
|
|
172
|
+
@element.gs_list.size
|
|
173
|
+
end
|
|
164
174
|
alias length size
|
|
165
175
|
|
|
166
|
-
def [](index, length = nil)
|
|
176
|
+
def [](index, length = nil)
|
|
177
|
+
slice_members(@element.gs_list, index, length) { |gs| GradientStop.new(gs) }
|
|
178
|
+
end
|
|
167
179
|
|
|
168
|
-
def inspect
|
|
180
|
+
def inspect
|
|
181
|
+
"#<Pptx::GradientStops size=#{size}>"
|
|
182
|
+
end
|
|
169
183
|
end
|
|
170
184
|
|
|
171
185
|
# One colour stop in a gradient.
|
|
172
186
|
class GradientStop < ElementProxy
|
|
173
|
-
def color
|
|
187
|
+
def color
|
|
188
|
+
@color ||= ColorFormat.from_color_choice_parent(@element)
|
|
189
|
+
end
|
|
174
190
|
|
|
175
191
|
# Where along the gradient this stop sits, from 0.0 at the start to 1.0
|
|
176
192
|
# at the end.
|
|
177
|
-
def position
|
|
193
|
+
def position
|
|
194
|
+
@element.pos
|
|
195
|
+
end
|
|
178
196
|
|
|
179
197
|
def position=(value)
|
|
180
198
|
@element.pos = Float(value)
|
|
181
199
|
end
|
|
182
200
|
|
|
183
|
-
def inspect
|
|
201
|
+
def inspect
|
|
202
|
+
"#<Pptx::GradientStop position=#{position}>"
|
|
203
|
+
end
|
|
184
204
|
end
|
|
185
205
|
|
|
186
206
|
class LineFormat
|
|
@@ -189,9 +209,13 @@ module Pptx
|
|
|
189
209
|
end
|
|
190
210
|
|
|
191
211
|
# The `a:ln` element, added if not present.
|
|
192
|
-
def element
|
|
212
|
+
def element
|
|
213
|
+
@element ||= @parent.get_or_add_ln
|
|
214
|
+
end
|
|
193
215
|
|
|
194
|
-
def fill
|
|
216
|
+
def fill
|
|
217
|
+
@fill ||= FillFormat.from_fill_parent(element)
|
|
218
|
+
end
|
|
195
219
|
|
|
196
220
|
# Shortcut to the line's solid colour, making the fill solid on first use.
|
|
197
221
|
def color
|
|
@@ -210,7 +234,9 @@ module Pptx
|
|
|
210
234
|
# The dash pattern, or nil when it is inherited.
|
|
211
235
|
#
|
|
212
236
|
# @return [Pptx::Enum::Member, nil] a member of MSO_LINE_DASH_STYLE
|
|
213
|
-
def dash_style
|
|
237
|
+
def dash_style
|
|
238
|
+
@parent.ln&.prstDash_val
|
|
239
|
+
end
|
|
214
240
|
|
|
215
241
|
# Set the dash pattern, or restore inheritance with nil -- which also
|
|
216
242
|
# drops a custom dash, since either one would override the inherited
|
|
@@ -229,6 +255,8 @@ module Pptx
|
|
|
229
255
|
element.w = value.nil? ? Pptx::Length.emu(0) : value
|
|
230
256
|
end
|
|
231
257
|
|
|
232
|
-
def inspect
|
|
258
|
+
def inspect
|
|
259
|
+
"#<Pptx::LineFormat width=#{width&.pt}>"
|
|
260
|
+
end
|
|
233
261
|
end
|
|
234
262
|
end
|
|
@@ -17,12 +17,18 @@ module Pptx
|
|
|
17
17
|
@element = element
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
def ==(other)
|
|
20
|
+
def ==(other)
|
|
21
|
+
other.is_a?(ElementProxy) && other.element == @element
|
|
22
|
+
end
|
|
21
23
|
alias eql? ==
|
|
22
24
|
|
|
23
|
-
def hash
|
|
25
|
+
def hash
|
|
26
|
+
@element.hash
|
|
27
|
+
end
|
|
24
28
|
|
|
25
|
-
def inspect
|
|
29
|
+
def inspect
|
|
30
|
+
"#<#{self.class.name} <#{@element.nsptag}>>"
|
|
31
|
+
end
|
|
26
32
|
end
|
|
27
33
|
|
|
28
34
|
# A proxy that knows its parent, and through it the part it belongs to.
|
|
@@ -38,7 +44,9 @@ module Pptx
|
|
|
38
44
|
end
|
|
39
45
|
|
|
40
46
|
# The package part this object lives in.
|
|
41
|
-
def part
|
|
47
|
+
def part
|
|
48
|
+
@parent.part
|
|
49
|
+
end
|
|
42
50
|
end
|
|
43
51
|
|
|
44
52
|
# A proxy wrapping a part's root element, such as `p:sld`.
|
data/lib/ruby_pptx/enum/base.rb
CHANGED
|
@@ -27,12 +27,18 @@ module Pptx
|
|
|
27
27
|
# True when this member has no XML representation. Such members are
|
|
28
28
|
# return values only: they describe a state the file format expresses by
|
|
29
29
|
# some other means, so they can be returned but never written.
|
|
30
|
-
def xml_value?
|
|
30
|
+
def xml_value?
|
|
31
|
+
!(@xml_value.nil? || @xml_value.empty?)
|
|
32
|
+
end
|
|
31
33
|
|
|
32
|
-
def to_i
|
|
34
|
+
def to_i
|
|
35
|
+
@value
|
|
36
|
+
end
|
|
33
37
|
alias to_int to_i
|
|
34
38
|
|
|
35
|
-
def to_sym
|
|
39
|
+
def to_sym
|
|
40
|
+
@name
|
|
41
|
+
end
|
|
36
42
|
|
|
37
43
|
def <=>(other)
|
|
38
44
|
case other
|
|
@@ -41,15 +47,23 @@ module Pptx
|
|
|
41
47
|
end
|
|
42
48
|
end
|
|
43
49
|
|
|
44
|
-
def ==(other)
|
|
50
|
+
def ==(other)
|
|
51
|
+
(self <=> other)&.zero? || false
|
|
52
|
+
end
|
|
45
53
|
alias eql? ==
|
|
46
54
|
|
|
47
|
-
def hash
|
|
55
|
+
def hash
|
|
56
|
+
@value.hash
|
|
57
|
+
end
|
|
48
58
|
|
|
49
59
|
# e.g. "MIDDLE (3)"
|
|
50
|
-
def to_s
|
|
60
|
+
def to_s
|
|
61
|
+
"#{@name} (#{@value})"
|
|
62
|
+
end
|
|
51
63
|
|
|
52
|
-
def inspect
|
|
64
|
+
def inspect
|
|
65
|
+
"#{@enum.short_name}.#{@name}"
|
|
66
|
+
end
|
|
53
67
|
end
|
|
54
68
|
|
|
55
69
|
# Base for every enumeration. Members are declared with {.member} and
|
|
@@ -70,11 +84,17 @@ module Pptx
|
|
|
70
84
|
member
|
|
71
85
|
end
|
|
72
86
|
|
|
73
|
-
def members
|
|
87
|
+
def members
|
|
88
|
+
@members ||= []
|
|
89
|
+
end
|
|
74
90
|
|
|
75
|
-
def each(&)
|
|
91
|
+
def each(&)
|
|
92
|
+
members.each(&)
|
|
93
|
+
end
|
|
76
94
|
|
|
77
|
-
def short_name
|
|
95
|
+
def short_name
|
|
96
|
+
name.to_s.split("::").last
|
|
97
|
+
end
|
|
78
98
|
|
|
79
99
|
# Look a member up by symbolic name or MS API value.
|
|
80
100
|
#
|
|
@@ -12,7 +12,9 @@ module Pptx
|
|
|
12
12
|
module PROG_ID
|
|
13
13
|
# One embeddable Office file type.
|
|
14
14
|
Member = Data.define(:name, :prog_id, :icon_filename, :width, :height) do
|
|
15
|
-
def to_s
|
|
15
|
+
def to_s
|
|
16
|
+
"PROG_ID.#{name}"
|
|
17
|
+
end
|
|
16
18
|
alias_method :inspect, :to_s
|
|
17
19
|
end
|
|
18
20
|
|
data/lib/ruby_pptx/geometry.rb
CHANGED
|
@@ -39,7 +39,9 @@ module Pptx
|
|
|
39
39
|
|
|
40
40
|
# Destructuring and splatting, which is what lets a Point stand in for the
|
|
41
41
|
# `[x, y]` array everywhere this library already unpacks one.
|
|
42
|
-
def to_ary
|
|
42
|
+
def to_ary
|
|
43
|
+
[x, y]
|
|
44
|
+
end
|
|
43
45
|
|
|
44
46
|
def +(other)
|
|
45
47
|
other = Point.from(other)
|
|
@@ -51,8 +53,13 @@ module Pptx
|
|
|
51
53
|
Point.new(x: x - other.x, y: y - other.y)
|
|
52
54
|
end
|
|
53
55
|
|
|
54
|
-
def to_s
|
|
55
|
-
|
|
56
|
+
def to_s
|
|
57
|
+
"(#{x.inches.round(3)}in, #{y.inches.round(3)}in)"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def inspect
|
|
61
|
+
"#<Pptx::Point #{self}>"
|
|
62
|
+
end
|
|
56
63
|
end
|
|
57
64
|
|
|
58
65
|
# The extent of a shape: a width and a height.
|
|
@@ -68,22 +75,37 @@ module Pptx
|
|
|
68
75
|
super(width: Geometry.length(width, :width), height: Geometry.length(height, :height))
|
|
69
76
|
end
|
|
70
77
|
|
|
71
|
-
def to_ary
|
|
78
|
+
def to_ary
|
|
79
|
+
[width, height]
|
|
80
|
+
end
|
|
72
81
|
|
|
73
82
|
# Scale both extents, for `size * 2` or `size * 0.5`.
|
|
74
|
-
def *(factor)
|
|
83
|
+
def *(factor)
|
|
84
|
+
Size.new(width: width * factor, height: height * factor)
|
|
85
|
+
end
|
|
75
86
|
|
|
76
|
-
def aspect_ratio
|
|
87
|
+
def aspect_ratio
|
|
88
|
+
width.emu.to_f / height.emu
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def to_s
|
|
92
|
+
"#{width.inches.round(3)}in x #{height.inches.round(3)}in"
|
|
93
|
+
end
|
|
77
94
|
|
|
78
|
-
def
|
|
79
|
-
|
|
95
|
+
def inspect
|
|
96
|
+
"#<Pptx::Size #{self}>"
|
|
97
|
+
end
|
|
80
98
|
end
|
|
81
99
|
|
|
82
100
|
class << self
|
|
83
101
|
# @return [Pptx::Point]
|
|
84
|
-
def point(x, y)
|
|
102
|
+
def point(x, y)
|
|
103
|
+
Point.new(x: x, y: y)
|
|
104
|
+
end
|
|
85
105
|
|
|
86
106
|
# @return [Pptx::Size]
|
|
87
|
-
def size(width, height)
|
|
107
|
+
def size(width, height)
|
|
108
|
+
Size.new(width: width, height: height)
|
|
109
|
+
end
|
|
88
110
|
end
|
|
89
111
|
end
|