Skip to content

Commit 2637da0

Browse files
committedJul 12, 2016
support for the integer part of numbers
1 parent ccf4f01 commit 2637da0

File tree

5 files changed

+117
-10
lines changed

5 files changed

+117
-10
lines changed
 

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ The following data from the CLDR is supported.
3939
- Dates ⚡
4040
- Times ❌
4141
- Numbers
42-
- Basic
42+
- Basic
4343
- Currency ❌
4444
- Percent ❌
4545
- Decimal ❌
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
defmodule CLDRex.Formatters.NumberFormatter do
2+
@moduledoc false
3+
import CLDRex.Utils
4+
5+
alias CLDRex.Main
6+
alias CLDRex.Parsers.NumberParser
7+
8+
@type locale :: atom | String.t
9+
10+
def format(number, format, locale) do
11+
format
12+
|> NumberParser.parse(locale)
13+
|> process_tokens(number, locale)
14+
end
15+
16+
defp process_tokens(%{grouping: _g, first_grouping: fg, fractional_part: _fp}, number, locale) do
17+
{integer, remainder} = number
18+
|> to_string
19+
|> Integer.parse
20+
21+
grouping_size = String.length(fg)
22+
23+
integer
24+
|> Integer.digits
25+
|> Enum.chunk(grouping_size)
26+
|> Enum.reduce([], fn (g, acc) -> Enum.concat(acc, [Enum.join(g)]) end)
27+
|> Enum.join(group(locale))
28+
end
29+
30+
defp group(locale) do
31+
Main.cldr_main_data
32+
|> get_in([locale, :numbers, :symbols, :group])
33+
end
34+
end

‎lib/cldrex/numbers.ex

+14
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,28 @@ defmodule CLDRex.Numbers do
44
# Provide number localization including conversion to currency, percentage, and
55
# decimal values.
66
# """
7+
import CLDRex.Utils
8+
9+
alias CLDRex.Main
10+
alias CLDRex.Formatters.NumberFormatter
11+
712
@type locale :: atom | String.t
813

914
@doc """
1015
Localize the given number into the given locale.
1116
"""
1217
@spec localize(number, locale) :: String.t
1318
def localize(number, locale) do
19+
locale = normalize_locale(locale)
20+
fallback = fallback(locale)
21+
22+
pattern = get_in(Main.cldr_main_data,
23+
[locale, :numbers, :decimal_pattern])
24+
25+
if !pattern, do: pattern = get_in(Main.cldr_main_data,
26+
[locale, :numbers, :decimal_pattern])
1427

28+
NumberFormatter.format(number, pattern, locale)
1529
end
1630

1731
@doc """

‎lib/cldrex/parsers/number_parser.ex

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
defmodule CLDRex.Parsers.NumberParser do
2+
@moduledoc false
3+
alias CLDRex.Main
4+
5+
def parse(format_string, locale) do
6+
format_string = to_string(format_string)
7+
[whole_part, fractional_part] = extract_base_parts(format_string, locale)
8+
[grouping, first_grouping] = extract_groupings(whole_part, locale)
9+
10+
%{grouping: grouping, first_grouping: first_grouping, fractional_part: fractional_part}
11+
end
12+
13+
defp extract_base_parts(format_string, locale),
14+
do: String.split(format_string, ".", parts: 2)
15+
16+
defp extract_groupings(format_string, locale),
17+
do: String.split(format_string, ",", parts: 2)
18+
end

‎lib/cldrex/parsers/xml_parser.ex

+50-9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ defmodule CLDRex.Parsers.XMLParser do
2222
end
2323

2424
defp process_file(file) do
25+
IO.puts "Processing #{inspect(file)}"
2526
# the replace is an ugly hack because the doc uses a relative path which
2627
# breaks at compile time, so we need to change that path
2728
doc = @main_path
@@ -35,20 +36,21 @@ defmodule CLDRex.Parsers.XMLParser do
3536
display_pattern: extract_display_pattern(doc),
3637
languages: extract_languages(doc),
3738
territories: extract_territories(doc),
38-
calendar: extract_calendar(doc)
39+
calendar: extract_calendar(doc),
40+
numbers: Map.get(extract_numbers(doc), :numbers, %{})
3941
})
4042
end
4143

4244
defp extract_display_pattern(doc) do
4345
doc
44-
|> xpath(~x"//localeDisplayPattern/localePattern/text()")
46+
|> xpath(~x"//localeDisplayPattern/localePattern/text()"s)
4547
|> to_string
4648
end
4749

4850
defp extract_languages(doc) do
4951
doc
5052
|> xpath(~x"//languages/language"l,
51-
locale: ~x"./@type", language: ~x"./text()")
53+
locale: ~x"./@type", language: ~x"./text()"s)
5254
|> Enum.reduce(%{}, fn(l, acc) ->
5355
loc = l.locale |> to_string |> String.to_atom
5456
lng = l.language |> to_string
@@ -59,14 +61,53 @@ defmodule CLDRex.Parsers.XMLParser do
5961
defp extract_territories(doc) do
6062
doc
6163
|> xpath(~x"//territories/territory"l,
62-
un_code: ~x"./@type", name: ~x"./text()")
64+
un_code: ~x"./@type", name: ~x"./text()"s)
6365
|> Enum.reduce(%{}, fn(l, acc) ->
6466
code = l.un_code |> to_string |> String.to_atom
6567
name = l.name |> to_string
6668
Map.put(acc, code, name)
6769
end)
6870
end
6971

72+
defp extract_numbers(doc) do
73+
numbers = xpath(doc, ~x"//numbers"e)
74+
75+
case numbers do
76+
nil -> %{}
77+
_ ->
78+
numbers_map = xmap(doc, numbers: [
79+
~x"//numbers",
80+
decimal_pattern: ~x"./decimalFormats/decimalFormatLength/decimalFormat/pattern[1]/text()"s,
81+
decimal_formats: [
82+
~x"./decimalFormats/decimalFormatLength"l,
83+
type: ~x"./@type",
84+
patterns: [
85+
~x"./decimalFormat/pattern"l,
86+
type: ~x"./@type",
87+
count: ~x"./@count",
88+
pattern: ~x"./text()"s
89+
]
90+
]
91+
])
92+
93+
symbols = if xpath(numbers, ~x"//numbers/symbols"e) do
94+
xmap(numbers, symbols: [
95+
~x"//numbers/symbols",
96+
decimal: ~x"./decimal/text()"s,
97+
group: ~x"./group/text()"s,
98+
percent: ~x"./percentSign/text()"s,
99+
plus: ~x"./plusSign/text()"s,
100+
minus: ~x"./minusSign/text()"s
101+
])
102+
end
103+
104+
case symbols do
105+
nil -> numbers_map
106+
_ -> put_in(numbers_map, [:numbers, :symbols], symbols.symbols)
107+
end
108+
end
109+
end
110+
70111
defp extract_calendar(doc) do
71112
doc
72113
|> extract_calendar_map
@@ -86,7 +127,7 @@ defmodule CLDRex.Parsers.XMLParser do
86127
months: [
87128
~x"./month"l,
88129
month: ~x"./@type",
89-
label: ~x"./text()"
130+
label: ~x"./text()"s
90131
]
91132
]
92133
],
@@ -99,24 +140,24 @@ defmodule CLDRex.Parsers.XMLParser do
99140
days: [
100141
~x"./day"l,
101142
day: ~x"./@type",
102-
label: ~x"./text()"
143+
label: ~x"./text()"s
103144
]
104145
]
105146
],
106147
date_formats: [
107148
~x"./dateFormats/dateFormatLength"l,
108149
length: ~x"./@type",
109-
format: ~x"./dateFormat/pattern/text()"
150+
format: ~x"./dateFormat/pattern/text()"s
110151
],
111152
time_formats: [
112153
~x"./timeFormats/timeFormatLength"l,
113154
length: ~x"./@type",
114-
format: ~x"./timeFormat/pattern/text()"
155+
format: ~x"./timeFormat/pattern/text()"s
115156
],
116157
date_time_formats: [
117158
~x"./dateTimeFormats/dateTimeFormatLength"l,
118159
length: ~x"./@type",
119-
format: ~x"./dateTimeFormat/pattern/text()"
160+
format: ~x"./dateTimeFormat/pattern/text()"s
120161
]
121162
])
122163
end

0 commit comments

Comments
 (0)
Please sign in to comment.