Skip to content

[Epic] Accessibility (a11y) — alt text, decorative flag, reading order #22

@MHoroszowski

Description

@MHoroszowski

Problem

Accessibility is the lowest-hanging fork-leverage fruit for enterprise / government adoption. Section 508 / WCAG / ADA compliance requires alt text on every non-decorative shape. Today: descr= and title= attributes on <p:cNvPr> round-trip on read for pictures only, but no public Shape.alt_text getter/setter exists across the broader shape hierarchy. The "Mark as decorative" flag (Office 2019+) is unsupported. Reading order — which screen-readers depend on for slide narration — has no API. Issue scanny/python-pptx#508 covers alt text for ALL objects, and there is a clean shortlist-labeled PR sitting open (scanny/python-pptx#911 by pa-t, with scanny himself flagging it shortlist). This is the canonical quick-win epic.

Sub-features

  • Shape.alt_text getter+setter writing to <p:cNvPr descr=> (read existing data; create attribute if missing)
  • Shape.alt_title getter+setter for <p:cNvPr title=> (separate from descr per Microsoft accessibility guidance)
  • Shape.is_decorative boolean — emits <adec:decorative val="1"/> in <a:extLst> (Office 2019+)
  • Reading-order API: Slide.shapes.reading_order returns iterable in tab-order; setter to reorder via <p:nvSpPr>/<p:cNvPr> IDs and the slide's <p:tabLst>
  • Shape.is_hidden_from_accessibility — alias / convenience for is_decorative
  • Picture-specific alt-text shortcut (already partial; promote to public API)
  • Lint helper: Slide.accessibility_issues() returns shapes lacking alt-text or marked-decorative

Prior art

  • Open PRs: scanny/python-pptx#911 — alt-text properties + setters (pa-t, shortlist label by scanny himself, last activity 2025-07-31). Highest-quality cherry-pick candidate. scanny/python-pptx#1097 lower-quality variant. scanny/python-pptx#512 older. scanny/python-pptx#567 title/descr/hidden predecessor.
  • Forks: semaverse-ai/semaverse-pptx feat(shapes): raw alt-text accessors — modernized variant.
  • User issues this would close: #508, #882 (Sensitivity labels — adjacent topic; out-of-scope for v1 but mentioning here so the issue links).
  • OOXML: PresentationML §19.3.1.12 <p:cNvPr> (descr, title attrs), DrawingML extLst with <adec:decorative val="1"/> namespace http://schemas.microsoft.com/office/drawing/2017/decorative. Reading order: PresentationML <p:tabLst> (rare, fallback is shape z-order).
  • Code paths: src/pptx/shapes/base.py, src/pptx/oxml/shapes/__init__.py, new src/pptx/accessibility.py for the lint helper.

Acceptance criteria

  • picture.alt_text = "Bar chart of Q3 revenue by region" writes the descr attribute and round-trips.
  • A presentation authored with all shapes alt-tagged passes Microsoft Accessibility Checker in PowerPoint.
  • slide.accessibility_issues() returns an empty list for a fully-tagged slide.
  • 12+ unit tests + 3 behave scenarios.

Effort: S — quick-win

Cherry-pick scanny#911 as Phase A; decorative + reading-order are Phase B.

Labels

status:quick-win, priority:P0 — high enterprise demand, small implementation. Pair with Transparency epic as fastest first releases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:a11yFeature area: a11yepicMulti-feature roadmap epicprior-art:forkActive community fork has shipped thisprior-art:upstream-prOpen PR on scanny/python-pptx is candidate cherry-pickpriority:P0Highest user demand or strategic valuestatus:quick-winHigh user demand, small implementation

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions