extenso_pt 0.6.11 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bda081245b46894dcdc0ee69bb3d017305685073058cc8208cc9feb73192712c
4
- data.tar.gz: f6e4d59a022b7a610512269852b63b7636db9e393a90ba40a9ecc69c4b3ff806
3
+ metadata.gz: c74a57f4a545150449d04897170c65c2a88c8288a90c654b354002ee0f3cf615
4
+ data.tar.gz: 9900cc3428be8efc92eb195234bc50d00e11b6fa56c0d143ae5e9f9f0fb63159
5
5
  SHA512:
6
- metadata.gz: c96aa7ad2d9e7c44dea958422af50bc2e1c997e5f96375ec53a5ba898dd25c6c597c051b6bc01536d8a592dfa8a674884e65c968ea7cbacfcd12e08e01ce67cf
7
- data.tar.gz: 6bbf579b1b20fbfd58e88455c8b13da4ca24746de2f89cd59fa09d5ec10c2ef4854a8fc890b0fe7bde2818431cde2108eb77a72f4f1b643bdee25087eb5ddb19
6
+ metadata.gz: 8ad0445fe292697d1a8a8807a81d6bc2821f9857011d3851b1aeae500d3b46de8cb54d4e4e569119df333913fa6c5b13efa6e9a8772c29164d73d7db7f5a2bbb
7
+ data.tar.gz: f899825b52820a909a7b1ce30dc2438f8ccb2fb5311bd273763427dfcfd80705366d6f7fd2ec7dce271f0ae691c7d7db7706d9db4c84cf787bb067a07bd1a011
@@ -0,0 +1,12 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+ EnabledByDefault: true
4
+
5
+ Style/Copyright:
6
+ Enabled: false
7
+
8
+ Lint/ConstantResolution:
9
+ Enabled: false
10
+
11
+ Style/ConstantVisibility:
12
+ Enabled: false
@@ -1,24 +1,81 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- extenso_pt (0.6.11)
5
- bigdecimal (~> 1.4)
4
+ extenso_pt (0.7.3)
5
+ bigdecimal
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- bigdecimal (1.4.4)
11
- minitest (5.14.0)
10
+ ast (2.4.1)
11
+ backport (1.1.2)
12
+ benchmark (0.1.0)
13
+ bigdecimal (2.0.0)
14
+ e2mmap (0.1.0)
15
+ jaro_winkler (1.5.4)
16
+ kwalify (0.7.2)
17
+ maruku (0.7.3)
18
+ mini_portile2 (2.4.0)
19
+ minitest (5.14.2)
20
+ nokogiri (1.10.10)
21
+ mini_portile2 (~> 2.4.0)
22
+ parallel (1.19.2)
23
+ parser (2.7.2.0)
24
+ ast (~> 2.4.1)
25
+ psych (3.1.0)
26
+ rainbow (3.0.0)
12
27
  rake (13.0.1)
28
+ reek (6.0.1)
29
+ kwalify (~> 0.7.0)
30
+ parser (>= 2.5.0.0, < 2.8, != 2.5.1.1)
31
+ psych (~> 3.1.0)
32
+ rainbow (>= 2.0, < 4.0)
33
+ regexp_parser (1.8.1)
34
+ reverse_markdown (2.0.0)
35
+ nokogiri
36
+ rexml (3.2.4)
37
+ rubocop (0.92.0)
38
+ parallel (~> 1.10)
39
+ parser (>= 2.7.1.5)
40
+ rainbow (>= 2.2.2, < 4.0)
41
+ regexp_parser (>= 1.7)
42
+ rexml
43
+ rubocop-ast (>= 0.5.0)
44
+ ruby-progressbar (~> 1.7)
45
+ unicode-display_width (>= 1.4.0, < 2.0)
46
+ rubocop-ast (0.7.1)
47
+ parser (>= 2.7.1.5)
48
+ ruby-progressbar (1.10.1)
49
+ solargraph (0.39.17)
50
+ backport (~> 1.1)
51
+ benchmark
52
+ bundler (>= 1.17.2)
53
+ e2mmap
54
+ jaro_winkler (~> 1.5)
55
+ maruku (~> 0.7, >= 0.7.3)
56
+ nokogiri (~> 1.9, >= 1.9.1)
57
+ parser (~> 2.3)
58
+ reverse_markdown (>= 1.0.5, < 3)
59
+ rubocop (~> 0.52)
60
+ thor (~> 1.0)
61
+ tilt (~> 2.0)
62
+ yard (~> 0.9, >= 0.9.24)
63
+ thor (1.0.1)
64
+ tilt (2.0.10)
65
+ unicode-display_width (1.7.0)
66
+ yard (0.9.25)
13
67
 
14
68
  PLATFORMS
15
69
  ruby
16
70
 
17
71
  DEPENDENCIES
18
- bundler (~> 1.17)
72
+ bundler
19
73
  extenso_pt!
20
- minitest (~> 5.0)
74
+ minitest
21
75
  rake
76
+ reek
77
+ rubocop
78
+ solargraph
22
79
 
23
80
  BUNDLED WITH
24
- 1.17.2
81
+ 2.1.4
@@ -2,41 +2,43 @@
2
2
 
3
3
  lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'extenso_pt/version'
5
+ require('extenso_pt/version')
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = 'extenso_pt'
9
- spec.version = ExtensoPt::VERSION
10
- spec.authors = ['Hernâni Rodrigues Vaz']
11
- spec.email = ['hernanirvaz@gmail.com']
12
- spec.homepage = 'https://github.com/hernanilr/extenso_pt'
13
- spec.license = 'MIT'
8
+ spec.name = 'extenso_pt'
9
+ spec.version = ExtensoPt::VERSION
10
+ spec.authors = ['Hernâni Rodrigues Vaz']
11
+ spec.email = ['hernanirvaz@gmail.com']
12
+ spec.homepage = 'https://github.com/hernanilr/extenso_pt'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = '~> 2.7'
14
15
 
15
- spec.summary = 'Produz extenso em portugês de portugal, brasil '\
16
- 'ou numeracao romana.'
16
+ spec.summary = 'Produz extenso em portugês de portugal, brasil ou numeracao romana.'
17
17
  spec.description = spec.summary
18
- spec.description += ' Os valores podem ser um numerico, uma string de '\
19
- 'digitos ou um conjunto destes agrupados em (array, range, hash). '\
20
- 'O extenso pode ser produzido na escala longa (utilizada em todos os '\
21
- 'países lusófonos) ou na escala curta (utilizada no Brasil). Pode ainda '\
22
- 'produzir numeracao romana e vice versa.'
18
+ spec.description += ' Os valores podem ser um numerico, uma string de digitos ou um conjunto destes agrupados em '\
19
+ '(array, range, hash). O extenso pode ser produzido na escala longa (utilizada em todos os países lusófonos) ou '\
20
+ 'na escala curta (utilizada no Brasil). Pode ainda produzir numeracao romana e vice versa.'
23
21
 
24
- spec.metadata['yard.run'] = 'yard' # use "yard" to build full HTML docs.
22
+ # use "yard" to build full HTML docs.
23
+ spec.metadata['yard.run'] = 'yard'
25
24
  spec.metadata['homepage_uri'] = spec.homepage
26
25
 
27
26
  # Specify which files should be added to the gem when it is released.
28
27
  # loads the files in the RubyGem that have been added into git.
29
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
30
- `git ls-files -z`.split("\x0").reject \
31
- { |f| f.match(%r{^(test|spec|features)/}) }
32
- end
28
+ spec.files =
29
+ Dir.chdir(File.expand_path(__dir__)) do
30
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
31
+ end
33
32
  spec.bindir = 'exe'
34
33
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
35
34
  spec.require_paths = ['lib']
36
35
 
37
- spec.add_development_dependency 'bundler', '~> 1.17'
38
- spec.add_development_dependency 'minitest', '~> 5.0'
39
- spec.add_development_dependency 'rake'
36
+ spec.add_development_dependency('bundler')
37
+ spec.add_development_dependency('minitest')
38
+ spec.add_development_dependency('rake')
39
+ spec.add_development_dependency('reek')
40
+ spec.add_development_dependency('rubocop')
41
+ spec.add_development_dependency('solargraph')
40
42
 
41
- spec.add_dependency 'bigdecimal', '~> 1.4'
43
+ spec.add_dependency('bigdecimal')
42
44
  end
@@ -1,21 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bigdecimal/util'
4
- require 'extenso_pt/constantes'
5
- require 'extenso_pt/variaveis'
6
- require 'extenso_pt/extenso'
7
- require 'extenso_pt/romana'
8
- require 'extenso_pt/version'
3
+ require('bigdecimal/util')
4
+ require('extenso_pt/extenso')
5
+ require('extenso_pt/romana')
6
+ require('extenso_pt/version')
9
7
 
10
8
  # @author Hernani Rodrigues Vaz
11
9
  module ExtensoPt
12
- class Error < StandardError; end
13
- # Produz extenso em portugues de portugal ou brasil
14
- # (valor numerico pode ser uma string digitos)
10
+ # expressao regular da numeracao romana
11
+ RO_RE = /^M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i.freeze
12
+ # chaves parametrizacao moeda permitidas
13
+ MOEDA = %i[moeda_singular fracao_singular moeda_plural fracao_plural lc].freeze
14
+ # somente portugues de portugal ou brasil permitidos, qualquer outro locale equivale usar :pt
15
+ EXTLC = %i[pt br].freeze
16
+
17
+ # Processa objeto criando extenso(s) em portugues de portugal ou brasil
15
18
  #
19
+ # @note valor numerico pode ser uma string digitos
16
20
  # @param [Hash<String, Symbol>] moeda opcoes parametrizar moeda/fracao
17
- # @option moeda [Symbol] :lc locale do extenso -
18
- # portugues de portugal (:pt) portugues do brasil (:br)
21
+ # @option moeda [Symbol] :lc locale do extenso - portugues de portugal (:pt) portugues do brasil (:br)
19
22
  # @option moeda [String] :moeda_singular moeda no singular
20
23
  # @option moeda [String] :fracao_singular fracao no singular
21
24
  # @option moeda [String] :moeda_plural moeda no plural
@@ -26,83 +29,74 @@ module ExtensoPt
26
29
  # Hash<extensos> se objecto for (Hash)
27
30
  def extenso(moeda = { lc: :pt })
28
31
  # parametrizar moeda
29
- ExtensoPt.prmo(moeda.parametrizar)
32
+ ExtensoPt.parametrizar_moeda(moeda.parametrizar)
30
33
 
31
34
  processa
32
35
  end
33
36
 
34
- # Processa objeto criando extenso(s) em portugues de portugal ou brasil
35
- #
36
- # @return [String, Array<String>, Hash<String>]
37
- # String<extenso> se objecto for (String, Float, Integer),
38
- # Array<extensos> se objecto for (Array, Range),
39
- # Hash<extensos> se objecto for (Hash)
40
- def processa
41
- # converte valores do Hash nos seus extensos
42
- if is_a?(Hash) then map { |k, v| [k, v.processa] }.to_h
43
- # converte objecto num Array com os valores convertidos nos seus extensos
44
- elsif respond_to?(:to_a) then to_a.map(&:processa)
45
- else
46
- # converte objeto em string digitos utilizando bigdecimal para
47
- # evitar problemas com aritmetica virgula flutuante em valores >1e12
48
- # parametrizar parte inteira/fracionaria (@ai, @nf) da string digitos
49
- ExtensoPt.prif(to_d.to_s('F'))
50
-
51
- # processar extenso - valores >1e24 sao ignorados
52
- ExtensoPt.cvai.count > 8 ? '' : ExtensoPt.ejun
53
- end
54
- end
55
-
56
- # Parametrizacao por defeito para :br
57
- #
58
- # @return [Hash<String, Symbol>] parametrizacao moeda
37
+ # @return [Hash<String, Symbol>] parametrizacao moeda por defeito para :br & inferencias & errados
59
38
  def parametrizar
60
- if value?(:br) &&
61
- %i[moeda_singular moeda_plural].all? { |e| !keys.include?(e) }
62
- { lc: :br, moeda_singular: 'REAL', moeda_plural: 'REAIS',
63
- fracao_singular: 'CENTAVO', fracao_plural: 'CENTAVOS' }
39
+ if value?(:br) && %i[moeda_singular moeda_plural].all? { |syb| !keys.include?(syb) }
40
+ { lc: :br, moeda_singular: 'REAL', moeda_plural: 'REAIS', fracao_singular: 'CENTAVO', fracao_plural: 'CENTAVOS' }
64
41
  else
65
- inferir_singular
42
+ inferir_singular.eliminar_errados
66
43
  end
67
44
  end
68
45
 
69
- # Parametrizacao singular inferindo do plural
70
- #
71
- # @return [Hash<String, Symbol>] parametrizacao moeda
46
+ # @return [Hash<String, Symbol>] parametrizacao moeda singular inferindo do plural
72
47
  def inferir_singular
73
- self[:moeda_singular] ||= if fetch(:moeda_plural, '')[-1] == 'S'
74
- fetch(:moeda_plural, '')[0..-2]
75
- end
76
- self[:fracao_singular] ||= if fetch(:fracao_plural, '')[-1] == 'S'
77
- fetch(:fracao_plural, '')[0..-2]
78
- end
79
- # eliminar parametros errados
80
- keep_if { |k, v| MOEDA.include?(k) && (k != :lc || EXTLC.include?(v)) }
48
+ mdp = fetch(:moeda_plural, '')
49
+ frp = fetch(:fracao_plural, '')
50
+ self[:moeda_singular] ||= (mdp[0..-2] if mdp[-1] == 'S')
51
+ self[:fracao_singular] ||= (frp[0..-2] if frp[-1] == 'S')
52
+ self
81
53
  end
82
54
 
83
- # Testa se contem numeracao romana
84
- #
85
- # @return [true, false] sim ou nao numeracao romana
86
- def romana?
87
- is_a?(String) ? RO_RE.match?(upcase) : false
55
+ # @return [Hash<String, Symbol>] parametrizacao moeda eliminar parametros errados
56
+ def eliminar_errados
57
+ keep_if { |key, val| MOEDA.include?(key) && (key != :lc || EXTLC.include?(val)) }
88
58
  end
89
59
 
90
- # Produz numeracao romana a partir de valor numerico
91
- # ou valor numerico a partir da numeracao romana
92
- # (valor numerico pode ser uma string digitos)
93
- #
94
- # @return [String, Integer] numeracao romana ou valor numerico
60
+ # @return (see #extenso)
61
+ def processa
62
+ # converte num Array com os valores convertidos nos seus extensos
63
+ return to_a.map(&:processa) if is_a?(Range) || is_a?(Array)
64
+ # converte valores do Hash nos seus extensos
65
+ return transform_values(&:processa) if is_a?(Hash)
66
+
67
+ # converte objeto em string digitos utilizando bigdecimal para
68
+ # evitar problemas com aritmetica virgula flutuante em valores >1e12
69
+ # valores negativos sao convertidos em positivos
70
+ # parametrizar parte inteira/fracionaria (@ai, @nf) da string digitos
71
+ ExtensoPt.parametrizar_grupos(to_d.abs.to_s('F'))
72
+
73
+ # processar extenso - valores >= 1e24 sao ignorados
74
+ ExtensoPt.grupos.count > 8 ? '' : ExtensoPt.extenso_completo
75
+ end
76
+
77
+ # @note valor numerico pode ser uma string digitos
78
+ # @return [String, Integer] numeracao romana a partir de numerico ou inteiro a partir da numeracao romana
95
79
  def romana
80
+ # converte num Array com os valores convertidos
81
+ return to_a.map(&:romana) if is_a?(Range) || is_a?(Array)
96
82
  # converte os valores do Hash
97
- if is_a?(Hash) then map { |k, v| [k, v.romana] }.to_h
98
- # converte objecto num Array com os valores convertidos
99
- elsif respond_to?(:to_a) then to_a.map(&:romana)
100
- # numeracao romana a partir de inteiro ou string digitos
101
- # (ignora parte fracionaria)
102
- elsif (inteiro = to_i) != 0 then ExtensoPt.ri2r(inteiro)
83
+ return transform_values(&:romana) if is_a?(Hash)
84
+
85
+ romana_base(to_i.abs)
86
+ end
87
+
88
+ # @return (see #romana)
89
+ def romana_base(inteiro)
90
+ # numeracao romana a partir de inteiro ou string digitos (ignora parte fracionaria & negativos)
91
+ return ExtensoPt.ri2r(inteiro) unless inteiro.zero?
92
+
103
93
  # inteiro a partir da numeracao romana
104
- else RO_RE.match?(to_s) ? ExtensoPt.rr2i(upcase, 0) : ''
105
- end
94
+ RO_RE.match?(to_s) ? ExtensoPt.rr2i(upcase, 0) : ''
95
+ end
96
+
97
+ # @return [true, false] testa se contem numeracao romana
98
+ def romana?
99
+ is_a?(String) ? RO_RE.match?(upcase) : false
106
100
  end
107
101
  end
108
102
 
@@ -2,111 +2,170 @@
2
2
 
3
3
  # @author Hernani Rodrigues Vaz
4
4
  module ExtensoPt
5
- # Produz extenso das centenas em portugues de portugal ou brasil
5
+ # extensos 1-19; 20-90; 100-900
6
+ e013a = %w[UM DOIS TRÊS QUATRO CINCO SEIS SETE OITO NOVE DEZ ONZE DOZE TREZE].freeze
7
+ e019a = %w[QUINZE DEZASSEIS DEZASSETE DEZOITO DEZANOVE].freeze
8
+ e090a = %w[VINTE TRINTA QUARENTA CINQUENTA SESSENTA SETENTA OITENTA NOVENTA].freeze
9
+ e900a = %w[CEM CENTO DUZENTOS TREZENTOS QUATROCENTOS QUINHENTOS SEISCENTOS SETECENTOS OITOCENTOS NOVECENTOS].freeze
10
+ A0020 = { pt: [''] + e013a + ['CATORZE'] + e019a, br: [''] + e013a + ['QUATORZE'] + e019a }.freeze
11
+ A0100 = { pt: ['', ''] + e090a, br: ['', ''] + e090a }.freeze
12
+ A1000 = { pt: [''] + e900a, br: [''] + e900a }.freeze
13
+
14
+ # singular extensos 1e3 ate 1e24
15
+ # @note escala segundo convencao entre varios paises,
16
+ # na 9a Conferencia Geral de Pesos e Medidas (12-21 de Outubro de 1948),
17
+ # organizada pelo Bureau International des Poids et Mesures
18
+ # @example
19
+ # 1 000 000 = milhao
20
+ # 1 000 000 000 000 = biliao
21
+ # 1 000 000 000 000 000 000 = triliao
22
+ # 1 000 000 000 000 000 000 000 000 = quadriliao
23
+ # 1 000 000 000 000 000 000 000 000 000 000 = quintiliao
24
+ # 1 000 000 000 000 000 000 000 000 000 000 000 000 = sextiliao
25
+ S1E24 = {
26
+ pt: ['', 'MIL', ' MILHÃO', ' MIL MILHÃO', ' BILIÃO', ' MIL BILIÃO', ' TRILIÃO', ' MIL TRILIÃO'],
27
+ br: ['', 'MIL', ' MILHÃO', ' BILHÃO', ' TRILHÃO', ' QUADRILHÃO', ' QUINTILHÃO', ' SEXTILHÃO']
28
+ }.freeze
29
+
30
+ # plural extensos 1e3 ate 1e24
31
+ # @note escala segundo convencao entre varios paises,
32
+ # na 9a Conferencia Geral de Pesos e Medidas (12-21 de Outubro de 1948),
33
+ # organizada pelo Bureau International des Poids et Mesures
34
+ P1E24 = {
35
+ pt: ['', ' MIL', ' MILHÕES', ' MIL MILHÕES', ' BILIÕES', ' MIL BILIÕES', ' TRILIÕES', ' MIL TRILIÕES'],
36
+ br: ['', ' MIL', ' MILHÕES', ' BILHÕES', ' TRILHÕES', ' QUADRILHÕES', ' QUINTILHÕES', ' SEXTILHÕES']
37
+ }.freeze
38
+
39
+ # Parametrizar variaveis da moeda
6
40
  #
7
- # @param [Integer] mil o valor dum grupo 3 digitos a converter
8
- # @return [String] extenso das centenas
9
- def self.e900(mil)
10
- A1000[@lc][(mil > 100 ? 1 : 0) + mil / 100] +
11
- (mil > 100 && (mil % 100).positive? ? ' E ' : '')
41
+ # @param [Hash<String, Symbol>] moeda opcoes parametrizar moeda/fracao
42
+ # @option moeda [Symbol] :lc locale do extenso - portugues de portugal (:pt) portugues do brasil (:br)
43
+ # @option moeda [String] :moeda_singular moeda no singular
44
+ # @option moeda [String] :fracao_singular fracao no singular
45
+ # @option moeda [String] :moeda_plural moeda no plural
46
+ # @option moeda [String] :fracao_plural fracao no plural
47
+ def self.parametrizar_moeda(moeda)
48
+ # parametrizacao por defeito
49
+ # the first mention of a @<variable> creates that instance variable in the current object ie: self = ExtensoPt
50
+ @lc = moeda[:lc] || :pt
51
+ @ms = moeda[:moeda_singular] || 'EURO'
52
+ @fs = moeda[:fracao_singular] || 'CÊNTIMO'
53
+ @mp = moeda[:moeda_plural] || "#{@ms}S"
54
+ @fp = moeda[:fracao_plural] || "#{@fs}S"
12
55
  end
13
56
 
14
- # Produz extenso das dezenas em portugues de portugal ou brasil
57
+ # Parametrizar variaveis parte inteira e fracionaria
15
58
  #
59
+ # @param [String] digitos do valor monetario a converter
60
+ def self.parametrizar_grupos(digitos)
61
+ # cria array de grupos 3 digitos da parte inteira ex: 123022.12 => [22, 123]
62
+ @ai = digitos[/^\d+/].reverse.scan(/\d{1,3}/).map { |grp| Integer(grp.reverse) }
63
+
64
+ # obtem parte fracionaria da string digitos arredondada a 2 casas decimais ex: 123022.124 => 12, 123022.125 => 13
65
+ @nf = (Float(digitos[/\.\d*/]) * 100).round
66
+ end
67
+
68
+ # @return [Array<Integer>] grupos 3 digitos da parte inteira
69
+ def self.grupos
70
+ @ai
71
+ end
72
+
73
+ # @return [Integer] soma grupos 1-8 de digitos
74
+ def self.soma_grupos
75
+ Integer(@ai[0]) + Integer(@ai[1] || 0) * 2 + Integer(@ai[2..].to_a.inject(:+) || 0) * 2
76
+ end
77
+
78
+ # @return [true, false] sim ou nao proposicao DE
79
+ def self.testa_de?
80
+ Integer(@ai[0..1].inject(:+)).zero? && Integer(@ai[2..].to_a.inject(:+) || 0).positive?
81
+ end
82
+
83
+ # @param [Integer] mil o valor dum grupo 3 digitos a converter
84
+ # @return [String] extenso das centenas em portugues de portugal ou brasil
85
+ def self.centenas(mil)
86
+ cem = mil > 100
87
+ A1000[@lc][(cem ? 1 : 0) + mil / 100] + (cem && (mil % 100).positive? ? ' E ' : '')
88
+ end
89
+
16
90
  # @param [Integer] cem a centena dum grupo 3 digitos a converter
17
- # @return [String] extenso das dezenas
18
- def self.e090(cem)
19
- A0100[@lc][cem / 10] +
20
- (cem > 20 && (cem % 10).positive? ? ' E ' : '')
91
+ # @return [String] extenso das dezenas em portugues de portugal ou brasil
92
+ def self.dezenas(cem)
93
+ A0100[@lc][cem / 10] + (cem > 20 && (cem % 10).positive? ? ' E ' : '')
21
94
  end
22
95
 
23
- # Produz extenso das unidades em portugues de portugal ou brasil
24
- #
25
96
  # @param [Integer] cem a centena dum grupo 3 digitos a converter
26
- # @return [String] extenso das unidades
27
- def self.e009(cem)
97
+ # @return [String] extenso das unidades em portugues de portugal ou brasil
98
+ def self.unidades(cem)
28
99
  A0020[@lc][cem < 20 ? cem : cem % 10]
29
100
  end
30
101
 
31
- # Produz extenso da parte fracionaria em portugues de portugal ou brasil
32
- #
33
- # @return [String] extenso da parte fracionaria
34
- def self.ef99
35
- if cnf?
36
- e090(@nf) + e009(@nf) + ' ' + (@nf > 1 ? @fp : @fs)
102
+ # @return [String] proposicao E & extenso da parte fracionaria em portugues de portugal ou brasil
103
+ def self.fracionaria
104
+ if @nf.positive?
105
+ "#{soma_grupos.positive? ? ' E ' : ''}#{dezenas(@nf)}#{unidades(@nf)} #{@nf > 1 ? @fp : @fs}"
37
106
  else
38
107
  ''
39
108
  end
40
109
  end
41
110
 
42
- # Produz final da moeda em portugues de portugal ou brasil
43
- #
44
- # @return [String] final da moeda
45
- def self.efim
46
- t = c124
47
- if t.positive?
48
- # proposicao DE entre parte inteira e moeda
49
- # moeda singular/plural
50
- # proposicao E entre moeda e parte fracionaria
51
- (cde? ? ' DE ' : ' ') + (t > 1 ? @mp : @ms) + (cnf? ? ' E ' : '')
111
+ # @return [String] final da moeda em portugues de portugal ou brasil
112
+ def self.final
113
+ som = soma_grupos
114
+ if som.positive?
115
+ # proposicao DE entre parte inteira e moeda & moeda singular/plural
116
+ "#{testa_de? ? ' DE ' : ' '}#{som > 1 ? @mp : @ms}"
52
117
  else
53
118
  ''
54
- end + ef99
119
+ end + fracionaria
55
120
  end
56
121
 
57
- # Produz separador entre grupos 3 digitos
58
- #
59
122
  # @param [Integer] pos posicao actual nos grupos 3 digitos
60
- # @return [String] separador entre grupos 3 digitos
61
- def self.edgs(pos)
62
- if pos.positive? && @ai[pos - 1].positive?
63
- @ai[pos - 1] > 100 ? ' ' : ' E '
123
+ # @return [String] proposicao E entre grupos 3 digitos
124
+ def self.proposicao_grupo(pos)
125
+ grp = @ai[pos - 1]
126
+ if pos.positive? && grp.positive?
127
+ grp > 100 ? ' ' : ' E '
64
128
  else
65
129
  ''
66
130
  end
67
131
  end
68
132
 
69
- # Produz qualificador grupo de 3 digitos em portugues de portugal ou brasil
70
- #
71
133
  # @param [Integer] pos posicao actual nos grupos 3 digitos
72
- # @return [String] qualificador grupo de 3 digitos
73
- def self.e124(pos)
74
- if @ai[pos].positive?
75
- @ai[pos] > 1 ? P1E24[@lc][pos] : S1E24[@lc][pos]
134
+ # @return [String] qualificador grupo de 3 digitos em portugues de portugal ou brasil
135
+ def self.qualificador_grupo(pos)
136
+ grp = @ai[pos]
137
+ if grp.positive?
138
+ grp > 1 ? P1E24[@lc][pos] : S1E24[@lc][pos]
76
139
  else
77
140
  ''
78
- end + edgs(pos)
141
+ end + proposicao_grupo(pos)
79
142
  end
80
143
 
81
- # Produz extenso de grupo 3 digitos em portugues de portugal ou brasil
82
- #
83
144
  # @param [Integer] pos posicao actual nos grupos 3 digitos
84
- # @return [String] extenso do grupo 3 digitos
85
- def self.edg3(pos)
145
+ # @return [String] extenso do grupo 3 digitos em portugues de portugal ou brasil
146
+ def self.extenso_grupo(pos)
147
+ grp = @ai[pos]
148
+ dez = grp % 100
86
149
  # caso especial MIL EUROS
87
- if pos == 1 && @ai[pos] == 1
150
+ if pos == 1 && grp == 1
88
151
  ''
89
152
  else
90
- e900(@ai[pos]) + e090(@ai[pos] % 100) + e009(@ai[pos] % 100)
91
- end + e124(pos)
153
+ # extenso das centenas + extenso das dezenas + extenso das unidades
154
+ "#{centenas(grp)}#{dezenas(dez)}#{unidades(dez)}"
155
+ end + qualificador_grupo(pos)
92
156
  end
93
157
 
94
- # Produz extenso da parte inteira e fracionaria
95
- #
96
158
  # @param [Integer] pos posicao no grupo 3 digitos
97
159
  # @param [String] ext extenso em construcao
98
- # @return [String] extenso do valor monetario
99
- def self.ejun(pos = 0, ext = '')
160
+ # @return [String] extenso do valor monetario completo
161
+ def self.extenso_completo(pos = 0, ext = '')
100
162
  # testa fim do valor monetario
101
163
  if pos >= @ai.count
102
164
  # caso especial de zero
103
- (c124 + @nf).zero? ? 'ZERO ' + @mp : ext + efim
165
+ (soma_grupos + @nf).zero? ? "ZERO #{@mp}" : "#{ext}#{final}"
104
166
  else
105
- # converte grupo 3 digitos na posicao corrente
106
- # envoca proxima posicao
107
- ejun(pos + 1, edg3(pos) + ext)
167
+ # converte grupo 3 digitos na posicao corrente & envoca proxima posicao
168
+ extenso_completo(pos + 1, extenso_grupo(pos) + ext)
108
169
  end
109
170
  end
110
- # private_class_method :e900, :e090, :e009, :ef99, :efim,
111
- # :edgs, :e124, :edg3
112
171
  end
@@ -2,27 +2,24 @@
2
2
 
3
3
  # @author Hernani Rodrigues Vaz
4
4
  module ExtensoPt
5
- # Produz numeral romano a partir de inteiro
6
- #
5
+ # numeracao romana ordem decrescente (ordem importante)
6
+ ROMAN = { M: 1000, CM: 900, D: 500, CD: 400, C: 100, XC: 90, L: 50, XL: 40, X: 10, IX: 9, V: 5, IV: 4, I: 1 }.freeze
7
+
7
8
  # @param [Integer] inteiro a converter
8
9
  # @return [String] numeral romano do inteiro
9
10
  def self.ri2r(inteiro)
10
11
  return '' if inteiro.zero?
11
12
 
12
- # numeracao romana nao tem negativos
13
- inteiro = inteiro.abs if inteiro.negative?
14
- ROMAN.each { |r, v| return r.to_s + ri2r(inteiro - v) if v <= inteiro }
13
+ ROMAN.each { |srm, val| return "#{srm}#{ri2r(inteiro - val)}" if val <= inteiro }
15
14
  end
16
15
 
17
- # Produz inteiro a partir de numeral romano
18
- #
19
16
  # @param [String] numeral romano a converter
20
17
  # @param [Integer] ultimo valor convertido
21
18
  # @return [Integer] inteiro do numeral romano
22
19
  def self.rr2i(numeral, ultimo)
23
20
  return 0 if numeral.empty?
24
21
 
25
- v = ROMAN[numeral[-1].to_sym]
26
- v < ultimo ? (rr2i(numeral.chop, v) - v) : (rr2i(numeral.chop, v) + v)
22
+ val = ROMAN[numeral[-1].to_sym]
23
+ rr2i(numeral.chop, val) + (val < ultimo ? -val : val)
27
24
  end
28
25
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ExtensoPt
4
- VERSION = '0.6.11'
4
+ VERSION = '0.7.3'
5
5
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extenso_pt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.11
4
+ version: 0.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hernâni Rodrigues Vaz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-03 00:00:00.000000000 Z
11
+ date: 2020-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.17'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.17'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '5.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '5.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,20 +52,62 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: reek
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: solargraph
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
55
97
  - !ruby/object:Gem::Dependency
56
98
  name: bigdecimal
57
99
  requirement: !ruby/object:Gem::Requirement
58
100
  requirements:
59
- - - "~>"
101
+ - - ">="
60
102
  - !ruby/object:Gem::Version
61
- version: '1.4'
103
+ version: '0'
62
104
  type: :runtime
63
105
  prerelease: false
64
106
  version_requirements: !ruby/object:Gem::Requirement
65
107
  requirements:
66
- - - "~>"
108
+ - - ">="
67
109
  - !ruby/object:Gem::Version
68
- version: '1.4'
110
+ version: '0'
69
111
  description: Produz extenso em portugês de portugal, brasil ou numeracao romana. Os
70
112
  valores podem ser um numerico, uma string de digitos ou um conjunto destes agrupados
71
113
  em (array, range, hash). O extenso pode ser produzido na escala longa (utilizada
@@ -79,6 +121,7 @@ extra_rdoc_files: []
79
121
  files:
80
122
  - ".gitignore"
81
123
  - ".project_alt.json"
124
+ - ".rubocop.yml"
82
125
  - ".travis.yml"
83
126
  - Gemfile
84
127
  - Gemfile.lock
@@ -89,10 +132,8 @@ files:
89
132
  - bin/setup
90
133
  - extenso_pt.gemspec
91
134
  - lib/extenso_pt.rb
92
- - lib/extenso_pt/constantes.rb
93
135
  - lib/extenso_pt/extenso.rb
94
136
  - lib/extenso_pt/romana.rb
95
- - lib/extenso_pt/variaveis.rb
96
137
  - lib/extenso_pt/version.rb
97
138
  homepage: https://github.com/hernanilr/extenso_pt
98
139
  licenses:
@@ -106,16 +147,16 @@ require_paths:
106
147
  - lib
107
148
  required_ruby_version: !ruby/object:Gem::Requirement
108
149
  requirements:
109
- - - ">="
150
+ - - "~>"
110
151
  - !ruby/object:Gem::Version
111
- version: '0'
152
+ version: '2.7'
112
153
  required_rubygems_version: !ruby/object:Gem::Requirement
113
154
  requirements:
114
155
  - - ">="
115
156
  - !ruby/object:Gem::Version
116
157
  version: '0'
117
158
  requirements: []
118
- rubygems_version: 3.0.3
159
+ rubygems_version: 3.1.2
119
160
  signing_key:
120
161
  specification_version: 4
121
162
  summary: Produz extenso em portugês de portugal, brasil ou numeracao romana.
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # @author Hernani Rodrigues Vaz
4
- module ExtensoPt
5
- # chaves parametrizacao moeda permitidas
6
- MOEDA = %i[moeda_singular fracao_singular
7
- moeda_plural fracao_plural lc].freeze
8
- # somente portugues de portugal ou brasil permitidos
9
- # qualquer outro locale equivale usar :pt
10
- EXTLC = %i[pt br].freeze
11
- # extensos 1 ate 19
12
- A0020 = {
13
- pt: ['', 'UM', 'DOIS', 'TRÊS', 'QUATRO', 'CINCO', 'SEIS', 'SETE',
14
- 'OITO', 'NOVE', 'DEZ', 'ONZE', 'DOZE', 'TREZE', 'CATORZE',
15
- 'QUINZE', 'DEZASSEIS', 'DEZASSETE', 'DEZOITO', 'DEZANOVE'],
16
- br: ['', 'UM', 'DOIS', 'TRES', 'QUATRO', 'CINCO', 'SEIS', 'SETE',
17
- 'OITO', 'NOVE', 'DEZ', 'ONZE', 'DOZE', 'TREZE', 'QUATORZE',
18
- 'QUINZE', 'DEZESSEIS', 'DEZESSETE', 'DEZOITO', 'DEZENOVE']
19
- }.freeze
20
- # extensos 20 ate 90
21
- A0100 = {
22
- pt: ['', '', 'VINTE', 'TRINTA', 'QUARENTA', 'CINQUENTA', 'SESSENTA',
23
- 'SETENTA', 'OITENTA', 'NOVENTA'],
24
- br: ['', '', 'VINTE', 'TRINTA', 'QUARENTA', 'CINQUENTA', 'SESSENTA',
25
- 'SETENTA', 'OITENTA', 'NOVENTA']
26
- }.freeze
27
- # extensos 100 ate 900
28
- A1000 = {
29
- pt: ['', 'CEM', 'CENTO', 'DUZENTOS', 'TREZENTOS', 'QUATROCENTOS',
30
- 'QUINHENTOS', 'SEISCENTOS', 'SETECENTOS', 'OITOCENTOS', 'NOVECENTOS'],
31
- br: ['', 'CEM', 'CENTO', 'DUZENTOS', 'TREZENTOS', 'QUATROCENTOS',
32
- 'QUINHENTOS', 'SEISCENTOS', 'SETECENTOS', 'OITOCENTOS', 'NOVECENTOS']
33
- }.freeze
34
-
35
- # singular extensos 1e3 ate 1e24
36
- # escala segundo convencao entre varios paises,
37
- # na 9a Conferencia Geral de Pesos e Medidas (12-21 de Outubro de 1948),
38
- # organizada pelo Bureau International des Poids et Mesures
39
- # @example
40
- # 1 000 000 = milhao
41
- # 1 000 000 000 000 = biliao
42
- # 1 000 000 000 000 000 000 = triliao
43
- # 1 000 000 000 000 000 000 000 000 = quadriliao
44
- # 1 000 000 000 000 000 000 000 000 000 000 = quintiliao
45
- # 1 000 000 000 000 000 000 000 000 000 000 000 000 = sextiliao
46
- S1E24 = { pt: ['', 'MIL', ' MILHÃO', ' MIL MILHÃO', ' BILIÃO',
47
- ' MIL BILIÃO', ' TRILIÃO', ' MIL TRILIÃO'],
48
- br: ['', 'MIL', ' MILHÃO', ' BILHÃO', ' TRILHÃO',
49
- ' QUADRILHÃO', ' QUINTILHÃO', ' SEXTILHÃO'] }.freeze
50
- # plural extensos 1e3 ate 1e24
51
- P1E24 = { pt: ['', ' MIL', ' MILHÕES', ' MIL MILHÕES', ' BILIÕES',
52
- ' MIL BILIÕES', ' TRILIÕES', ' MIL TRILIÕES'],
53
- br: ['', ' MIL', ' MILHÕES', ' BILHÕES', ' TRILHÕES',
54
- ' QUADRILHÕES', ' QUINTILHÕES', ' SEXTILHÕES'] }.freeze
55
-
56
- # numeracao romana
57
- ROMAN = { M: 1000, CM: 900,
58
- D: 500, CD: 400,
59
- C: 100, XC: 90,
60
- L: 50, XL: 40,
61
- X: 10, IX: 9,
62
- V: 5, IV: 4,
63
- I: 1 }.freeze
64
- # exprecao regular da numeracao romana
65
- RO_RE = /^M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i.freeze
66
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # @author Hernani Rodrigues Vaz
4
- module ExtensoPt
5
- # Parametrizar moeda
6
- #
7
- # @param [Hash<String, Symbol>] moeda opcoes parametrizar moeda/fracao
8
- # @option moeda [Symbol] :lc locale do extenso -
9
- # portugues de portugal (:pt) portugues do brasil (:br)
10
- # @option moeda [String] :moeda_singular moeda no singular
11
- # @option moeda [String] :fracao_singular fracao no singular
12
- # @option moeda [String] :moeda_plural moeda no plural
13
- # @option moeda [String] :fracao_plural fracao no plural
14
- def self.prmo(moeda)
15
- # parametrizacao por defeito
16
- # the first mention of a @<variable> creates that instance variable
17
- # in the current object ie: self = ExtensoPt
18
- @lc = moeda[:lc] || :pt
19
- @ms = moeda[:moeda_singular] || 'EURO'
20
- @fs = moeda[:fracao_singular] || 'CÊNTIMO'
21
- @mp = moeda[:moeda_plural] || @ms + 'S'
22
- @fp = moeda[:fracao_plural] || @fs + 'S'
23
- end
24
-
25
- # Parametrizar parte inteira e fracionaria
26
- #
27
- # @param [String] digitos do valor monetario a converter
28
- def self.prif(digitos)
29
- # cria array de grupos 3 digitos da parte inteira
30
- # ex: 123022.12 => [22, 123]
31
- @ai = digitos[/^\d+/].to_s.reverse.scan(/\d{1,3}/)
32
- .map { |i| i.reverse.to_i }
33
-
34
- # obtem parte fracionaria da string digitos
35
- # ex: 123022.12 => 12
36
- # arredondada a 2 casas decimais (centimos/centavos)
37
- @nf = (digitos[/\.\d*/].to_f * 100).round
38
- end
39
-
40
- # @return [Array<Integer>] grupos 3 digitos da parte inteira
41
- def self.cvai
42
- @ai
43
- end
44
-
45
- # @return [Integer] soma grupos 1-8 de digitos
46
- def self.c124
47
- @ai[0].to_i + @ai[1].to_i * 2 + @ai[2..-1].to_a.inject(:+).to_i * 2
48
- end
49
-
50
- # @return [true, false] sim ou nao para controle proposicao DE
51
- def self.cde?
52
- @ai[0..1].to_a.inject(:+).to_i.zero? &&
53
- @ai[2..-1].to_a.inject(:+).to_i.positive?
54
- end
55
-
56
- # @return [true, false] sim ou nao para controle proposicao E
57
- def self.cnf?
58
- @nf.positive?
59
- end
60
- # private_class_method :c124, :cde?, :cnf?
61
- end