返回 ppt-master
pptx-transitions.md
根目录 / skills / ppt-master / scripts / docs / pptx-transitions.md
1 # PPTX Transition Core
2
3 The shared transition core owns page-transition vocabulary, slide-advance
4 semantics, OOXML mutation, MCE preservation, package timing enablement, and
5 read-back validation for every PPTX route.
6
7 ## 1. Ownership
8
9 | Concern | Owner |
10 |---|---|
11 | Page transition registry | scripts/pptx_transitions.py |
12 | In-slide object animation | scripts/pptx_animations.py |
13 | Generated PPTX adapter | svg_to_pptx/pptx_package/builder.py |
14 | Template Fill adapter | template_fill_pptx/transitions.py |
15 | Native Enhance adapter | native_enhance_pptx_core.py |
16 | Public workflow | references/animations.md |
17
18 **Hard rule**: adapters resolve route policy, then call the shared core. They
19 must not build, replace, or patch a transition with route-local XML or regex.
20
21 ---
22
23 ## 2. Domain Model
24
25 | Layer | Meaning | OOXML |
26 |---|---|---|
27 | Enter | How the current slide appears from the preceding slide | Native effect, Effect Options, and duration |
28 | Sound | Optional cue played with the current slide's transition | `p:sndAc/p:stSnd/p:snd` with an embedded WAV relationship |
29 | Advance | How the current slide leaves for the next slide | advClick and advTm |
30
31 Enter policy:
32
33 | Policy | Behavior |
34 |---|---|
35 | preserve | Keep the source visual transition, including unknown extensions |
36 | replace | Write the requested supported effect |
37 | none | Write no visual effect |
38
39 Advance mode:
40
41 | Mode | Behavior |
42 |---|---|
43 | preserve | Keep source advClick and advTm |
44 | click | Click advance only |
45 | after | Timed advance only |
46 | both | Click or timed advance, whichever occurs first |
47 | narration | Timed advance from narration lead-in, audio duration, and page-tail padding; click disabled |
48
49 **Hard rule**: enter=none may coexist with a sound and/or timed advance. The
50 valid result is a non-visual `p:transition` with `p:sndAc`, advance attributes,
51 or both, and no visual-effect child.
52
53 ---
54
55 ## 3. Compatibility Contract
56
57 The native registry covers the complete current PowerPoint transition gallery:
58 12 Subtle effects, 29 Exciting effects, and 7 Dynamic Content effects. New
59 selection, sidecars, plans, conversion traces, help, and writers use only these
60 48 native keys.
61
62 Eight established low-level names remain valid at input boundaries. They
63 normalize to one native effect plus native `effect_options`; they are not a
64 second transition registry:
65
66 | Compatibility input | Native request |
67 |---|---|
68 | `strips` | `wipe` with `direction: right` |
69 | `circle` | `shape` with `shape: circle` |
70 | `diamond` | `shape` with `shape: diamond` |
71 | `plus` | `shape` with `shape: plus` |
72 | `newsflash` | `flash` |
73 | `pull` | `uncover` |
74 | `wedge` | `clock` with `style: wedge` |
75 | `wheel` | `clock` with `style: clockwise` |
76
77 Standard PresentationML effects use a direct `p:transition` carrier:
78
79 | Effect | Required primary child and attributes |
80 |---|---|
81 | fade | p:fade |
82 | push | p:push dir=r |
83 | wipe | p:wipe dir=r |
84 | split | p:split |
85 | cut | p:cut |
86 | random_bars | p:randomBar dir=vert |
87 | shape | p:circle |
88 | uncover | p:pull dir=r |
89 | cover | p:cover dir=r |
90 | dissolve | p:dissolve |
91 | checkerboard | p:checker |
92 | blinds | p:blinds dir=vert |
93 | clock | p:wheel spokes=1 |
94 | random | p:random |
95 | box | p:zoom |
96 | comb | p:comb |
97
98 Office 2010 effects use a `p14` Choice with a `p:fade` Fallback:
99
100 | Effect | Required primary child and attributes |
101 |---|---|
102 | reveal | p14:reveal dir=r |
103 | flash | p14:flash |
104 | ripple | p14:ripple |
105 | honeycomb | p14:honeycomb |
106 | glitter | p14:glitter |
107 | vortex | p14:vortex dir=r |
108 | shred | p14:shred dir=out |
109 | switch | p14:switch dir=r |
110 | flip | p14:flip dir=r |
111 | gallery | p14:gallery dir=r |
112 | cube | p14:prism dir=r |
113 | doors | p14:doors dir=vert |
114 | zoom | p14:warp dir=in |
115 | pan | p14:pan dir=r |
116 | ferris_wheel | p14:ferris dir=r |
117 | conveyor | p14:conveyor dir=r |
118 | rotate | p14:prism dir=r isContent=1 |
119 | window | p14:window |
120 | orbit | p14:prism dir=r isContent=1 isInverted=1 |
121 | fly_through | p14:flythrough |
122
123 Office 2012 effects use a `p15` Choice with a `p:fade` Fallback:
124
125 | Effect | Required primary child and attributes |
126 |---|---|
127 | fall_over | p15:prstTrans prst=fallOver invX=1 |
128 | drape | p15:prstTrans prst=drape invX=1 |
129 | curtains | p15:prstTrans prst=curtains |
130 | wind | p15:prstTrans prst=wind |
131 | prestige | p15:prstTrans prst=prestige |
132 | fracture | p15:prstTrans prst=fracture |
133 | crush | p15:prstTrans prst=crush |
134 | peel_off | p15:prstTrans prst=peelOff invX=1 |
135 | page_curl | p15:prstTrans prst=pageCurlSingle invX=1 |
136 | airplane | p15:prstTrans prst=airplane |
137 | origami | p15:prstTrans prst=origami |
138
139 `morph` uses `p159:morph option=byObject` in an Office 2015 Choice with a
140 `p:fade` Fallback. `none` is the explicit no-visual-effect input and therefore
141 is not a registry entry.
142
143 ### 3.1 Native Effect Options
144
145 Use `effect_options` only with an explicit native `effect`. Omitted options use
146 the PowerPoint-authored `default` reported by `--describe-transition`:
147
148 | Effect | Supported options |
149 |---|---|
150 | `morph` | `morph_by`: `object`, `word`, `character` |
151 | `fade` | `style`: `smoothly`, `through_black` |
152 | `push`, `wipe`, `vortex`, `cube`, `pan`, `rotate`, `orbit` | `direction`: `left`, `right`, `up`, `down` |
153 | `split` | `orientation`: `horizontal`, `vertical`; `direction`: `out`, `in` |
154 | `reveal` | `direction`: `right`, `left`; `through_black`: boolean |
155 | `cut` | `through_black`: boolean |
156 | `random_bars`, `blinds`, `doors` | `orientation`: `vertical`, `horizontal` |
157 | `checkerboard` | `direction`: `across`, `down` |
158 | `comb`, `window` | `orientation`: `horizontal`, `vertical` |
159 | `shape` | `shape`: `circle`, `diamond`, `plus` |
160 | `uncover`, `cover` | `direction`: `left`, `right`, `up`, `down`, `up_left`, `up_right`, `down_left`, `down_right` |
161 | `fall_over`, `drape`, `wind`, `peel_off`, `airplane`, `origami` | `direction`: `right`, `left` |
162 | `page_curl` | `direction`: `right`, `left`; `pages`: `single`, `double` |
163 | `clock` | `style`: `clockwise`, `counterclockwise`, `wedge` |
164 | `ripple` | `origin`: `center`, `up_left`, `up_right`, `down_left`, `down_right` |
165 | `glitter` | `shape`: `diamond`, `hexagon`; `direction`: `right`, `left`, `up`, `down` |
166 | `shred` | `pattern`: `strips`, `rectangle`; `direction`: `out`, `in` |
167 | `switch`, `flip`, `gallery`, `ferris_wheel`, `conveyor` | `direction`: `right`, `left` |
168 | `box`, `zoom` | `direction`: `out`, `in` |
169 | `fly_through` | `direction`: `in`, `out`; `bounce`: boolean |
170 | All other native effects | No Effect Options |
171
172 Example:
173
174 ~~~json
175 {
176 "transition": {
177 "effect": "page_curl",
178 "effect_options": {
179 "direction": "left",
180 "pages": "double"
181 },
182 "duration": 0.6,
183 "sound": "sounds/bigsoundbank/<file>.wav"
184 }
185 }
186 ~~~
187
188 `transition.sound` is optional and accepts a `.wav` path resolved by the
189 generated-project adapter. A bundled-library choice is synced on demand only
190 after the visual transition plan is complete, then referenced by its
191 project-relative `sounds/<namespace>/<file>.wav` path. The adapter packages the
192 file and passes the shared core an embedded relationship id/name; the core
193 never reads `templates/sounds/` or resolves library ids.
194
195 Inspect the exact contract, including compatibility desugaring:
196
197 ~~~bash
198 python3 skills/ppt-master/scripts/pptx_animations.py --describe-transition page_curl
199 python3 skills/ppt-master/scripts/pptx_animations.py --describe-transition diamond
200 ~~~
201
202 Read-back reports the canonical native effect, its complete effective options,
203 the raw OOXML child, and raw attributes. This makes option loss a validation
204 failure rather than a silent downgrade.
205
206 **Hard rule — no downgrade**:
207
208 - Never rename or remove an established effect.
209 - Never omit its established direction or split attributes.
210 - Reject an unknown requested effect; never substitute fade.
211 - Preserve an unknown source effect when the route selects preserve.
212 - An extension counts as successful only when the primary Choice contains the
213 requested effect. A fallback alone is not success.
214
215 ### 3.2 Deterministic Morph Identity
216
217 The generated route may add an explicit `slides.<destination>.morph` block to
218 bind direct-root SVG groups across adjacent slides. The sidecar stable key is
219 lowered to the same top-level `p:cNvPr@name="!!<key>"` on both final
220 Slide-local objects. This does not create an Animation Pane row and does not
221 change either object's numeric shape id.
222
223 The full plan is resolved before any SVG conversion so a source group named by
224 the following slide remains a stable top-level target. Names are written only
225 after flat/structured/preserve processing has finished; structured slide-shape
226 roster expectations are then refreshed. Package read-back requires:
227
228 - the declared source to be the immediately preceding public slide;
229 - exactly one `!!<key>` object on each side;
230 - the same OOXML object container type on both sides;
231 - Morph by object on the destination; and
232 - no structural target, same-slide name collision, group/key conflict, or
233 undeclared shared `!!` name on a Morph edge.
234
235 Morph without an explicit pair block retains PowerPoint's automatic matching
236 behavior. Explicit pairing is generated-route authoring; direct-PPTX routes
237 continue to preserve existing object names and transition XML.
238
239 ---
240
241 ## 4. Route Mapping
242
243 | Route | Default enter | Default advance | Compatibility note |
244 |---|---|---|---|
245 | Generated PPTX CLI | fade, 0.4s; no sound | click | auto-advance maps to both; an optional sidecar sound is project-local |
246 | Recorded narration | Preserve resolved enter | narration | none remains visually none |
247 | Template Fill | preserve source | preserve source | explicit effects replace; legacy advance_after maps to both |
248 | Native Enhance | Confirmed global/per-slide plan effect | Confirmed timing module | With audio off, an enabled global transition or explicit global `none` applies to all pages; with audio on, the scope flag controls non-narrated pages |
249
250 Template Fill changes source transitions only when its CLI or per-slide plan
251 selects a replacement, removal, or timed advance. Native Enhance uses its
252 confirmed plan. The public `create_pptx_with_native_svg` Python API retains its
253 legacy 0.5s default; the generated-deck CLI explicitly passes 0.4s.
254
255 ---
256
257 ## 5. OOXML Rules
258
259 **Slide child order**:
260
261 ~~~text
262 p:cSld
263 p:clrMapOvr
264 p:transition or transition mc:AlternateContent
265 p:timing
266 p:extLst
267 ~~~
268
269 One slide may contain at most one logical transition carrier:
270
271 - one direct p:transition; or
272 - one root-level mc:AlternateContent whose Choice/Fallback branches contain
273 p:transition.
274
275 Mutation rules:
276
277 | Operation | Direct transition | AlternateContent |
278 |---|---|---|
279 | preserve | Leave unchanged | Leave wrapper and branches unchanged |
280 | advance-only | Patch direct attributes | Patch Choice and Fallback identically |
281 | replace | Replace the direct carrier | Remove the whole wrapper, then write one carrier |
282 | none | Remove visual effect; retain a non-visual carrier when sound or timing is needed | Remove the whole wrapper; write a non-visual carrier when sound or timing is needed |
283
284 **Sound placement**: for a direct transition, append `p:sndAc` inside
285 `p:transition` after the visual-effect child, when present. For
286 `mc:AlternateContent`, write the same sound action into both Choice and
287 Fallback transition carriers so older Office consumers do not lose the cue.
288 The slide relationship targets one packaged WAV part; replacing or removing a
289 requested generated sound must not leave a dangling relationship.
290
291 **MCE prefix rule**: Requires and Ignorable values contain textual prefix
292 names. Serialization must retain bindings for those exact names. Renaming an
293 effect prefix without updating these attributes corrupts compatibility.
294
295 **Package timing rule**: when a route writes advTm, set
296 ppt/presProps.xml p:presentationPr/p:showPr useTimings=1. Do not write showPr
297 into ppt/presentation.xml.
298
299 ---
300
301 ## 6. Validation and Read-Back
302
303 Reject:
304
305 - unknown effect names;
306 - options without an explicit native effect;
307 - unknown option fields or values for the selected effect;
308 - non-finite values, including NaN and Infinity;
309 - duration less than or equal to zero;
310 - a missing/non-file transition sound, a non-WAV transition sound, or an
311 unresolved/dangling sound relationship;
312 - negative advance or narration padding;
313 - booleans passed as numeric API values;
314 - multiple logical transition carriers;
315 - unresolved MCE Requires or Ignorable prefixes.
316 - invalid forced-Morph adjacency, identity uniqueness, object type, or
317 destination effect.
318
319 Read-back must report the canonical native effect and complete effective
320 options, while keeping the primary Choice child separate from the fallback. It
321 must also report raw effect attributes, carrier type, duration, click mode, and
322 automatic advance time, plus the transition sound relationship/name when
323 present. Package validation must run after writing, not only before mutation.
324
325 Use inline smoke commands and gitignored projects/_smoke_* artifacts. Do not
326 add a tests directory or test_*.py files.
327
327 lines MARKDOWN