diff --git a/crates/typst-pdf/src/tags/mod.rs b/crates/typst-pdf/src/tags/mod.rs index d19307054..3827bf5db 100644 --- a/crates/typst-pdf/src/tags/mod.rs +++ b/crates/typst-pdf/src/tags/mod.rs @@ -23,6 +23,7 @@ use typst_library::model::{ TermsElem, }; use typst_library::pdf::{ArtifactElem, ArtifactKind, PdfMarkerTag, PdfMarkerTagKind}; +use typst_library::text::RawElem; use typst_library::visualize::ImageElem; use typst_syntax::Span; @@ -177,6 +178,22 @@ pub(crate) fn handle_start( } else if let Some(quote) = elem.to_packed::() { // TODO: should the attribution be handled somehow? if quote.block.val() { Tag::BlockQuote.into() } else { Tag::InlineQuote.into() } + } else if let Some(raw) = elem.to_packed::() { + let desc = raw.lang.opt_ref().and_then(|lang_token| { + let lower = lang_token.to_lowercase(); + let (lang, _) = RawElem::languages() + .into_iter() + .find(|(_, tokens)| tokens.contains(&lower.as_str()))?; + + // TODO: localization + Some(if raw.block.val() { + format!("code block {lang}") + } else { + format!("inline code {lang}") + }) + }); + push_stack(gc, elem, StackEntryKind::Code(desc))?; + return Ok(()); } else { return Ok(()); }; @@ -399,6 +416,15 @@ fn pop_stack(gc: &mut GlobalContext, entry: StackEntry) { ctx.entry = Some(tag); return; } + StackEntryKind::Code(desc) => { + let code = TagNode::group(Tag::Code, entry.nodes); + if desc.is_some() { + let desc = TagNode::group(Tag::Span.with_alt_text(desc), Vec::new()); + TagNode::group(Tag::NonStruct, vec![desc, code]) + } else { + code + } + } }; gc.tags.push(node); @@ -749,6 +775,7 @@ pub(crate) enum StackEntryKind { /// The footnote entry at the end of the page. Contains the [`Location`] of /// the [`FootnoteElem`](typst_library::model::FootnoteElem). FootnoteEntry(Location), + Code(Option), } impl StackEntryKind { @@ -844,6 +871,7 @@ impl StackEntryKind { StackEntryKind::Link(..) => !is_pdf_ua, StackEntryKind::FootnoteRef(_) => false, StackEntryKind::FootnoteEntry(_) => false, + StackEntryKind::Code(_) => false, } } } @@ -965,6 +993,12 @@ pub(crate) enum TagNode { FootnoteEntry(Location), } +impl TagNode { + pub fn group(tag: impl Into, children: Vec) -> Self { + TagNode::Group(tag.into(), children) + } +} + #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub(crate) struct Placeholder(usize);