A presentation with three slides — each carries its own title — registered under p:sldIdLst in ppt/presentation.xml and emitted as slide1.xml, slide2.xml, slide3.xml.
Library verdicts: python-pptx: — pptxjs: pass
| Feature id | pptx/multiple-slides |
|---|---|
| Format | pptx |
| Category | slide-content |
| Spec | ecma-376-5-part-1 § 19.3.1 p:sldIdLst |
| ID / part | Predicate | XPath | python-pptx | pptxjs |
|---|---|---|---|---|
slide1-title-presentppt/slides/slide1.xml | existSlide 1 must carry the text 'Slide one title'. | //a:t[normalize-space()='Slide one title'] | — | — |
slide2-title-presentppt/slides/slide2.xml | existSlide 2 must carry the text 'Slide two title'. | //a:t[normalize-space()='Slide two title'] | — | — |
slide3-title-presentppt/slides/slide3.xml | existSlide 3 must carry the text 'Slide three title'. | //a:t[normalize-space()='Slide three title'] | — | — |
| ID | Predicate | Selector | python-pptx | pptxjs |
|---|---|---|---|---|
multiple-slides-three-slide-nodes | css_selector/ equal-countThe renderer must emit exactly three slide container nodes. | .slide, [data-slide], section[data-slide], section.slide, .pptx-slide | — | pass |
multiple-slides-title-one-visible | css_selector/ match-text = Slide one titleThe first rendered slide must carry the text 'Slide one title'. Fallback text-match in case the count assertion passes but slide ordering is unclear. | .slide, [data-slide], section[data-slide], section.slide, .pptx-slide | — | pass |
scripts/gen_multiple_slides.py
#!/usr/bin/env python3
"""Generate ``fixtures/pptx/multiple-slides.pptx``.
A three-slide presentation — each slide carries its own title —
exercising the presentation-level <p:sldIdLst> and the slideN.xml
part-name convention. Designed to satisfy the assertions in
``features/pptx/multiple-slides.json``.
"""
from __future__ import annotations
from pathlib import Path
from pptx import Presentation
import datetime as _dt
_REPRODUCIBLE_DT = _dt.datetime(2000, 1, 1, 0, 0, 0)
_REPO_ROOT = Path(__file__).resolve().parent.parent
_OUT = _REPO_ROOT / "fixtures" / "pptx" / "multiple-slides.pptx"
def main() -> int:
prs = Presentation()
# slide_layouts[5] is the "title only" layout — a title placeholder and
# nothing else. Each slide here uses it so the asserted title text is
# the only non-boilerplate content we add.
for text in ("Slide one title", "Slide two title", "Slide three title"):
slide = prs.slides.add_slide(prs.slide_layouts[5])
slide.shapes.title.text = text
_OUT.parent.mkdir(parents=True, exist_ok=True)
prs.save(_OUT, zip_date_time=_REPRODUCIBLE_DT)
print(_OUT)
return 0
if __name__ == "__main__":
raise SystemExit(main()){
"$schema": "../manifest.schema.json",
"id": "pptx/multiple-slides",
"title": "Presentation with multiple slides",
"format": "pptx",
"category": "slide-content",
"summary": "A presentation with three slides — each carries its own title — registered under p:sldIdLst in ppt/presentation.xml and emitted as slide1.xml, slide2.xml, slide3.xml.",
"spec": {
"source": "ecma-376-5-part-1",
"clause": "19.3.1",
"element": "p:sldIdLst",
"rnc_reference": "spec/ecma-376-5/part-1/rnc/PresentationML.rnc",
"xsd_reference": "spec/ecma-376-5/part-1/xsd/pml.xsd",
"notes": "python-pptx registers each slide added via slides.add_slide() as a <p:sldId> under <p:sldIdLst> in ppt/presentation.xml, and writes each slide's body as ppt/slides/slideN.xml. The manifest asserts one title per slide-part rather than a count on sldIdLst, since the XPath assertion vocabulary doesn't include equal-count."
},
"fixtures": {
"machine": "pptx/multiple-slides",
"office": "pptx/multiple-slides"
},
"generator": {
"python": "scripts/gen_multiple_slides.py"
},
"assertions": [
{
"id": "slide1-title-present",
"part": "ppt/slides/slide1.xml",
"namespaces": {
"p": "http://schemas.openxmlformats.org/presentationml/2006/main",
"a": "http://schemas.openxmlformats.org/drawingml/2006/main"
},
"xpath": "//a:t[normalize-space()='Slide one title']",
"must": "exist",
"description": "Slide 1 must carry the text 'Slide one title'."
},
{
"id": "slide2-title-present",
"part": "ppt/slides/slide2.xml",
"namespaces": {
"p": "http://schemas.openxmlformats.org/presentationml/2006/main",
"a": "http://schemas.openxmlformats.org/drawingml/2006/main"
},
"xpath": "//a:t[normalize-space()='Slide two title']",
"must": "exist",
"description": "Slide 2 must carry the text 'Slide two title'."
},
{
"id": "slide3-title-present",
"part": "ppt/slides/slide3.xml",
"namespaces": {
"p": "http://schemas.openxmlformats.org/presentationml/2006/main",
"a": "http://schemas.openxmlformats.org/drawingml/2006/main"
},
"xpath": "//a:t[normalize-space()='Slide three title']",
"must": "exist",
"description": "Slide 3 must carry the text 'Slide three title'."
}
],
"render_assertions": [
{
"id": "multiple-slides-three-slide-nodes",
"kind": "css_selector",
"selector": ".slide, [data-slide], section[data-slide], section.slide, .pptx-slide",
"must": "equal-count",
"count": 3,
"description": "The renderer must emit exactly three slide container nodes."
},
{
"id": "multiple-slides-title-one-visible",
"kind": "css_selector",
"selector": ".slide, [data-slide], section[data-slide], section.slide, .pptx-slide",
"must": "match-text",
"value": "Slide one title",
"description": "The first rendered slide must carry the text 'Slide one title'. Fallback text-match in case the count assertion passes but slide ordering is unclear."
}
]
}
