pptx/slide-with-subtitle

A title slide carries a subtitle placeholder shape whose text body contains subtitle text below the title.

Library verdicts: python-pptx: — pptxjs: fail

Metadata

Feature idpptx/slide-with-subtitle
Formatpptx
Categoryslide-content
Spececma-376-5-part-1 § 19.3.1.36 p:ph

XPath assertions

ID / partPredicateXPathpython-pptxpptxjs
subtitle-placeholder-text-present
ppt/slides/slide1.xml
exist
A shape marked as a subTitle placeholder must carry a text run whose value is 'A subtitle appears below the title'.
//p:sp[p:nvSpPr/p:nvPr/p:ph[@type='subTitle']]//a:t[normalize-space()='A subtitle appears below the title']
subtitle-placeholder-type
ppt/slides/slide1.xml
equal = subTitle
The placeholder carrying the subtitle text must declare type='subTitle'.
//p:sp[.//a:t[normalize-space()='A subtitle appears below the title']]/p:nvSpPr/p:nvPr/p:ph/@type

Render assertions

IDPredicateSelectorpython-pptxpptxjs
slide-subtitle-text-presentcss_selector/ match-text = A subtitle appears below the title
A DOM node marked as a subTitle placeholder (via data-placeholder-type or a .pptx-subtitle class) must contain the subtitle text. Falls back to h2 for renderers that use semantic HTML for subtitles.
[data-placeholder-type='subTitle'], .pptx-subtitle, h2fail
slide-countcss_selector/ equal-count
Exactly one slide container must be rendered. Catches renderers that emit zero slides (hard failure) or duplicate the slide.
section.pptx-slide, .pptx-slide, section[data-slide], .slide, [data-slide]
slide-has-landmark-a11ycss_selector/ exist
Accessibility: a slide should surface as a landmark for screen readers — either with a landmark role (region/article/group), or hooked to the title/subtitle via aria-labelledby, or named with aria-label. Accepts any of these; a renderer that emits the slide as a plain <div> with no ARIA hook fails this assertion.
[role='region'], [role='article'], [role='group'], [aria-labelledby], [aria-label], section[aria-label], section[aria-labelledby], .pptx-slide[aria-label], .pptx-slide[aria-labelledby], [data-slide-index][aria-label], [data-slide-index][aria-labelledby]

Generator source

scripts/gen_slide_with_subtitle.py

#!/usr/bin/env python3
"""Generate ``fixtures/pptx/slide-with-subtitle.pptx``.

A minimal one-slide presentation exercising the ``p:ph type="subTitle"``
subtitle placeholder on the title-slide layout. Designed to satisfy the
assertions in ``features/pptx/slide-with-subtitle.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" / "slide-with-subtitle.pptx"


def main() -> int:
    prs = Presentation()
    # slide_layouts[0] is the title + subtitle layout.
    slide = prs.slides.add_slide(prs.slide_layouts[0])
    slide.shapes.title.text = "Title with subtitle"
    slide.placeholders[1].text = "A subtitle appears below the title"
    _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())

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "pptx/slide-with-subtitle",
  "title": "Slide subtitle placeholder",
  "format": "pptx",
  "category": "slide-content",
  "summary": "A title slide carries a subtitle placeholder shape whose text body contains subtitle text below the title.",
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "19.3.1.36",
    "element": "p:ph",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/PresentationML.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/pml.xsd",
    "notes": "PowerPoint marks a subtitle placeholder with <p:ph type=\"subTitle\"/> on the title-slide layout (slide_layouts[0]). Text lives in the <p:txBody>/<a:p>/<a:r>/<a:t> chain on the same <p:sp>."
  },
  "fixtures": {
    "machine": "pptx/slide-with-subtitle",
    "office": "pptx/slide-with-subtitle"
  },
  "generator": {
    "python": "scripts/gen_slide_with_subtitle.py"
  },
  "assertions": [
    {
      "id": "subtitle-placeholder-text-present",
      "part": "ppt/slides/slide1.xml",
      "namespaces": {
        "p": "http://schemas.openxmlformats.org/presentationml/2006/main",
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//p:sp[p:nvSpPr/p:nvPr/p:ph[@type='subTitle']]//a:t[normalize-space()='A subtitle appears below the title']",
      "must": "exist",
      "description": "A shape marked as a subTitle placeholder must carry a text run whose value is 'A subtitle appears below the title'."
    },
    {
      "id": "subtitle-placeholder-type",
      "part": "ppt/slides/slide1.xml",
      "namespaces": {
        "p": "http://schemas.openxmlformats.org/presentationml/2006/main",
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main"
      },
      "xpath": "//p:sp[.//a:t[normalize-space()='A subtitle appears below the title']]/p:nvSpPr/p:nvPr/p:ph/@type",
      "must": "equal",
      "value": "subTitle",
      "description": "The placeholder carrying the subtitle text must declare type='subTitle'."
    }
  ],
  "render_assertions": [
    {
      "id": "slide-subtitle-text-present",
      "kind": "css_selector",
      "selector": "[data-placeholder-type='subTitle'], .pptx-subtitle, h2",
      "must": "match-text",
      "value": "A subtitle appears below the title",
      "description": "A DOM node marked as a subTitle placeholder (via data-placeholder-type or a .pptx-subtitle class) must contain the subtitle text. Falls back to h2 for renderers that use semantic HTML for subtitles."
    },
    {
      "id": "slide-count",
      "kind": "css_selector",
      "selector": "section.pptx-slide, .pptx-slide, section[data-slide], .slide, [data-slide]",
      "must": "equal-count",
      "count": 1,
      "description": "Exactly one slide container must be rendered. Catches renderers that emit zero slides (hard failure) or duplicate the slide."
    },
    {
      "id": "slide-has-landmark-a11y",
      "kind": "css_selector",
      "selector": "[role='region'], [role='article'], [role='group'], [aria-labelledby], [aria-label], section[aria-label], section[aria-labelledby], .pptx-slide[aria-label], .pptx-slide[aria-labelledby], [data-slide-index][aria-label], [data-slide-index][aria-labelledby]",
      "must": "exist",
      "description": "Accessibility: a slide should surface as a landmark for screen readers — either with a landmark role (region/article/group), or hooked to the title/subtitle via aria-labelledby, or named with aria-label. Accepts any of these; a renderer that emits the slide as a plain <div> with no ARIA hook fails this assertion."
    }
  ]
}

Fixture

Download slide-with-subtitle.pptx (27.5 KB)

Reference preview

Reference (machine, page 1 PNG)

pptx/slide-with-subtitle page 1 reference

Reference PDF


Download PDF Open in PDF.js

Spec notes

PowerPoint marks a subtitle placeholder with <p:ph type="subTitle"/> on the title-slide layout (slide_layouts[0]). Text lives in the <p:txBody>/<a:p>/<a:r>/<a:t> chain on the same <p:sp>.