diff --git a/crates/typst-library/src/meta/document.rs b/crates/typst-library/src/meta/document.rs index 200b5d9dd..f81d8f8a2 100644 --- a/crates/typst-library/src/meta/document.rs +++ b/crates/typst-library/src/meta/document.rs @@ -27,6 +27,9 @@ pub struct DocumentElem { /// The document's authors. pub author: Author, + /// The document's keywords. + pub keywords: Keywords, + /// The page runs. #[internal] #[variadic] @@ -77,6 +80,7 @@ impl LayoutRoot for DocumentElem { pages, title: self.title(styles), author: self.author(styles).0, + keywords: self.keywords(styles).0, }) } } @@ -91,3 +95,14 @@ cast! { v: EcoString => Self(vec![v]), v: Array => Self(v.into_iter().map(Value::cast).collect::>()?), } + +/// A list of keywords. +#[derive(Debug, Default, Clone, Hash)] +pub struct Keywords(Vec); + +cast! { + Keywords, + self => self.0.into_value(), + v: EcoString => Self(vec![v]), + v: Array => Self(v.into_iter().map(Value::cast).collect::>()?), +} diff --git a/crates/typst/src/doc.rs b/crates/typst/src/doc.rs index e3913c1cd..91f9ec208 100644 --- a/crates/typst/src/doc.rs +++ b/crates/typst/src/doc.rs @@ -28,6 +28,8 @@ pub struct Document { pub title: Option, /// The document's author. pub author: Vec, + /// The document's keywords. + pub keywords: Vec, } /// A finished layout with items at fixed positions. diff --git a/crates/typst/src/export/pdf/mod.rs b/crates/typst/src/export/pdf/mod.rs index 6a5aacf55..4043c928e 100644 --- a/crates/typst/src/export/pdf/mod.rs +++ b/crates/typst/src/export/pdf/mod.rs @@ -132,6 +132,14 @@ fn write_catalog(ctx: &mut PdfContext) { info.author(TextStr(&authors.join(", "))); xmp.creator(authors.iter().map(|s| s.as_str())); } + + let keywords = &ctx.document.keywords; + if !keywords.is_empty() { + let joined = keywords.join(", "); + info.keywords(TextStr(&joined)); + xmp.pdf_keywords(&joined); + } + info.creator(TextStr("Typst")); info.finish(); xmp.creator_tool("Typst");