diff --git a/crates/typst-library/src/meta/figure.rs b/crates/typst-library/src/meta/figure.rs index bab7790a9..0a02df570 100644 --- a/crates/typst-library/src/meta/figure.rs +++ b/crates/typst-library/src/meta/figure.rs @@ -1,4 +1,5 @@ use std::str::FromStr; +use typst::util::option_eq; use super::{ Count, Counter, CounterKey, CounterUpdate, LocalName, Numbering, NumberingPattern, @@ -380,7 +381,7 @@ impl Outlinable for FigureElem { supplement += TextElem::packed('\u{a0}'); } - let separator = caption.separator(StyleChain::default()); + let separator = caption.get_separator(StyleChain::default()); realized = supplement + numbers + separator + caption.body(); } @@ -455,8 +456,10 @@ pub struct FigureCaption { /// caption: [A rectangle], /// ) /// ``` - #[default(TextElem::packed(": "))] - pub separator: Content, + /// + /// If set to `{auto}`, the separator will be adapted to the current + /// [language]($text.lang) and [region]($text.region). + pub separator: Smart, /// The caption's body. /// @@ -498,10 +501,40 @@ pub struct FigureCaption { pub location: Option, } +impl FigureCaption { + /// Gets the default separator in the given language and (optionally) + /// region. + fn local_separator(lang: Lang, region: Option) -> &'static str { + match lang { + Lang::CHINESE => ":", + Lang::FRENCH if option_eq(region, "CH") => "\u{202f}: ", + Lang::FRENCH => "\u{a0}: ", + Lang::DANISH + | Lang::DUTCH + | Lang::ENGLISH + | Lang::GERMAN + | Lang::ITALIAN + | Lang::RUSSIAN + | Lang::SPANISH + | Lang::SWEDISH + | _ => ": ", + } + } + + fn get_separator(&self, styles: StyleChain) -> Content { + self.separator(styles).unwrap_or_else(|| { + TextElem::packed(Self::local_separator( + TextElem::lang_in(styles), + TextElem::region_in(styles), + )) + }) + } +} + impl Synthesize for FigureCaption { fn synthesize(&mut self, _: &mut Vt, styles: StyleChain) -> SourceResult<()> { self.push_position(self.position(styles)); - self.push_separator(self.separator(styles)); + self.push_separator(Smart::Custom(self.get_separator(styles))); Ok(()) } } @@ -518,7 +551,7 @@ impl Show for FigureCaption { if !supplement.is_empty() { supplement += TextElem::packed('\u{a0}'); } - realized = supplement + numbers + self.separator(styles) + realized; + realized = supplement + numbers + self.get_separator(styles) + realized; } Ok(realized) diff --git a/tests/ref/meta/figure.png b/tests/ref/meta/figure.png index 83bd7b7ff..1bc3b0dcf 100644 Binary files a/tests/ref/meta/figure.png and b/tests/ref/meta/figure.png differ diff --git a/tests/typ/meta/figure.typ b/tests/typ/meta/figure.typ index 7d618d062..36e2da471 100644 --- a/tests/typ/meta/figure.typ +++ b/tests/typ/meta/figure.typ @@ -109,3 +109,25 @@ We can clearly see that @fig-cylinder and table(columns: 2)[a][b], caption: [The table with custom separator.], ) + +--- +// Test localized default separator +#set text(lang: "fr", region: "CH") + +#figure( + circle(), + caption: [Un cercle.], +) +#set text(lang: "es") + +#figure( + polygon.regular(size: 1cm, vertices: 3), + caption: [Un triángulo.], +) + +#set text(lang: "fr", region: "CA") + +#figure( + square(), + caption: [Un carré.], +)