From 5415d86bfca800c9c293a653f59c9aa821218214 Mon Sep 17 00:00:00 2001 From: duyetpt Date: Wed, 29 Nov 2017 12:38:42 +0700 Subject: [PATCH] Support Vietnamese (#152) * support Vietnamese --- CHANGELOG.md | 1 + README.rdoc | 10 ++ .../i18n/locales/numbers.vi.yml | 13 +++ .../strategies/array_joiner/languages.rb | 1 + .../strategies/array_joiner/languages/vi.rb | 10 ++ .../figures_converter/decorators.rb | 1 + .../figures_converter/decorators/vi.rb | 3 + .../figures_converter/decorators/vi/base.rb | 12 +++ .../decorators/vi/fractional.rb | 12 +++ .../decorators/vi/integral.rb | 12 +++ .../strategies/figures_converter/languages.rb | 1 + .../figures_converter/languages/vi.rb | 96 +++++++++++++++++++ lib/numbers_and_words/translations.rb | 1 + lib/numbers_and_words/translations/vi.rb | 21 ++++ .../array/fixture_examples/vi.yml | 30 ++++++ .../float/fixture_examples/vi.yml | 19 ++++ .../integer/fixture_examples/vi.yml | 60 ++++++++++++ .../numbers_and_words_spec.rb | 2 +- 18 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 lib/numbers_and_words/i18n/locales/numbers.vi.yml create mode 100644 lib/numbers_and_words/strategies/array_joiner/languages/vi.rb create mode 100644 lib/numbers_and_words/strategies/figures_converter/decorators/vi.rb create mode 100644 lib/numbers_and_words/strategies/figures_converter/decorators/vi/base.rb create mode 100644 lib/numbers_and_words/strategies/figures_converter/decorators/vi/fractional.rb create mode 100644 lib/numbers_and_words/strategies/figures_converter/decorators/vi/integral.rb create mode 100644 lib/numbers_and_words/strategies/figures_converter/languages/vi.rb create mode 100644 lib/numbers_and_words/translations/vi.rb create mode 100644 spec/numbers_and_words/array/fixture_examples/vi.yml create mode 100644 spec/numbers_and_words/float/fixture_examples/vi.yml create mode 100644 spec/numbers_and_words/integer/fixture_examples/vi.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index f8738546..b4be37d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features * Your contribution here. + * Add support for Vietnamese language ## 0.11.2 (August 14, 2017) diff --git a/README.rdoc b/README.rdoc index b787f823..ab604d8c 100644 --- a/README.rdoc +++ b/README.rdoc @@ -82,6 +82,9 @@ Converte números em letras utilizando a biblioteca I18n. I18n.with_locale(:cs) { 42.to_words } => "čtyřicetdva" + I18n.with_locale(:vi) { 42.to_words } + => "bốn mươi hai" + 21.to_words => "twenty-one" => "veintiuno" @@ -100,6 +103,7 @@ Converte números em letras utilizando a biblioteca I18n. => "tjugo-en" => "dvacetjedna" => "vinte e um" + => "hai mươi mốt" 231.to_words => "two hundred thirty-one" @@ -119,6 +123,7 @@ Converte números em letras utilizando a biblioteca I18n. => "två hundra trettio-en" => "dvě stě třicetjedna" => "duzentos e trinta e um" + => "hai trăm ba mươi mốt" 4030.to_words => "four thousand thirty" @@ -137,6 +142,7 @@ Converte números em letras utilizando a biblioteca I18n. => "vierthousanddertig" => "fyra tusen trettio" => "čtyři tisíce třicet" + => "bốn nghìn không trăm ba mươi" 1000100.to_words => "one million one hundred" @@ -155,6 +161,7 @@ Converte números em letras utilizando a biblioteca I18n. => "één miljoen honderd" => "en miljoner en hundra" => "jeden milión jedno sto" + => "một triệu một trăm" 1000000000000000000000000000000000.to_words => "one decillion" @@ -184,6 +191,7 @@ Converte números em letras utilizando a biblioteca I18n. => ["üks", "kaks", "kolm"] => ["ერთი", "ორი", "სამი"] => ["jedna", "dva", "tři"] + => ["một", "hai", "ba"] [11, 22, 133].to_words => ["eleven", "twenty-two", "one hundred thirty-three"] @@ -202,6 +210,7 @@ Converte números em letras utilizando a biblioteca I18n. => ["elf", "tweeentwintig", "honderddrieendertig"] => ["elva", "tjugo-två", "en hundra trettio-tre"] => ["jedenáct", "dvacetdva", "jedno sto třicettři"] + => ["mười một", "hai mươi hai", "một trăm ba mươi ba"] 21.77.to_words => "twenty-one and seventy-seven hundredths" @@ -209,6 +218,7 @@ Converte números em letras utilizando a biblioteca I18n. => "двадцять одна цiла i сiмдесят сiм сотих" => "huszonegy egész hetvenhét század" => "twenty-one point seven seven" + => "hai mươi mốt phẩy bảy mươi bảy" == Language options / Языковые опции diff --git a/lib/numbers_and_words/i18n/locales/numbers.vi.yml b/lib/numbers_and_words/i18n/locales/numbers.vi.yml new file mode 100644 index 00000000..592c6157 --- /dev/null +++ b/lib/numbers_and_words/i18n/locales/numbers.vi.yml @@ -0,0 +1,13 @@ +vi: + numbers: + ones: ['không', 'một', 'hai', 'ba', 'bốn', 'năm', 'sáu', 'bảy', 'tám', 'chín'] + teens: [_, 'mười một', 'mười hai', 'mười ba', 'mười bốn', 'mười lăm', 'mười sáu', 'mười bảy', 'thứ mười tám', 'mười chín'] + tens: [_, 'mười', 'hai mươi', 'ba mươi', 'bốn mươi', 'năm mươi', 'sáu mươi', 'bảy mươi', 'tám mươi', 'chín mươi'] + hundreds: 'trăm' + mega: [_, 'nghìn', 'triệu', 'tỷ', 'nghìn tỷ', 'triệu tỷ'] + units: + tens: + one: 'mốt' + five: 'lăm' + ones_union: 'linh' + micro_separator: 'phẩy' diff --git a/lib/numbers_and_words/strategies/array_joiner/languages.rb b/lib/numbers_and_words/strategies/array_joiner/languages.rb index f1e13493..02c868b1 100644 --- a/lib/numbers_and_words/strategies/array_joiner/languages.rb +++ b/lib/numbers_and_words/strategies/array_joiner/languages.rb @@ -11,6 +11,7 @@ require 'numbers_and_words/strategies/array_joiner/languages/ua' require 'numbers_and_words/strategies/array_joiner/languages/pt-BR' require 'numbers_and_words/strategies/array_joiner/languages/cs' +require 'numbers_and_words/strategies/array_joiner/languages/vi' module NumbersAndWords module Strategies diff --git a/lib/numbers_and_words/strategies/array_joiner/languages/vi.rb b/lib/numbers_and_words/strategies/array_joiner/languages/vi.rb new file mode 100644 index 00000000..49bc6c23 --- /dev/null +++ b/lib/numbers_and_words/strategies/array_joiner/languages/vi.rb @@ -0,0 +1,10 @@ +module NumbersAndWords + module Strategies + module ArrayJoiner + module Languages + class Vi < Base + end + end + end + end +end diff --git a/lib/numbers_and_words/strategies/figures_converter/decorators.rb b/lib/numbers_and_words/strategies/figures_converter/decorators.rb index 5d4d1934..c703fcd5 100644 --- a/lib/numbers_and_words/strategies/figures_converter/decorators.rb +++ b/lib/numbers_and_words/strategies/figures_converter/decorators.rb @@ -8,6 +8,7 @@ require 'numbers_and_words/strategies/figures_converter/decorators/hu' require 'numbers_and_words/strategies/figures_converter/decorators/ua' require 'numbers_and_words/strategies/figures_converter/decorators/cs' +require 'numbers_and_words/strategies/figures_converter/decorators/vi' module NumbersAndWords module Strategies diff --git a/lib/numbers_and_words/strategies/figures_converter/decorators/vi.rb b/lib/numbers_and_words/strategies/figures_converter/decorators/vi.rb new file mode 100644 index 00000000..2aad94b8 --- /dev/null +++ b/lib/numbers_and_words/strategies/figures_converter/decorators/vi.rb @@ -0,0 +1,3 @@ +require 'numbers_and_words/strategies/figures_converter/decorators/vi/base' +require 'numbers_and_words/strategies/figures_converter/decorators/vi/fractional' +require 'numbers_and_words/strategies/figures_converter/decorators/vi/integral' diff --git a/lib/numbers_and_words/strategies/figures_converter/decorators/vi/base.rb b/lib/numbers_and_words/strategies/figures_converter/decorators/vi/base.rb new file mode 100644 index 00000000..88ef11a7 --- /dev/null +++ b/lib/numbers_and_words/strategies/figures_converter/decorators/vi/base.rb @@ -0,0 +1,12 @@ +module NumbersAndWords + module Strategies + module FiguresConverter + module Decorators + module Vi + class Base < Decorators::Base + end + end + end + end + end +end diff --git a/lib/numbers_and_words/strategies/figures_converter/decorators/vi/fractional.rb b/lib/numbers_and_words/strategies/figures_converter/decorators/vi/fractional.rb new file mode 100644 index 00000000..a80846f8 --- /dev/null +++ b/lib/numbers_and_words/strategies/figures_converter/decorators/vi/fractional.rb @@ -0,0 +1,12 @@ +module NumbersAndWords + module Strategies + module FiguresConverter + module Decorators + module Vi + class Fractional < Base + end + end + end + end + end +end diff --git a/lib/numbers_and_words/strategies/figures_converter/decorators/vi/integral.rb b/lib/numbers_and_words/strategies/figures_converter/decorators/vi/integral.rb new file mode 100644 index 00000000..6c7466ff --- /dev/null +++ b/lib/numbers_and_words/strategies/figures_converter/decorators/vi/integral.rb @@ -0,0 +1,12 @@ +module NumbersAndWords + module Strategies + module FiguresConverter + module Decorators + module Vi + class Integral < Base + end + end + end + end + end +end diff --git a/lib/numbers_and_words/strategies/figures_converter/languages.rb b/lib/numbers_and_words/strategies/figures_converter/languages.rb index 9d83dccb..d892fe9d 100644 --- a/lib/numbers_and_words/strategies/figures_converter/languages.rb +++ b/lib/numbers_and_words/strategies/figures_converter/languages.rb @@ -23,6 +23,7 @@ require 'numbers_and_words/strategies/figures_converter/languages/families/cyrillic' require 'numbers_and_words/strategies/figures_converter/languages/ru' require 'numbers_and_words/strategies/figures_converter/languages/ua' +require 'numbers_and_words/strategies/figures_converter/languages/vi' module NumbersAndWords module Strategies diff --git a/lib/numbers_and_words/strategies/figures_converter/languages/vi.rb b/lib/numbers_and_words/strategies/figures_converter/languages/vi.rb new file mode 100644 index 00000000..06fd1bc0 --- /dev/null +++ b/lib/numbers_and_words/strategies/figures_converter/languages/vi.rb @@ -0,0 +1,96 @@ +module NumbersAndWords + module Strategies + module FiguresConverter + module Languages + class Vi < Base + def print_words + value = super + remove_billion_noice(value) + end + + def strings_logic + if fractional? + if fraction_number_zeros_leading.zero? + @options.options[:integeral] = true + integeral_string_logic + else + fractional_with_zero_leading_string_logic + end + else + integeral_string_logic + end + end + + def fractional_with_zero_leading_string_logic + leading_zeros = [0] * fraction_number_zeros_leading + (@figures + leading_zeros).map(&:to_words) + end + + def integeral_string_logic + if @figures.capacity_count + number_without_capacity_to_words + complex_number_to_words + elsif hundreds? + hundreds_number_to_words + elsif @figures.tens || @figures.ones + simple_number_to_words + else + [] + end + end + + def hundreds? + @figures.hundreds || + (@figures.size == 3 && (@figures.teens || @figures.tens || @figures.ones)) + end + + def hundreds(options = {}) + if @figures.hundreds.to_i.zero? + translate :hundreds, 0, options + else + super + end + end + + def ones(options = {}) + if @figures.capacity_length >= 2 + ones_union(options) + else + super + end + end + + def ones_union(options = {}) + translate :ones_union, @figures.ones, options + end + + def fractional? + !@options.options[:fractional].nil? && !@options.options[:integeral] + end + + def fraction_length + return 0 unless @options.options[:fractional] + @options.options[:fractional][:length] + end + + def fraction_number_zeros_leading + fraction_length - @figures.length + end + + def remove_billion_noice(value) + parts = value.split(billion_unit).map(&:strip) + if value.end_with?(billion_unit) + parts.insert(-1, billion_unit).join(' ') + else + return value if parts.size <= 2 + parts.insert(-2, billion_unit).join(' ') + end + end + + def billion_unit + translate :mega, 3 + end + end + end + end + end +end diff --git a/lib/numbers_and_words/translations.rb b/lib/numbers_and_words/translations.rb index 67f3334d..120e67e1 100644 --- a/lib/numbers_and_words/translations.rb +++ b/lib/numbers_and_words/translations.rb @@ -22,6 +22,7 @@ require 'numbers_and_words/translations/pt-BR' require 'numbers_and_words/translations/ka' require 'numbers_and_words/translations/cs' +require 'numbers_and_words/translations/vi' module NumbersAndWords module Translations diff --git a/lib/numbers_and_words/translations/vi.rb b/lib/numbers_and_words/translations/vi.rb new file mode 100644 index 00000000..a9d7c895 --- /dev/null +++ b/lib/numbers_and_words/translations/vi.rb @@ -0,0 +1,21 @@ +module NumbersAndWords + module Translations + class Vi < Base + include NumbersAndWords::Translations::Families::Latin + include NumbersAndWords::Translations::Extensions::FractionSignificance + def ones_of_tens(number, options = {}) + return t(%i[units tens one].join('.')) if number == 1 + return t(%i[units tens five].join('.')) if number == 5 + ones(number, options) + end + + def tens_with_ones(numbers, options = {}) + [tens(numbers[1]), ones_of_tens(numbers[0], options)].join options[:separator] || ' ' + end + + def ones_union(number, options = {}) + [t(:ones_union), ones(number, options)].join options[:separator] || ' ' + end + end + end +end diff --git a/spec/numbers_and_words/array/fixture_examples/vi.yml b/spec/numbers_and_words/array/fixture_examples/vi.yml new file mode 100644 index 00000000..ad0f7be8 --- /dev/null +++ b/spec/numbers_and_words/array/fixture_examples/vi.yml @@ -0,0 +1,30 @@ +to_words: + simple_example: + ? + - 1 + - 2 + - 3 + : + - một + - hai + - ba + complex_example: + ? + - 101 + - 21 + - 13 + : + - một trăm linh một + - hai mươi mốt + - mười ba + complex_example_with_options: + options: + :remove_zero: true + ? + - 0.1 + - 0.31 + - 0.012 + : + - không phẩy một + - không phẩy ba mươi mốt + - không phẩy không một hai diff --git a/spec/numbers_and_words/float/fixture_examples/vi.yml b/spec/numbers_and_words/float/fixture_examples/vi.yml new file mode 100644 index 00000000..8ecbc0ef --- /dev/null +++ b/spec/numbers_and_words/float/fixture_examples/vi.yml @@ -0,0 +1,19 @@ +to_words: + fractional: + 0.1: không phẩy một + 0.7: không phẩy bảy + 0.01: không phẩy không một + 0.012: không phẩy không một hai + 0.77: không phẩy bảy mươi bảy + 0.777: không phẩy bảy trăm bảy mươi bảy + 0.7777: không phẩy bảy nghìn bảy trăm bảy mươi bảy + 0.77777: không phẩy bảy mươi bảy nghìn bảy trăm bảy mươi bảy + 0.777777: không phẩy bảy trăm bảy mươi bảy nghìn bảy trăm bảy mươi bảy + 0.7777777: không phẩy bảy triệu bảy trăm bảy mươi bảy nghìn bảy trăm bảy mươi bảy + 0.77777777: không phẩy bảy mươi bảy triệu bảy trăm bảy mươi bảy nghìn bảy trăm bảy mươi bảy + 0.777777777: không phẩy bảy trăm bảy mươi bảy triệu bảy trăm bảy mươi bảy nghìn bảy trăm bảy mươi bảy + 0.2935174315119: không phẩy hai nghìn chín trăm ba mươi lăm tỷ một trăm bảy mươi bốn triệu ba trăm mười lăm nghìn một trăm mười chín + 21.77: hai mươi mốt phẩy bảy mươi bảy + 111.999: một trăm mười một phẩy chín trăm chín mươi chín + 4242.7463: bốn nghìn hai trăm bốn mươi hai phẩy bảy nghìn bốn trăm sáu mươi ba + 4242.07463: bốn nghìn hai trăm bốn mươi hai phẩy không bảy bốn sáu ba diff --git a/spec/numbers_and_words/integer/fixture_examples/vi.yml b/spec/numbers_and_words/integer/fixture_examples/vi.yml new file mode 100644 index 00000000..8109a06f --- /dev/null +++ b/spec/numbers_and_words/integer/fixture_examples/vi.yml @@ -0,0 +1,60 @@ +to_words: + ones: + 0: không + 1: một + 9: chín + teens: + 10: mười + 11: mười một + 19: mười chín + 20: hai mươi + 21: hai mươi mốt + 80: tám mươi + 90: chín mươi + 99: chín mươi chín + hundreds: + 100: một trăm + 101: một trăm linh một + 111: một trăm mười một + 120: một trăm hai mươi + 121: một trăm hai mươi mốt + 900: chín trăm + 909: chín trăm linh chín + 919: chín trăm mười chín + 990: chín trăm chín mươi + 999: chín trăm chín mươi chín + thousands: + 1000: một nghìn + 2000: hai nghìn + 4000: bốn nghìn + 5000: năm nghìn + 5010: năm nghìn không trăm mười + 11000: mười một nghìn + 21000: hai mươi mốt nghìn + 999000: chín trăm chín mươi chín nghìn + 999999: chín trăm chín mươi chín nghìn chín trăm chín mươi chín + millions: + 1000000: một triệu + 2000000: hai triệu + 4000000: bốn triệu + 5000000: năm triệu + 999000000: chín trăm chín mươi chín triệu + 999000999: chín trăm chín mươi chín triệu chín trăm chín mươi chín + 999999000: chín trăm chín mươi chín triệu chín trăm chín mươi chín nghìn + 999999999: chín trăm chín mươi chín triệu chín trăm chín mươi chín nghìn chín trăm chín mươi chín + billions: + 1000000000: một tỷ + 1500000000: một tỷ năm trăm triệu + 1174315110: một tỷ một trăm bảy mươi bốn triệu ba trăm mười lăm nghìn một trăm mười + 1174315119: một tỷ một trăm bảy mươi bốn triệu ba trăm mười lăm nghìn một trăm mười chín + 15174315119: mười lăm tỷ một trăm bảy mươi bốn triệu ba trăm mười lăm nghìn một trăm mười chín + 35174315119: ba mươi lăm tỷ một trăm bảy mươi bốn triệu ba trăm mười lăm nghìn một trăm mười chín + 935174315119: chín trăm ba mươi lăm tỷ một trăm bảy mươi bốn triệu ba trăm mười lăm nghìn một trăm mười chín + trillions: + 2935174315119: hai nghìn chín trăm ba mươi lăm tỷ một trăm bảy mươi bốn triệu ba trăm mười lăm nghìn một trăm mười chín + 2000000000000: hai nghìn tỷ + 2100000000000: hai nghìn một trăm tỷ + quadrillionth: + 1000000000000000: một triệu tỷ + 1200000000000000: một triệu hai trăm nghìn tỷ + 1200200000000000: một triệu hai trăm nghìn hai trăm tỷ diff --git a/spec/numbers_and_words/numbers_and_words_spec.rb b/spec/numbers_and_words/numbers_and_words_spec.rb index 02b7da61..6f61574f 100644 --- a/spec/numbers_and_words/numbers_and_words_spec.rb +++ b/spec/numbers_and_words/numbers_and_words_spec.rb @@ -15,7 +15,7 @@ [Float].each do |type| describe type do - %i[cs en-GB en es fr hu pt-BR ru ua].each do |locale| + %i[cs en-GB en es fr hu pt-BR ru ua vi].each do |locale| context locale do around(:each) { |example| ::I18n.with_locale(locale) { example.run } }