Skip to content

Commit 9aec53f

Browse files
committed
CLDR 48 tests in the green
1 parent 8cd19f8 commit 9aec53f

File tree

7 files changed

+112
-89
lines changed

7 files changed

+112
-89
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
Note that as of Cldr Locale Display version 1.5.0, Elixir 1.12 or later is required.
44

5+
## Cldr Locale Display v1.7.0
6+
7+
This is the changelog for Cldr Locale Display v1.7.0 released on ______, 2025. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_locale_display/tags)
8+
9+
### Enhancements
10+
11+
* Updates to [CLDR 48](https://cldr.unicode.org/downloads/cldr-48) data and tests.
12+
513
## Cldr Locale Display v1.6.2
614

715
This is the changelog for Cldr Locale Display v1.6.2 released on October 14th, 2025. For older changelogs please consult the release tag on [GitHub](https://github.com/elixir-cldr/cldr_locale_display/tags)

lib/cldr/backend.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ defmodule Cldr.LocaleDisplay.Backend do
5151
5252
* `:prefer` signals the preferred name for
5353
a subtag when there are alternatives.
54-
The default is `:default`. Few subtags
54+
The default is `:standard`. Few subtags
5555
provide alternative renderings. Some of
5656
the alternative preferences are `:short`,
5757
`:long`, `:menu` and `:variant`.
@@ -126,7 +126,7 @@ defmodule Cldr.LocaleDisplay.Backend do
126126
127127
* `:prefer` signals the preferred name for
128128
a subtag when there are alternatives.
129-
The default is `:default`. Few subtags
129+
The default is `:standard`. Few subtags
130130
provide alternative renderings. Some of
131131
the alternative preferences are`:short`,
132132
`:long`, `:menu` and `:variant`.

lib/cldr/locale_display.ex

Lines changed: 51 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ defmodule Cldr.LocaleDisplay do
5252
5353
* `:prefer` signals the preferred name for
5454
a subtag when there are alternatives.
55-
The default is `:default`. Few subtags
55+
The default is `:standard`. Few subtags
5656
provide alternative renderings. Some of
5757
the alternative preferences are`:short`,
5858
`:long`, `:menu` and `:variant`.
@@ -116,50 +116,55 @@ defmodule Cldr.LocaleDisplay do
116116

117117
def display_name(%LanguageTag{} = language_tag, options) do
118118
{in_locale, backend} = Cldr.locale_and_backend_from(options)
119-
language_display = Keyword.get(options, :language_display, :standard)
120-
prefer = Keyword.get(options, :prefer, :default)
119+
options = Keyword.merge(default_options(), options)
120+
121+
standard_or_dialect = Keyword.get(options, :language_display)
122+
prefer = Keyword.get(options, :prefer)
123+
124+
# FIXME Catering for legacy
125+
prefer = if prefer == :default, do: :standard, else: prefer
121126

122127
with {:ok, in_locale} <- Cldr.validate_locale(in_locale, backend) do
123128
options = Keyword.put(options, :locale, in_locale)
124129

125130
{:ok, display_names} =
126131
Module.concat(in_locale.backend, :LocaleDisplay).display_names(in_locale)
127132

128-
match_fun = &language_match_fun(&1, &2, display_names.language)
129-
130-
case first_match(
131-
language_tag,
132-
match_fun,
133-
@omit_script_if_only_one,
134-
language_display,
135-
prefer
136-
) do
137-
{language_name, matched_tags} ->
138-
language_tag = merge_extensions_and_private_use(language_tag)
139-
140-
subtag_names =
141-
language_tag
142-
|> subtag_names(@basic_tag_order -- matched_tags, display_names, prefer)
143-
|> List.flatten()
144-
|> Enum.map(&replace_parens_with_brackets/1)
145-
|> join_subtags(display_names)
146-
147-
extension_names =
148-
@extension_order
149-
|> Enum.map(&Cldr.DisplayName.display_name(Map.fetch!(language_tag, &1), options))
150-
|> Enum.reject(&empty?/1)
151-
|> join_subtags(display_names)
152-
153-
{:ok, format_display_name(language_name, subtag_names, extension_names, display_names)}
154-
155-
nil ->
156-
{:error,
157-
{Cldr.DisplayName.NoDataError,
158-
"The locale #{inspect(in_locale)} has no display name data."}}
159-
end
133+
match_fun =
134+
&language_match_fun(&1, &2, :language, prefer, display_names)
135+
136+
{matched_tags, language_name} =
137+
first_match(language_tag, match_fun, @omit_script_if_only_one, standard_or_dialect)
138+
139+
language_tag =
140+
merge_extensions_and_private_use(language_tag)
141+
142+
subtag_names =
143+
language_tag
144+
|> subtag_names(@basic_tag_order -- matched_tags, prefer, display_names)
145+
|> List.flatten()
146+
|> Enum.map(&replace_parens_with_brackets/1)
147+
|> join_subtags(display_names)
148+
149+
extension_names =
150+
@extension_order
151+
|> Enum.map(&Cldr.DisplayName.display_name(Map.fetch!(language_tag, &1), options))
152+
|> Enum.reject(&empty?/1)
153+
|> join_subtags(display_names)
154+
155+
{:ok, format_display_name(language_name, subtag_names, extension_names, display_names)}
160156
end
161157
end
162158

159+
defp default_options do
160+
[
161+
prefer: :standard,
162+
add_likely_subtags: false,
163+
language_display: :standard,
164+
prefer: :standar
165+
]
166+
end
167+
163168
@doc """
164169
Returns a localised display name for a
165170
locale.
@@ -186,7 +191,7 @@ defmodule Cldr.LocaleDisplay do
186191
187192
* `:prefer` signals the preferred name for
188193
a subtag when there are alternatives.
189-
The default is `:default`. Few subtags
194+
The default is `:standard`. Few subtags
190195
provide alternative renderings. Some of
191196
the alternative preferences are`:short`,
192197
`:long`, `:menu` and `:variant`.
@@ -249,30 +254,24 @@ defmodule Cldr.LocaleDisplay do
249254

250255
# If matching on the compound locale then we
251256
# don't need to take any action
252-
defp first_match(language_tag, match_fun, omit_script_if_only_one?, :dialect, prefer) do
253-
case Cldr.Locale.first_match(language_tag, match_fun, omit_script_if_only_one?) do
254-
{language_name, matched_tags} ->
255-
{get_display_preference(language_name, prefer), matched_tags}
256-
257-
nil ->
258-
nil
259-
end
257+
defp first_match(language_tag, match_fun, omit_script_if_only_one?, :dialect) do
258+
Cldr.Locale.first_match(language_tag, match_fun, omit_script_if_only_one?)
260259
end
261260

262261
# If we don't want a compound language then we need to omit
263262
# the territory when matching but restore it afterwards so
264263
# its generated as a subtag
265264
@reinstate_subtags [:territory, :script]
266265

267-
defp first_match(language_tag, match_fun, omit_script_if_only_one?, :standard, prefer) do
266+
defp first_match(language_tag, match_fun, omit_script_if_only_one?, :standard) do
268267
language_tag =
269268
Enum.reduce(@reinstate_subtags, language_tag, fn key, tag ->
270269
Map.put(tag, key, nil)
271270
end)
272271

273272
case Cldr.Locale.first_match(language_tag, match_fun, omit_script_if_only_one?) do
274-
{language_name, matched_tags} ->
275-
{get_display_preference(language_name, prefer), matched_tags -- @reinstate_subtags}
273+
{matched_tags, display_name} ->
274+
{matched_tags -- @reinstate_subtags, display_name}
276275

277276
nil ->
278277
nil
@@ -297,11 +296,11 @@ defmodule Cldr.LocaleDisplay do
297296
|> List.to_string()
298297
end
299298

300-
defp subtag_names(_locale, [], _display_names, _prefer) do
299+
defp subtag_names(_locale, [], _prefer, _display_names) do
301300
[]
302301
end
303302

304-
defp subtag_names(locale, subtags, display_names, prefer) do
303+
defp subtag_names(locale, subtags, prefer, display_names) do
305304
subtags
306305
|> Enum.map(&get_display_name(locale, display_names, &1, prefer))
307306
|> Enum.reject(&empty?/1)
@@ -359,9 +358,9 @@ defmodule Cldr.LocaleDisplay do
359358
Enum.reduce(fields, &Cldr.Substitution.substitute([&2, &1], join_pattern))
360359
end
361360

362-
defp language_match_fun(locale_name, matched_tags, language_names) do
363-
if display_name = Map.get(language_names, locale_name) do
364-
{display_name, matched_tags}
361+
defp language_match_fun(locale_name, matched_tags, field, prefer, display_names) do
362+
if display_name = get_in(display_names, [field, locale_name, prefer]) do
363+
{matched_tags, display_name}
365364
else
366365
nil
367366
end

lib/cldr/locale_display/t.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ defmodule Cldr.LocaleDisplay.T do
3030
# Returns the localised value for the key. If there is
3131
# no available key name then just return the value.
3232

33-
defp display_value(:language, _key_name, value, transform, _in_locale, display_names, _prefer) do
33+
defp display_value(:language, _key_name, value, transform, in_locale, display_names, prefer) do
3434
key_name =
3535
if transform.h0 == :hybrid,
3636
do: get_in(display_names, [:types, :h0, :hybrid]),
3737
else: get_in(display_names, [:keys, :t])
3838

3939
value_name =
4040
value
41-
|> Cldr.display_name()
41+
|> Cldr.LocaleDisplay.display_name!(prefer: prefer, locale: in_locale)
4242
|> replace_parens_with_brackets()
4343

4444
if key_name do

lib/cldr/locale_display/u.ex

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -126,25 +126,28 @@ defmodule Cldr.LocaleDisplay.U do
126126
backend_module.known_subdivisions(locale)[subdivision]
127127
end
128128

129-
def get_timezone(zone, locale) do
129+
def get_timezone(timezone, locale) do
130130
backend_module = Module.concat(locale.backend, LocaleDisplay)
131-
{:ok, zone_names} = backend_module.time_zone_names(locale)
132131
{:ok, territory_format} = backend_module.territory_format(locale)
133-
zone_parts = String.split(zone, "/")
134-
downcase_zone_parts = Enum.map(zone_parts, &String.downcase/1)
135132

136-
case get_in(zone_names, downcase_zone_parts) do
137-
nil ->
138-
derive_zone_name(zone, zone_names, downcase_zone_parts, zone_parts, territory_format)
133+
with {:ok, display_name} <- timezone_display_name(timezone, locale) do
134+
Cldr.Substitution.substitute([display_name], territory_format)
135+
end
136+
end
137+
138+
def timezone_display_name(timezone, locale) do
139+
cond do
140+
territory = territory_has_only_this_zone(timezone) ->
141+
Cldr.Territory.display_name(territory, locale: locale)
139142

140-
zone_map ->
141-
case Map.get(zone_map, :exemplar_city) do
142-
nil ->
143-
derive_zone_name(zone, zone_names, downcase_zone_parts, zone_parts, territory_format)
143+
exemplar_city = exemplar_city(timezone, locale) ->
144+
{:ok, exemplar_city}
144145

145-
exemplar_city ->
146-
Cldr.Substitution.substitute([exemplar_city], territory_format)
147-
end
146+
derived_name = derive_zone_name(timezone, locale) ->
147+
{:ok, derived_name}
148+
149+
true ->
150+
{:ok, timezone}
148151
end
149152
end
150153

@@ -153,23 +156,36 @@ defmodule Cldr.LocaleDisplay.U do
153156
# the second part as a city name by replacing "_" with " ". This applies to zones like
154157
# "America/Los_Angeles", "America/New_York" and so on.
155158

156-
defp derive_zone_name(zone, zone_names, downcase_zone_parts, zone_parts, territory_format) do
157-
with [downcase_region, _downcase_city] <- downcase_zone_parts do
158-
case Map.get(zone_names, downcase_region) do
159-
nil ->
160-
zone
161-
162-
_region ->
163-
[_region, city] = zone_parts
164-
zone_name = String.replace(city, "_", " ")
165-
Cldr.Substitution.substitute([zone_name], territory_format)
166-
end
167-
else
168-
_other ->
169-
zone
159+
defp derive_zone_name(zone, locale) do
160+
backend_module = Module.concat(locale.backend, LocaleDisplay)
161+
{:ok, zone_names} = backend_module.time_zone_names(locale)
162+
zone_parts = String.split(zone, "/")
163+
downcase_zone_parts = Enum.map(zone_parts, &String.downcase/1)
164+
165+
if Map.get(zone_names, hd(downcase_zone_parts)) do
166+
zone_parts
167+
|> List.last()
168+
|> String.replace("_", " ")
169+
end
170+
end
171+
172+
defp territory_has_only_this_zone(zone) do
173+
territory = Cldr.Timezone.territories_by_timezone[zone]
174+
175+
if Cldr.Timezone.timezone_count_for_territory(territory) == 1 do
176+
territory
170177
end
171178
end
172179

180+
defp exemplar_city(zone, locale) do
181+
backend_module = Module.concat(locale.backend, LocaleDisplay)
182+
{:ok, zone_names} = backend_module.time_zone_names(locale)
183+
zone_parts = String.split(zone, "/")
184+
downcase_zone_parts = Enum.map(zone_parts, &String.downcase/1)
185+
186+
get_in(zone_names, downcase_zone_parts ++ [:exemplar_city])
187+
end
188+
173189
def get_currency(currency, locale) do
174190
case Cldr.Currency.currency_for_code(currency, locale.backend) do
175191
{:ok, currency} -> currency.symbol

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule Cldr.LocaleDisplay.MixProject do
22
use Mix.Project
33

4-
@version "1.6.2"
4+
@version "1.7.0"
55

66
def project do
77
[

test/locale_display_name_test.exs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ defmodule Cldr.LocaleDisplayName.Test do
6060
assert Cldr.display_name(~l(zh-Hans), language_display: :dialect) ==
6161
"Simplified Chinese (China)"
6262

63-
assert Cldr.display_name(~l(zh-Hant)u) == "Chinese (Traditional)"
64-
assert Cldr.display_name(~l(zh-Hans)u) == "Chinese (Simplified)"
65-
assert Cldr.display_name(~l(zh-Hant)) == "Chinese (Traditional, Taiwan)"
66-
assert Cldr.display_name(~l(zh-Hans)) == "Chinese (Simplified, China)"
63+
assert Cldr.display_name(~l(zh-Hant)u) == "Traditional Chinese"
64+
assert Cldr.display_name(~l(zh-Hans)u) == "Simplified Chinese"
65+
assert Cldr.display_name(~l(zh-Hant)) == "Traditional Chinese (Taiwan)"
66+
assert Cldr.display_name(~l(zh-Hans)) == "Simplified Chinese (China)"
6767
end
6868

6969
test "More complex language tags" do

0 commit comments

Comments
 (0)