Packages

ex_cldr

0.0.11
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.

Retired package: Deprecated

Current section

Files

Jump to
ex_cldr lib cldr number rbnf processor.ex
Raw

lib/cldr/number/rbnf/processor.ex

defmodule Cldr.Rbnf.Processor do
defmacro __using__(_opts) do
quote location: :keep do
alias Cldr.Number
import Cldr.Rbnf.Processor
defp do_rule(number, locale, function, rule, parsed) do
parsed
|> Enum.map(fn {operation, argument} ->
# IO.puts "Rule: #{inspect operation} on #{inspect number} with argument #{inspect argument}"
do_operation(operation, number, locale, function, rule, argument)
# |> IO.inspect
end)
|> :erlang.iolist_to_binary
end
defp do_operation(:literal, _number, _locale, _function, _rule, string) do
string
end
defp do_operation(:modulo, number, locale, function, rule, nil)
when is_number(number) and number < 0 do
apply(__MODULE__, function, [abs(number), locale])
end
defp do_operation(:modulo, number, locale, function, rule, {:format, format})
when is_number(number) and number < 0 do
Cldr.Number.to_string(abs(number), locale: locale, format: format)
end
defp do_operation(:modulo, number, locale, function, rule, nil)
when is_integer(number) do
mod = number - (div(number, rule.divisor) * rule.divisor)
apply(__MODULE__, function, [mod, locale])
end
# For Fractional rules we format the integral part
defp do_operation(:modulo, number, locale, function, _rule, nil)
when is_float(number) do
format_fraction(number, locale)
end
defp do_operation(:modulo, number, locale, _function, rule, {:rule, rule_name}) do
mod = number - (div(number, rule.divisor) * rule.divisor)
apply(__MODULE__, rule_name, [mod, locale])
end
defp do_operation(:modulo, number, locale, function, rule, {:format, format}) do
mod = number - (div(number, rule.divisor) * rule.divisor)
Cldr.Number.to_string(mod, locale: locale, format: format)
end
# For Fractional rules we format the fraction as individual digits.
defp do_operation(:quotient, number, locale, function, rule, nil)
when is_float(number) do
apply(__MODULE__, function, [trunc(number), locale])
end
defp do_operation(:quotient, number, locale, function, rule, nil) do
divisor = div(number, rule.divisor)
apply(__MODULE__, function, [divisor, locale])
end
defp do_operation(:quotient, number, locale, _function, rule, {:rule, rule_name}) do
divisor = div(number, rule.divisor)
apply(__MODULE__, rule_name, [divisor, locale])
end
defp do_operation(:call, number, locale, _function, _rule, {:format, format}) do
Cldr.Number.to_string(number, locale: locale, format: format)
end
defp do_operation(:call, number, locale, _function, _rule, {:rule, rule_name}) do
apply(__MODULE__, rule_name, [number, locale])
end
defp do_operation(:ordinal, number, locale, _function, _rule, plurals) do
plural = Cldr.Number.Ordinal.plural_rule(number, locale)
Map.get(plurals, plural) || Map.get(plurals, :other)
end
defp do_operation(:cardinal, number, locale, _function, _rule, plurals) do
plural = Cldr.Number.Cardinal.plural_rule(number, locale)
Map.get(plurals, plural) || Map.get(plurals, :other)
end
defp do_operation(:conditional, number, locale, function, rule, argument) do
mod = number - (div(number, rule.divisor) * rule.divisor)
if mod > 0 do
do_rule(mod, locale, function, rule, argument)
else
""
end
end
defp format_fraction(number, locale) do
fraction = number
|> Cldr.Number.Math.fraction_as_integer
|> Integer.to_string
|> String.split("", trim: true)
|> Enum.map(&String.to_integer/1)
|> Enum.map(&Cldr.Rbnf.Spellout.spellout_cardinal(&1, locale))
|> Enum.join(" ")
end
@before_compile Cldr.Rbnf.Processor
end
end
@public_rulesets :public_rulesets
def define_rules(rule_group_name, env) do
Module.register_attribute(env.module, @public_rulesets, [])
iterate_rules rule_group_name, fn (rule_group, locale, access, rule) ->
{:ok, parsed} = Cldr.Rbnf.Rule.parse(rule.definition)
function_body = rule_body(locale, rule_group, rule, parsed)
define_rule(rule.base_value, rule.range, rule_group, locale, function_body)
|> add_function_to_exports(access, env.module, locale)
|> Code.eval_quoted([], env)
end
end
defp iterate_rules(rule_group_type, fun) do
all_rules = Cldr.Rbnf.for_all_locales[rule_group_type]
unless is_nil(all_rules) do
for {locale, _rule_group} <- all_rules do
for {rule_group, %{access: access, rules: rules}} <- all_rules[locale] do
for rule <- rules do
fun.(rule_group, locale, access, rule)
end
end
end
end
end
defp define_rule("-x", _range, rule_group, locale, body) do
quote do
def unquote(rule_group)(number, unquote(locale))
when Kernel.and(is_number(number), number < 0), do: unquote(body)
end
end
# Improper fraction rule
defp define_rule("x.x", _range, rule_group, locale, body) do
quote do
def unquote(rule_group)(number, unquote(locale))
when is_float(number), do: unquote(body)
end
end
defp define_rule("x,x", range, rule_group, locale, body) do
define_rule("x.x", range, rule_group, locale, body)
end
defp define_rule(0, "undefined", rule_group, locale, body) do
quote do
def unquote(rule_group)(number, unquote(locale))
when is_integer(number), do: unquote(body)
end
end
defp define_rule(base_value, "undefined", rule_group, locale, body)
when is_integer(base_value) do
quote do
def unquote(rule_group)(number, unquote(locale))
when Kernel.and(is_integer(number), number >= unquote(base_value)),
do: unquote(body)
end
end
defp define_rule(base_value, range, rule_group, locale, body)
when is_integer(range) and is_integer(base_value) do
quote do
def unquote(rule_group)(number, unquote(locale))
when Kernel.and(is_integer(number),
Kernel.and(number >= unquote(base_value), number < unquote(range))),
do: unquote(body)
end
end
defp define_rule(base_value, "undefined", rule_group, locale, body)
when is_integer(base_value) do
quote do
def unquote(rule_group)(number, unquote(locale))
when Kernel.and(is_integer(number), number >= unquote(base_value)),
do: unquote(body)
end
end
defp define_rule("Inf", _range, _rule_group, _locale, _body) do
{:error, "Infinite rule sets are not implemented"}
end
defp define_rule("NaN", _range, _rule_group, _locale, _body) do
{:error, "NaN rule sets are not implemented"}
end
defp define_rule("0.x", _range, _rule_group, _locale, _body) do
{:error, "Proper Fraction rule sets are not implemented"}
end
defp define_rule("x.0", _range, _rule_group, _locale, _body) do
{:error, "Master rule sets are not implemented"}
end
# Get the AST of the rule body
defp rule_body(locale, rule_group, rule, parsed) do
quote do
do_rule(number,
unquote(locale),
unquote(rule_group),
unquote(Macro.escape(rule)),
unquote(Macro.escape(parsed)))
end
end
# Keep track of the public rulesets per locale so we can introspect the
# public interface
defp add_function_to_exports({:def, _aliases, [{:when, _, [{name, _, _} | _]} | _]} = function,
"public", module, locale) do
public_rulesets = Module.get_attribute(module, @public_rulesets) || %{}
locale_public_rulesets = [name | (Map.get(public_rulesets, locale) || [])]
Module.put_attribute module, @public_rulesets,
Map.put(public_rulesets, locale, Enum.uniq(locale_public_rulesets))
function
end
defp add_function_to_exports(function, _access, _module, _locale) do
function
end
defmacro __before_compile__(env) do
quote do
def rule_sets(locale) do
unquote(Macro.escape(Module.get_attribute(env.module, :public_rulesets)))
|> Map.get(locale)
end
end
end
end