Module: YaKansuji

Defined in:
lib/ya_kansuji.rb,
lib/ya_kansuji/version.rb,
lib/ya_kansuji/formatter.rb,
lib/ya_kansuji/core_refine.rb,
lib/ya_kansuji/formatter/gov.rb,
lib/ya_kansuji/formatter/lawyer.rb,
lib/ya_kansuji/formatter/simple.rb,
lib/ya_kansuji/formatter/judic_h.rb,
lib/ya_kansuji/formatter/judic_v.rb

Overview

Simple kansuji formatter

Defined Under Namespace

Modules: CoreRefine, Formatter

Constant Summary collapse

UNIT_EXP3 =
%w(  ).freeze
UNIT_EXP4 =
%w(     𥝱       恒河沙 阿僧祇 那由他 不可思議 無量大数).freeze
MAX_VALUE =
(10_000**(UNIT_EXP4.size + 1)) - 1
NUM_ALT_CHARS =
'〇一二三四五六七八九0123456789零壱壹弌弐貳貮参參弎肆伍陸漆質柒捌玖拾什陌佰阡仟萬秭'
NUM_NORMALIZED_CHARS =
'01234567890123456789011122233345677789十十百百千千万𥝱'
REGEXP_PART =

rubocop:disable Lint/DuplicateRegexpCharacterClassElement

%r{
  [
    #{(NUM_ALT_CHARS + NUM_NORMALIZED_CHARS).chars.uniq.join}
    #{(UNIT_EXP3 + UNIT_EXP4).find_all { |u| u.length == 1 }.join}
    卄廿卅丗卌皕
  ] |
  #{UNIT_EXP4.find_all { |u| u.length > 1 }.join('|')}
}x.freeze
REGEXP =

rubocop:enable Lint/DuplicateRegexpCharacterClassElement

/(?:マイナス)?(?:#{REGEXP_PART})+/.freeze
VERSION =
'1.2.0'
@@formatters =
{}

Class Method Summary collapse

Class Method Details

.formatter(sym) ⇒ Object



94
95
96
# File 'lib/ya_kansuji.rb', line 94

def formatter(sym)
  @@formatters[sym]
end

.formattersObject



98
99
100
# File 'lib/ya_kansuji.rb', line 98

def formatters
  @@formatters
end

.register_formatter(sym, proc = nil, &block) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'lib/ya_kansuji.rb', line 84

def register_formatter(sym, proc = nil, &block)
  if block_given?
    @@formatters[sym] = block
  elsif proc.respond_to? :call
    @@formatters[sym] = proc
  else
    raise ArgumentError, 'Registering invalid formatter.'
  end
end

.to_i(str) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ya_kansuji.rb', line 27

def to_i(str)
  str = str.to_s.tr(NUM_ALT_CHARS, NUM_NORMALIZED_CHARS)
  str.gsub!(/[,,、[:space:]]/, '')
  matched = REGEXP.match(str) or return 0
  ret3 = 0
  ret4 = 0
  curnum = nil
  if str.respond_to? :_to_i_ya_kansuji_orig
    to_i_meth = :_to_i_ya_kansuji_orig
  else
    to_i_meth = :to_i
  end
  matched[0].scan(REGEXP_PART).each do |c|
    case c
    when '1', '2', '3', '4', '5', '6', '7', '8', '9'
      if curnum
        curnum *= 10
      else
        curnum = 0
      end
      curnum += c.public_send(to_i_meth)
    when '0'
      curnum and curnum *= 10
    when '', '廿'
      ret3 += 20
      curnum = nil
    when '', ''
      ret3 += 30
      curnum = nil
    when ''
      ret3 += 40
      curnum = nil
    when ''
      ret3 += 200
      curnum = nil
    when *UNIT_EXP4
      if curnum
        ret3 += curnum
        curnum = nil
      end
      ret3 = 1 if ret3.zero?
      ret4 += ret3 * (10**((UNIT_EXP4.index(c) + 1) * 4))
      ret3 = 0
    when *UNIT_EXP3
      curnum ||= 1
      ret3 += curnum * (10**(UNIT_EXP3.index(c) + 1))
      curnum = nil
    end
  end
  if curnum
    ret3 += curnum
    curnum = nil
  end
  ret = ret4 + ret3
  matched[0].start_with?('マイナス') ? -ret : ret
end

.to_kan(num, formatter = :simple, options = {}) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/ya_kansuji.rb', line 102

def to_kan(num, formatter = :simple, options = {})
  num.respond_to?(:_to_i_ya_kansuji_orig) ? num = num._to_i_ya_kansuji_orig : num = num.to_i
  if num.abs > MAX_VALUE
    raise RangeError, "Value must be between #{-MAX_VALUE} and #{MAX_VALUE}"
  end

  return "マイナス#{to_kan(-num, formatter, options)}" if num.negative?

  if formatter.respond_to? :call
    formatter.call num, options
  elsif @@formatters[formatter]
    @@formatters[formatter].call num, options
  else
    raise ArgumentError, "Unable to find formatter #{formatter}"
  end
end