mirror of
https://github.com/typst/typst
synced 2025-08-15 15:38:33 +08:00
Add support for file embedding
This commit is contained in:
parent
ea021a29e3
commit
9622906e69
@ -1,5 +1,15 @@
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
|
||||
use crate::embed::embed_files;
|
||||
use crate::image::handle_image;
|
||||
use crate::link::handle_link;
|
||||
use crate::metadata::build_metadata;
|
||||
use crate::outline::build_outline;
|
||||
use crate::page::PageLabelExt;
|
||||
use crate::shape::handle_shape;
|
||||
use crate::text::handle_text;
|
||||
use crate::util::{convert_path, display_font, AbsExt, TransformExt};
|
||||
use crate::PdfOptions;
|
||||
use krilla::annotation::Annotation;
|
||||
use krilla::configure::{Configuration, PdfVersion, ValidationError};
|
||||
use krilla::destination::{NamedDestination, XyzDestination};
|
||||
@ -19,16 +29,6 @@ use typst_library::text::{Font, Lang};
|
||||
use typst_library::visualize::{Geometry, Paint};
|
||||
use typst_syntax::Span;
|
||||
|
||||
use crate::image::handle_image;
|
||||
use crate::link::handle_link;
|
||||
use crate::metadata::build_metadata;
|
||||
use crate::outline::build_outline;
|
||||
use crate::page::PageLabelExt;
|
||||
use crate::shape::handle_shape;
|
||||
use crate::text::handle_text;
|
||||
use crate::util::{convert_path, display_font, AbsExt, TransformExt};
|
||||
use crate::PdfOptions;
|
||||
|
||||
pub fn convert(
|
||||
typst_document: &PagedDocument,
|
||||
options: &PdfOptions,
|
||||
@ -53,6 +53,7 @@ pub fn convert(
|
||||
);
|
||||
|
||||
convert_pages(&mut gc, &mut document)?;
|
||||
embed_files(&typst_document, &mut document)?;
|
||||
|
||||
document.set_outline(build_outline(&gc));
|
||||
document.set_metadata(build_metadata(&gc));
|
||||
|
52
crates/typst-pdf/src/embed.rs
Normal file
52
crates/typst-pdf/src/embed.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use krilla::embed::{AssociationKind, EmbeddedFile};
|
||||
use krilla::Document;
|
||||
use std::sync::Arc;
|
||||
use typst_library::diag::{bail, SourceResult};
|
||||
use typst_library::foundations::{NativeElement, StyleChain};
|
||||
use typst_library::layout::PagedDocument;
|
||||
use typst_library::pdf::{EmbedElem, EmbeddedFileRelationship};
|
||||
use typst_syntax::Span;
|
||||
|
||||
pub(crate) fn embed_files(
|
||||
typst_doc: &PagedDocument,
|
||||
document: &mut Document,
|
||||
) -> SourceResult<()> {
|
||||
let elements = typst_doc.introspector.query(&EmbedElem::elem().select());
|
||||
|
||||
for elem in &elements {
|
||||
let embed = elem.to_packed::<EmbedElem>().unwrap();
|
||||
let derived_path = &embed.path.derived;
|
||||
let path = derived_path.to_string();
|
||||
let mime_type =
|
||||
embed.mime_type(StyleChain::default()).clone().map(|s| s.to_string());
|
||||
let description = embed
|
||||
.description(StyleChain::default())
|
||||
.clone()
|
||||
.map(|s| s.to_string());
|
||||
let association_kind = match embed.relationship(StyleChain::default()) {
|
||||
None => AssociationKind::Unspecified,
|
||||
Some(e) => match e {
|
||||
EmbeddedFileRelationship::Source => AssociationKind::Source,
|
||||
EmbeddedFileRelationship::Data => AssociationKind::Data,
|
||||
EmbeddedFileRelationship::Alternative => AssociationKind::Alternative,
|
||||
EmbeddedFileRelationship::Supplement => AssociationKind::Supplement,
|
||||
},
|
||||
};
|
||||
let data: Arc<dyn AsRef<[u8]> + Send + Sync> = Arc::new(embed.data.clone());
|
||||
|
||||
let file = EmbeddedFile {
|
||||
path,
|
||||
mime_type,
|
||||
description,
|
||||
association_kind,
|
||||
data: data.into(),
|
||||
compress: true,
|
||||
};
|
||||
|
||||
if document.embed_file(file).is_none() {
|
||||
bail!(Span::detached(), "attempted to embed file {derived_path} twice");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
//! Exporting Typst documents to PDF.
|
||||
|
||||
mod convert;
|
||||
mod embed;
|
||||
mod image;
|
||||
mod link;
|
||||
mod metadata;
|
||||
|
Loading…
x
Reference in New Issue
Block a user