fix: make figure captions sibling elements

if the caption is contained within the figure screen readers might ignore it
This commit is contained in:
Tobias Schmitz 2025-07-14 10:31:17 +02:00
parent e4021390a3
commit 9bbfe4c14a
No known key found for this signature in database
3 changed files with 11 additions and 5 deletions

View File

@ -294,7 +294,7 @@ const HEADING_RULE: ShowFn<HeadingElem> = |elem, engine, styles| {
const FIGURE_RULE: ShowFn<FigureElem> = |elem, _, styles| {
let span = elem.span();
let mut realized = elem.body.clone();
let mut realized = PdfMarkerTag::FigureBody(elem.body.clone());
// Build the caption, if any.
if let Some(caption) = elem.caption.get_cloned(styles) {

View File

@ -132,6 +132,8 @@ macro_rules! pdf_marker_tag {
pdf_marker_tag! {
/// `TOC`
OutlineBody,
/// `Figure`
FigureBody,
/// `Lbl` (marker) of the list item
ListItemLabel,
/// `LBody` of the enum item

View File

@ -60,6 +60,7 @@ pub(crate) fn handle_start(
push_stack(gc, loc, StackEntryKind::Outline(OutlineCtx::new()))?;
return Ok(());
}
PdfMarkerTagKind::FigureBody => TagKind::Figure.into(),
PdfMarkerTagKind::ListItemLabel => {
push_stack(gc, loc, StackEntryKind::ListItemLabel)?;
return Ok(());
@ -81,8 +82,13 @@ pub(crate) fn handle_start(
push_stack(gc, loc, StackEntryKind::List(ListCtx::new(numbering)))?;
return Ok(());
} else if let Some(_) = elem.to_packed::<FigureElem>() {
let alt = None; // TODO
TagKind::Figure.with_alt_text(alt)
// Wrap the figure tag and the sibling caption in a container, if the
// caption is contained within the figure like recommended for tables
// screen readers might ignore it.
// TODO: maybe this could be a `NonStruct` tag?
TagKind::P.into()
} else if let Some(_) = elem.to_packed::<FigureCaption>() {
TagKind::Caption.into()
} else if let Some(image) = elem.to_packed::<ImageElem>() {
let alt = image.alt.get_as_ref().map(|s| s.to_string());
@ -98,8 +104,6 @@ pub(crate) fn handle_start(
} else {
TagKind::Figure.with_alt_text(alt)
}
} else if let Some(_) = elem.to_packed::<FigureCaption>() {
TagKind::Caption.into()
} else if let Some(table) = elem.to_packed::<TableElem>() {
let table_id = gc.tags.next_table_id();
let summary = table.summary.get_as_ref().map(|s| s.to_string());