Add a transition to a slide in a presentation

Slide transitions are stored on the slide that appears after the transition. The transition markup is a child of the slide root.

Transition markup

<p:sld xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
  <p:cSld>
    <p:spTree>
      <p:nvGrpSpPr>
        <p:cNvPr id="1" name=""/>
        <p:cNvGrpSpPr/>
        <p:nvPr/>
      </p:nvGrpSpPr>
      <p:grpSpPr/>
    </p:spTree>
  </p:cSld>
  <p:transition spd="fast">
    <p:fade/>
  </p:transition>
</p:sld>

The transition element can specify speed, advance timing, sound, and transition-specific child elements such as fade or push.

Important attributes include:

AttributeMeaning
advClickWhether a mouse click advances the slide. If omitted, the default is true.
advTmAuto-advance time in milliseconds. If omitted, no auto-advance time is set.
spdTransition speed, commonly slow, med, or fast.

For example, a random-bar transition can advance after three seconds:

<p:transition spd="slow" advClick="1" advTm="3000">
  <p:randomBar dir="horz"/>
</p:transition>

Markup compatibility

Some transition features are stored with newer Office namespaces. For example, PowerPoint 2010 introduced a transition duration attribute in the p14 namespace. A compatible package can wrap that richer transition in mc:AlternateContent, with a fallback transition that omits the newer attribute.

When documenting a writer for this page, include both the richer choice and a fallback only after the fixture proves that ooxmlsdk preserves or processes the compatibility markup correctly for the selected feature flags.

Rust workflow

#![allow(unused)]
fn main() {
pub fn add_fade_transition(
  path: &Path,
  slide_index: usize,
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
  let mut document = PresentationDocument::new_from_file_with_settings(path, lazy_settings())?;
  let presentation_part = document.presentation_part()?;
  let Some(slide_part) = presentation_part.slide_parts(&document).nth(slide_index) else {
    return Err(format!("slide index {slide_index} not found").into());
  };
  let xml = slide_part.data_as_str(&document)?.unwrap_or_default();
  let updated_xml =
    replace_or_insert_transition(xml, r#"<p:transition spd="fast"><p:fade/></p:transition>"#)?;

  slide_part.set_data(&mut document, updated_xml.into_bytes())?;

  let mut buffer = Cursor::new(Vec::new());
  document.save(&mut buffer)?;
  Ok(buffer.into_inner())
}
}

The listing inserts or replaces only the <p:transition/> element and preserves the rest of the slide XML. For richer Office-version-specific transition markup, include a compatibility fallback and test the selected mce behavior.