Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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