Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add full alt-text (title and description) support for pictures and inline shapes #1530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
EwoutH wants to merge 3 commits into python-openxml:master
base: master
Choose a base branch
Loading
from EwoutH:alt

Conversation

@EwoutH
Copy link

@EwoutH EwoutH commented Nov 10, 2025
edited
Loading

Builds on #227 and #317.

Summary

This PR introduces first-class support for Word Alt Text in python-docx. Users can now set and read both the Alt Text Title and Alt Text Description (as shown in Word’s Accessibility pane) directly through the API when inserting or editing pictures.

Motive

Previously, python-docx did not expose a clean API for working with image alternative text. Users had to manually manipulate XML to set or retrieve <wp:docPr> attributes (title, descr). This enhancement improves accessibility workflows and enables automated tools (e.g., alt-text generators) to embed compliant descriptions directly into Word documents.

Implementation

  • CT_NonVisualDrawingProps (oxml/shape.py): Added optional attributes title and descr.
  • CT_Inline.new() / new_pic_inline(): Accept and apply title / descr to <wp:docPr>.
  • StoryPart.new_pic_inline(): Added title and descr parameters and forwarded them to CT_Inline.new_pic_inline().
  • Run.add_picture() and Document.add_picture(): Updated to accept and pass through title and descr for inline pictures.
  • InlineShape (shape.py): Added new alt_text and alt_title properties for convenient read/write access to docPr.descr and docPr.title.

Usage Examples

from docx import Document
from docx.shared import Inches
doc = Document()
# Insert an image with alt text
doc.add_picture(
 "chart.png",
 width=Inches(5),
 descr="Line chart showing sales growth from 2020 to 2024.",
 title="Sales Growth Chart"
)
# Access or modify alt text of an existing shape
shape = doc.inline_shapes[0]
print(shape.alt_text) # "Line chart showing sales growth from 2020 to 2024."
shape.alt_text = "Updated alt text description."
shape.alt_title = "Updated title."
doc.save("report_with_alt_text.docx")

Additional Notes

  • Verified functionality using a test script that inserted an image, saved, reloaded, and confirmed alt_title and alt_text persisted correctly.
  • No breaking API changes; title and descr are optional.
  • Works across all story parts (document, headers, footers).
  • Backwards compatible with existing documents.
  • Enables accessibility tooling, automated captioning, and alt-text validation in Word documents.

...ingProps
Expose the `<wp:docPr>` attributes used for image title and alt text in Word. These correspond to the "Alt Text (Title)" and "Alt Text (Description)" fields shown in the Word UI.
Based on the approach from PR python-openxml#227 ("Add support for image title and alt text"), limited here to adding OptionalAttribute definitions in the OXML layer.
- Extend StoryPart.new_pic_inline() with optional `title` and `descr` parameters.
- Pass these through to CT_Inline.new_pic_inline() for setting <wp:docPr> attributes.
- Update Run.add_picture() to accept and forward `title` and `descr` to StoryPart.
Part of the effort to enable setting image alternative text (accessibility title/description) when adding pictures.
Expose read/write access to image alternative text stored in <wp:docPr> via new `InlineShape.alt_text` (description) and `InlineShape.alt_title` (title) properties.
Copy link
Author

EwoutH commented Nov 10, 2025

While adding alt-text, I ran into an API/compatibility issue.

I’d like to let users set alt text at insertion time via:

  • Document.add_picture(...)
  • Run.add_picture(...)

These are public APIs. Internally they call:

  • StoryPart.new_pic_inline(...)
  • CT_Inline.new_pic_inline(...)

However, the existing API and tests assume a 3-arg positional call chain:

document.add_picture(path, width, height)
run.add_picture(path, width, height)
part.new_pic_inline(image, width, height)

If we extend this with positional title / descr, we either:

  • break those expectations and risk user code,
  • or start passing extra None arguments around, which is brittle and obscures intent.

I think there are three options:

  1. Keep add_picture as-is; only add:

    • InlineShape.alt_text
    • InlineShape.alt_title
      Users set alt text after insertion:
    shape = doc.add_picture("img.png")
    shape.alt_text = "..."
  2. Extend via keyword-only args (backwards compatible):

    • add_picture(..., *, title=None, descr=None)
    • Plumb these through internally as keyword args only.
  3. Internal-only clean break (future-proof core, public stays stable)

    • Keep public APIs as-is (users can optionally pass title/descr as kwargs).
    • Make internal constructors keyword-only and clearer:
      • StoryPart.new_inline_picture(..., *, width=None, height=None, title=None, descr=None)
        (optionally keep new_pic_inline(...) as a shim that calls new_inline_picture(...) and deprecate it)
      • CT_Inline.new_pic_inline(..., *, title=None, descr=None) and CT_Inline.new(..., *, title=None, descr=None)
    • Run.add_picture(...) forwards only provided kwargs to new_inline_picture(...).
    • This gives us a clean, extensible internal surface (ready for future options like wrapping/hyperlink) without changing public behavior. Guidance requested on whether to include the shim + deprecation, or go straight to the new names.

@scanny Which option would you prefer?

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

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

AltStyle によって変換されたページ (->オリジナル) /