ya_kansuji 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog +10 -1
- data/README.md +5 -0
- data/lib/ya_kansuji/core_ext/integer.rb +2 -2
- data/lib/ya_kansuji/core_ext/string.rb +1 -1
- data/lib/ya_kansuji/core_refine.rb +4 -4
- data/lib/ya_kansuji/formatter/gov.rb +6 -2
- data/lib/ya_kansuji/formatter/judic_h.rb +7 -3
- data/lib/ya_kansuji/formatter/judic_v.rb +7 -3
- data/lib/ya_kansuji/formatter/lawyer.rb +7 -3
- data/lib/ya_kansuji/formatter/simple.rb +21 -11
- data/lib/ya_kansuji/formatter.rb +22 -0
- data/lib/ya_kansuji/version.rb +3 -1
- data/lib/ya_kansuji.rb +7 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97f2f4c063933b7c86ede7c11d8d34704e612f7eb4e82e2f60f469d8aa8ded4c
|
|
4
|
+
data.tar.gz: 4aa55c66f2d6b5ae168278e0b2b1a096e062ae1a3e96d31bcb118f415c184bb0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0203eaef1b77450bd6ea5c9666cf695bfe72fd7fb21d966d18bb177fa38db3ca500dff690841c3f1b5d25b9406c62f7bf38a90be98f6c5983f5df68fe65df8cb
|
|
7
|
+
data.tar.gz: 7a420d832dbd4da1149ac293820dca4f510226c53513bc1f579d2fa889cc8b16708f717406c76be8937f21623090eaf7d073896234296598e40e36a8275091ae
|
data/ChangeLog
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
2026-07-14 Tatsuki Sugiura <sugi@nemui.org>
|
|
2
|
+
|
|
3
|
+
* Version: 1.2.0
|
|
4
|
+
* Require Ruby 2.3.0 or later
|
|
5
|
+
* Accept formatter and options on Integer#to_kan core extension
|
|
6
|
+
* Accept :kansuji as base symbol on String#to_i core extension
|
|
7
|
+
* Raise RangeError when formatting values outside the supported 72-digit range
|
|
8
|
+
* Avoid circular require warnings between the main and refinement entrypoints
|
|
9
|
+
* Optimize formatter chunk processing (up to ~9x faster, far fewer allocations)
|
|
10
|
+
|
|
1
11
|
2026-07-13 Tatsuki Sugiura <sugi@nemui.org>
|
|
2
12
|
|
|
3
13
|
* Version: 1.1.0
|
|
@@ -19,4 +29,3 @@
|
|
|
19
29
|
2019-04-15 Tatsuki Sugiura <sugi@nemui.org>
|
|
20
30
|
|
|
21
31
|
* Version: 0.1.0
|
|
22
|
-
|
data/README.md
CHANGED
|
@@ -59,6 +59,9 @@ YaKansuji.to_kan(12345) # => 一万二千三百四十五
|
|
|
59
59
|
YaKansuji.to_kan(-12345) # => マイナス一万二千三百四十五
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
対応する値域は `-(10**72 - 1)` から `10**72 - 1` です。
|
|
63
|
+
数値として整数化した値がこの範囲を超える場合、`RangeError` が発生します。
|
|
64
|
+
|
|
62
65
|
このさい、2つめの引数にシンボルを渡すことにより、フォーマッタを切り替えることができます。
|
|
63
66
|
|
|
64
67
|
```ruby
|
|
@@ -113,6 +116,7 @@ using YaKansuji::CoreRefine
|
|
|
113
116
|
|
|
114
117
|
puts "二万".to_i # => 20000
|
|
115
118
|
puts 20000.to_kan #= > "二万"
|
|
119
|
+
puts 20000.to_kan(:gov) # => "2万"
|
|
116
120
|
```
|
|
117
121
|
|
|
118
122
|
ちなみに、 `to_i` に base が渡された場合は、漢数字が解釈されずにビルトインクラスのものが呼ばれます。
|
|
@@ -121,6 +125,7 @@ puts 20000.to_kan #= > "二万"
|
|
|
121
125
|
using YaKansuji::CoreRefine
|
|
122
126
|
|
|
123
127
|
puts "12万".to_i # => 120000
|
|
128
|
+
puts "12万".to_i(:kansuji) # => 120000
|
|
124
129
|
puts "12万".to_i(16) # => 18
|
|
125
130
|
```
|
|
126
131
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'ya_kansuji'
|
|
4
|
-
|
|
5
3
|
module YaKansuji
|
|
6
4
|
# String and Integer refinements with YaKansuji
|
|
7
5
|
module CoreRefine
|
|
@@ -16,9 +14,11 @@ module YaKansuji
|
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
refine Integer do
|
|
19
|
-
def to_kan(formatter = :simple)
|
|
20
|
-
YaKansuji.to_kan self, formatter
|
|
17
|
+
def to_kan(formatter = :simple, options = {})
|
|
18
|
+
YaKansuji.to_kan self, formatter, options
|
|
21
19
|
end
|
|
22
20
|
end
|
|
23
21
|
end
|
|
24
22
|
end
|
|
23
|
+
|
|
24
|
+
require 'ya_kansuji' unless YaKansuji.respond_to?(:to_i) && YaKansuji.respond_to?(:to_kan)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module YaKansuji
|
|
2
4
|
module Formatter
|
|
3
5
|
# Formatter for Japan government-style kansuji
|
|
@@ -8,10 +10,12 @@ module YaKansuji
|
|
|
8
10
|
return '0' if num.zero?
|
|
9
11
|
|
|
10
12
|
parts = []
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
chunks = Formatter.split_by_unit4(num)
|
|
14
|
+
(chunks.size - 1).downto(0) do |idx4|
|
|
15
|
+
i4 = chunks[idx4]
|
|
13
16
|
next if i4.zero?
|
|
14
17
|
|
|
18
|
+
unit4 = Formatter::UNIT4_UNITS[idx4]
|
|
15
19
|
if i4 == 1
|
|
16
20
|
parts << "1#{unit4}"
|
|
17
21
|
next
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Simple kansuji formatter
|
|
2
4
|
module YaKansuji
|
|
3
5
|
module Formatter
|
|
@@ -8,12 +10,14 @@ module YaKansuji
|
|
|
8
10
|
def call(num, _options = {})
|
|
9
11
|
return '0' if num.zero?
|
|
10
12
|
|
|
11
|
-
ret = ''
|
|
13
|
+
ret = +''
|
|
12
14
|
head = true
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
chunks = Formatter.split_by_unit4(num)
|
|
16
|
+
(chunks.size - 1).downto(0) do |idx4|
|
|
17
|
+
i4 = chunks[idx4]
|
|
15
18
|
next if i4.zero?
|
|
16
19
|
|
|
20
|
+
unit4 = Formatter::UNIT4_UNITS[idx4]
|
|
17
21
|
if head
|
|
18
22
|
ret << (i4.to_s + unit4)
|
|
19
23
|
else
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Simple kansuji formatter
|
|
2
4
|
module YaKansuji
|
|
3
5
|
module Formatter
|
|
@@ -8,12 +10,14 @@ module YaKansuji
|
|
|
8
10
|
def call(num, _options = {})
|
|
9
11
|
return '〇' if num.zero?
|
|
10
12
|
|
|
11
|
-
ret = ''
|
|
13
|
+
ret = +''
|
|
12
14
|
head = true
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
chunks = Formatter.split_by_unit4(num)
|
|
16
|
+
(chunks.size - 1).downto(0) do |idx4|
|
|
17
|
+
i4 = chunks[idx4]
|
|
15
18
|
next if i4.zero?
|
|
16
19
|
|
|
20
|
+
unit4 = Formatter::UNIT4_UNITS[idx4]
|
|
17
21
|
if head
|
|
18
22
|
ret << (i4.to_s + unit4)
|
|
19
23
|
else
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Simple kansuji formatter
|
|
2
4
|
module YaKansuji
|
|
3
5
|
module Formatter
|
|
@@ -8,11 +10,13 @@ module YaKansuji
|
|
|
8
10
|
def call(num, _options = {})
|
|
9
11
|
return '0' if num.zero?
|
|
10
12
|
|
|
11
|
-
ret = ''
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
ret = +''
|
|
14
|
+
chunks = Formatter.split_by_unit4(num)
|
|
15
|
+
(chunks.size - 1).downto(0) do |idx4|
|
|
16
|
+
i4 = chunks[idx4]
|
|
14
17
|
next if i4.zero?
|
|
15
18
|
|
|
19
|
+
unit4 = Formatter::UNIT4_UNITS[idx4]
|
|
16
20
|
if i4 == 1
|
|
17
21
|
ret << "1#{unit4}"
|
|
18
22
|
next
|
|
@@ -4,33 +4,43 @@ module YaKansuji
|
|
|
4
4
|
module Formatter
|
|
5
5
|
# Simple kansuji formatter
|
|
6
6
|
module Simple
|
|
7
|
+
DIGITS = %w(一 二 三 四 五 六 七 八 九).freeze
|
|
8
|
+
UNITS = ([''] + UNIT_EXP3).freeze
|
|
9
|
+
|
|
7
10
|
module_function
|
|
8
11
|
|
|
9
12
|
def call(num, _options = {})
|
|
10
13
|
return '零' if num.zero?
|
|
11
14
|
|
|
12
|
-
ret =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
ret = nil
|
|
16
|
+
chunks = Formatter.split_by_unit4(num)
|
|
17
|
+
(chunks.size - 1).downto(0) do |idx4|
|
|
18
|
+
i4 = chunks[idx4]
|
|
15
19
|
next if i4.zero?
|
|
16
20
|
|
|
21
|
+
ret ||= +''
|
|
22
|
+
unit4 = Formatter::UNIT4_UNITS[idx4]
|
|
17
23
|
if i4 == 1
|
|
18
|
-
ret
|
|
24
|
+
ret << '一' << unit4
|
|
19
25
|
next
|
|
20
26
|
end
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
|
|
28
|
+
divisor = 1000
|
|
29
|
+
3.downto(0) do |idx3|
|
|
30
|
+
i3 = (i4 / divisor) % 10
|
|
31
|
+
divisor /= 10
|
|
23
32
|
next if i3.zero?
|
|
24
33
|
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
unit3 = UNITS[idx3]
|
|
35
|
+
if i3 == 1 && !unit3.empty?
|
|
36
|
+
ret << unit3
|
|
27
37
|
else
|
|
28
|
-
ret
|
|
38
|
+
ret << DIGITS[i3 - 1] << unit3
|
|
29
39
|
end
|
|
30
40
|
end
|
|
31
|
-
ret
|
|
41
|
+
ret << unit4
|
|
32
42
|
end
|
|
33
|
-
ret
|
|
43
|
+
ret || ''
|
|
34
44
|
end
|
|
35
45
|
YaKansuji.register_formatter :simple, self
|
|
36
46
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module YaKansuji
|
|
4
|
+
# Shared helpers for built-in formatters.
|
|
5
|
+
module Formatter
|
|
6
|
+
UNIT4_BASE = 10_000
|
|
7
|
+
UNIT4_CHUNK_LIMIT = UNIT_EXP4.size + 1
|
|
8
|
+
UNIT4_UNITS = ([''] + UNIT_EXP4).freeze
|
|
9
|
+
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
def split_by_unit4(num)
|
|
13
|
+
chunks = []
|
|
14
|
+
UNIT4_CHUNK_LIMIT.times do
|
|
15
|
+
num, chunk = num.divmod(UNIT4_BASE)
|
|
16
|
+
chunks << chunk
|
|
17
|
+
break if num.zero?
|
|
18
|
+
end
|
|
19
|
+
chunks
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/ya_kansuji/version.rb
CHANGED
data/lib/ya_kansuji.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'ya_kansuji/version'
|
|
4
|
-
require 'ya_kansuji/core_refine'
|
|
5
4
|
|
|
6
5
|
# Yet another Kansuji library for ruby.
|
|
7
6
|
module YaKansuji
|
|
8
7
|
UNIT_EXP3 = %w(十 百 千).freeze
|
|
9
8
|
UNIT_EXP4 = %w(万 億 兆 京 垓 𥝱 穣 溝 澗 正 載 極 恒河沙 阿僧祇 那由他 不可思議 無量大数).freeze
|
|
9
|
+
MAX_VALUE = (10_000**(UNIT_EXP4.size + 1)) - 1
|
|
10
10
|
NUM_ALT_CHARS = '〇一二三四五六七八九0123456789零壱壹弌弐貳貮参參弎肆伍陸漆質柒捌玖拾什陌佰阡仟萬秭'
|
|
11
11
|
NUM_NORMALIZED_CHARS = '01234567890123456789011122233345677789十十百百千千万𥝱'
|
|
12
12
|
# rubocop:disable Lint/DuplicateRegexpCharacterClassElement
|
|
@@ -101,6 +101,10 @@ module YaKansuji
|
|
|
101
101
|
|
|
102
102
|
def to_kan(num, formatter = :simple, options = {})
|
|
103
103
|
num.respond_to?(:_to_i_ya_kansuji_orig) ? num = num._to_i_ya_kansuji_orig : num = num.to_i
|
|
104
|
+
if num.abs > MAX_VALUE
|
|
105
|
+
raise RangeError, "Value must be between #{-MAX_VALUE} and #{MAX_VALUE}"
|
|
106
|
+
end
|
|
107
|
+
|
|
104
108
|
return "マイナス#{to_kan(-num, formatter, options)}" if num.negative?
|
|
105
109
|
|
|
106
110
|
if formatter.respond_to? :call
|
|
@@ -113,8 +117,10 @@ module YaKansuji
|
|
|
113
117
|
end
|
|
114
118
|
end
|
|
115
119
|
|
|
120
|
+
require 'ya_kansuji/formatter'
|
|
116
121
|
require 'ya_kansuji/formatter/simple'
|
|
117
122
|
require 'ya_kansuji/formatter/gov'
|
|
118
123
|
require 'ya_kansuji/formatter/lawyer'
|
|
119
124
|
require 'ya_kansuji/formatter/judic_v'
|
|
120
125
|
require 'ya_kansuji/formatter/judic_h'
|
|
126
|
+
require 'ya_kansuji/core_refine' unless defined?(YaKansuji::CoreRefine)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ya_kansuji
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tatsuki Sugiura
|
|
@@ -27,6 +27,7 @@ files:
|
|
|
27
27
|
- lib/ya_kansuji/core_ext/integer.rb
|
|
28
28
|
- lib/ya_kansuji/core_ext/string.rb
|
|
29
29
|
- lib/ya_kansuji/core_refine.rb
|
|
30
|
+
- lib/ya_kansuji/formatter.rb
|
|
30
31
|
- lib/ya_kansuji/formatter/gov.rb
|
|
31
32
|
- lib/ya_kansuji/formatter/judic_h.rb
|
|
32
33
|
- lib/ya_kansuji/formatter/judic_v.rb
|
|
@@ -46,7 +47,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
46
47
|
requirements:
|
|
47
48
|
- - ">="
|
|
48
49
|
- !ruby/object:Gem::Version
|
|
49
|
-
version: 2.
|
|
50
|
+
version: 2.3.0
|
|
50
51
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
52
|
requirements:
|
|
52
53
|
- - ">="
|