mirror of
https://github.com/typst/typst
synced 2025-06-17 10:52:53 +08:00
WIP [no ci]
This commit is contained in:
parent
1552cdf0f8
commit
529ae78561
@ -9,11 +9,11 @@ use crate::introspection::Locatable;
|
||||
// TODO: docs
|
||||
#[elem(Locatable, Show)]
|
||||
pub struct PdfTagElem {
|
||||
#[default(PdfStructElem::NonStruct)]
|
||||
pub kind: PdfStructElem,
|
||||
#[default(PdfTagKind::NonStruct)]
|
||||
pub kind: PdfTagKind,
|
||||
|
||||
/// An alternate description
|
||||
pub alt_desc: Option<EcoString>,
|
||||
/// An alternate description.
|
||||
pub alt: Option<EcoString>,
|
||||
/// Exact replacement for this structure element and its children.
|
||||
pub actual_text: Option<EcoString>,
|
||||
/// The expanded form of an abbreviation/acronym.
|
||||
@ -34,7 +34,7 @@ impl Show for Packed<PdfTagElem> {
|
||||
// TODO: docs
|
||||
/// PDF structure elements
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum PdfStructElem {
|
||||
pub enum PdfTagKind {
|
||||
// grouping elements
|
||||
/// (Part)
|
||||
Part,
|
||||
@ -146,9 +146,9 @@ pub enum PdfStructElem {
|
||||
}
|
||||
|
||||
cast! {
|
||||
PdfStructElem,
|
||||
PdfTagKind,
|
||||
self => match self {
|
||||
PdfStructElem::Part => "part".into_value(),
|
||||
PdfTagKind::Part => "part".into_value(),
|
||||
_ => todo!(),
|
||||
},
|
||||
"part" => Self::Part,
|
||||
|
@ -2,6 +2,7 @@ use krilla::action::{Action, LinkAction};
|
||||
use krilla::annotation::{Annotation, LinkAnnotation, Target};
|
||||
use krilla::destination::XyzDestination;
|
||||
use krilla::geom::Rect;
|
||||
use krilla::tagging::Tag;
|
||||
use typst_library::layout::{Abs, Point, Position, Size};
|
||||
use typst_library::model::Destination;
|
||||
|
||||
@ -45,6 +46,8 @@ pub(crate) fn handle_link(
|
||||
let rect = Rect::from_ltrb(x1, y1, x2, y2).unwrap();
|
||||
|
||||
// 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 {
|
||||
Destination::Url(u) => {
|
||||
@ -70,7 +73,13 @@ pub(crate) fn handle_link(
|
||||
};
|
||||
|
||||
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(
|
||||
placeholder,
|
||||
|
@ -8,8 +8,11 @@ use krilla::tagging::{
|
||||
};
|
||||
use typst_library::foundations::{Content, StyleChain};
|
||||
use typst_library::introspection::Location;
|
||||
use typst_library::model::{HeadingElem, OutlineElem, OutlineEntry};
|
||||
use typst_library::pdf::{ArtifactElem, ArtifactKind, PdfStructElem, PdfTagElem};
|
||||
use typst_library::model::{
|
||||
CiteElem, FigureCaption, FigureElem, HeadingElem, LinkElem, OutlineElem,
|
||||
OutlineEntry, RefElem,
|
||||
};
|
||||
use typst_library::pdf::{ArtifactElem, ArtifactKind, PdfTagElem, PdfTagKind};
|
||||
|
||||
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 {
|
||||
let mut tree = TagTree::new();
|
||||
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.
|
||||
fn parent_nodes(&mut self) -> (bool, &mut Vec<TagNode>) {
|
||||
if let Some((_, _, parent_nodes)) = self.stack.last_mut() {
|
||||
(false, parent_nodes)
|
||||
pub(crate) fn parent_nodes(&mut self) -> (Option<&mut Tag>, &mut Vec<TagNode>) {
|
||||
if let Some((_, tag, parent_nodes)) = self.stack.last_mut() {
|
||||
(Some(tag), parent_nodes)
|
||||
} else {
|
||||
(true, &mut self.tree)
|
||||
(None, &mut self.tree)
|
||||
}
|
||||
}
|
||||
|
||||
fn context_supports(&self, tag: &Tag) -> bool {
|
||||
let Some((_, parent, _)) = self.stack.last() else { return 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!(),
|
||||
}
|
||||
fn context_supports(&self, _tag: &Tag) -> bool {
|
||||
// TODO: generate using: https://pdfa.org/resource/iso-ts-32005-hierarchical-inclusion-rules/
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,7 +180,7 @@ pub(crate) fn handle_start(
|
||||
let tag = if let Some(pdf_tag) = elem.to_packed::<PdfTagElem>() {
|
||||
let kind = pdf_tag.kind(StyleChain::default());
|
||||
match kind {
|
||||
PdfStructElem::Part => Tag::Part,
|
||||
PdfTagKind::Part => Tag::Part,
|
||||
_ => todo!(),
|
||||
}
|
||||
} 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>() {
|
||||
Tag::TOC
|
||||
} else if let Some(_outline_entry) = elem.to_packed::<OutlineEntry>() {
|
||||
} else if let Some(_) = elem.to_packed::<OutlineEntry>() {
|
||||
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 {
|
||||
return;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user