diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-04-19 12:17:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-19 10:17:03 +0000 |
commit | 7787cab521ccc6b4d8533ebe9b45563046e0463d (patch) | |
tree | d1277fa3846f24cc99859310da3d7f099c73bfc5 /components/layout/quotes.rs | |
parent | 3ab5b8c4472129798b63cfb40b63ae672763b653 (diff) | |
download | servo-7787cab521ccc6b4d8533ebe9b45563046e0463d.tar.gz servo-7787cab521ccc6b4d8533ebe9b45563046e0463d.zip |
layout: Combine `layout_2020` and `layout_thread_2020` into a crate called `layout` (#36613)
Now that legacy layout has been removed, the name `layout_2020` doesn't
make much sense any longer, also it's 2025 now for better or worse. The
split between the "layout thread" and "layout" also doesn't make as much
sense since layout doesn't run on it's own thread. There's a possibility
that it will in the future, but that should be something that the user
of the crate controls rather than layout iself.
This is part of the larger layout interface cleanup and optimization
that
@Looriool and I are doing.
Testing: Covered by existing tests as this is just code movement.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/layout/quotes.rs')
-rw-r--r-- | components/layout/quotes.rs | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/components/layout/quotes.rs b/components/layout/quotes.rs new file mode 100644 index 00000000000..05e9e06fe89 --- /dev/null +++ b/components/layout/quotes.rs @@ -0,0 +1,427 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// Quotes data is obtained from ICU CLDR data file /tmp/cldr-common-46.0.zip. + +// TODO(xiaochengh): This file should better be moved to elsewhere and maintained automatically. +// Or even better, extend the icu create to provide the data directly. + +use std::collections::HashMap; +use std::sync::OnceLock; + +use icu_locid::Locale; + +#[derive(Clone, Copy, Debug)] +pub struct QuotePair { + pub opening: char, + pub closing: char, +} + +#[derive(Clone, Copy, Debug)] +struct QuotesData { + quotes: QuotePair, + alternative_quotes: QuotePair, +} + +impl QuotesData { + const fn from(chars: (char, char, char, char)) -> Self { + QuotesData { + quotes: QuotePair { + opening: chars.0, + closing: chars.1, + }, + alternative_quotes: QuotePair { + opening: chars.2, + closing: chars.3, + }, + } + } +} + +static DEFAULT_QUOTES: QuotesData = + QuotesData::from(('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')); + +static QUOTES_MAP: OnceLock<HashMap<&'static str, QuotesData>> = OnceLock::new(); + +fn create_quotes_map() -> HashMap<&'static str, QuotesData> { + let input = [ + ("aa", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ab", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("af", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ak", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("an", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ann", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("apc", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("arn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("as", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("asa", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("az", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ba", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bal", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bem", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bew", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bez", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bgc", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bgn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bho", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("blt", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("brx", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("bss", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("byn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("cad", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("cch", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ccp", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ce", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ceb", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("cgg", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("cho", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("chr", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("cic", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ckb", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("co", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("csw", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("cu", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("cy", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("da", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("dav", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("dje", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("doi", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("dv", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("dz", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ebu", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ee", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("en", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("eo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("es", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("fil", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("fo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("frr", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("fur", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("fy", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ga", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("gaa", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("gd", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("gez", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("gl", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("gn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("gu", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("guz", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("gv", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ha", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("haw", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("hi", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("hnj", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("id", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ig", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ii", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("io", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("iu", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("jbo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("jmc", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("jv", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kaa", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kaj", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kam", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kcg", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kde", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kea", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ken", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kgp", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("khq", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ki", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kl", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kln", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("km", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ko", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kok", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kpe", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ks", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ksb", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ksh", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ku", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kw", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("kxv", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("la", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("lg", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("lkt", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("lmo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ln", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("lo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("lrc", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ltg", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("lu", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("luo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("lv", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mai", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mas", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mdf", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mer", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mfe", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mgh", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mgo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mhn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mi", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mic", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ml", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mni", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("moh", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mr", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ms", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mt", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("mus", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("my", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("myv", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("naq", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("nb", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("nd", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("nds", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ne", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("nn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("nqo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("nr", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("nus", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("nv", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ny", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("nyn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("oc", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("om", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("or", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("os", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("osa", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("pa", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("pap", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("pcm", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("pis", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("prg", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ps", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("pt", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("qu", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("quc", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("raj", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("rhg", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("rif", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("rm", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("rof", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("rwk", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("sa", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("saq", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("sat", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("sbp", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("scn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("sd", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("se", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("seh", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ses", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("shn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("si", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("sid", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("skr", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("sma", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("smj", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("smn", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("sms", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("so", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ss", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ssy", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("su", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("sw", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("szl", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ta", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("te", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("teo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("tg", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("th", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("tig", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("to", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("tok", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("tpi", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("tr", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("trv", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("trw", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ts", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("tt", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("twq", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("tyv", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("tzm", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ug", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("vai", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("ve", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("vec", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("vi", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("vmw", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("vo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("vun", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("wa", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("wae", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("wal", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("wbp", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("wo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("xh", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("xnr", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("xog", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("yi", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("yo", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("yrl", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("za", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("zh", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("zu", ('\u{201c}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("agq", ('\u{201e}', '\u{201d}', '\u{201a}', '\u{2019}')), + ("ff", ('\u{201e}', '\u{201d}', '\u{201a}', '\u{2019}')), + ("am", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("az-Arab", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("az-Cyrl", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("fa", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("fr-CH", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("gsw", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("jgo", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("kkj", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("mzn", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("sdh", ('\u{ab}', '\u{bb}', '\u{2039}', '\u{203a}')), + ("ar", ('\u{201d}', '\u{201c}', '\u{2019}', '\u{2018}')), + ("lld", ('\u{201d}', '\u{201c}', '\u{2019}', '\u{2018}')), + ("ms-Arab", ('\u{201d}', '\u{201c}', '\u{2019}', '\u{2018}')), + ("syr", ('\u{201d}', '\u{201c}', '\u{2019}', '\u{2018}')), + ("ur", ('\u{201d}', '\u{201c}', '\u{2019}', '\u{2018}')), + ("ast", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("blo", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("bm", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("br", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("ca", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("dyo", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("el", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("es-US", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("eu", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("ewo", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("ie", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("it", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("kab", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("kk", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("lij", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("mg", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("mua", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("nnh", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("pt-PT", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("sc", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("sg", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("sq", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("ti", ('\u{ab}', '\u{bb}', '\u{201c}', '\u{201d}')), + ("bas", ('\u{ab}', '\u{bb}', '\u{201e}', '\u{201c}')), + ("be", ('\u{ab}', '\u{bb}', '\u{201e}', '\u{201c}')), + ("cv", ('\u{ab}', '\u{bb}', '\u{201e}', '\u{201c}')), + ("ky", ('\u{ab}', '\u{bb}', '\u{201e}', '\u{201c}')), + ("ru", ('\u{ab}', '\u{bb}', '\u{201e}', '\u{201c}')), + ("sah", ('\u{ab}', '\u{bb}', '\u{201e}', '\u{201c}')), + ("uk", ('\u{ab}', '\u{bb}', '\u{201e}', '\u{201c}')), + ("bg", ('\u{201e}', '\u{201c}', '\u{201e}', '\u{201c}')), + ("lt", ('\u{201e}', '\u{201c}', '\u{201e}', '\u{201c}')), + ("bs-Cyrl", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("cs", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("de", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("dsb", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("et", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("hr", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("hsb", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("is", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("lb", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("luy", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("mk", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("sk", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("sl", ('\u{201e}', '\u{201c}', '\u{201a}', '\u{2018}')), + ("bs", ('\u{201e}', '\u{201d}', '\u{2018}', '\u{2019}')), + ("dua", ('\u{ab}', '\u{bb}', '\u{2018}', '\u{2019}')), + ("el-POLYTON", ('\u{ab}', '\u{bb}', '\u{2018}', '\u{2019}')), + ("ksf", ('\u{ab}', '\u{bb}', '\u{2018}', '\u{2019}')), + ("no", ('\u{ab}', '\u{bb}', '\u{2018}', '\u{2019}')), + ("rw", ('\u{ab}', '\u{bb}', '\u{2018}', '\u{2019}')), + ("fi", ('\u{201d}', '\u{201d}', '\u{2019}', '\u{2019}')), + ("he", ('\u{201d}', '\u{201d}', '\u{2019}', '\u{2019}')), + ("lag", ('\u{201d}', '\u{201d}', '\u{2019}', '\u{2019}')), + ("rn", ('\u{201d}', '\u{201d}', '\u{2019}', '\u{2019}')), + ("sn", ('\u{201d}', '\u{201d}', '\u{2019}', '\u{2019}')), + ("sv", ('\u{201d}', '\u{201d}', '\u{2019}', '\u{2019}')), + ("fr-CA", ('\u{ab}', '\u{bb}', '\u{201d}', '\u{201c}')), + ("fr", ('\u{ab}', '\u{bb}', '\u{ab}', '\u{bb}')), + ("hy", ('\u{ab}', '\u{bb}', '\u{ab}', '\u{bb}')), + ("yav", ('\u{ab}', '\u{bb}', '\u{ab}', '\u{bb}')), + ("hu", ('\u{201e}', '\u{201d}', '\u{bb}', '\u{ab}')), + ("ia", ('\u{2018}', '\u{2019}', '\u{201c}', '\u{201d}')), + ("nso", ('\u{2018}', '\u{2019}', '\u{201c}', '\u{201d}')), + ("ti-ER", ('\u{2018}', '\u{2019}', '\u{201c}', '\u{201d}')), + ("tn", ('\u{2018}', '\u{2019}', '\u{201c}', '\u{201d}')), + ("ja", ('\u{300c}', '\u{300d}', '\u{300e}', '\u{300f}')), + ("yue", ('\u{300c}', '\u{300d}', '\u{300e}', '\u{300f}')), + ("zh-Hant", ('\u{300c}', '\u{300d}', '\u{300e}', '\u{300f}')), + ("ka", ('\u{201e}', '\u{201c}', '\u{ab}', '\u{bb}')), + ("nl", ('\u{2018}', '\u{2019}', '\u{2018}', '\u{2019}')), + ("nmg", ('\u{201e}', '\u{201d}', '\u{ab}', '\u{bb}')), + ("pl", ('\u{201e}', '\u{201d}', '\u{ab}', '\u{bb}')), + ("ro", ('\u{201e}', '\u{201d}', '\u{ab}', '\u{bb}')), + ("shi", ('\u{ab}', '\u{bb}', '\u{201e}', '\u{201d}')), + ("zgh", ('\u{ab}', '\u{bb}', '\u{201e}', '\u{201d}')), + ("sr", ('\u{201e}', '\u{201d}', '\u{2019}', '\u{2019}')), + ("st", ('\u{201c}', '\u{2019}', '\u{201c}', '\u{201d}')), + ("tk", ('\u{201c}', '\u{201d}', '\u{201c}', '\u{201d}')), + ("uz", ('\u{201c}', '\u{201d}', '\u{2019}', '\u{2018}')), + ] + .map(|(lang, chars)| (lang, QuotesData::from(chars))); + HashMap::from(input) +} + +fn quotes_data_for_lang(lang: &str) -> QuotesData { + // All valid language codes are at least two bytes long. + if lang.len() < 2 { + return DEFAULT_QUOTES; + } + + let quotes_map = QUOTES_MAP.get_or_init(create_quotes_map); + + // Found an exact match for the requested lang. + if let Some(quotes_data) = quotes_map.get(lang) { + return *quotes_data; + } + + // Try parsing lang as a Locale and canonicalizing the subtags, then see if + // we can match it with region or script subtags, if present, or just the + // primary language tag. + let locale = match lang.parse::<Locale>() { + Err(_) => return DEFAULT_QUOTES, + Ok(locale) => locale, + }; + + let lang = locale.id.language.to_string(); + + if let Some(quotes_data) = quotes_map.get(lang.as_str()) { + return *quotes_data; + } + + if let Some(quotes_data) = locale + .id + .region + .and_then(|region| quotes_map.get(format!("{lang}-{region}").as_str())) + { + return *quotes_data; + } + + if let Some(quotes_data) = locale + .id + .script + .and_then(|script| quotes_map.get(format!("{lang}-{script}").as_str())) + { + return *quotes_data; + } + + DEFAULT_QUOTES +} + +pub fn quotes_for_lang(lang: &str, depth: usize) -> QuotePair { + let quotes_data = quotes_data_for_lang(lang); + match depth { + 0 => quotes_data.quotes, + _ => quotes_data.alternative_quotes, + } +} |