mirror of
https://github.com/typst/typst
synced 2025-06-17 19:02:51 +08:00
WIP [no ci]
This commit is contained in:
parent
1552cdf0f8
commit
529ae78561
@ -9,11 +9,11 @@ use crate::introspection::Locatable;
|
|||||||
// TODO: docs
|
// TODO: docs
|
||||||
#[elem(Locatable, Show)]
|
#[elem(Locatable, Show)]
|
||||||
pub struct PdfTagElem {
|
pub struct PdfTagElem {
|
||||||
#[default(PdfStructElem::NonStruct)]
|
#[default(PdfTagKind::NonStruct)]
|
||||||
pub kind: PdfStructElem,
|
pub kind: PdfTagKind,
|
||||||
|
|
||||||
/// An alternate description
|
/// An alternate description.
|
||||||
pub alt_desc: Option<EcoString>,
|
pub alt: Option<EcoString>,
|
||||||
/// Exact replacement for this structure element and its children.
|
/// Exact replacement for this structure element and its children.
|
||||||
pub actual_text: Option<EcoString>,
|
pub actual_text: Option<EcoString>,
|
||||||
/// The expanded form of an abbreviation/acronym.
|
/// The expanded form of an abbreviation/acronym.
|
||||||
@ -34,7 +34,7 @@ impl Show for Packed<PdfTagElem> {
|
|||||||
// TODO: docs
|
// TODO: docs
|
||||||
/// PDF structure elements
|
/// PDF structure elements
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum PdfStructElem {
|
pub enum PdfTagKind {
|
||||||
// grouping elements
|
// grouping elements
|
||||||
/// (Part)
|
/// (Part)
|
||||||
Part,
|
Part,
|
||||||
@ -146,9 +146,9 @@ pub enum PdfStructElem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cast! {
|
cast! {
|
||||||
PdfStructElem,
|
PdfTagKind,
|
||||||
self => match self {
|
self => match self {
|
||||||
PdfStructElem::Part => "part".into_value(),
|
PdfTagKind::Part => "part".into_value(),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
"part" => Self::Part,
|
"part" => Self::Part,
|
||||||
|
@ -2,6 +2,7 @@ use krilla::action::{Action, LinkAction};
|
|||||||
use krilla::annotation::{Annotation, LinkAnnotation, Target};
|
use krilla::annotation::{Annotation, LinkAnnotation, Target};
|
||||||
use krilla::destination::XyzDestination;
|
use krilla::destination::XyzDestination;
|
||||||
use krilla::geom::Rect;
|
use krilla::geom::Rect;
|
||||||
|
use krilla::tagging::Tag;
|
||||||
use typst_library::layout::{Abs, Point, Position, Size};
|
use typst_library::layout::{Abs, Point, Position, Size};
|
||||||
use typst_library::model::Destination;
|
use typst_library::model::Destination;
|
||||||
|
|
||||||
@ -45,6 +46,8 @@ pub(crate) fn handle_link(
|
|||||||
let rect = Rect::from_ltrb(x1, y1, x2, y2).unwrap();
|
let rect = Rect::from_ltrb(x1, y1, x2, y2).unwrap();
|
||||||
|
|
||||||
// TODO: Support quad points.
|
// TODO: Support quad points.
|
||||||
|
// > Beginning with PDF 1.7, use of the Link structure element to enclose
|
||||||
|
// > multiple link annotations is deprecated.
|
||||||
|
|
||||||
let target = match dest {
|
let target = match dest {
|
||||||
Destination::Url(u) => {
|
Destination::Url(u) => {
|
||||||
@ -70,7 +73,13 @@ pub(crate) fn handle_link(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let placeholder = gc.tags.reserve_placeholder();
|
let placeholder = gc.tags.reserve_placeholder();
|
||||||
gc.tags.push(TagNode::Placeholder(placeholder));
|
let mut node = TagNode::Placeholder(placeholder);
|
||||||
|
let (parent_tag, _) = gc.tags.parent_nodes();
|
||||||
|
if !matches!(parent_tag, Some(Tag::Link | Tag::Reference)) {
|
||||||
|
node = TagNode::Group(Link, )
|
||||||
|
}
|
||||||
|
// Prepend so the link annotation is the first child.
|
||||||
|
gc.tags.prepend();
|
||||||
|
|
||||||
fc.push_annotation(
|
fc.push_annotation(
|
||||||
placeholder,
|
placeholder,
|
||||||
|
@ -8,8 +8,11 @@ use krilla::tagging::{
|
|||||||
};
|
};
|
||||||
use typst_library::foundations::{Content, StyleChain};
|
use typst_library::foundations::{Content, StyleChain};
|
||||||
use typst_library::introspection::Location;
|
use typst_library::introspection::Location;
|
||||||
use typst_library::model::{HeadingElem, OutlineElem, OutlineEntry};
|
use typst_library::model::{
|
||||||
use typst_library::pdf::{ArtifactElem, ArtifactKind, PdfStructElem, PdfTagElem};
|
CiteElem, FigureCaption, FigureElem, HeadingElem, LinkElem, OutlineElem,
|
||||||
|
OutlineEntry, RefElem,
|
||||||
|
};
|
||||||
|
use typst_library::pdf::{ArtifactElem, ArtifactKind, PdfTagElem, PdfTagKind};
|
||||||
|
|
||||||
use crate::convert::GlobalContext;
|
use crate::convert::GlobalContext;
|
||||||
|
|
||||||
@ -72,6 +75,14 @@ impl Tags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn prepend(&mut self, node: TagNode) {
|
||||||
|
if let Some((_, _, nodes)) = self.stack.last_mut() {
|
||||||
|
nodes.insert(0, node);
|
||||||
|
} else {
|
||||||
|
self.tree.insert(0, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn build_tree(&mut self) -> TagTree {
|
pub(crate) fn build_tree(&mut self) -> TagTree {
|
||||||
let mut tree = TagTree::new();
|
let mut tree = TagTree::new();
|
||||||
let nodes = std::mem::take(&mut self.tree);
|
let nodes = std::mem::take(&mut self.tree);
|
||||||
@ -99,60 +110,17 @@ impl Tags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the current parent's list of children and whether it is the tree root.
|
/// Returns the current parent's list of children and whether it is the tree root.
|
||||||
fn parent_nodes(&mut self) -> (bool, &mut Vec<TagNode>) {
|
pub(crate) fn parent_nodes(&mut self) -> (Option<&mut Tag>, &mut Vec<TagNode>) {
|
||||||
if let Some((_, _, parent_nodes)) = self.stack.last_mut() {
|
if let Some((_, tag, parent_nodes)) = self.stack.last_mut() {
|
||||||
(false, parent_nodes)
|
(Some(tag), parent_nodes)
|
||||||
} else {
|
} else {
|
||||||
(true, &mut self.tree)
|
(None, &mut self.tree)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn context_supports(&self, tag: &Tag) -> bool {
|
fn context_supports(&self, _tag: &Tag) -> bool {
|
||||||
let Some((_, parent, _)) = self.stack.last() else { return true };
|
// TODO: generate using: https://pdfa.org/resource/iso-ts-32005-hierarchical-inclusion-rules/
|
||||||
|
true
|
||||||
use Tag::*;
|
|
||||||
|
|
||||||
match parent {
|
|
||||||
Part => true,
|
|
||||||
Article => !matches!(tag, Article),
|
|
||||||
Section => true,
|
|
||||||
BlockQuote => todo!(),
|
|
||||||
Caption => todo!(),
|
|
||||||
TOC => matches!(tag, TOC | TOCI),
|
|
||||||
// TODO: NonStruct is allowed to but (currently?) not supported by krilla
|
|
||||||
TOCI => matches!(tag, TOC | Lbl | Reference | P),
|
|
||||||
Index => todo!(),
|
|
||||||
P => todo!(),
|
|
||||||
H1(_) => todo!(),
|
|
||||||
H2(_) => todo!(),
|
|
||||||
H3(_) => todo!(),
|
|
||||||
H4(_) => todo!(),
|
|
||||||
H5(_) => todo!(),
|
|
||||||
H6(_) => todo!(),
|
|
||||||
L(_list_numbering) => todo!(),
|
|
||||||
LI => todo!(),
|
|
||||||
Lbl => todo!(),
|
|
||||||
LBody => todo!(),
|
|
||||||
Table => todo!(),
|
|
||||||
TR => todo!(),
|
|
||||||
TH(_table_header_scope) => todo!(),
|
|
||||||
TD => todo!(),
|
|
||||||
THead => todo!(),
|
|
||||||
TBody => todo!(),
|
|
||||||
TFoot => todo!(),
|
|
||||||
InlineQuote => todo!(),
|
|
||||||
Note => todo!(),
|
|
||||||
Reference => todo!(),
|
|
||||||
BibEntry => todo!(),
|
|
||||||
Code => todo!(),
|
|
||||||
Link => todo!(),
|
|
||||||
Annot => todo!(),
|
|
||||||
Figure(_) => todo!(),
|
|
||||||
Formula(_) => todo!(),
|
|
||||||
Datetime => todo!(),
|
|
||||||
Terms => todo!(),
|
|
||||||
Title => todo!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +180,7 @@ pub(crate) fn handle_start(
|
|||||||
let tag = if let Some(pdf_tag) = elem.to_packed::<PdfTagElem>() {
|
let tag = if let Some(pdf_tag) = elem.to_packed::<PdfTagElem>() {
|
||||||
let kind = pdf_tag.kind(StyleChain::default());
|
let kind = pdf_tag.kind(StyleChain::default());
|
||||||
match kind {
|
match kind {
|
||||||
PdfStructElem::Part => Tag::Part,
|
PdfTagKind::Part => Tag::Part,
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
} else if let Some(heading) = elem.to_packed::<HeadingElem>() {
|
} else if let Some(heading) = elem.to_packed::<HeadingElem>() {
|
||||||
@ -229,8 +197,19 @@ pub(crate) fn handle_start(
|
|||||||
}
|
}
|
||||||
} else if let Some(_) = elem.to_packed::<OutlineElem>() {
|
} else if let Some(_) = elem.to_packed::<OutlineElem>() {
|
||||||
Tag::TOC
|
Tag::TOC
|
||||||
} else if let Some(_outline_entry) = elem.to_packed::<OutlineEntry>() {
|
} else if let Some(_) = elem.to_packed::<OutlineEntry>() {
|
||||||
Tag::TOCI
|
Tag::TOCI
|
||||||
|
} else if let Some(_) = elem.to_packed::<FigureElem>() {
|
||||||
|
let alt = None; // TODO
|
||||||
|
Tag::Figure(alt)
|
||||||
|
} else if let Some(_) = elem.to_packed::<FigureCaption>() {
|
||||||
|
Tag::Caption
|
||||||
|
} else if let Some(_) = elem.to_packed::<LinkElem>() {
|
||||||
|
Tag::Link
|
||||||
|
} else if let Some(_) = elem.to_packed::<RefElem>() {
|
||||||
|
Tag::Reference
|
||||||
|
} else if let Some(_) = elem.to_packed::<CiteElem>() {
|
||||||
|
Tag::Reference
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user