mirror of
https://github.com/typst/typst
synced 2025-08-18 00:48:34 +08:00
Compare commits
4 Commits
2621c6416e
...
4b57373653
Author | SHA1 | Date | |
---|---|---|---|
|
4b57373653 | ||
|
e43b8bbb7f | ||
|
9bbfe4c14a | ||
|
e4021390a3 |
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -2,11 +2,13 @@ use krilla::tagging::{ListNumbering, TagKind};
|
||||
|
||||
use crate::tags::TagNode;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ListCtx {
|
||||
numbering: ListNumbering,
|
||||
items: Vec<ListItem>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ListItem {
|
||||
label: Vec<TagNode>,
|
||||
body: Option<Vec<TagNode>>,
|
||||
|
@ -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());
|
||||
@ -391,18 +395,20 @@ impl Tags {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct TableId(u32);
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct LinkId(u32);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct StackEntry {
|
||||
pub(crate) loc: Location,
|
||||
pub(crate) kind: StackEntryKind,
|
||||
pub(crate) nodes: Vec<TagNode>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum StackEntryKind {
|
||||
Standard(Tag),
|
||||
Outline(OutlineCtx),
|
||||
|
@ -4,6 +4,7 @@ use typst_library::model::OutlineEntry;
|
||||
|
||||
use crate::tags::TagNode;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct OutlineCtx {
|
||||
stack: Vec<OutlineSection>,
|
||||
}
|
||||
@ -52,6 +53,7 @@ impl OutlineCtx {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct OutlineSection {
|
||||
entries: Vec<TagNode>,
|
||||
}
|
||||
|
@ -12,15 +12,17 @@ use typst_library::pdf::{TableCellKind, TableHeaderScope};
|
||||
|
||||
use crate::tags::{TableId, TagNode};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct TableCtx {
|
||||
pub(crate) id: TableId,
|
||||
pub(crate) summary: Option<String>,
|
||||
rows: Vec<Vec<GridCell>>,
|
||||
min_width: usize,
|
||||
}
|
||||
|
||||
impl TableCtx {
|
||||
pub(crate) fn new(id: TableId, summary: Option<String>) -> Self {
|
||||
Self { id, summary, rows: Vec::new() }
|
||||
Self { id, summary, rows: Vec::new(), min_width: 0 }
|
||||
}
|
||||
|
||||
fn get(&self, x: usize, y: usize) -> Option<&TableCtxCell> {
|
||||
@ -64,14 +66,15 @@ impl TableCtx {
|
||||
|
||||
// Extend the table grid to fit this cell.
|
||||
let required_height = y + rowspan.get();
|
||||
let required_width = x + colspan.get();
|
||||
self.min_width = self.min_width.max(x + colspan.get());
|
||||
if self.rows.len() < required_height {
|
||||
self.rows
|
||||
.resize(required_height, vec![GridCell::Missing; required_width]);
|
||||
.resize(required_height, vec![GridCell::Missing; self.min_width]);
|
||||
}
|
||||
for row in self.rows.iter_mut() {
|
||||
if row.len() < self.min_width {
|
||||
row.resize_with(self.min_width, || GridCell::Missing);
|
||||
}
|
||||
let row = &mut self.rows[y];
|
||||
if row.len() < required_width {
|
||||
row.resize_with(required_width, || GridCell::Missing);
|
||||
}
|
||||
|
||||
// Store references to the cell for all spanned cells.
|
||||
@ -180,11 +183,7 @@ impl TableCtx {
|
||||
)
|
||||
.into(),
|
||||
};
|
||||
|
||||
// Wrap content in a paragraph.
|
||||
// TODO: maybe avoid nested paragraphs?
|
||||
let par = TagNode::Group(TagKind::P.into(), cell.nodes);
|
||||
Some(TagNode::Group(tag, vec![par]))
|
||||
Some(TagNode::Group(tag, cell.nodes))
|
||||
})
|
||||
.collect();
|
||||
|
||||
@ -254,7 +253,7 @@ impl TableCtx {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
enum GridCell {
|
||||
Cell(TableCtxCell),
|
||||
Spanned(usize, usize),
|
||||
@ -288,7 +287,7 @@ impl GridCell {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
struct TableCtxCell {
|
||||
x: u32,
|
||||
y: u32,
|
||||
@ -422,7 +421,7 @@ mod tests {
|
||||
TagNode::Group(
|
||||
TagKind::TH(TableHeaderCell::new(scope).with_headers(TagIdRefs { ids }))
|
||||
.with_id(Some(id)),
|
||||
vec![TagNode::Group(TagKind::P.into(), Vec::new())],
|
||||
Vec::new(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -433,7 +432,7 @@ mod tests {
|
||||
.collect();
|
||||
TagNode::Group(
|
||||
TagKind::TD(TableDataCell::new().with_headers(TagIdRefs { ids })).into(),
|
||||
vec![TagNode::Group(TagKind::P.into(), Vec::new())],
|
||||
Vec::new(),
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user