Packages

ex_cldr

2.24.0-rc.2
2.47.5 2.47.4 2.47.3 2.47.2 2.47.1 2.47.0 2.46.0 2.45.2 2.45.1 2.45.0 2.44.1 2.44.0 2.43.2 2.43.1 2.43.0 2.42.0 2.41.1 2.41.0 2.40.4 2.40.3 2.40.2 2.40.1 2.40.0 2.39.2 2.39.1 2.39.0 2.38.1 2.38.0 2.37.5 2.37.4 2.37.3 retired 2.37.2 2.37.1 2.37.0 2.36.0 2.35.1 2.35.0 retired 2.34.2 2.34.1 2.34.0 2.33.2 2.33.1 2.33.1-rc.0 2.33.0 2.32.1 2.32.0 2.31.0 2.30.0 2.29.0 2.28.0 2.27.1 2.27.0 retired 2.26.3 2.26.2 2.26.1 2.26.0 2.25.0 2.24.2 2.24.1 2.24.0 2.24.0-rc.6 2.24.0-rc.5 2.24.0-rc.4 2.24.0-rc.3 2.24.0-rc.2 2.24.0-rc.1 2.24.0-rc.0 2.23.2 2.23.1 2.23.0 2.22.1 2.22.0 2.21.0 2.20.0 2.20.0-rc.3 2.20.0-rc.2 2.20.0-rc.1 2.20.0-rc.0 2.19.1 2.19.0 2.18.2 2.18.1 2.18.0 2.18.0-rc.0 2.17.2 2.17.1 2.17.0 2.16.2 2.16.1 2.16.1-rc.0 2.16.0 2.15.0 2.14.1 2.14.0 2.14.0-rc.0 2.13.0 2.12.1 2.12.0 2.11.1 2.11.0 2.10.2 2.10.1 2.10.0 retired 2.9.0 2.8.1 2.8.0 2.7.2 2.7.1 2.7.0 2.6.2 2.6.1 2.6.0 2.5.0 2.4.3 2.4.2 2.4.1 2.4.0 2.3.2 2.3.1 2.3.0 2.2.7 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 2.2.1 2.2.0 2.1.0 2.0.4 2.0.3 2.0.2 2.0.1 2.0.0 2.0.0-rc.3 retired 2.0.0-rc.2 retired 2.0.0-rc.1 retired 2.0.0-rc.0 retired 1.8.2 1.8.1 1.8.0 1.7.1 1.7.0 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.2 1.5.1 1.5.0 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 retired 1.4.0-rc.3 retired 1.4.0-rc.2 retired 1.4.0-rc.1 retired 1.4.0-rc.0 retired 1.3.2 1.3.1 1.3.0 1.2.0 1.1.0 1.0.0 1.0.0-rc.3 retired 1.0.0-rc.2 retired 1.0.0-rc.1 retired 1.0.0-rc.0 retired 0.13.1 0.13.0 0.12.2 retired 0.12.1 retired 0.12.0 retired 0.11.0 retired 0.10.0 retired 0.9.0 retired 0.8.3 retired 0.8.2 retired 0.8.1 retired 0.8.0 retired 0.7.0 retired 0.6.2 retired 0.6.1 retired 0.6.0 retired 0.5.2 retired 0.5.1 retired 0.5.0 retired 0.4.2 retired 0.4.1 retired 0.4.0 retired 0.3.0 retired 0.2.1 retired 0.2.0 retired 0.1.3 retired 0.1.2 retired 0.1.1 retired 0.1.0 retired 0.0.20 retired 0.0.19 retired 0.0.18 retired 0.0.17 retired 0.0.16 retired 0.0.15 retired 0.0.14 retired 0.0.13 retired 0.0.12 retired 0.0.11 retired 0.0.10 retired 0.0.8 retired 0.0.7 retired 0.0.6 retired 0.0.5 retired 0.0.4 retired 0.0.3 retired

Common Locale Data Repository (CLDR) functions for Elixir to localize and format numbers, dates, lists, messages, languages, territories and units with support for over 700 locales for internationalized (i18n) and localized (L10N) applications.

Current section

Files

Jump to
ex_cldr lib cldr locale loader.ex
Raw

lib/cldr/locale/loader.ex

defmodule Cldr.Locale.Loader do
@moduledoc false
# Encapsulate only the code that loads a
# locale from a .json file
# The intent is to isolate all the code that
# loads a locale so that eventually this can be
# shifted from here to the data consolidation phase
# if/when we choose to store locales in erlang
# term format rather than json.
# One intermediate step will be to shift the data
# structure manipulation into the consolidation phase
# leaving only the requirement to form atom and integer
# keys in the appropriate place.
alias Cldr.Config
@doc """
Read the locale json, decode it and make any necessary transformations.
This is the only place that we read the locale and we only
read it once. All other uses of locale data are references
to this data.
Additionally the intention is that this is read only at compile time
and used to construct accessor functions in other modules so that
during production run there is no file access or decoding.
"""
@spec get_locale(Cldr.Locale.locale_name(), config_or_backend :: Config.t() | Cldr.backend()) ::
map() | no_return()
def get_locale(locale, %{data_dir: _} = config) do
do_get_locale(locale, config)
end
def get_locale(locale, backend) when is_atom(backend) do
do_get_locale(locale, backend.__cldr__(:config))
end
@doc false
def do_get_locale(locale, config) do
{:ok, path} =
case Config.locale_path(locale, config) do
{:ok, path} ->
{:ok, path}
{:error, :not_found} ->
raise RuntimeError, message: "Locale definition was not found for #{locale}"
end
do_get_locale(locale, path, Cldr.Locale.Cache.compiling?())
end
@alt_keys ["default", "menu", "short", "long", "variant", "standard"]
@lenient_parse_keys ["date", "general", "number"]
@language_keys ["language", "language_variants"]
@remaining_modules Cldr.Config.required_modules() --
[
"locale_display_names", "languages", "lenient_parse", "dates"
]
@doc false
def do_get_locale(locale, path, false) do
path
|> read_locale_file!
|> Config.json_library().decode!
|> assert_valid_keys!(locale)
|> Cldr.Map.integerize_keys(filter: "list_formats")
|> Cldr.Map.integerize_keys(filter: "number_formats")
|> Cldr.Map.atomize_values(filter: "number_systems")
|> Cldr.Map.atomize_keys(filter: "locale_display_names", skip: @language_keys)
|> Cldr.Map.atomize_keys(filter: :language, only: @alt_keys)
|> Cldr.Map.atomize_keys(filter: "languages", only: @alt_keys)
|> Cldr.Map.atomize_keys(filter: "lenient_parse", only: @lenient_parse_keys)
|> Cldr.Map.atomize_keys(filter: @remaining_modules)
|> structure_date_formats()
|> Cldr.Map.atomize_keys(level: 1..1)
|> Map.put(:name, locale)
end
@doc false
def do_get_locale(locale, path, true) do
Cldr.Locale.Cache.get_locale(locale, path)
end
# Read the file.
defp read_locale_file!(path) do
Cldr.maybe_log("Cldr.Config reading locale file #{inspect(path)}")
{:ok, contents} = File.open(path, [:read, :binary, :utf8], &IO.read(&1, :all))
contents
end
@date_atoms [
"exemplar_city", "long", "standard", "generic",
"short", "daylight", "formal",
"daylight_savings", "generic"
]
defp structure_date_formats(content) do
dates =
content
|> Map.get("dates")
|> Cldr.Map.integerize_keys(only: Cldr.Config.keys_to_integerize())
|> Cldr.Map.deep_map(fn
{:number_system, value} ->
{:number_system,
Cldr.Map.atomize_values(value) |> Cldr.Map.stringify_keys(except: :all)}
other ->
other
end)
|> Cldr.Map.atomize_keys(only: @date_atoms)
|> Cldr.Map.atomize_keys(filter: "calendars")
|> Cldr.Map.atomize_keys(filter: "time_zone_names", level: 1..2)
|> Cldr.Map.atomize_keys(level: 1..1)
Map.put(content, :dates, dates)
end
@doc false
def underscore(string) when is_binary(string) do
string
|> Cldr.String.to_underscore()
end
def underscore(other), do: other
# Simple check that the locale content contains what we expect
# by checking it has the keys we used when the locale was consolidated.
# Set the environment variable DEV to bypass this check. That is
# only required if adding new content modules to a locale - which is
# an uncommon activity.
defp assert_valid_keys!(content, locale) do
for module <- Config.required_modules() do
if !Map.has_key?(content, module) and !Elixir.System.get_env("DEV") do
raise RuntimeError,
message:
"Locale file #{inspect(locale)} is invalid - map key #{inspect(module)} was not found."
end
end
content
end
end