diff --git a/crates/typst/src/text/smartquote.rs b/crates/typst/src/text/smartquote.rs index dbcca6dc3..4bb5ca019 100644 --- a/crates/typst/src/text/smartquote.rs +++ b/crates/typst/src/text/smartquote.rs @@ -2,7 +2,9 @@ use ecow::EcoString; use unicode_segmentation::UnicodeSegmentation; use crate::diag::{bail, StrResult}; -use crate::foundations::{array, cast, dict, elem, Array, Dict, FromValue, Smart, Str}; +use crate::foundations::{ + array, cast, dict, elem, Array, Dict, FromValue, Packed, PlainText, Smart, Str, +}; use crate::layout::Dir; use crate::syntax::is_newline; use crate::text::{Lang, Region}; @@ -26,7 +28,7 @@ use crate::text::{Lang, Region}; /// # Syntax /// This function also has dedicated syntax: The normal quote characters /// (`'` and `"`). Typst automatically makes your quotes smart. -#[elem(name = "smartquote")] +#[elem(name = "smartquote", PlainText)] pub struct SmartQuoteElem { /// Whether this should be a double quote. #[default(true)] @@ -85,6 +87,16 @@ pub struct SmartQuoteElem { pub quotes: Smart, } +impl PlainText for Packed { + fn plain_text(&self, text: &mut EcoString) { + if self.double.unwrap_or(true) { + text.push_str("\""); + } else { + text.push_str("'"); + } + } +} + /// State machine for smart quote substitution. #[derive(Debug, Clone)] pub struct SmartQuoter { diff --git a/tests/ref/bugs/3662-pdf-smartquotes.png b/tests/ref/bugs/3662-pdf-smartquotes.png new file mode 100644 index 000000000..c272a8ffd Binary files /dev/null and b/tests/ref/bugs/3662-pdf-smartquotes.png differ diff --git a/tests/typ/bugs/3662-pdf-smartquotes.typ b/tests/typ/bugs/3662-pdf-smartquotes.typ new file mode 100644 index 000000000..36dc8a15d --- /dev/null +++ b/tests/typ/bugs/3662-pdf-smartquotes.typ @@ -0,0 +1,12 @@ +// Smart quotes were not appearing in the PDF outline, because they didn't +// implement `PlainText` +// https://github.com/typst/typst/issues/3662 + +--- += It's "Unnormal Heading" += It’s “Normal Heading” + +#set smartquote(enabled: false) += It's "Unnormal Heading" += It's 'single quotes' += It’s “Normal Heading” \ No newline at end of file