ruby_pptx 0.1.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 +7 -0
- data/CHANGELOG.md +83 -0
- data/LICENSE +21 -0
- data/NOTICE +48 -0
- data/README.md +272 -0
- data/lib/ruby_pptx/action.rb +120 -0
- data/lib/ruby_pptx/autoshape_spec.rb +337 -0
- data/lib/ruby_pptx/builder.rb +228 -0
- data/lib/ruby_pptx/chart/categories.rb +208 -0
- data/lib/ruby_pptx/chart/chart.rb +443 -0
- data/lib/ruby_pptx/chart/combo.rb +230 -0
- data/lib/ruby_pptx/chart/data.rb +147 -0
- data/lib/ruby_pptx/chart/format.rb +647 -0
- data/lib/ruby_pptx/chart/workbook_writer.rb +212 -0
- data/lib/ruby_pptx/chart/xml_writer.rb +953 -0
- data/lib/ruby_pptx/chart/xy_data.rb +182 -0
- data/lib/ruby_pptx/core_ext.rb +12 -0
- data/lib/ruby_pptx/dml/color.rb +155 -0
- data/lib/ruby_pptx/dml/effect.rb +33 -0
- data/lib/ruby_pptx/dml/fill.rb +234 -0
- data/lib/ruby_pptx/element_proxy.rb +53 -0
- data/lib/ruby_pptx/enum/action.rb +46 -0
- data/lib/ruby_pptx/enum/base.rb +139 -0
- data/lib/ruby_pptx/enum/chart.rb +278 -0
- data/lib/ruby_pptx/enum/dml.rb +237 -0
- data/lib/ruby_pptx/enum/lang.rb +441 -0
- data/lib/ruby_pptx/enum/prog_id.rb +38 -0
- data/lib/ruby_pptx/enum/shapes.rb +514 -0
- data/lib/ruby_pptx/enum/text.rb +108 -0
- data/lib/ruby_pptx/errors.rb +15 -0
- data/lib/ruby_pptx/geometry.rb +89 -0
- data/lib/ruby_pptx/image.rb +347 -0
- data/lib/ruby_pptx/length.rb +120 -0
- data/lib/ruby_pptx/media.rb +64 -0
- data/lib/ruby_pptx/numeric_lengths.rb +30 -0
- data/lib/ruby_pptx/opc/constants.rb +205 -0
- data/lib/ruby_pptx/opc/oxml.rb +99 -0
- data/lib/ruby_pptx/opc/pack_uri.rb +146 -0
- data/lib/ruby_pptx/opc/package.rb +482 -0
- data/lib/ruby_pptx/opc/serialized.rb +229 -0
- data/lib/ruby_pptx/opc/spec.rb +37 -0
- data/lib/ruby_pptx/oxml/action.rb +43 -0
- data/lib/ruby_pptx/oxml/chart.rb +785 -0
- data/lib/ruby_pptx/oxml/content_model.rb +186 -0
- data/lib/ruby_pptx/oxml/core_properties.rb +145 -0
- data/lib/ruby_pptx/oxml/dml/color.rb +115 -0
- data/lib/ruby_pptx/oxml/dml/fill.rb +137 -0
- data/lib/ruby_pptx/oxml/element.rb +329 -0
- data/lib/ruby_pptx/oxml/ns.rb +115 -0
- data/lib/ruby_pptx/oxml/presentation.rb +110 -0
- data/lib/ruby_pptx/oxml/section.rb +65 -0
- data/lib/ruby_pptx/oxml/shapes/autoshape.rb +310 -0
- data/lib/ruby_pptx/oxml/shapes/groupshape.rb +217 -0
- data/lib/ruby_pptx/oxml/shapes/other.rb +405 -0
- data/lib/ruby_pptx/oxml/shapes/shared.rb +292 -0
- data/lib/ruby_pptx/oxml/simple_types.rb +563 -0
- data/lib/ruby_pptx/oxml/slide.rb +290 -0
- data/lib/ruby_pptx/oxml/table.rb +253 -0
- data/lib/ruby_pptx/oxml/text.rb +324 -0
- data/lib/ruby_pptx/oxml/theme.rb +93 -0
- data/lib/ruby_pptx/package.rb +139 -0
- data/lib/ruby_pptx/parts/chart.rb +75 -0
- data/lib/ruby_pptx/parts/core_properties.rb +40 -0
- data/lib/ruby_pptx/parts/embedded_package.rb +43 -0
- data/lib/ruby_pptx/parts/image.rb +55 -0
- data/lib/ruby_pptx/parts/media.rb +17 -0
- data/lib/ruby_pptx/parts/presentation.rb +79 -0
- data/lib/ruby_pptx/parts/slide.rb +221 -0
- data/lib/ruby_pptx/parts/theme.rb +26 -0
- data/lib/ruby_pptx/pattern_matching.rb +50 -0
- data/lib/ruby_pptx/presentation.rb +128 -0
- data/lib/ruby_pptx/refinements.rb +21 -0
- data/lib/ruby_pptx/section.rb +130 -0
- data/lib/ruby_pptx/shapes/adjustments.rb +83 -0
- data/lib/ruby_pptx/shapes/authoring.rb +110 -0
- data/lib/ruby_pptx/shapes/base.rb +138 -0
- data/lib/ruby_pptx/shapes/freeform.rb +141 -0
- data/lib/ruby_pptx/shapes/placeholder.rb +184 -0
- data/lib/ruby_pptx/shapes/shape.rb +337 -0
- data/lib/ruby_pptx/shapes/shape_tree.rb +634 -0
- data/lib/ruby_pptx/sliceable.rb +34 -0
- data/lib/ruby_pptx/slide.rb +430 -0
- data/lib/ruby_pptx/table.rb +316 -0
- data/lib/ruby_pptx/table_paging.rb +91 -0
- data/lib/ruby_pptx/templates/default.pptx +0 -0
- data/lib/ruby_pptx/templates/docx-icon.emf +0 -0
- data/lib/ruby_pptx/templates/generic-icon.emf +0 -0
- data/lib/ruby_pptx/templates/media-speaker.png +0 -0
- data/lib/ruby_pptx/templates/notes.xml +23 -0
- data/lib/ruby_pptx/templates/notesMaster.xml +352 -0
- data/lib/ruby_pptx/templates/pptx-icon.emf +0 -0
- data/lib/ruby_pptx/templates/slideMaster.xml +277 -0
- data/lib/ruby_pptx/templates/theme.xml +321 -0
- data/lib/ruby_pptx/templates/xlsx-icon.emf +0 -0
- data/lib/ruby_pptx/text/fitter.rb +72 -0
- data/lib/ruby_pptx/text/font_metrics.rb +221 -0
- data/lib/ruby_pptx/text/text.rb +393 -0
- data/lib/ruby_pptx/theme.rb +98 -0
- data/lib/ruby_pptx/version.rb +5 -0
- data/lib/ruby_pptx.rb +90 -0
- metadata +174 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Generated by tools/generate_autoshape_spec.py from python-pptx. Do not edit by hand.
|
|
4
|
+
|
|
5
|
+
require "ruby_pptx/enum/shapes"
|
|
6
|
+
|
|
7
|
+
module Pptx
|
|
8
|
+
# Per auto-shape-type metadata: the name PowerPoint gives a new shape
|
|
9
|
+
# of that type, and the default values of its adjustment handles.
|
|
10
|
+
module AutoShapeSpec
|
|
11
|
+
SPECS = {
|
|
12
|
+
ACTION_BUTTON_BACK_OR_PREVIOUS: { basename: "Action Button: Back or Previous",
|
|
13
|
+
default_adjustments: [].freeze }.freeze,
|
|
14
|
+
ACTION_BUTTON_BEGINNING: { basename: "Action Button: Beginning",
|
|
15
|
+
default_adjustments: [].freeze }.freeze,
|
|
16
|
+
ACTION_BUTTON_CUSTOM: { basename: "Action Button: Custom", default_adjustments: [].freeze }.freeze,
|
|
17
|
+
ACTION_BUTTON_DOCUMENT: { basename: "Action Button: Document", default_adjustments: [].freeze }.freeze,
|
|
18
|
+
ACTION_BUTTON_END: { basename: "Action Button: End", default_adjustments: [].freeze }.freeze,
|
|
19
|
+
ACTION_BUTTON_FORWARD_OR_NEXT: { basename: "Action Button: Forward or Next",
|
|
20
|
+
default_adjustments: [].freeze }.freeze,
|
|
21
|
+
ACTION_BUTTON_HELP: { basename: "Action Button: Help", default_adjustments: [].freeze }.freeze,
|
|
22
|
+
ACTION_BUTTON_HOME: { basename: "Action Button: Home", default_adjustments: [].freeze }.freeze,
|
|
23
|
+
ACTION_BUTTON_INFORMATION: { basename: "Action Button: Information",
|
|
24
|
+
default_adjustments: [].freeze }.freeze,
|
|
25
|
+
ACTION_BUTTON_MOVIE: { basename: "Action Button: Movie", default_adjustments: [].freeze }.freeze,
|
|
26
|
+
ACTION_BUTTON_RETURN: { basename: "Action Button: Return", default_adjustments: [].freeze }.freeze,
|
|
27
|
+
ACTION_BUTTON_SOUND: { basename: "Action Button: Sound", default_adjustments: [].freeze }.freeze,
|
|
28
|
+
ARC: { basename: "Arc", default_adjustments: [["adj1", 16_200_000], ["adj2", 0]].freeze }.freeze,
|
|
29
|
+
BALLOON: { basename: "Rounded Rectangular Callout",
|
|
30
|
+
default_adjustments: [["adj1", -20833], ["adj2", 62500], ["adj3", 16667]].freeze }.freeze,
|
|
31
|
+
BENT_ARROW: { basename: "Bent Arrow",
|
|
32
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000], ["adj3", 25000],
|
|
33
|
+
["adj4", 43750]].freeze }.freeze,
|
|
34
|
+
BENT_UP_ARROW: { basename: "Bent-Up Arrow",
|
|
35
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000],
|
|
36
|
+
["adj3", 25000]].freeze }.freeze,
|
|
37
|
+
BEVEL: { basename: "Bevel", default_adjustments: [["adj", 12500]].freeze }.freeze,
|
|
38
|
+
BLOCK_ARC: { basename: "Block Arc",
|
|
39
|
+
default_adjustments: [["adj1", 10_800_000], ["adj2", 0], ["adj3", 25000]].freeze }.freeze,
|
|
40
|
+
CAN: { basename: "Can", default_adjustments: [["adj", 25000]].freeze }.freeze,
|
|
41
|
+
CHART_PLUS: { basename: "Chart Plus", default_adjustments: [].freeze }.freeze,
|
|
42
|
+
CHART_STAR: { basename: "Chart Star", default_adjustments: [].freeze }.freeze,
|
|
43
|
+
CHART_X: { basename: "Chart X", default_adjustments: [].freeze }.freeze,
|
|
44
|
+
CHEVRON: { basename: "Chevron", default_adjustments: [["adj", 50000]].freeze }.freeze,
|
|
45
|
+
CHORD: { basename: "Chord",
|
|
46
|
+
default_adjustments: [["adj1", 2_700_000], ["adj2", 16_200_000]].freeze }.freeze,
|
|
47
|
+
CIRCULAR_ARROW: { basename: "Circular Arrow",
|
|
48
|
+
default_adjustments: [["adj1", 12500], ["adj2", 1_142_319], ["adj3", 20_457_681], ["adj4", 10_800_000],
|
|
49
|
+
["adj5", 12500]].freeze }.freeze,
|
|
50
|
+
CLOUD: { basename: "Cloud", default_adjustments: [].freeze }.freeze,
|
|
51
|
+
CLOUD_CALLOUT: { basename: "Cloud Callout",
|
|
52
|
+
default_adjustments: [["adj1", -20833], ["adj2", 62500]].freeze }.freeze,
|
|
53
|
+
CORNER: { basename: "Corner", default_adjustments: [["adj1", 50000], ["adj2", 50000]].freeze }.freeze,
|
|
54
|
+
CORNER_TABS: { basename: "Corner Tabs", default_adjustments: [].freeze }.freeze,
|
|
55
|
+
CROSS: { basename: "Cross", default_adjustments: [["adj", 25000]].freeze }.freeze,
|
|
56
|
+
CUBE: { basename: "Cube", default_adjustments: [["adj", 25000]].freeze }.freeze,
|
|
57
|
+
CURVED_DOWN_ARROW: { basename: "Curved Down Arrow",
|
|
58
|
+
default_adjustments: [["adj1", 25000], ["adj2", 50000],
|
|
59
|
+
["adj3", 25000]].freeze }.freeze,
|
|
60
|
+
CURVED_DOWN_RIBBON: { basename: "Curved Down Ribbon",
|
|
61
|
+
default_adjustments: [["adj1", 25000], ["adj2", 50000],
|
|
62
|
+
["adj3", 12500]].freeze }.freeze,
|
|
63
|
+
CURVED_LEFT_ARROW: { basename: "Curved Left Arrow",
|
|
64
|
+
default_adjustments: [["adj1", 25000], ["adj2", 50000],
|
|
65
|
+
["adj3", 25000]].freeze }.freeze,
|
|
66
|
+
CURVED_RIGHT_ARROW: { basename: "Curved Right Arrow",
|
|
67
|
+
default_adjustments: [["adj1", 25000], ["adj2", 50000],
|
|
68
|
+
["adj3", 25000]].freeze }.freeze,
|
|
69
|
+
CURVED_UP_ARROW: { basename: "Curved Up Arrow",
|
|
70
|
+
default_adjustments: [["adj1", 25000], ["adj2", 50000],
|
|
71
|
+
["adj3", 25000]].freeze }.freeze,
|
|
72
|
+
CURVED_UP_RIBBON: { basename: "Curved Up Ribbon",
|
|
73
|
+
default_adjustments: [["adj1", 25000], ["adj2", 50000],
|
|
74
|
+
["adj3", 12500]].freeze }.freeze,
|
|
75
|
+
DECAGON: { basename: "Decagon", default_adjustments: [["vf", 105_146]].freeze }.freeze,
|
|
76
|
+
DIAGONAL_STRIPE: { basename: "Diagonal Stripe", default_adjustments: [["adj", 50000]].freeze }.freeze,
|
|
77
|
+
DIAMOND: { basename: "Diamond", default_adjustments: [].freeze }.freeze,
|
|
78
|
+
DODECAGON: { basename: "Dodecagon", default_adjustments: [].freeze }.freeze,
|
|
79
|
+
DONUT: { basename: "Donut", default_adjustments: [["adj", 25000]].freeze }.freeze,
|
|
80
|
+
DOUBLE_BRACE: { basename: "Double Brace", default_adjustments: [["adj", 8333]].freeze }.freeze,
|
|
81
|
+
DOUBLE_BRACKET: { basename: "Double Bracket", default_adjustments: [["adj", 16667]].freeze }.freeze,
|
|
82
|
+
DOUBLE_WAVE: { basename: "Double Wave",
|
|
83
|
+
default_adjustments: [["adj1", 6250], ["adj2", 0]].freeze }.freeze,
|
|
84
|
+
DOWN_ARROW: { basename: "Down Arrow",
|
|
85
|
+
default_adjustments: [["adj1", 50000], ["adj2", 50000]].freeze }.freeze,
|
|
86
|
+
DOWN_ARROW_CALLOUT: { basename: "Down Arrow Callout",
|
|
87
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000], ["adj3", 25000],
|
|
88
|
+
["adj4", 64977]].freeze }.freeze,
|
|
89
|
+
DOWN_RIBBON: { basename: "Down Ribbon",
|
|
90
|
+
default_adjustments: [["adj1", 16667], ["adj2", 50000]].freeze }.freeze,
|
|
91
|
+
EXPLOSION1: { basename: "Explosion", default_adjustments: [].freeze }.freeze,
|
|
92
|
+
EXPLOSION2: { basename: "Explosion", default_adjustments: [].freeze }.freeze,
|
|
93
|
+
FLOWCHART_ALTERNATE_PROCESS: { basename: "Alternate process", default_adjustments: [].freeze }.freeze,
|
|
94
|
+
FLOWCHART_CARD: { basename: "Card", default_adjustments: [].freeze }.freeze,
|
|
95
|
+
FLOWCHART_COLLATE: { basename: "Collate", default_adjustments: [].freeze }.freeze,
|
|
96
|
+
FLOWCHART_CONNECTOR: { basename: "Connector", default_adjustments: [].freeze }.freeze,
|
|
97
|
+
FLOWCHART_DATA: { basename: "Data", default_adjustments: [].freeze }.freeze,
|
|
98
|
+
FLOWCHART_DECISION: { basename: "Decision", default_adjustments: [].freeze }.freeze,
|
|
99
|
+
FLOWCHART_DELAY: { basename: "Delay", default_adjustments: [].freeze }.freeze,
|
|
100
|
+
FLOWCHART_DIRECT_ACCESS_STORAGE: { basename: "Direct Access Storage",
|
|
101
|
+
default_adjustments: [].freeze }.freeze,
|
|
102
|
+
FLOWCHART_DISPLAY: { basename: "Display", default_adjustments: [].freeze }.freeze,
|
|
103
|
+
FLOWCHART_DOCUMENT: { basename: "Document", default_adjustments: [].freeze }.freeze,
|
|
104
|
+
FLOWCHART_EXTRACT: { basename: "Extract", default_adjustments: [].freeze }.freeze,
|
|
105
|
+
FLOWCHART_INTERNAL_STORAGE: { basename: "Internal Storage", default_adjustments: [].freeze }.freeze,
|
|
106
|
+
FLOWCHART_MAGNETIC_DISK: { basename: "Magnetic Disk", default_adjustments: [].freeze }.freeze,
|
|
107
|
+
FLOWCHART_MANUAL_INPUT: { basename: "Manual Input", default_adjustments: [].freeze }.freeze,
|
|
108
|
+
FLOWCHART_MANUAL_OPERATION: { basename: "Manual Operation", default_adjustments: [].freeze }.freeze,
|
|
109
|
+
FLOWCHART_MERGE: { basename: "Merge", default_adjustments: [].freeze }.freeze,
|
|
110
|
+
FLOWCHART_MULTIDOCUMENT: { basename: "Multidocument", default_adjustments: [].freeze }.freeze,
|
|
111
|
+
FLOWCHART_OFFLINE_STORAGE: { basename: "Offline Storage", default_adjustments: [].freeze }.freeze,
|
|
112
|
+
FLOWCHART_OFFPAGE_CONNECTOR: { basename: "Off-page Connector", default_adjustments: [].freeze }.freeze,
|
|
113
|
+
FLOWCHART_OR: { basename: "Or", default_adjustments: [].freeze }.freeze,
|
|
114
|
+
FLOWCHART_PREDEFINED_PROCESS: { basename: "Predefined Process", default_adjustments: [].freeze }.freeze,
|
|
115
|
+
FLOWCHART_PREPARATION: { basename: "Preparation", default_adjustments: [].freeze }.freeze,
|
|
116
|
+
FLOWCHART_PROCESS: { basename: "Process", default_adjustments: [].freeze }.freeze,
|
|
117
|
+
FLOWCHART_PUNCHED_TAPE: { basename: "Punched Tape", default_adjustments: [].freeze }.freeze,
|
|
118
|
+
FLOWCHART_SEQUENTIAL_ACCESS_STORAGE: { basename: "Sequential Access Storage",
|
|
119
|
+
default_adjustments: [].freeze }.freeze,
|
|
120
|
+
FLOWCHART_SORT: { basename: "Sort", default_adjustments: [].freeze }.freeze,
|
|
121
|
+
FLOWCHART_STORED_DATA: { basename: "Stored Data", default_adjustments: [].freeze }.freeze,
|
|
122
|
+
FLOWCHART_SUMMING_JUNCTION: { basename: "Summing Junction", default_adjustments: [].freeze }.freeze,
|
|
123
|
+
FLOWCHART_TERMINATOR: { basename: "Terminator", default_adjustments: [].freeze }.freeze,
|
|
124
|
+
FOLDED_CORNER: { basename: "Folded Corner", default_adjustments: [].freeze }.freeze,
|
|
125
|
+
FRAME: { basename: "Frame", default_adjustments: [["adj1", 12500]].freeze }.freeze,
|
|
126
|
+
FUNNEL: { basename: "Funnel", default_adjustments: [].freeze }.freeze,
|
|
127
|
+
GEAR_6: { basename: "Gear 6", default_adjustments: [["adj1", 15000], ["adj2", 3526]].freeze }.freeze,
|
|
128
|
+
GEAR_9: { basename: "Gear 9", default_adjustments: [["adj1", 10000], ["adj2", 1763]].freeze }.freeze,
|
|
129
|
+
HALF_FRAME: { basename: "Half Frame",
|
|
130
|
+
default_adjustments: [["adj1", 33333], ["adj2", 33333]].freeze }.freeze,
|
|
131
|
+
HEART: { basename: "Heart", default_adjustments: [].freeze }.freeze,
|
|
132
|
+
HEPTAGON: { basename: "Heptagon",
|
|
133
|
+
default_adjustments: [["hf", 102_572], ["vf", 105_210]].freeze }.freeze,
|
|
134
|
+
HEXAGON: { basename: "Hexagon", default_adjustments: [["adj", 25000], ["vf", 115_470]].freeze }.freeze,
|
|
135
|
+
HORIZONTAL_SCROLL: { basename: "Horizontal Scroll",
|
|
136
|
+
default_adjustments: [["adj", 12500]].freeze }.freeze,
|
|
137
|
+
ISOSCELES_TRIANGLE: { basename: "Isosceles Triangle",
|
|
138
|
+
default_adjustments: [["adj", 50000]].freeze }.freeze,
|
|
139
|
+
LEFT_ARROW: { basename: "Left Arrow",
|
|
140
|
+
default_adjustments: [["adj1", 50000], ["adj2", 50000]].freeze }.freeze,
|
|
141
|
+
LEFT_ARROW_CALLOUT: { basename: "Left Arrow Callout",
|
|
142
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000], ["adj3", 25000],
|
|
143
|
+
["adj4", 64977]].freeze }.freeze,
|
|
144
|
+
LEFT_BRACE: { basename: "Left Brace",
|
|
145
|
+
default_adjustments: [["adj1", 8333], ["adj2", 50000]].freeze }.freeze,
|
|
146
|
+
LEFT_BRACKET: { basename: "Left Bracket", default_adjustments: [["adj", 8333]].freeze }.freeze,
|
|
147
|
+
LEFT_CIRCULAR_ARROW: { basename: "Left Circular Arrow",
|
|
148
|
+
default_adjustments: [["adj1", 12500], ["adj2", -1_142_319], ["adj3", 1_142_319], ["adj4", 10_800_000],
|
|
149
|
+
["adj5", 12500]].freeze }.freeze,
|
|
150
|
+
LEFT_RIGHT_ARROW: { basename: "Left-Right Arrow",
|
|
151
|
+
default_adjustments: [["adj1", 50000], ["adj2", 50000]].freeze }.freeze,
|
|
152
|
+
LEFT_RIGHT_ARROW_CALLOUT: { basename: "Left-Right Arrow Callout",
|
|
153
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000], ["adj3", 25000],
|
|
154
|
+
["adj4", 48123]].freeze }.freeze,
|
|
155
|
+
LEFT_RIGHT_CIRCULAR_ARROW: { basename: "Left Right Circular Arrow",
|
|
156
|
+
default_adjustments: [["adj1", 12500], ["adj2", 1_142_319], ["adj3", 20_457_681], ["adj4", 11_942_319],
|
|
157
|
+
["adj5", 12500]].freeze }.freeze,
|
|
158
|
+
LEFT_RIGHT_RIBBON: { basename: "Left Right Ribbon",
|
|
159
|
+
default_adjustments: [["adj1", 50000], ["adj2", 50000],
|
|
160
|
+
["adj3", 16667]].freeze }.freeze,
|
|
161
|
+
LEFT_RIGHT_UP_ARROW: { basename: "Left-Right-Up Arrow",
|
|
162
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000],
|
|
163
|
+
["adj3", 25000]].freeze }.freeze,
|
|
164
|
+
LEFT_UP_ARROW: { basename: "Left-Up Arrow",
|
|
165
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000],
|
|
166
|
+
["adj3", 25000]].freeze }.freeze,
|
|
167
|
+
LIGHTNING_BOLT: { basename: "Lightning Bolt", default_adjustments: [].freeze }.freeze,
|
|
168
|
+
LINE_CALLOUT_1: { basename: "Line Callout 1",
|
|
169
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 112_500],
|
|
170
|
+
["adj4", -38333]].freeze }.freeze,
|
|
171
|
+
LINE_CALLOUT_1_ACCENT_BAR: { basename: "Line Callout 1 (Accent Bar)",
|
|
172
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 112_500],
|
|
173
|
+
["adj4", -38333]].freeze }.freeze,
|
|
174
|
+
LINE_CALLOUT_1_BORDER_AND_ACCENT_BAR: { basename: "Line Callout 1 (Border and Accent Bar)",
|
|
175
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333],
|
|
176
|
+
["adj3", 112_500], ["adj4", -38333]].freeze }.freeze,
|
|
177
|
+
LINE_CALLOUT_1_NO_BORDER: { basename: "Line Callout 1 (No Border)",
|
|
178
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 112_500],
|
|
179
|
+
["adj4", -38333]].freeze }.freeze,
|
|
180
|
+
LINE_CALLOUT_2: { basename: "Line Callout 2",
|
|
181
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 112_500],
|
|
182
|
+
["adj6", -46667]].freeze }.freeze,
|
|
183
|
+
LINE_CALLOUT_2_ACCENT_BAR: { basename: "Line Callout 2 (Accent Bar)",
|
|
184
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 112_500],
|
|
185
|
+
["adj6", -46667]].freeze }.freeze,
|
|
186
|
+
LINE_CALLOUT_2_BORDER_AND_ACCENT_BAR: { basename: "Line Callout 2 (Border and Accent Bar)",
|
|
187
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 112_500],
|
|
188
|
+
["adj6", -46667]].freeze }.freeze,
|
|
189
|
+
LINE_CALLOUT_2_NO_BORDER: { basename: "Line Callout 2 (No Border)",
|
|
190
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 112_500],
|
|
191
|
+
["adj6", -46667]].freeze }.freeze,
|
|
192
|
+
LINE_CALLOUT_3: { basename: "Line Callout 3",
|
|
193
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 100_000],
|
|
194
|
+
["adj6", -16667], ["adj7", 112_963], ["adj8", -8333]].freeze }.freeze,
|
|
195
|
+
LINE_CALLOUT_3_ACCENT_BAR: { basename: "Line Callout 3 (Accent Bar)",
|
|
196
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 100_000],
|
|
197
|
+
["adj6", -16667], ["adj7", 112_963], ["adj8", -8333]].freeze }.freeze,
|
|
198
|
+
LINE_CALLOUT_3_BORDER_AND_ACCENT_BAR: { basename: "Line Callout 3 (Border and Accent Bar)",
|
|
199
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 100_000],
|
|
200
|
+
["adj6", -16667], ["adj7", 112_963], ["adj8", -8333]].freeze }.freeze,
|
|
201
|
+
LINE_CALLOUT_3_NO_BORDER: { basename: "Line Callout 3 (No Border)",
|
|
202
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 100_000],
|
|
203
|
+
["adj6", -16667], ["adj7", 112_963], ["adj8", -8333]].freeze }.freeze,
|
|
204
|
+
LINE_CALLOUT_4: { basename: "Line Callout 3",
|
|
205
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 100_000],
|
|
206
|
+
["adj6", -16667], ["adj7", 112_963], ["adj8", -8333]].freeze }.freeze,
|
|
207
|
+
LINE_CALLOUT_4_ACCENT_BAR: { basename: "Line Callout 3 (Accent Bar)",
|
|
208
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 100_000],
|
|
209
|
+
["adj6", -16667], ["adj7", 112_963], ["adj8", -8333]].freeze }.freeze,
|
|
210
|
+
LINE_CALLOUT_4_BORDER_AND_ACCENT_BAR: { basename: "Line Callout 3 (Border and Accent Bar)",
|
|
211
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 100_000],
|
|
212
|
+
["adj6", -16667], ["adj7", 112_963], ["adj8", -8333]].freeze }.freeze,
|
|
213
|
+
LINE_CALLOUT_4_NO_BORDER: { basename: "Line Callout 3 (No Border)",
|
|
214
|
+
default_adjustments: [["adj1", 18750], ["adj2", -8333], ["adj3", 18750], ["adj4", -16667], ["adj5", 100_000],
|
|
215
|
+
["adj6", -16667], ["adj7", 112_963], ["adj8", -8333]].freeze }.freeze,
|
|
216
|
+
LINE_INVERSE: { basename: "Straight Connector", default_adjustments: [].freeze }.freeze,
|
|
217
|
+
MATH_DIVIDE: { basename: "Division",
|
|
218
|
+
default_adjustments: [["adj1", 23520], ["adj2", 5880], ["adj3", 11760]].freeze }.freeze,
|
|
219
|
+
MATH_EQUAL: { basename: "Equal",
|
|
220
|
+
default_adjustments: [["adj1", 23520], ["adj2", 11760]].freeze }.freeze,
|
|
221
|
+
MATH_MINUS: { basename: "Minus", default_adjustments: [["adj1", 23520]].freeze }.freeze,
|
|
222
|
+
MATH_MULTIPLY: { basename: "Multiply", default_adjustments: [["adj1", 23520]].freeze }.freeze,
|
|
223
|
+
MATH_NOT_EQUAL: { basename: "Not Equal",
|
|
224
|
+
default_adjustments: [["adj1", 23520], ["adj2", 6_600_000],
|
|
225
|
+
["adj3", 11760]].freeze }.freeze,
|
|
226
|
+
MATH_PLUS: { basename: "Plus", default_adjustments: [["adj1", 23520]].freeze }.freeze,
|
|
227
|
+
MOON: { basename: "Moon", default_adjustments: [["adj", 50000]].freeze }.freeze,
|
|
228
|
+
NON_ISOSCELES_TRAPEZOID: { basename: "Non-isosceles Trapezoid",
|
|
229
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000]].freeze }.freeze,
|
|
230
|
+
NOTCHED_RIGHT_ARROW: { basename: "Notched Right Arrow",
|
|
231
|
+
default_adjustments: [["adj1", 50000], ["adj2", 50000]].freeze }.freeze,
|
|
232
|
+
NO_SYMBOL: { basename: "\"No\" Symbol", default_adjustments: [["adj", 18750]].freeze }.freeze,
|
|
233
|
+
OCTAGON: { basename: "Octagon", default_adjustments: [["adj", 29289]].freeze }.freeze,
|
|
234
|
+
OVAL: { basename: "Oval", default_adjustments: [].freeze }.freeze,
|
|
235
|
+
OVAL_CALLOUT: { basename: "Oval Callout",
|
|
236
|
+
default_adjustments: [["adj1", -20833], ["adj2", 62500]].freeze }.freeze,
|
|
237
|
+
PARALLELOGRAM: { basename: "Parallelogram", default_adjustments: [["adj", 25000]].freeze }.freeze,
|
|
238
|
+
PENTAGON: { basename: "Pentagon", default_adjustments: [["adj", 50000]].freeze }.freeze,
|
|
239
|
+
PIE: { basename: "Pie", default_adjustments: [["adj1", 0], ["adj2", 16_200_000]].freeze }.freeze,
|
|
240
|
+
PIE_WEDGE: { basename: "Pie", default_adjustments: [].freeze }.freeze,
|
|
241
|
+
PLAQUE: { basename: "Plaque", default_adjustments: [["adj", 16667]].freeze }.freeze,
|
|
242
|
+
PLAQUE_TABS: { basename: "Plaque Tabs", default_adjustments: [].freeze }.freeze,
|
|
243
|
+
QUAD_ARROW: { basename: "Quad Arrow",
|
|
244
|
+
default_adjustments: [["adj1", 22500], ["adj2", 22500], ["adj3", 22500]].freeze }.freeze,
|
|
245
|
+
QUAD_ARROW_CALLOUT: { basename: "Quad Arrow Callout",
|
|
246
|
+
default_adjustments: [["adj1", 18515], ["adj2", 18515], ["adj3", 18515],
|
|
247
|
+
["adj4", 48123]].freeze }.freeze,
|
|
248
|
+
RECTANGLE: { basename: "Rectangle", default_adjustments: [].freeze }.freeze,
|
|
249
|
+
RECTANGULAR_CALLOUT: { basename: "Rectangular Callout",
|
|
250
|
+
default_adjustments: [["adj1", -20833], ["adj2", 62500]].freeze }.freeze,
|
|
251
|
+
REGULAR_PENTAGON: { basename: "Regular Pentagon",
|
|
252
|
+
default_adjustments: [["hf", 105_146], ["vf", 110_557]].freeze }.freeze,
|
|
253
|
+
RIGHT_ARROW: { basename: "Right Arrow",
|
|
254
|
+
default_adjustments: [["adj1", 50000], ["adj2", 50000]].freeze }.freeze,
|
|
255
|
+
RIGHT_ARROW_CALLOUT: { basename: "Right Arrow Callout",
|
|
256
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000], ["adj3", 25000],
|
|
257
|
+
["adj4", 64977]].freeze }.freeze,
|
|
258
|
+
RIGHT_BRACE: { basename: "Right Brace",
|
|
259
|
+
default_adjustments: [["adj1", 8333], ["adj2", 50000]].freeze }.freeze,
|
|
260
|
+
RIGHT_BRACKET: { basename: "Right Bracket", default_adjustments: [["adj", 8333]].freeze }.freeze,
|
|
261
|
+
RIGHT_TRIANGLE: { basename: "Right Triangle", default_adjustments: [].freeze }.freeze,
|
|
262
|
+
ROUNDED_RECTANGLE: { basename: "Rounded Rectangle",
|
|
263
|
+
default_adjustments: [["adj", 16667]].freeze }.freeze,
|
|
264
|
+
ROUNDED_RECTANGULAR_CALLOUT: { basename: "Rounded Rectangular Callout",
|
|
265
|
+
default_adjustments: [["adj1", -20833], ["adj2", 62500],
|
|
266
|
+
["adj3", 16667]].freeze }.freeze,
|
|
267
|
+
ROUND_1_RECTANGLE: { basename: "Round Single Corner Rectangle",
|
|
268
|
+
default_adjustments: [["adj", 16667]].freeze }.freeze,
|
|
269
|
+
ROUND_2_DIAG_RECTANGLE: { basename: "Round Diagonal Corner Rectangle",
|
|
270
|
+
default_adjustments: [["adj1", 16667], ["adj2", 0]].freeze }.freeze,
|
|
271
|
+
ROUND_2_SAME_RECTANGLE: { basename: "Round Same Side Corner Rectangle",
|
|
272
|
+
default_adjustments: [["adj1", 16667], ["adj2", 0]].freeze }.freeze,
|
|
273
|
+
SMILEY_FACE: { basename: "Smiley Face", default_adjustments: [["adj", 4653]].freeze }.freeze,
|
|
274
|
+
SNIP_1_RECTANGLE: { basename: "Snip Single Corner Rectangle",
|
|
275
|
+
default_adjustments: [["adj", 16667]].freeze }.freeze,
|
|
276
|
+
SNIP_2_DIAG_RECTANGLE: { basename: "Snip Diagonal Corner Rectangle",
|
|
277
|
+
default_adjustments: [["adj1", 0], ["adj2", 16667]].freeze }.freeze,
|
|
278
|
+
SNIP_2_SAME_RECTANGLE: { basename: "Snip Same Side Corner Rectangle",
|
|
279
|
+
default_adjustments: [["adj1", 16667], ["adj2", 0]].freeze }.freeze,
|
|
280
|
+
SNIP_ROUND_RECTANGLE: { basename: "Snip and Round Single Corner Rectangle",
|
|
281
|
+
default_adjustments: [["adj1", 16667], ["adj2", 16667]].freeze }.freeze,
|
|
282
|
+
SQUARE_TABS: { basename: "Square Tabs", default_adjustments: [].freeze }.freeze,
|
|
283
|
+
STAR_10_POINT: { basename: "10-Point Star",
|
|
284
|
+
default_adjustments: [["adj", 42533], ["hf", 105_146]].freeze }.freeze,
|
|
285
|
+
STAR_12_POINT: { basename: "12-Point Star", default_adjustments: [["adj", 37500]].freeze }.freeze,
|
|
286
|
+
STAR_16_POINT: { basename: "16-Point Star", default_adjustments: [["adj", 37500]].freeze }.freeze,
|
|
287
|
+
STAR_24_POINT: { basename: "24-Point Star", default_adjustments: [["adj", 37500]].freeze }.freeze,
|
|
288
|
+
STAR_32_POINT: { basename: "32-Point Star", default_adjustments: [["adj", 37500]].freeze }.freeze,
|
|
289
|
+
STAR_4_POINT: { basename: "4-Point Star", default_adjustments: [["adj", 12500]].freeze }.freeze,
|
|
290
|
+
STAR_5_POINT: { basename: "5-Point Star",
|
|
291
|
+
default_adjustments: [["adj", 19098], ["hf", 105_146], ["vf", 110_557]].freeze }.freeze,
|
|
292
|
+
STAR_6_POINT: { basename: "6-Point Star",
|
|
293
|
+
default_adjustments: [["adj", 28868], ["hf", 115_470]].freeze }.freeze,
|
|
294
|
+
STAR_7_POINT: { basename: "7-Point Star",
|
|
295
|
+
default_adjustments: [["adj", 34601], ["hf", 102_572], ["vf", 105_210]].freeze }.freeze,
|
|
296
|
+
STAR_8_POINT: { basename: "8-Point Star", default_adjustments: [["adj", 37500]].freeze }.freeze,
|
|
297
|
+
STRIPED_RIGHT_ARROW: { basename: "Striped Right Arrow",
|
|
298
|
+
default_adjustments: [["adj1", 50000], ["adj2", 50000]].freeze }.freeze,
|
|
299
|
+
SUN: { basename: "Sun", default_adjustments: [["adj", 25000]].freeze }.freeze,
|
|
300
|
+
SWOOSH_ARROW: { basename: "Swoosh Arrow",
|
|
301
|
+
default_adjustments: [["adj1", 25000], ["adj2", 16667]].freeze }.freeze,
|
|
302
|
+
TEAR: { basename: "Teardrop", default_adjustments: [["adj", 100_000]].freeze }.freeze,
|
|
303
|
+
TRAPEZOID: { basename: "Trapezoid", default_adjustments: [["adj", 25000]].freeze }.freeze,
|
|
304
|
+
UP_ARROW: { basename: "Up Arrow",
|
|
305
|
+
default_adjustments: [["adj1", 50000], ["adj2", 50000]].freeze }.freeze,
|
|
306
|
+
UP_ARROW_CALLOUT: { basename: "Up Arrow Callout",
|
|
307
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000], ["adj3", 25000],
|
|
308
|
+
["adj4", 64977]].freeze }.freeze,
|
|
309
|
+
UP_DOWN_ARROW: { basename: "Up-Down Arrow",
|
|
310
|
+
default_adjustments: [["adj1", 50000], ["adj1", 50000], ["adj2", 50000],
|
|
311
|
+
["adj2", 50000]].freeze }.freeze,
|
|
312
|
+
UP_DOWN_ARROW_CALLOUT: { basename: "Up-Down Arrow Callout",
|
|
313
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000], ["adj3", 25000],
|
|
314
|
+
["adj4", 48123]].freeze }.freeze,
|
|
315
|
+
UP_RIBBON: { basename: "Up Ribbon",
|
|
316
|
+
default_adjustments: [["adj1", 16667], ["adj2", 50000]].freeze }.freeze,
|
|
317
|
+
U_TURN_ARROW: { basename: "U-Turn Arrow",
|
|
318
|
+
default_adjustments: [["adj1", 25000], ["adj2", 25000], ["adj3", 25000], ["adj4", 43750],
|
|
319
|
+
["adj5", 75000]].freeze }.freeze,
|
|
320
|
+
VERTICAL_SCROLL: { basename: "Vertical Scroll", default_adjustments: [["adj", 12500]].freeze }.freeze,
|
|
321
|
+
WAVE: { basename: "Wave", default_adjustments: [["adj1", 12500], ["adj2", 0]].freeze }.freeze
|
|
322
|
+
}.freeze
|
|
323
|
+
|
|
324
|
+
module_function
|
|
325
|
+
|
|
326
|
+
# @param shape_type [Pptx::Enum::MSO_SHAPE]
|
|
327
|
+
def for(shape_type)
|
|
328
|
+
SPECS.fetch(Enum::MSO_SHAPE.fetch(shape_type).name) do
|
|
329
|
+
raise ArgumentError, "no auto-shape spec for #{shape_type.inspect}"
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def basename(shape_type) = self.for(shape_type)[:basename]
|
|
334
|
+
|
|
335
|
+
def default_adjustments(shape_type) = self.for(shape_type)[:default_adjustments]
|
|
336
|
+
end
|
|
337
|
+
end
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pptx
|
|
4
|
+
# Build a presentation declaratively.
|
|
5
|
+
#
|
|
6
|
+
# This is a thin layer over the ordinary API — every method here is a call
|
|
7
|
+
# the imperative API can make directly — but it keeps position and size out
|
|
8
|
+
# of positional arguments and lets a whole deck read top to bottom:
|
|
9
|
+
#
|
|
10
|
+
# deck = Pptx.build do |d|
|
|
11
|
+
# d.slide("Title Slide") do |s|
|
|
12
|
+
# s.title = "Annual Report"
|
|
13
|
+
# s.subtitle = "Prepared in Ruby"
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# d.section("Detail") do
|
|
17
|
+
# d.slide("Blank") do |s|
|
|
18
|
+
# s.shape :ROUNDED_RECTANGLE, at: [Pptx.inches(1), Pptx.inches(1)],
|
|
19
|
+
# size: [Pptx.inches(3), Pptx.inches(1)],
|
|
20
|
+
# fill: "1F497D", text: "Next steps"
|
|
21
|
+
# end
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# deck.save("out.pptx")
|
|
26
|
+
#
|
|
27
|
+
# @param template [String, IO, nil] a deck to start from; the built-in
|
|
28
|
+
# default template when omitted
|
|
29
|
+
# @return [Presentation]
|
|
30
|
+
def self.build(template = nil)
|
|
31
|
+
presentation = template ? Presentation.open(template) : Presentation.new_default
|
|
32
|
+
yield DeckBuilder.new(presentation) if block_given?
|
|
33
|
+
presentation
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# The object yielded by {Pptx.build}.
|
|
37
|
+
class DeckBuilder
|
|
38
|
+
attr_reader :presentation
|
|
39
|
+
|
|
40
|
+
def initialize(presentation)
|
|
41
|
+
@presentation = presentation
|
|
42
|
+
@current_section = nil
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Add a slide based on +layout+, which may be a layout name, an index, or
|
|
46
|
+
# a {SlideLayout}.
|
|
47
|
+
#
|
|
48
|
+
# @return [Slide]
|
|
49
|
+
def slide(layout = "Title and Content")
|
|
50
|
+
slide_layout = resolve_layout(layout)
|
|
51
|
+
slide = @presentation.slides.add(slide_layout)
|
|
52
|
+
@current_section << slide if @current_section
|
|
53
|
+
yield SlideBuilder.new(slide) if block_given?
|
|
54
|
+
slide
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Group the slides added inside the block into a named section.
|
|
58
|
+
#
|
|
59
|
+
# @return [Section]
|
|
60
|
+
def section(name)
|
|
61
|
+
previous = @current_section
|
|
62
|
+
@current_section = @presentation.sections.add(name)
|
|
63
|
+
begin
|
|
64
|
+
yield if block_given?
|
|
65
|
+
@current_section
|
|
66
|
+
ensure
|
|
67
|
+
@current_section = previous
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Set the slide size, e.g. `deck.slide_size = :widescreen`.
|
|
72
|
+
#
|
|
73
|
+
# Accepts `:widescreen` (13.333 x 7.5in), `:standard` (10 x 7.5in), or an
|
|
74
|
+
# explicit [width, height] pair.
|
|
75
|
+
def slide_size=(value)
|
|
76
|
+
width, height =
|
|
77
|
+
case value
|
|
78
|
+
when :widescreen then [Pptx.inches(13.333), Pptx.inches(7.5)]
|
|
79
|
+
when :standard then [Pptx.inches(10), Pptx.inches(7.5)]
|
|
80
|
+
else value
|
|
81
|
+
end
|
|
82
|
+
@presentation.slide_width = width
|
|
83
|
+
@presentation.slide_height = height
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def resolve_layout(layout)
|
|
89
|
+
return layout if layout.is_a?(SlideLayout)
|
|
90
|
+
|
|
91
|
+
@presentation.slide_layouts[layout] ||
|
|
92
|
+
raise(NotFoundError, "no slide layout #{layout.inspect}")
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# The object yielded by {DeckBuilder#slide}.
|
|
97
|
+
class SlideBuilder
|
|
98
|
+
attr_reader :slide
|
|
99
|
+
|
|
100
|
+
def initialize(slide)
|
|
101
|
+
@slide = slide
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# The title placeholder's text.
|
|
105
|
+
def title=(text)
|
|
106
|
+
placeholder = @slide.shapes.title or
|
|
107
|
+
raise NotFoundError, "this slide's layout has no title placeholder"
|
|
108
|
+
|
|
109
|
+
placeholder.text = text
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# The text of the placeholder with `idx` 1, which is the body on a content
|
|
113
|
+
# layout and the subtitle on a title layout.
|
|
114
|
+
def body=(text)
|
|
115
|
+
self[1] = text
|
|
116
|
+
end
|
|
117
|
+
alias subtitle= body=
|
|
118
|
+
|
|
119
|
+
# Set the text of the placeholder with the given `idx`.
|
|
120
|
+
def []=(idx, text)
|
|
121
|
+
placeholder = @slide.placeholders[idx] or
|
|
122
|
+
raise NotFoundError, "this slide has no placeholder with idx #{idx}"
|
|
123
|
+
|
|
124
|
+
placeholder.text = text
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Add a text box.
|
|
128
|
+
#
|
|
129
|
+
# @return [Shape]
|
|
130
|
+
def text(content, at:, size: nil, font_size: nil, bold: nil, italic: nil,
|
|
131
|
+
color: nil, font: nil, align: nil)
|
|
132
|
+
box = @slide.shapes.add_textbox(at: at, size: size || [Pptx.inches(4), Pptx.inches(1)])
|
|
133
|
+
box.text_frame.text = content
|
|
134
|
+
style_text(box.text_frame, font_size: font_size, bold: bold, italic: italic,
|
|
135
|
+
color: color, font: font, align: align)
|
|
136
|
+
box
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Add an auto shape.
|
|
140
|
+
#
|
|
141
|
+
# @return [Shape]
|
|
142
|
+
def shape(shape_type, at:, size:, fill: nil, line: nil, text: nil, **text_options)
|
|
143
|
+
auto_shape = @slide.shapes.add_shape(shape_type, at: at, size: size)
|
|
144
|
+
apply_fill(auto_shape, fill)
|
|
145
|
+
apply_line(auto_shape, line)
|
|
146
|
+
if text
|
|
147
|
+
auto_shape.text_frame.text = text
|
|
148
|
+
style_text(auto_shape.text_frame, **text_options)
|
|
149
|
+
end
|
|
150
|
+
auto_shape
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Add a picture. Omit +size+ for the image's native size, or give one
|
|
154
|
+
# dimension to scale the other with it.
|
|
155
|
+
#
|
|
156
|
+
# @return [Picture]
|
|
157
|
+
def picture(image, at:, width: nil, height: nil)
|
|
158
|
+
@slide.shapes.add_picture(image, at: at, width: width, height: height)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Add a table filled from +rows+, an array of arrays.
|
|
162
|
+
#
|
|
163
|
+
# @return [Table]
|
|
164
|
+
def table(rows, at:, size:, header: true)
|
|
165
|
+
rows = rows.to_a
|
|
166
|
+
raise ArgumentError, "table needs at least one row" if rows.empty?
|
|
167
|
+
|
|
168
|
+
columns = rows.map(&:size).max
|
|
169
|
+
frame = @slide.shapes.add_table(rows.size, columns, at: at, size: size)
|
|
170
|
+
table = frame.table
|
|
171
|
+
table.first_row = header
|
|
172
|
+
rows.each_with_index do |row, row_index|
|
|
173
|
+
row.each_with_index { |value, col| table.cell(row_index, col).text = value.to_s }
|
|
174
|
+
end
|
|
175
|
+
table
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Add a chart.
|
|
179
|
+
#
|
|
180
|
+
# s.chart :COLUMN_CLUSTERED, categories: %w[East West],
|
|
181
|
+
# series: { "Q1" => [1, 2] },
|
|
182
|
+
# at: [x, y], size: [w, h]
|
|
183
|
+
#
|
|
184
|
+
# @return [Chart]
|
|
185
|
+
def chart(chart_type, categories:, series:, at:, size:)
|
|
186
|
+
data = ChartData.new
|
|
187
|
+
data.categories = categories
|
|
188
|
+
series.each { |name, values| data.add_series(name, values) }
|
|
189
|
+
@slide.shapes.add_chart(chart_type, data, at: at, size: size).chart
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
private
|
|
193
|
+
|
|
194
|
+
def style_text(text_frame, font_size: nil, bold: nil, italic: nil,
|
|
195
|
+
color: nil, font: nil, align: nil)
|
|
196
|
+
paragraph = text_frame.paragraphs.first
|
|
197
|
+
paragraph.alignment = align if align
|
|
198
|
+
# Apply to every run so a multi-run value styles consistently.
|
|
199
|
+
runs = text_frame.paragraphs.flat_map(&:runs)
|
|
200
|
+
runs.each do |run|
|
|
201
|
+
run.font.size = font_size if font_size
|
|
202
|
+
run.font.bold = bold unless bold.nil?
|
|
203
|
+
run.font.italic = italic unless italic.nil?
|
|
204
|
+
run.font.name = font if font
|
|
205
|
+
run.font.color.rgb = rgb(color) if color
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def apply_fill(shape, fill)
|
|
210
|
+
return if fill.nil?
|
|
211
|
+
return shape.fill.background if fill == :none
|
|
212
|
+
|
|
213
|
+
shape.fill.solid
|
|
214
|
+
shape.fill.fore_color.rgb = rgb(fill)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def apply_line(shape, line)
|
|
218
|
+
return if line.nil?
|
|
219
|
+
|
|
220
|
+
color, width = line.is_a?(Hash) ? [line[:color], line[:width]] : [line, nil]
|
|
221
|
+
shape.line.color.rgb = rgb(color) if color
|
|
222
|
+
shape.line.width = width if width
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# A colour may be given as an RGBColor or as a hex string.
|
|
226
|
+
def rgb(value) = value.is_a?(RGBColor) ? value : RGBColor.from_string(value)
|
|
227
|
+
end
|
|
228
|
+
end
|