From 042330cd66dfbeaa4ee31c2d8615af95f01c9d27 Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Wed, 23 Jul 2025 15:21:35 +0200 Subject: [PATCH] feat: add alt field to figure --- crates/typst-layout/src/rules.rs | 3 ++- crates/typst-library/src/model/figure.rs | 3 +++ crates/typst-library/src/pdf/accessibility.rs | 7 ++++--- crates/typst-pdf/src/tags/mod.rs | 9 ++++++--- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/crates/typst-layout/src/rules.rs b/crates/typst-layout/src/rules.rs index eb3d10b14..456c73b71 100644 --- a/crates/typst-layout/src/rules.rs +++ b/crates/typst-layout/src/rules.rs @@ -282,7 +282,8 @@ const HEADING_RULE: ShowFn = |elem, engine, styles| { const FIGURE_RULE: ShowFn = |elem, _, styles| { let span = elem.span(); - let mut realized = PdfMarkerTag::FigureBody(elem.body.clone()); + let mut realized = + PdfMarkerTag::FigureBody(elem.alt.get_cloned(styles), elem.body.clone()); // Build the caption, if any. if let Some(caption) = elem.caption.get_cloned(styles) { diff --git a/crates/typst-library/src/model/figure.rs b/crates/typst-library/src/model/figure.rs index f4b45f897..11d775b69 100644 --- a/crates/typst-library/src/model/figure.rs +++ b/crates/typst-library/src/model/figure.rs @@ -103,6 +103,9 @@ use crate::visualize::ImageElem; /// ``` #[elem(scope, Locatable, Synthesize, Count, ShowSet, Refable, Outlinable)] pub struct FigureElem { + /// An alternative description of the figure. + pub alt: Option, + /// The content of the figure. Often, an [image]. #[required] pub body: Content, diff --git a/crates/typst-library/src/pdf/accessibility.rs b/crates/typst-library/src/pdf/accessibility.rs index 53ae4d4f0..5705eabe8 100644 --- a/crates/typst-library/src/pdf/accessibility.rs +++ b/crates/typst-library/src/pdf/accessibility.rs @@ -1,5 +1,6 @@ use std::num::NonZeroU32; +use ecow::EcoString; use typst_macros::{Cast, elem, func}; use typst_utils::NonZeroExt; @@ -118,8 +119,8 @@ impl Construct for PdfMarkerTag { } macro_rules! pdf_marker_tag { - ($(#[doc = $doc:expr] $variant:ident$(($($name:ident: $ty:ident)+))?,)+) => { - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + ($(#[doc = $doc:expr] $variant:ident$(($($name:ident: $ty:ty)+))?,)+) => { + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum PdfMarkerTagKind { $( #[doc = $doc] @@ -147,7 +148,7 @@ pdf_marker_tag! { /// `TOC` OutlineBody, /// `Figure` - FigureBody, + FigureBody(alt: Option), /// `L` bibliography list Bibliography(numbered: bool), /// `LBody` wrapping `BibEntry` diff --git a/crates/typst-pdf/src/tags/mod.rs b/crates/typst-pdf/src/tags/mod.rs index 0d8df6fb6..a07721048 100644 --- a/crates/typst-pdf/src/tags/mod.rs +++ b/crates/typst-pdf/src/tags/mod.rs @@ -59,15 +59,18 @@ pub(crate) fn handle_start( } let mut tag: TagKind = if let Some(tag) = elem.to_packed::() { - match tag.kind { + match &tag.kind { PdfMarkerTagKind::OutlineBody => { push_stack(gc, loc, StackEntryKind::Outline(OutlineCtx::new()))?; return Ok(()); } - PdfMarkerTagKind::FigureBody => Tag::Figure(None).into(), + PdfMarkerTagKind::FigureBody(alt) => { + let alt = alt.as_ref().map(|s| s.to_string()); + Tag::Figure(alt).into() + } PdfMarkerTagKind::Bibliography(numbered) => { let numbering = - if numbered { ListNumbering::Decimal } else { ListNumbering::None }; + if *numbered { ListNumbering::Decimal } else { ListNumbering::None }; push_stack(gc, loc, StackEntryKind::List(ListCtx::new(numbering)))?; return Ok(()); }