Compare commits

...

2 Commits

Author SHA1 Message Date
Tobias Schmitz
451b0815ff
feat: mark numbering prefix of heading and outline as Lbl 2025-07-14 17:11:02 +02:00
Tobias Schmitz
0df9da7ce6
feat: generate tags for terms 2025-07-14 16:37:16 +02:00
4 changed files with 13 additions and 6 deletions

View File

@ -179,9 +179,9 @@ const TERMS_RULE: ShowFn<TermsElem> = |elem, _, styles| {
for child in elem.children.iter() { for child in elem.children.iter() {
let mut seq = vec![]; let mut seq = vec![];
seq.extend(unpad.clone()); seq.extend(unpad.clone());
seq.push(child.term.clone().strong()); seq.push(PdfMarkerTag::ListItemLabel(child.term.clone().strong()));
seq.push(separator.clone()); seq.push(separator.clone());
seq.push(child.description.clone()); seq.push(PdfMarkerTag::ListItemBody(child.description.clone()));
// Text in wide term lists shall always turn into paragraphs. // Text in wide term lists shall always turn into paragraphs.
if !tight { if !tight {
@ -275,7 +275,7 @@ const HEADING_RULE: ShowFn<HeadingElem> = |elem, engine, styles| {
let spacing = HElem::new(SPACING_TO_NUMBERING.into()).with_weak(true).pack(); let spacing = HElem::new(SPACING_TO_NUMBERING.into()).with_weak(true).pack();
realized = numbering + spacing + realized; realized = PdfMarkerTag::Label(numbering) + spacing + realized;
} }
let block = if indent != Abs::zero() { let block = if indent != Abs::zero() {
@ -477,7 +477,6 @@ const OUTLINE_ENTRY_RULE: ShowFn<OutlineEntry> = |elem, engine, styles| {
let context = Context::new(None, Some(styles)); let context = Context::new(None, Some(styles));
let context = context.track(); let context = context.track();
// TODO(accessibility): prefix should be wrapped in a `Lbl` structure element
let prefix = elem.prefix(engine, context, span)?; let prefix = elem.prefix(engine, context, span)?;
let body = elem.body().at(span)?; let body = elem.body().at(span)?;
let page = elem.page(engine, context, span)?; let page = elem.page(engine, context, span)?;

View File

@ -21,6 +21,7 @@ use crate::layout::{
RepeatElem, Sides, RepeatElem, Sides,
}; };
use crate::model::{HeadingElem, NumberingPattern, ParElem, Refable}; use crate::model::{HeadingElem, NumberingPattern, ParElem, Refable};
use crate::pdf::PdfMarkerTag;
use crate::text::{LocalName, SpaceElem, TextElem}; use crate::text::{LocalName, SpaceElem, TextElem};
/// A table of contents, figures, or other elements. /// A table of contents, figures, or other elements.
@ -493,7 +494,7 @@ impl OutlineEntry {
let styles = context.styles().at(span)?; let styles = context.styles().at(span)?;
let numbers = let numbers =
outlinable.counter().display_at_loc(engine, loc, styles, numbering)?; outlinable.counter().display_at_loc(engine, loc, styles, numbering)?;
Ok(Some(outlinable.prefix(numbers))) Ok(Some(PdfMarkerTag::Label(outlinable.prefix(numbers))))
} }
/// Creates the default inner content of the entry. /// Creates the default inner content of the entry.

View File

@ -138,4 +138,6 @@ pdf_marker_tag! {
ListItemLabel, ListItemLabel,
/// `LBody` of the enum item /// `LBody` of the enum item
ListItemBody, ListItemBody,
/// A generic `Lbl`
Label,
} }

View File

@ -18,7 +18,7 @@ use typst_library::introspection::Location;
use typst_library::layout::RepeatElem; use typst_library::layout::RepeatElem;
use typst_library::model::{ use typst_library::model::{
Destination, EnumElem, FigureCaption, FigureElem, HeadingElem, ListElem, Outlinable, Destination, EnumElem, FigureCaption, FigureElem, HeadingElem, ListElem, Outlinable,
OutlineEntry, TableCell, TableElem, OutlineEntry, TableCell, TableElem, TermsElem,
}; };
use typst_library::pdf::{ArtifactElem, ArtifactKind, PdfMarkerTag, PdfMarkerTagKind}; use typst_library::pdf::{ArtifactElem, ArtifactKind, PdfMarkerTag, PdfMarkerTagKind};
use typst_library::visualize::ImageElem; use typst_library::visualize::ImageElem;
@ -69,6 +69,7 @@ pub(crate) fn handle_start(
push_stack(gc, loc, StackEntryKind::ListItemBody)?; push_stack(gc, loc, StackEntryKind::ListItemBody)?;
return Ok(()); return Ok(());
} }
PdfMarkerTagKind::Label => TagKind::Lbl.into(),
} }
} else if let Some(entry) = elem.to_packed::<OutlineEntry>() { } else if let Some(entry) = elem.to_packed::<OutlineEntry>() {
push_stack(gc, loc, StackEntryKind::OutlineEntry(entry.clone()))?; push_stack(gc, loc, StackEntryKind::OutlineEntry(entry.clone()))?;
@ -81,6 +82,10 @@ pub(crate) fn handle_start(
let numbering = ListNumbering::Decimal; // TODO: infer numbering from `enum.numbering` let numbering = ListNumbering::Decimal; // TODO: infer numbering from `enum.numbering`
push_stack(gc, loc, StackEntryKind::List(ListCtx::new(numbering)))?; push_stack(gc, loc, StackEntryKind::List(ListCtx::new(numbering)))?;
return Ok(()); return Ok(());
} else if let Some(_enumeration) = elem.to_packed::<TermsElem>() {
let numbering = ListNumbering::None;
push_stack(gc, loc, StackEntryKind::List(ListCtx::new(numbering)))?;
return Ok(());
} else if let Some(_) = elem.to_packed::<FigureElem>() { } else if let Some(_) = elem.to_packed::<FigureElem>() {
// Wrap the figure tag and the sibling caption in a container, if the // Wrap the figure tag and the sibling caption in a container, if the
// caption is contained within the figure like recommended for tables // caption is contained within the figure like recommended for tables