Packages

Simple library for spelling numbers into English or Indonesian language (Bahasa Indonesia).

Current section

Files

Jump to
say_number lib say_number.ex
Raw

lib/say_number.ex

defmodule SayNumber do
import SayNumber.Gettext
@moduledoc """
Main module to handle spelling of a number.
"""
alias SayNumber.Patcher.Indonesian, as: IDPatcher
@doc """
Say number, supply an integer and locale,
get the pronounciable words. Currently supported locale:
* English (default)
* Indonesian Language (Bahasa Indonesia)
Current `number` limit is: `999_999_999_999_999`
Returns a string.
## Examples
iex> SayNumber.spell(1899)
"One thousand eight hundred ninety nine"
iex> SayNumber.spell(91_000, "id")
"Sembilan puluh satu ribu"
"""
def spell(number, locale \\ "en") do
Gettext.put_locale(SayNumber.Gettext, locale)
IO.puts(Gettext.get_locale(SayNumber.Gettext))
IO.puts("**** 3")
number
|> do_spell()
|> patch_by_locale(locale)
|> String.capitalize()
end
defp do_spell(n) when n >= 1_000_000_000_000_000,
do: raise(gettext("Too large number"))
defp do_spell(0), do: gettext("zero")
defp do_spell(1), do: gettext("one")
defp do_spell(2), do: gettext("two")
defp do_spell(3), do: gettext("three")
defp do_spell(4), do: gettext("four")
defp do_spell(5), do: gettext("five")
defp do_spell(6), do: gettext("six")
defp do_spell(7), do: gettext("seven")
defp do_spell(8), do: gettext("eight")
defp do_spell(9), do: gettext("nine")
defp do_spell(10), do: gettext("ten")
defp do_spell(11), do: gettext("eleven")
defp do_spell(12), do: gettext("twelve")
defp do_spell(13), do: gettext("thirteen")
defp do_spell(14), do: gettext("fourteen")
defp do_spell(15), do: gettext("fifteen")
defp do_spell(16), do: gettext("sixteen")
defp do_spell(17), do: gettext("seventeen")
defp do_spell(18), do: gettext("eighteen")
defp do_spell(19), do: gettext("nineteen")
defp do_spell(20), do: gettext("twenty")
defp do_spell(30), do: gettext("thirty")
defp do_spell(40), do: gettext("forty")
defp do_spell(50), do: gettext("fifty")
defp do_spell(60), do: gettext("sixty")
defp do_spell(70), do: gettext("seventy")
defp do_spell(80), do: gettext("eighty")
defp do_spell(90), do: gettext("ninety")
# Below hundred.
defp do_spell(n) when n < 100 do
multiple_of_tens = div(n, 10) * 10
remaining = n - multiple_of_tens
construct_string(multiple_of_tens, "", remaining)
end
# Below thousand.
defp do_spell(n) when n < 1000 do
multiple_of_hundreds = div(n, 100)
remaining = rem(n, 100)
construct_string(
multiple_of_hundreds,
gettext("hundred"),
remaining
)
end
# Below million.
defp do_spell(n) when n < 1_000_000 do
multiple_of_hundreds = div(n, 1000)
remaining = rem(n, 1000)
construct_string(
multiple_of_hundreds,
gettext("thousand"),
remaining
)
end
# Below billion.
defp do_spell(n) when n < 1_000_000_000 do
multiple_of_hundreds = div(n, 1_000_000)
remaining = rem(n, 1_000_000)
construct_string(
multiple_of_hundreds,
gettext("million"),
remaining
)
end
# Below trillion.
defp do_spell(n) when n < 1_000_000_000_000 do
multiple_of_hundreds = div(n, 1_000_000_000)
remaining = rem(n, 1_000_000_000)
construct_string(
multiple_of_hundreds,
gettext("billion"),
remaining
)
end
# Below quadrillion.
defp do_spell(n) when n < 1_000_000_000_000_000 do
multiple_of_hundreds = div(n, 1_000_000_000_000)
remaining = rem(n, 1_000_000_000_000)
construct_string(
multiple_of_hundreds,
gettext("trillion"),
remaining
)
end
# Need to write this method in order to prevent infinite loop for 200, 3000, etc.
# Directly append the number of base with the base itself.
defp construct_string(number_of_base, base, 0) do
[do_spell(number_of_base), base]
|> Enum.join(" ")
end
defp construct_string(number_of_base, base, remaining) do
[do_spell(number_of_base), base, do_spell(remaining)]
|> Enum.reject(&(&1 == ""))
|> Enum.join(" ")
end
defp patch_by_locale(string, locale) do
if locale == "id" do
IDPatcher.perform(string)
else
string
end
end
end