From d65d9d0fe648415bb61e90042c3a98d865391b95 Mon Sep 17 00:00:00 2001 From: Heinenen <37484430+Heinenen@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:26:49 +0200 Subject: [PATCH] Localization with custom key-value format (#3728) --- crates/typst/src/math/equation.rs | 41 +------ crates/typst/src/model/bibliography.rs | 38 +------ crates/typst/src/model/heading.rs | 41 +------ crates/typst/src/model/outline.rs | 41 +------ crates/typst/src/model/table.rs | 37 +------ crates/typst/src/text/lang.rs | 109 ++++++++++++++++++- crates/typst/src/text/raw.rs | 40 +------ crates/typst/src/visualize/image/mod.rs | 40 +------ crates/typst/translations/ar.txt | 7 ++ crates/typst/translations/cs.txt | 7 ++ crates/typst/translations/da.txt | 7 ++ crates/typst/translations/de.txt | 7 ++ crates/typst/translations/en.txt | 7 ++ crates/typst/translations/es.txt | 7 ++ crates/typst/translations/et.txt | 7 ++ crates/typst/translations/fi.txt | 7 ++ crates/typst/translations/fr.txt | 7 ++ crates/typst/translations/gr.txt | 7 ++ crates/typst/translations/hu.txt | 7 ++ crates/typst/translations/it.txt | 7 ++ crates/typst/translations/ja.txt | 7 ++ crates/typst/translations/nb.txt | 7 ++ crates/typst/translations/nl.txt | 7 ++ crates/typst/translations/nn.txt | 7 ++ crates/typst/translations/pl.txt | 7 ++ crates/typst/translations/pt-PT.txt | 7 ++ crates/typst/translations/pt.txt | 7 ++ crates/typst/translations/ro.txt | 8 ++ crates/typst/translations/ru.txt | 7 ++ crates/typst/translations/sl.txt | 7 ++ crates/typst/translations/sq.txt | 7 ++ crates/typst/translations/sr.txt | 7 ++ crates/typst/translations/sv.txt | 7 ++ crates/typst/translations/tl.txt | 7 ++ crates/typst/translations/tr.txt | 7 ++ crates/typst/translations/ua.txt | 7 ++ crates/typst/translations/vi.txt | 8 ++ crates/typst/translations/zh-TW.txt | 7 ++ crates/typst/translations/zh.txt | 7 ++ tests/ref/text-language-fallback-english.png | Bin 0 -> 922 bytes tests/suite/text/lang.typ | 6 + 41 files changed, 351 insertions(+), 261 deletions(-) create mode 100644 crates/typst/translations/ar.txt create mode 100644 crates/typst/translations/cs.txt create mode 100644 crates/typst/translations/da.txt create mode 100644 crates/typst/translations/de.txt create mode 100644 crates/typst/translations/en.txt create mode 100644 crates/typst/translations/es.txt create mode 100644 crates/typst/translations/et.txt create mode 100644 crates/typst/translations/fi.txt create mode 100644 crates/typst/translations/fr.txt create mode 100644 crates/typst/translations/gr.txt create mode 100644 crates/typst/translations/hu.txt create mode 100644 crates/typst/translations/it.txt create mode 100644 crates/typst/translations/ja.txt create mode 100644 crates/typst/translations/nb.txt create mode 100644 crates/typst/translations/nl.txt create mode 100644 crates/typst/translations/nn.txt create mode 100644 crates/typst/translations/pl.txt create mode 100644 crates/typst/translations/pt-PT.txt create mode 100644 crates/typst/translations/pt.txt create mode 100644 crates/typst/translations/ro.txt create mode 100644 crates/typst/translations/ru.txt create mode 100644 crates/typst/translations/sl.txt create mode 100644 crates/typst/translations/sq.txt create mode 100644 crates/typst/translations/sr.txt create mode 100644 crates/typst/translations/sv.txt create mode 100644 crates/typst/translations/tl.txt create mode 100644 crates/typst/translations/tr.txt create mode 100644 crates/typst/translations/ua.txt create mode 100644 crates/typst/translations/vi.txt create mode 100644 crates/typst/translations/zh-TW.txt create mode 100644 crates/typst/translations/zh.txt create mode 100644 tests/ref/text-language-fallback-english.png diff --git a/crates/typst/src/math/equation.rs b/crates/typst/src/math/equation.rs index c5cb91322..4e844d076 100644 --- a/crates/typst/src/math/equation.rs +++ b/crates/typst/src/math/equation.rs @@ -19,10 +19,9 @@ use crate::math::{ use crate::model::{Numbering, Outlinable, ParElem, Refable, Supplement}; use crate::syntax::Span; use crate::text::{ - families, variant, Font, FontFamily, FontList, FontWeight, Lang, LocalName, Region, - TextElem, + families, variant, Font, FontFamily, FontList, FontWeight, LocalName, TextElem, }; -use crate::util::{option_eq, NonZeroExt, Numeric}; +use crate::util::{NonZeroExt, Numeric}; use crate::World; /// A mathematical equation. @@ -302,41 +301,7 @@ impl Count for Packed { } impl LocalName for Packed { - fn local_name(lang: Lang, region: Option) -> &'static str { - match lang { - Lang::ALBANIAN => "Ekuacion", - Lang::ARABIC => "معادلة", - Lang::BOKMÅL => "Ligning", - Lang::CATALAN => "Equació", - Lang::CHINESE if option_eq(region, "TW") => "方程式", - Lang::CHINESE => "公式", - Lang::CZECH => "Rovnice", - Lang::DANISH => "Ligning", - Lang::DUTCH => "Vergelijking", - Lang::ESTONIAN => "Valem", - Lang::FILIPINO => "Ekwasyon", - Lang::FINNISH => "Yhtälö", - Lang::FRENCH => "Équation", - Lang::GERMAN => "Gleichung", - Lang::GREEK => "Εξίσωση", - Lang::HUNGARIAN => "Egyenlet", - Lang::ITALIAN => "Equazione", - Lang::NYNORSK => "Likning", - Lang::POLISH => "Równanie", - Lang::PORTUGUESE => "Equação", - Lang::ROMANIAN => "Ecuația", - Lang::RUSSIAN => "Уравнение", - Lang::SERBIAN => "Једначина", - Lang::SLOVENIAN => "Enačba", - Lang::SPANISH => "Ecuación", - Lang::SWEDISH => "Ekvation", - Lang::TURKISH => "Denklem", - Lang::UKRAINIAN => "Рівняння", - Lang::VIETNAMESE => "Phương trình", - Lang::JAPANESE => "式", - Lang::ENGLISH | _ => "Equation", - } - } + const KEY: &'static str = "equation"; } impl Refable for Packed { diff --git a/crates/typst/src/model/bibliography.rs b/crates/typst/src/model/bibliography.rs index 576d1171b..b7a10b923 100644 --- a/crates/typst/src/model/bibliography.rs +++ b/crates/typst/src/model/bibliography.rs @@ -40,7 +40,7 @@ use crate::syntax::{Span, Spanned}; use crate::text::{ FontStyle, Lang, LocalName, Region, SubElem, SuperElem, TextElem, WeightDelta, }; -use crate::util::{option_eq, LazyHash, NonZeroExt, PicoStr}; +use crate::util::{LazyHash, NonZeroExt, PicoStr}; use crate::World; /// A bibliography / reference listing. @@ -283,41 +283,7 @@ impl ShowSet for Packed { } impl LocalName for Packed { - fn local_name(lang: Lang, region: Option) -> &'static str { - match lang { - Lang::ALBANIAN => "Bibliografi", - Lang::ARABIC => "المراجع", - Lang::BOKMÅL => "Bibliografi", - Lang::CATALAN => "Bibliografia", - Lang::CHINESE if option_eq(region, "TW") => "書目", - Lang::CHINESE => "参考文献", - Lang::CZECH => "Bibliografie", - Lang::DANISH => "Bibliografi", - Lang::DUTCH => "Bibliografie", - Lang::ESTONIAN => "Viited", - Lang::FILIPINO => "Bibliograpiya", - Lang::FINNISH => "Viitteet", - Lang::FRENCH => "Bibliographie", - Lang::GERMAN => "Bibliographie", - Lang::GREEK => "Βιβλιογραφία", - Lang::HUNGARIAN => "Irodalomjegyzék", - Lang::ITALIAN => "Bibliografia", - Lang::NYNORSK => "Bibliografi", - Lang::POLISH => "Bibliografia", - Lang::PORTUGUESE => "Bibliografia", - Lang::ROMANIAN => "Bibliografie", - Lang::RUSSIAN => "Библиография", - Lang::SERBIAN => "Литература", - Lang::SLOVENIAN => "Literatura", - Lang::SPANISH => "Bibliografía", - Lang::SWEDISH => "Bibliografi", - Lang::TURKISH => "Kaynakça", - Lang::UKRAINIAN => "Бібліографія", - Lang::VIETNAMESE => "Tài liệu tham khảo", - Lang::JAPANESE => "参考文献", - Lang::ENGLISH | _ => "Bibliography", - } - } + const KEY: &'static str = "bibliography"; } /// A loaded bibliography. diff --git a/crates/typst/src/model/heading.rs b/crates/typst/src/model/heading.rs index 314f54826..d3976948e 100644 --- a/crates/typst/src/model/heading.rs +++ b/crates/typst/src/model/heading.rs @@ -9,8 +9,8 @@ use crate::foundations::{ use crate::introspection::{Count, Counter, CounterUpdate, Locatable}; use crate::layout::{BlockElem, Em, HElem, VElem}; use crate::model::{Numbering, Outlinable, Refable, Supplement}; -use crate::text::{FontWeight, Lang, LocalName, Region, SpaceElem, TextElem, TextSize}; -use crate::util::{option_eq, NonZeroExt}; +use crate::text::{FontWeight, LocalName, SpaceElem, TextElem, TextSize}; +use crate::util::NonZeroExt; /// A section heading. /// @@ -294,40 +294,5 @@ impl Outlinable for Packed { } impl LocalName for Packed { - fn local_name(lang: Lang, region: Option) -> &'static str { - match lang { - Lang::ALBANIAN => "Kapitull", - Lang::ARABIC => "الفصل", - Lang::BOKMÅL => "Kapittel", - Lang::CATALAN => "Secció", - Lang::CHINESE if option_eq(region, "TW") => "小節", - Lang::CHINESE => "小节", - Lang::CZECH => "Kapitola", - Lang::DANISH => "Afsnit", - Lang::DUTCH => "Hoofdstuk", - Lang::ESTONIAN => "Peatükk", - Lang::FILIPINO => "Seksyon", - Lang::FINNISH => "Osio", - Lang::FRENCH => "Chapitre", - Lang::GERMAN => "Abschnitt", - Lang::GREEK => "Κεφάλαιο", - Lang::HUNGARIAN => "Fejezet", - Lang::ITALIAN => "Sezione", - Lang::NYNORSK => "Kapittel", - Lang::POLISH => "Sekcja", - Lang::PORTUGUESE if option_eq(region, "PT") => "Secção", - Lang::PORTUGUESE => "Seção", - Lang::ROMANIAN => "Secțiunea", - Lang::RUSSIAN => "Раздел", - Lang::SERBIAN => "Поглавље", - Lang::SLOVENIAN => "Poglavje", - Lang::SPANISH => "Sección", - Lang::SWEDISH => "Kapitel", - Lang::TURKISH => "Bölüm", - Lang::UKRAINIAN => "Розділ", - Lang::VIETNAMESE => "Phần", // TODO: This may be wrong. - Lang::JAPANESE => "節", - Lang::ENGLISH | _ => "Section", - } - } + const KEY: &'static str = "heading"; } diff --git a/crates/typst/src/model/outline.rs b/crates/typst/src/model/outline.rs index a85d1cdf5..e92306567 100644 --- a/crates/typst/src/model/outline.rs +++ b/crates/typst/src/model/outline.rs @@ -15,8 +15,8 @@ use crate::model::{ Destination, HeadingElem, NumberingPattern, ParElem, ParbreakElem, Refable, }; use crate::syntax::Span; -use crate::text::{Lang, LinebreakElem, LocalName, Region, SpaceElem, TextElem}; -use crate::util::{option_eq, NonZeroExt}; +use crate::text::{LinebreakElem, LocalName, SpaceElem, TextElem}; +use crate::util::NonZeroExt; /// A table of contents, figures, or other elements. /// @@ -272,42 +272,7 @@ impl ShowSet for Packed { } impl LocalName for Packed { - fn local_name(lang: Lang, region: Option) -> &'static str { - match lang { - Lang::ALBANIAN => "Përmbajtja", - Lang::ARABIC => "المحتويات", - Lang::BOKMÅL => "Innhold", - Lang::CATALAN => "Índex", - Lang::CHINESE if option_eq(region, "TW") => "目錄", - Lang::CHINESE => "目录", - Lang::CZECH => "Obsah", - Lang::DANISH => "Indhold", - Lang::DUTCH => "Inhoudsopgave", - Lang::ESTONIAN => "Sisukord", - Lang::FILIPINO => "Talaan ng mga Nilalaman", - Lang::FINNISH => "Sisällys", - Lang::FRENCH => "Table des matières", - Lang::GERMAN => "Inhaltsverzeichnis", - Lang::GREEK => "Περιεχόμενα", - Lang::HUNGARIAN => "Tartalomjegyzék", - Lang::ITALIAN => "Indice", - Lang::NYNORSK => "Innhald", - Lang::POLISH => "Spis treści", - Lang::PORTUGUESE if option_eq(region, "PT") => "Índice", - Lang::PORTUGUESE => "Sumário", - Lang::ROMANIAN => "Cuprins", - Lang::RUSSIAN => "Содержание", - Lang::SERBIAN => "Садржај", - Lang::SLOVENIAN => "Kazalo", - Lang::SPANISH => "Índice", - Lang::SWEDISH => "Innehåll", - Lang::TURKISH => "İçindekiler", - Lang::UKRAINIAN => "Зміст", - Lang::VIETNAMESE => "Mục lục", - Lang::JAPANESE => "目次", - Lang::ENGLISH | _ => "Contents", - } - } + const KEY: &'static str = "outline"; } /// Marks an element as being able to be outlined. This is used to implement the diff --git a/crates/typst/src/model/table.rs b/crates/typst/src/model/table.rs index 50578780b..3a0c47c12 100644 --- a/crates/typst/src/model/table.rs +++ b/crates/typst/src/model/table.rs @@ -16,7 +16,7 @@ use crate::layout::{ }; use crate::model::Figurable; use crate::syntax::Span; -use crate::text::{Lang, LocalName, Region, TextElem}; +use crate::text::{LocalName, TextElem}; use crate::util::NonZeroExt; use crate::visualize::{Paint, Stroke}; @@ -317,40 +317,7 @@ impl LayoutMultiple for Packed { } impl LocalName for Packed { - fn local_name(lang: Lang, _: Option) -> &'static str { - match lang { - Lang::ALBANIAN => "Tabel", - Lang::ARABIC => "جدول", - Lang::BOKMÅL => "Tabell", - Lang::CATALAN => "Taula", - Lang::CHINESE => "表", - Lang::CZECH => "Tabulka", - Lang::DANISH => "Tabel", - Lang::DUTCH => "Tabel", - Lang::ESTONIAN => "Tabel", - Lang::FILIPINO => "Talaan", - Lang::FINNISH => "Taulukko", - Lang::FRENCH => "Tableau", - Lang::GERMAN => "Tabelle", - Lang::GREEK => "Πίνακας", - Lang::HUNGARIAN => "Táblázat", - Lang::ITALIAN => "Tabella", - Lang::NYNORSK => "Tabell", - Lang::POLISH => "Tabela", - Lang::PORTUGUESE => "Tabela", - Lang::ROMANIAN => "Tabelul", - Lang::RUSSIAN => "Таблица", - Lang::SERBIAN => "Табела", - Lang::SLOVENIAN => "Tabela", - Lang::SPANISH => "Tabla", - Lang::SWEDISH => "Tabell", - Lang::TURKISH => "Tablo", - Lang::UKRAINIAN => "Таблиця", - Lang::VIETNAMESE => "Bảng", - Lang::JAPANESE => "表", - Lang::ENGLISH | _ => "Table", - } - } + const KEY: &'static str = "table"; } impl Figurable for Packed {} diff --git a/crates/typst/src/text/lang.rs b/crates/typst/src/text/lang.rs index 111c929b0..a67fa33a6 100644 --- a/crates/typst/src/text/lang.rs +++ b/crates/typst/src/text/lang.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::str::FromStr; use ecow::EcoString; @@ -6,6 +7,46 @@ use crate::foundations::{cast, StyleChain}; use crate::layout::Dir; use crate::text::TextElem; +macro_rules! translation { + ($lang:literal) => { + ($lang, include_str!(concat!("../../translations/", $lang, ".txt"))) + }; +} + +const TRANSLATIONS: [(&str, &str); 31] = [ + translation!("ar"), + translation!("cs"), + translation!("da"), + translation!("de"), + translation!("en"), + translation!("es"), + translation!("et"), + translation!("fi"), + translation!("fr"), + translation!("gr"), + translation!("hu"), + translation!("it"), + translation!("ja"), + translation!("nb"), + translation!("nl"), + translation!("nn"), + translation!("pl"), + translation!("pt-PT"), + translation!("pt"), + translation!("ro"), + translation!("ru"), + translation!("sl"), + translation!("sq"), + translation!("sr"), + translation!("sv"), + translation!("tl"), + translation!("tr"), + translation!("ua"), + translation!("vi"), + translation!("zh-TW"), + translation!("zh"), +]; + /// An identifier for a natural language. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Lang([u8; 3], u8); @@ -26,11 +67,13 @@ impl Lang { pub const FRENCH: Self = Self(*b"fr ", 2); pub const GERMAN: Self = Self(*b"de ", 2); pub const GREEK: Self = Self(*b"gr ", 2); + pub const HUNGARIAN: Self = Self(*b"hu ", 2); pub const ITALIAN: Self = Self(*b"it ", 2); pub const JAPANESE: Self = Self(*b"ja ", 2); pub const NYNORSK: Self = Self(*b"nn ", 2); pub const POLISH: Self = Self(*b"pl ", 2); pub const PORTUGUESE: Self = Self(*b"pt ", 2); + pub const ROMANIAN: Self = Self(*b"ro ", 2); pub const RUSSIAN: Self = Self(*b"ru ", 2); pub const SERBIAN: Self = Self(*b"sr ", 2); pub const SLOVENIAN: Self = Self(*b"sl ", 2); @@ -39,8 +82,6 @@ impl Lang { pub const TURKISH: Self = Self(*b"tr ", 2); pub const UKRAINIAN: Self = Self(*b"ua ", 2); pub const VIETNAMESE: Self = Self(*b"vi ", 2); - pub const HUNGARIAN: Self = Self(*b"hu ", 2); - pub const ROMANIAN: Self = Self(*b"ro ", 2); /// Return the language code as an all lowercase string slice. pub fn as_str(&self) -> &str { @@ -159,8 +200,13 @@ cast! { /// The name with which an element is referenced. pub trait LocalName { + /// The key of an element in order to get its localized name. + const KEY: &'static str; + /// Get the name in the given language and (optionally) region. - fn local_name(lang: Lang, region: Option) -> &'static str; + fn local_name(lang: Lang, region: Option) -> &'static str { + localized_str(lang, region, Self::KEY) + } /// Gets the local name from the style chain. fn local_name_in(styles: StyleChain) -> &'static str @@ -171,6 +217,63 @@ pub trait LocalName { } } +/// Retrieves the localized string for a given language and region. +/// Silently falls back to English if no fitting string exists for +/// the given language + region. Panics if no fitting string exists +/// in both given language + region and English. +#[comemo::memoize] +pub fn localized_str(lang: Lang, region: Option, key: &str) -> &'static str { + let lang_region_bundle = parse_language_bundle(lang, region).unwrap(); + if let Some(str) = lang_region_bundle.get(key) { + return str; + } + let lang_bundle = parse_language_bundle(lang, None).unwrap(); + if let Some(str) = lang_bundle.get(key) { + return str; + } + let english_bundle = parse_language_bundle(Lang::ENGLISH, None).unwrap(); + english_bundle.get(key).unwrap() +} + +/// Parses the translation file for a given language and region. +/// Only returns an error if the language file is malformed. +#[comemo::memoize] +fn parse_language_bundle( + lang: Lang, + region: Option, +) -> Result, &'static str> { + let language_tuple = TRANSLATIONS.iter().find(|it| it.0 == lang_str(lang, region)); + let Some((_lang_name, language_file)) = language_tuple else { + return Ok(HashMap::new()); + }; + + let mut bundle = HashMap::new(); + let lines = language_file.trim().lines(); + for line in lines { + if line.trim().starts_with('#') { + continue; + } + let (key, val) = line + .split_once('=') + .ok_or("malformed translation file: line without \"=\"")?; + let (key, val) = (key.trim(), val.trim()); + if val.is_empty() { + return Err("malformed translation file: empty translation value"); + } + let duplicate = bundle.insert(key.trim(), val.trim()); + if duplicate.is_some() { + return Err("malformed translation file: duplicate key"); + } + } + Ok(bundle) +} + +/// Convert language + region to a string to be able to get a file name. +fn lang_str(lang: Lang, region: Option) -> EcoString { + EcoString::from(lang.as_str()) + + region.map_or_else(EcoString::new, |r| EcoString::from("-") + r.as_str()) +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/typst/src/text/raw.rs b/crates/typst/src/text/raw.rs index dc288a662..ae7525be8 100644 --- a/crates/typst/src/text/raw.rs +++ b/crates/typst/src/text/raw.rs @@ -9,6 +9,7 @@ use syntect::highlighting as synt; use syntect::parsing::{SyntaxDefinition, SyntaxSet, SyntaxSetBuilder}; use unicode_segmentation::UnicodeSegmentation; +use super::Lang; use crate::diag::{At, FileError, SourceResult, StrResult}; use crate::engine::Engine; use crate::foundations::{ @@ -19,10 +20,9 @@ use crate::layout::{BlockElem, Em, HAlignment}; use crate::model::{Figurable, ParElem}; use crate::syntax::{split_newlines, LinkedNode, Span, Spanned}; use crate::text::{ - FontFamily, FontList, Hyphenate, Lang, LinebreakElem, LocalName, Region, - SmartQuoteElem, TextElem, TextSize, + FontFamily, FontList, Hyphenate, LinebreakElem, LocalName, SmartQuoteElem, TextElem, + TextSize, }; -use crate::util::option_eq; use crate::visualize::Color; use crate::{syntax, World}; @@ -456,39 +456,7 @@ impl ShowSet for Packed { } impl LocalName for Packed { - fn local_name(lang: Lang, region: Option) -> &'static str { - match lang { - Lang::ALBANIAN => "List", - Lang::ARABIC => "قائمة", - Lang::BOKMÅL => "Utskrift", - Lang::CATALAN => "Llistat", - Lang::CHINESE if option_eq(region, "TW") => "程式", - Lang::CHINESE => "代码", - Lang::CZECH => "Seznam", - Lang::DANISH => "Liste", - Lang::DUTCH => "Listing", - Lang::ESTONIAN => "List", - Lang::FILIPINO => "Listahan", - Lang::FINNISH => "Listaus", - Lang::FRENCH => "Liste", - Lang::GERMAN => "Listing", - Lang::GREEK => "Παράθεση", - Lang::ITALIAN => "Codice", - Lang::NYNORSK => "Utskrift", - Lang::POLISH => "Program", - Lang::ROMANIAN => "Listă", // TODO: I dunno - Lang::RUSSIAN => "Листинг", - Lang::SERBIAN => "Програм", - Lang::SLOVENIAN => "Program", - Lang::SPANISH => "Listado", - Lang::SWEDISH => "Listing", - Lang::TURKISH => "Liste", - Lang::UKRAINIAN => "Лістинг", - Lang::VIETNAMESE => "Chương trình", // TODO: This may be wrong. - Lang::JAPANESE => "リスト", - Lang::ENGLISH | _ => "Listing", - } - } + const KEY: &'static str = "raw"; } impl Figurable for Packed {} diff --git a/crates/typst/src/visualize/image/mod.rs b/crates/typst/src/visualize/image/mod.rs index 2b80567db..c1715f7a3 100644 --- a/crates/typst/src/visualize/image/mod.rs +++ b/crates/typst/src/visualize/image/mod.rs @@ -26,8 +26,8 @@ use crate::layout::{ use crate::loading::Readable; use crate::model::Figurable; use crate::syntax::{Span, Spanned}; -use crate::text::{families, Lang, LocalName, Region}; -use crate::util::{option_eq, LazyHash}; +use crate::text::{families, LocalName}; +use crate::util::LazyHash; use crate::visualize::Path; use crate::World; @@ -264,41 +264,7 @@ impl LayoutSingle for Packed { } impl LocalName for Packed { - fn local_name(lang: Lang, region: Option) -> &'static str { - match lang { - Lang::ALBANIAN => "Figurë", - Lang::ARABIC => "شكل", - Lang::BOKMÅL => "Figur", - Lang::CATALAN => "Figura", - Lang::CHINESE if option_eq(region, "TW") => "圖", - Lang::CHINESE => "图", - Lang::CZECH => "Obrázek", - Lang::DANISH => "Figur", - Lang::DUTCH => "Figuur", - Lang::ESTONIAN => "Joonis", - Lang::FILIPINO => "Pigura", - Lang::FINNISH => "Kuva", - Lang::FRENCH => "Fig.", - Lang::GERMAN => "Abbildung", - Lang::GREEK => "Σχήμα", - Lang::HUNGARIAN => "Ábra", - Lang::ITALIAN => "Figura", - Lang::NYNORSK => "Figur", - Lang::POLISH => "Rysunek", - Lang::PORTUGUESE => "Figura", - Lang::ROMANIAN => "Figura", - Lang::RUSSIAN => "Рис.", - Lang::SERBIAN => "Слика", - Lang::SLOVENIAN => "Slika", - Lang::SPANISH => "Figura", - Lang::SWEDISH => "Figur", - Lang::TURKISH => "Şekil", - Lang::UKRAINIAN => "Рисунок", - Lang::VIETNAMESE => "Hình", - Lang::JAPANESE => "図", - Lang::ENGLISH | _ => "Figure", - } - } + const KEY: &'static str = "figure"; } impl Figurable for Packed {} diff --git a/crates/typst/translations/ar.txt b/crates/typst/translations/ar.txt new file mode 100644 index 000000000..5c17d379d --- /dev/null +++ b/crates/typst/translations/ar.txt @@ -0,0 +1,7 @@ +figure = شكل +table = جدول +equation = معادلة +bibliography = المراجع +heading = الفصل +outline = المحتويات +raw = قائمة \ No newline at end of file diff --git a/crates/typst/translations/cs.txt b/crates/typst/translations/cs.txt new file mode 100644 index 000000000..136705862 --- /dev/null +++ b/crates/typst/translations/cs.txt @@ -0,0 +1,7 @@ +figure = Obrázek +table = Tabulka +equation = Rovnice +bibliography = Bibliografie +heading = Kapitola +outline = Obsah +raw = Seznam \ No newline at end of file diff --git a/crates/typst/translations/da.txt b/crates/typst/translations/da.txt new file mode 100644 index 000000000..9664c3b0b --- /dev/null +++ b/crates/typst/translations/da.txt @@ -0,0 +1,7 @@ +figure = Figur +table = Tabel +equation = Ligning +bibliography = Bibliografi +heading = Afsnit +outline = Indhold +raw = Liste \ No newline at end of file diff --git a/crates/typst/translations/de.txt b/crates/typst/translations/de.txt new file mode 100644 index 000000000..8ba72adb4 --- /dev/null +++ b/crates/typst/translations/de.txt @@ -0,0 +1,7 @@ +figure = Abbildung +table = Tabelle +equation = Gleichung +bibliography = Bibliographie +heading = Abschnitt +outline = Inhaltsverzeichnis +raw = Listing \ No newline at end of file diff --git a/crates/typst/translations/en.txt b/crates/typst/translations/en.txt new file mode 100644 index 000000000..02e7accd1 --- /dev/null +++ b/crates/typst/translations/en.txt @@ -0,0 +1,7 @@ +figure = Figure +table = Table +equation = Equation +bibliography = Bibliography +heading = Section +outline = Contents +raw = Listing \ No newline at end of file diff --git a/crates/typst/translations/es.txt b/crates/typst/translations/es.txt new file mode 100644 index 000000000..b0e56642b --- /dev/null +++ b/crates/typst/translations/es.txt @@ -0,0 +1,7 @@ +figure = Figura +table = Tabla +equation = Ecuación +bibliography = Bibliografía +heading = Sección +outline = Índice +raw = Listado \ No newline at end of file diff --git a/crates/typst/translations/et.txt b/crates/typst/translations/et.txt new file mode 100644 index 000000000..01f23b4b1 --- /dev/null +++ b/crates/typst/translations/et.txt @@ -0,0 +1,7 @@ +figure = Joonis +table = Tabel +equation = Valem +bibliography = Viited +heading = Peatükk +outline = Sisukord +raw = List \ No newline at end of file diff --git a/crates/typst/translations/fi.txt b/crates/typst/translations/fi.txt new file mode 100644 index 000000000..da516d243 --- /dev/null +++ b/crates/typst/translations/fi.txt @@ -0,0 +1,7 @@ +figure = Kuva +table = Taulukko +equation = Yhtälö +bibliography = Viitteet +heading = Osio +outline = Sisällys +raw = Esimerkki \ No newline at end of file diff --git a/crates/typst/translations/fr.txt b/crates/typst/translations/fr.txt new file mode 100644 index 000000000..6c5b60f67 --- /dev/null +++ b/crates/typst/translations/fr.txt @@ -0,0 +1,7 @@ +figure = Fig. +table = Tableau +equation = Équation +bibliography = Bibliographie +heading = Chapitre +outline = Table des matières +raw = Liste \ No newline at end of file diff --git a/crates/typst/translations/gr.txt b/crates/typst/translations/gr.txt new file mode 100644 index 000000000..34aa3c44d --- /dev/null +++ b/crates/typst/translations/gr.txt @@ -0,0 +1,7 @@ +figure = Σχήμα +table = Πίνακας +equation = Εξίσωση +bibliography = Βιβλιογραφία +heading = Κεφάλαιο +outline = Περιεχόμενα +raw = Παράθεση \ No newline at end of file diff --git a/crates/typst/translations/hu.txt b/crates/typst/translations/hu.txt new file mode 100644 index 000000000..f1b616b73 --- /dev/null +++ b/crates/typst/translations/hu.txt @@ -0,0 +1,7 @@ +figure = Ábra +table = Táblázat +equation = Egyenlet +bibliography = Irodalomjegyzék +heading = Fejezet +outline = Tartalomjegyzék +# raw = \ No newline at end of file diff --git a/crates/typst/translations/it.txt b/crates/typst/translations/it.txt new file mode 100644 index 000000000..4c1cd90c2 --- /dev/null +++ b/crates/typst/translations/it.txt @@ -0,0 +1,7 @@ +figure = Figura +table = Tabella +equation = Equazione +bibliography = Bibliografia +heading = Sezione +outline = Indice +raw = Codice \ No newline at end of file diff --git a/crates/typst/translations/ja.txt b/crates/typst/translations/ja.txt new file mode 100644 index 000000000..6c1f6f9c0 --- /dev/null +++ b/crates/typst/translations/ja.txt @@ -0,0 +1,7 @@ +figure = 図 +table = 表 +equation = 式 +bibliography = 参考文献 +heading = 節 +outline = 目次 +raw = リスト \ No newline at end of file diff --git a/crates/typst/translations/nb.txt b/crates/typst/translations/nb.txt new file mode 100644 index 000000000..f51bcd75a --- /dev/null +++ b/crates/typst/translations/nb.txt @@ -0,0 +1,7 @@ +figure = Figur +table = Tabell +equation = Ligning +bibliography = Bibliografi +heading = Kapittel +outline = Innhold +raw = Utskrift \ No newline at end of file diff --git a/crates/typst/translations/nl.txt b/crates/typst/translations/nl.txt new file mode 100644 index 000000000..ecd464b3b --- /dev/null +++ b/crates/typst/translations/nl.txt @@ -0,0 +1,7 @@ +figure = Figuur +table = Tabel +equation = Vergelijking +bibliography = Bibliografie +heading = Hoofdstuk +outline = Inhoudsopgave +raw = Listing \ No newline at end of file diff --git a/crates/typst/translations/nn.txt b/crates/typst/translations/nn.txt new file mode 100644 index 000000000..b067bc56e --- /dev/null +++ b/crates/typst/translations/nn.txt @@ -0,0 +1,7 @@ +figure = Figur +table = Tabell +equation = Likning +bibliography = Bibliografi +heading = Kapittel +outline = Innhald +raw = Utskrift \ No newline at end of file diff --git a/crates/typst/translations/pl.txt b/crates/typst/translations/pl.txt new file mode 100644 index 000000000..c49342571 --- /dev/null +++ b/crates/typst/translations/pl.txt @@ -0,0 +1,7 @@ +figure = Rysunek +table = Tabela +equation = Równanie +bibliography = Bibliografia +heading = Sekcja +outline = Spis treści +raw = Program \ No newline at end of file diff --git a/crates/typst/translations/pt-PT.txt b/crates/typst/translations/pt-PT.txt new file mode 100644 index 000000000..6fbb586af --- /dev/null +++ b/crates/typst/translations/pt-PT.txt @@ -0,0 +1,7 @@ +# figure = +# table = +# equation = +# bibliography = +heading = Secção +outline = Índice +# raw = \ No newline at end of file diff --git a/crates/typst/translations/pt.txt b/crates/typst/translations/pt.txt new file mode 100644 index 000000000..a8372e6d0 --- /dev/null +++ b/crates/typst/translations/pt.txt @@ -0,0 +1,7 @@ +figure = Figura +table = Tabela +equation = Equação +bibliography = Bibliografia +heading = Seção +outline = Sumário +raw = Listagem \ No newline at end of file diff --git a/crates/typst/translations/ro.txt b/crates/typst/translations/ro.txt new file mode 100644 index 000000000..44d6bc8b6 --- /dev/null +++ b/crates/typst/translations/ro.txt @@ -0,0 +1,8 @@ +figure = Figura +table = Tabelul +equation = Ecuația +bibliography = Bibliografie +heading = Secțiunea +outline = Cuprins +# may be wrong +raw = Listă \ No newline at end of file diff --git a/crates/typst/translations/ru.txt b/crates/typst/translations/ru.txt new file mode 100644 index 000000000..fccf7bc9a --- /dev/null +++ b/crates/typst/translations/ru.txt @@ -0,0 +1,7 @@ +figure = Рис. +table = Таблица +equation = Уравнение +bibliography = Библиография +heading = Раздел +outline = Содержание +raw = Листинг \ No newline at end of file diff --git a/crates/typst/translations/sl.txt b/crates/typst/translations/sl.txt new file mode 100644 index 000000000..1375c4dda --- /dev/null +++ b/crates/typst/translations/sl.txt @@ -0,0 +1,7 @@ +figure = Slika +table = Tabela +equation = Enačba +bibliography = Literatura +heading = Poglavje +outline = Kazalo +raw = Program \ No newline at end of file diff --git a/crates/typst/translations/sq.txt b/crates/typst/translations/sq.txt new file mode 100644 index 000000000..3b4295458 --- /dev/null +++ b/crates/typst/translations/sq.txt @@ -0,0 +1,7 @@ +figure = Figurë +table = Tabel +equation = Ekuacion +bibliography = Bibliografi +heading = Kapitull +outline = Përmbajtja +raw = List \ No newline at end of file diff --git a/crates/typst/translations/sr.txt b/crates/typst/translations/sr.txt new file mode 100644 index 000000000..3a2f92b9b --- /dev/null +++ b/crates/typst/translations/sr.txt @@ -0,0 +1,7 @@ +figure = Слика +table = Табела +equation = Једначина +bibliography = Литература +heading = Поглавље +outline = Садржај +raw = Програм \ No newline at end of file diff --git a/crates/typst/translations/sv.txt b/crates/typst/translations/sv.txt new file mode 100644 index 000000000..61a394038 --- /dev/null +++ b/crates/typst/translations/sv.txt @@ -0,0 +1,7 @@ +figure = Figur +table = Tabell +equation = Ekvation +bibliography = Bibliografi +heading = Kapitel +outline = Innehåll +raw = Listing \ No newline at end of file diff --git a/crates/typst/translations/tl.txt b/crates/typst/translations/tl.txt new file mode 100644 index 000000000..a7b6b5712 --- /dev/null +++ b/crates/typst/translations/tl.txt @@ -0,0 +1,7 @@ +figure = Pigura +table = Talaan +equation = Ekwasyon +bibliography = Bibliograpiya +heading = Seksyon +outline = Talaan ng mga Nilalaman +raw = Listahan \ No newline at end of file diff --git a/crates/typst/translations/tr.txt b/crates/typst/translations/tr.txt new file mode 100644 index 000000000..a7068a4f1 --- /dev/null +++ b/crates/typst/translations/tr.txt @@ -0,0 +1,7 @@ +figure = Şekil +table = Tablo +equation = Denklem +bibliography = Kaynakça +heading = Bölüm +outline = İçindekiler +raw = Liste \ No newline at end of file diff --git a/crates/typst/translations/ua.txt b/crates/typst/translations/ua.txt new file mode 100644 index 000000000..30b409a6d --- /dev/null +++ b/crates/typst/translations/ua.txt @@ -0,0 +1,7 @@ +figure = Рисунок +table = Таблиця +equation = Рівняння +bibliography = Бібліографія +heading = Розділ +outline = Зміст +raw = Лістинг \ No newline at end of file diff --git a/crates/typst/translations/vi.txt b/crates/typst/translations/vi.txt new file mode 100644 index 000000000..a65ac09ab --- /dev/null +++ b/crates/typst/translations/vi.txt @@ -0,0 +1,8 @@ +figure = Hình +table = Bảng +equation = Phương trình +bibliography = Tài liệu tham khảo +heading = Phần +outline = Mục lục +# may be wrong +raw = Chương trình \ No newline at end of file diff --git a/crates/typst/translations/zh-TW.txt b/crates/typst/translations/zh-TW.txt new file mode 100644 index 000000000..88035d650 --- /dev/null +++ b/crates/typst/translations/zh-TW.txt @@ -0,0 +1,7 @@ +figure = 圖 +# table = +equation = 方程式 +bibliography = 書目 +heading = 小節 +outline = 目錄 +raw = 程式 \ No newline at end of file diff --git a/crates/typst/translations/zh.txt b/crates/typst/translations/zh.txt new file mode 100644 index 000000000..f862fff4a --- /dev/null +++ b/crates/typst/translations/zh.txt @@ -0,0 +1,7 @@ +figure = 图 +table = 表 +equation = 公式 +bibliography = 参考文献 +heading = 小节 +outline = 目录 +raw = 代码 \ No newline at end of file diff --git a/tests/ref/text-language-fallback-english.png b/tests/ref/text-language-fallback-english.png new file mode 100644 index 0000000000000000000000000000000000000000..1f4bf74d1fcb3db175293ac157ee5fb44811c848 GIT binary patch literal 922 zcmV;L17-Y)P)(muO5K(oQd;|XnqdFpMInIw zfd2m!K*WPK3G9`#VPMP+a05nWARrq<2^jSmhWo`zvd@YR6hAe|i}S6A3e;g74~eyz z(G9ku2EA{Yd{V1cdi9s3U~_-0dRtYyQTV95z-)sVd-+K{$AlCP2k%`4cDV>otmCli zXR91xk2*y_Ho+PB%6H5td`>EutzDf2OU{fYkHN}ZcvoBusgm8VRJ+)voOG#U_@x#m z^0V5aMq&5-%qsw3SNmXTPU0496DNb}X@Fa>M`|E3x>0R03S*b*F#Ne)|2bm=!R%)U zNChms~X_A>cA^yu=BT>@@0l$J}xP4u5Z!c^Ze~qHRF-3lH1>v zp$fnzsdYsoeTC}FI<>~Hza&cwZP)+eh*A}#9v3twca zH=@0kd>dyLtLz=RqgbB5Q6Uezs8Hp9b*}Dst<807*qoM6N<$f)3QK)c^nh literal 0 HcmV?d00001 diff --git a/tests/suite/text/lang.typ b/tests/suite/text/lang.typ index 74f701407..9bce5c3c3 100644 --- a/tests/suite/text/lang.typ +++ b/tests/suite/text/lang.typ @@ -72,3 +72,9 @@ --- text-region-bad-value --- // Error: 19-24 expected two letter region code (ISO 3166-1 alpha-2) #set text(region: "hey") + +--- text-language-fallback-english --- +#set text(lang: "qaa") +#outline() +#set text(lang: "qaa", region: "aa") +#outline() \ No newline at end of file