currency_to_words 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +93 -0
- data/VERSION +1 -0
- data/lib/cs_currency.rb +94 -0
- data/lib/currency_to_words.rb +95 -0
- metadata +80 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YmY4ZjNjNWQwYTg2MjAxMzg0MWY4M2U1ZTg5ZWE2YjhhZDcxMzIzYg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NGFkZjIwZmNkNzU4YTA5OTBlMGI1MGJmNTdmOWQ4Y2EwNmJhNTY5OQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZGYwM2E4YmJiNWZiNGMzOTk2OTI4NmJiNGM4MmI1MzhmZTNiMjE5N2U3M2Ey
|
10
|
+
Zjk2Zjk3NjUxYmQzNjc5Njg3YTAyYTliM2IzMWEzNGZhMmQwZGViODAwZWUz
|
11
|
+
NmZiMjdjYmRlMDZkZDYzMGQyOWM2N2RlMWNkODdiZmM5ZTRmZGY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NDg2MDJlMjQ5MjYxNTg5Y2Q2YWI2ZDBiM2YwOTA3MjI2ZjEzOWMxOWNiMDE0
|
14
|
+
NGM1OTUxNDViYTdiOGIwOTkwZWViNWQwYmQzZTE4NWFlYjM1NTAwMjY1YTQz
|
15
|
+
NThiZmIyNDVhNmRmMGU4ZDNmMjAzNWVkYzdhZGFkOTg0OGViNTA=
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Jakub Malina
|
2
|
+
|
3
|
+
THIS GEM LIBRARY IS MODIFICATION OF CURRENCY IN WORDS GEM BY BRUNO CARRERE.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
= Gem currency_to_words
|
2
|
+
|
3
|
+
Provides a view helper for Rails that translate a currency amount to words (eg. <tt>to_words(200)</tt> \=> 'dvě stě').
|
4
|
+
|
5
|
+
This helper comes with two supported locales (Czech and Polish) but it is possible and easy to implement your own (see "Implementing a new locale").
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
Add the gem to your Gemfile.
|
10
|
+
|
11
|
+
gem 'currency_to_words'
|
12
|
+
|
13
|
+
== Usage
|
14
|
+
|
15
|
+
Install gem and create locale file in your project where you want to provide translation from currency to words. You can use locale file from I18n files below section or create your own.
|
16
|
+
|
17
|
+
== Examples
|
18
|
+
|
19
|
+
In your views write for example:
|
20
|
+
currency_to_words(235.58)
|
21
|
+
|
22
|
+
== I18n files
|
23
|
+
|
24
|
+
=== Czech locale
|
25
|
+
|
26
|
+
cs:
|
27
|
+
number:
|
28
|
+
currency_in_words:
|
29
|
+
format: '%n'
|
30
|
+
options_precision:
|
31
|
+
precision: 2
|
32
|
+
delimiter: ''
|
33
|
+
significant: false
|
34
|
+
strip_insignificant_zeros: false
|
35
|
+
separator: '.'
|
36
|
+
raise: false
|
37
|
+
connector: ' a '
|
38
|
+
negative_format: '(%n)'
|
39
|
+
skip_and: true
|
40
|
+
ones: [nula, jedna, dvě, tři, čtyři, pět, šest, sedm, osm, devět]
|
41
|
+
teens: [deset, jedenáct, dvanáct, třináct, čtrnáct, patnáct, šestnáct, sedmnáct, osmnáct, devatenáct]
|
42
|
+
tens: [nil, nil,'dvacet','třicet','čtyřicet','padesát','šedesát','sedmdesát', 'osmdesát','devadesát']
|
43
|
+
hundreds: [sto, dvě stě, tři sta, čtyři sta, pět set, šest set, sedm set, osm set, devět set]
|
44
|
+
thousands_ones: [_, jeden, dva, tři, čtyři, pět, šest, sedm, osm, devět]
|
45
|
+
megs: [_, thousand, milion, bilion, trilion]
|
46
|
+
thousand:
|
47
|
+
one: 'tisíc'
|
48
|
+
few: 'tisíce'
|
49
|
+
other: 'tisíc'
|
50
|
+
milion:
|
51
|
+
one: 'milion'
|
52
|
+
few: 'miliony'
|
53
|
+
other: 'milionů'
|
54
|
+
bilion:
|
55
|
+
one: 'bilion'
|
56
|
+
few: 'biliony'
|
57
|
+
other: 'bilionů'
|
58
|
+
trilion:
|
59
|
+
one: 'trilion'
|
60
|
+
few: 'triliony'
|
61
|
+
other: 'trilionů'
|
62
|
+
currencies:
|
63
|
+
integer:
|
64
|
+
one: 'koruna'
|
65
|
+
few: 'koruny'
|
66
|
+
other: 'korun'
|
67
|
+
decimal:
|
68
|
+
one: 'haléř'
|
69
|
+
few: 'haléře'
|
70
|
+
other: 'haléřů'
|
71
|
+
|
72
|
+
== Missing locale?
|
73
|
+
|
74
|
+
If you need locale that is not supported yet, you can easily add one. All you need to do is translated locale file and create class in /lib.
|
75
|
+
Convention is that the class has to be named [locale]Currency.
|
76
|
+
|
77
|
+
So for example EnCurrency or FrCurrency. So override or duplicate the existing class and add diffrences of your language. Thats it!
|
78
|
+
|
79
|
+
== Inspiration
|
80
|
+
|
81
|
+
This project is heavily inspirated by {bcarrere/currency-in-words}[https://github.com/bcarrere/currency-in-words] and uses blocks of code from this repository.
|
82
|
+
|
83
|
+
Reason for creating my own repository was requirement to use I18n gem for "currency to words" translation and also for settings.
|
84
|
+
This means, that this gem can be configured from locale file and translation is not hardcoded to source of library.
|
85
|
+
|
86
|
+
== Contribution
|
87
|
+
|
88
|
+
Did you created locales that is not supported here yet? Please write me e-mail if you want contribute at majak108@gmail.com.
|
89
|
+
|
90
|
+
== Copyright
|
91
|
+
|
92
|
+
Copyright (c) 2014 Jakub Malina. See LICENSE.txt for
|
93
|
+
further details.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
data/lib/cs_currency.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module CurrencyToWords
|
3
|
+
|
4
|
+
# This is the strategy class for Czech language
|
5
|
+
class CsCurrency
|
6
|
+
|
7
|
+
def process number_parts
|
8
|
+
# default values
|
9
|
+
@skip_and = false
|
10
|
+
|
11
|
+
# scopes for I18n
|
12
|
+
@scope = [:number, :currency_in_words]
|
13
|
+
@currency_scope = [:number, :currency_in_words, :currencies]
|
14
|
+
|
15
|
+
# split to integer and decimal parts
|
16
|
+
int_part, dec_part = number_parts.map(&:to_i)
|
17
|
+
|
18
|
+
# find suitable unit form
|
19
|
+
int_unit = (I18n.t :integer, scope: @currency_scope, count: int_part) # always use int unit
|
20
|
+
dec_unit = (I18n.t :decimal, scope: @currency_scope, count: dec_part) if dec_part > 0
|
21
|
+
|
22
|
+
# connector between words
|
23
|
+
connector = (I18n.t :connector, scope: @scope)
|
24
|
+
|
25
|
+
# skip constant
|
26
|
+
@skip_and = (I18n.t :skip_and, scope: @scope)
|
27
|
+
|
28
|
+
# load number forms
|
29
|
+
@ones = (I18n.t :ones, scope: @scope)
|
30
|
+
@teens = (I18n.t :teens, scope: @scope)
|
31
|
+
@tens = (I18n.t :tens, scope: @scope)
|
32
|
+
@hundreds = (I18n.t :hundreds, scope: @scope)
|
33
|
+
@megs = (I18n.t :megs, scope: @scope)
|
34
|
+
@thousand_ones = (I18n.t :thousands_ones, scope: @scope)
|
35
|
+
|
36
|
+
# iteration algorithm for integer and decimal part
|
37
|
+
processed_int_part = (processed_by_group(int_part).compact << int_unit).flatten.join(' ')
|
38
|
+
processed_dec_part = (processed_by_group(dec_part).compact << dec_unit).flatten.join(' ')
|
39
|
+
|
40
|
+
# if decimal part is not 0, connect it to integer part with connector
|
41
|
+
if dec_part.zero?
|
42
|
+
processed_int_part
|
43
|
+
else
|
44
|
+
processed_int_part << connector << processed_dec_part
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def processed_by_group number, group=0
|
51
|
+
return [under_100(number, group)] if number.zero?
|
52
|
+
|
53
|
+
# q is modulo after dividing by 1000
|
54
|
+
# r is residue
|
55
|
+
q,r = number.divmod 1000
|
56
|
+
|
57
|
+
# if q is bigger than 0, iterate!
|
58
|
+
arr = processed_by_group(q, group+1) if q > 0
|
59
|
+
|
60
|
+
# return arr if r is 0
|
61
|
+
if r.zero?
|
62
|
+
arr
|
63
|
+
else
|
64
|
+
arr = arr.to_a
|
65
|
+
arr << under_1000(r, group)
|
66
|
+
group.zero? ? arr : arr << (I18n.t @megs[group], scope: @scope, count: number)
|
67
|
+
arr
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# algorithm part for numbers under 1000
|
72
|
+
def under_1000 number, group
|
73
|
+
q,r = number.divmod 100
|
74
|
+
arr = []
|
75
|
+
arr << @hundreds[q-1] if q > 0
|
76
|
+
r.zero? ? arr : arr.to_a << under_100(r, group)
|
77
|
+
arr << (' a' unless @skip_and || r.zero?).to_s if q > 0
|
78
|
+
arr
|
79
|
+
end
|
80
|
+
|
81
|
+
# algorithm part for numbers under 100
|
82
|
+
def under_100 number, group
|
83
|
+
case number
|
84
|
+
# in czech is different between form for ones, tens, hundreds and thousands
|
85
|
+
when 0..9 then group.zero? ? @ones[number] : @thousand_ones[number]
|
86
|
+
when 10..19 then @teens[number - 10]
|
87
|
+
else
|
88
|
+
q,r = number.divmod 10
|
89
|
+
@tens[q] + (' ' + @ones[r] unless r.zero?).to_s
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module CurrencyToWords
|
3
|
+
|
4
|
+
require 'cs_currency'
|
5
|
+
|
6
|
+
ActionView::Helpers::NumberHelper.class_eval do
|
7
|
+
|
8
|
+
def currency_to_words number, options = {}
|
9
|
+
# scopes
|
10
|
+
scope = [:number, :currency_in_words]
|
11
|
+
options_precision_scope = [:number, :currency_in_words, :options_precision]
|
12
|
+
|
13
|
+
# format of number
|
14
|
+
format = (I18n.t :format, scope: scope)
|
15
|
+
|
16
|
+
# options for precision to split int and decimal part
|
17
|
+
options_precision = {
|
18
|
+
:precision => (I18n.t :precision, scope: options_precision_scope),
|
19
|
+
:delimiter => (I18n.t :delimiter, scope: options_precision_scope),
|
20
|
+
:significant => (I18n.t :significant, scope: options_precision_scope),
|
21
|
+
:strip_insignificant_zeros => (I18n.t :strip_insignificant_zeros, scope: options_precision_scope),
|
22
|
+
:separator => (I18n.t :separator, scope: options_precision_scope),
|
23
|
+
:raise => (I18n.t :raise, scope: options_precision_scope)
|
24
|
+
}
|
25
|
+
|
26
|
+
# try to split number
|
27
|
+
begin
|
28
|
+
rounded_number = number_with_precision(number, options_precision)
|
29
|
+
rescue ActionView::Helpers::NumberHelper::InvalidNumberError => e
|
30
|
+
if options[:raise]
|
31
|
+
raise
|
32
|
+
else
|
33
|
+
rounded_number = format.gsub(/%n/, e.number)
|
34
|
+
return e.number.to_s.html_safe? ? rounded_number.html_safe : rounded_number
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# try to find locale class with language algorithm
|
39
|
+
begin
|
40
|
+
klass = "CurrencyToWords::#{I18n.locale.to_s.capitalize}Currency".constantize
|
41
|
+
rescue NameError
|
42
|
+
if options[:raise]
|
43
|
+
raise NameError, "Implement a class #{options[:locale].to_s.capitalize}Currency to support this locale, please."
|
44
|
+
else
|
45
|
+
klass = CsCurrency
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# map number parts
|
50
|
+
number_parts = rounded_number.split(options_precision[:separator]).map(&:to_i)
|
51
|
+
|
52
|
+
# Create instance of base class and try to process through.
|
53
|
+
base_class = CurrencyToWords::Currency.new(klass.new, number_parts, options)
|
54
|
+
processed_number = base_class.process
|
55
|
+
|
56
|
+
# return formatted number
|
57
|
+
format.gsub(/%n/, processed_number).html_safe
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Base class that will load language specific class with specific language algorithm.
|
62
|
+
class Currency
|
63
|
+
attr_reader :number_parts, :options, :texterizer
|
64
|
+
|
65
|
+
# constructor of Currency class
|
66
|
+
def initialize lang_class, splitted_number, options = {}
|
67
|
+
@lang_class = lang_class
|
68
|
+
@number_parts = splitted_number
|
69
|
+
@options = options
|
70
|
+
end
|
71
|
+
|
72
|
+
# Process and try to find language specific for current locale!
|
73
|
+
def process
|
74
|
+
if @lang_class.respond_to?('process')
|
75
|
+
processed_number = @lang_class.process @number_parts
|
76
|
+
if processed_number.is_a?(String)
|
77
|
+
return processed_number
|
78
|
+
else
|
79
|
+
raise TypeError, "a lang_class must return a String" if @options[:raise]
|
80
|
+
end
|
81
|
+
else
|
82
|
+
raise NoMethodError, "a lang_class must provide a 'lang_class' method" if @options[:raise]
|
83
|
+
end
|
84
|
+
|
85
|
+
# fallback on CsCurrency
|
86
|
+
unless @lang_class.instance_of?(CsCurrency)
|
87
|
+
@lang_class = CsCurrency.new
|
88
|
+
self.process
|
89
|
+
else
|
90
|
+
raise RuntimeError, "you should use the option ':raise => true' to see what goes wrong"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: currency_to_words
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jakub Malina
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: actionpack
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.1'
|
41
|
+
description: Rails 4 helper to_words that displays a currency amount in words (eg.
|
42
|
+
'one hundred dollars')
|
43
|
+
email: majak108@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files:
|
47
|
+
- LICENSE.txt
|
48
|
+
- README.rdoc
|
49
|
+
files:
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.rdoc
|
52
|
+
- VERSION
|
53
|
+
- lib/cs_currency.rb
|
54
|
+
- lib/currency_to_words.rb
|
55
|
+
homepage: https://github.com/kuba108/currency_to_words
|
56
|
+
licenses:
|
57
|
+
- MIT
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.4.1
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: Rails 4 helper to_words that displays a currency amount in words (eg. 'one
|
79
|
+
hundred dollars')
|
80
|
+
test_files: []
|