| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# For Emacs: -*- mode:cperl; eval: (folding-mode 1); coding:utf-8; -*- |
|
2
|
|
|
|
|
|
|
# |
|
3
|
|
|
|
|
|
|
# Copyright (c) Mike Schilli, 2001 (m@perlmeister.com) |
|
4
|
|
|
|
|
|
|
# Copyright (c) PetaMem, s.r.o. 2002-present |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package Lingua::JPN::Num2Word; |
|
7
|
|
|
|
|
|
|
# ABSTRACT: Number to word conversion in Japanese |
|
8
|
|
|
|
|
|
|
|
|
9
|
2
|
|
|
2
|
|
97773
|
use 5.16.0; |
|
|
2
|
|
|
|
|
8
|
|
|
10
|
2
|
|
|
2
|
|
703
|
use utf8; |
|
|
2
|
|
|
|
|
314
|
|
|
|
2
|
|
|
|
|
17
|
|
|
11
|
2
|
|
|
2
|
|
57
|
use warnings; |
|
|
2
|
|
|
|
|
12
|
|
|
|
2
|
|
|
|
|
103
|
|
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# {{{ use block |
|
14
|
|
|
|
|
|
|
|
|
15
|
2
|
|
|
2
|
|
14
|
use Carp; |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
204
|
|
|
16
|
2
|
|
|
2
|
|
1255
|
use Export::Attrs; |
|
|
2
|
|
|
|
|
21345
|
|
|
|
2
|
|
|
|
|
11
|
|
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# }}} |
|
19
|
|
|
|
|
|
|
# {{{ variables declaration |
|
20
|
|
|
|
|
|
|
our $VERSION = '0.2604300'; |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# {{{ lexicons — kanji / hiragana / romaji per script |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my %DIGIT = ( |
|
25
|
|
|
|
|
|
|
kanji => [ qw( 〇 一 二 三 四 五 六 七 八 九 ) ], |
|
26
|
|
|
|
|
|
|
hiragana => [ qw( ぜろ いち に さん よん ご ろく なな はち きゅう ) ], |
|
27
|
|
|
|
|
|
|
romaji => [ qw( zero ichi ni san yon go roku nana hachi kyu ) ], |
|
28
|
|
|
|
|
|
|
); |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# Scale words at each magnitude. Hundred (百), thousand (千), ten-thousand (万), |
|
31
|
|
|
|
|
|
|
# hundred-million (億), trillion (兆) — the canonical Japanese scale ladder. |
|
32
|
|
|
|
|
|
|
my %SCALE = ( |
|
33
|
|
|
|
|
|
|
kanji => { 10 => '十', 100 => '百', 1000 => '千', 10_000 => '万', |
|
34
|
|
|
|
|
|
|
100_000_000 => '億', 1_000_000_000_000 => '兆' }, |
|
35
|
|
|
|
|
|
|
hiragana => { 10 => 'じゅう', 100 => 'ひゃく', 1000 => 'せん', 10_000 => 'まん', |
|
36
|
|
|
|
|
|
|
100_000_000 => 'おく', 1_000_000_000_000 => 'ちょう' }, |
|
37
|
|
|
|
|
|
|
romaji => { 10 => 'ju', 100 => 'hyaku', 1000 => 'sen', 10_000 => 'man', |
|
38
|
|
|
|
|
|
|
100_000_000 => 'oku', 1_000_000_000_000 => 'cho' }, |
|
39
|
|
|
|
|
|
|
); |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Irregular hundreds (rendaku/gemination): |
|
42
|
|
|
|
|
|
|
# 300 さんびゃく sanbyaku |
|
43
|
|
|
|
|
|
|
# 600 ろっぴゃく roppyaku |
|
44
|
|
|
|
|
|
|
# 800 はっぴゃく happyaku |
|
45
|
|
|
|
|
|
|
my %HUNDRED_IRREGULAR = ( |
|
46
|
|
|
|
|
|
|
kanji => { 3 => '三百', 6 => '六百', 8 => '八百' }, |
|
47
|
|
|
|
|
|
|
hiragana => { 3 => 'さんびゃく', 6 => 'ろっぴゃく', 8 => 'はっぴゃく' }, |
|
48
|
|
|
|
|
|
|
romaji => { 3 => 'sanbyaku', 6 => 'roppyaku', 8 => 'happyaku' }, |
|
49
|
|
|
|
|
|
|
); |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# Irregular thousands: |
|
52
|
|
|
|
|
|
|
# 3000 さんぜん sanzen (rendaku) |
|
53
|
|
|
|
|
|
|
# 8000 はっせん hassen (gemination) |
|
54
|
|
|
|
|
|
|
my %THOUSAND_IRREGULAR = ( |
|
55
|
|
|
|
|
|
|
kanji => { 3 => '三千', 8 => '八千' }, |
|
56
|
|
|
|
|
|
|
hiragana => { 3 => 'さんぜん', 8 => 'はっせん' }, |
|
57
|
|
|
|
|
|
|
romaji => { 3 => 'sanzen', 8 => 'hassen' }, |
|
58
|
|
|
|
|
|
|
); |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
# Irregular trillion-block leaders (cho-prefixes): |
|
61
|
|
|
|
|
|
|
# 1兆 いっちょう itcho |
|
62
|
|
|
|
|
|
|
# 8兆 はっちょう hatcho |
|
63
|
|
|
|
|
|
|
# 10兆 じゅっちょう jutcho |
|
64
|
|
|
|
|
|
|
my %CHO_IRREGULAR = ( |
|
65
|
|
|
|
|
|
|
kanji => { 1 => '一兆', 8 => '八兆', 10 => '十兆' }, |
|
66
|
|
|
|
|
|
|
hiragana => { 1 => 'いっちょう', 8 => 'はっちょう', 10 => 'じゅっちょう' }, |
|
67
|
|
|
|
|
|
|
romaji => { 1 => 'itcho', 8 => 'hatcho', 10 => 'jutcho' }, |
|
68
|
|
|
|
|
|
|
); |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
# }}} |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# }}} |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# {{{ num2jpn_cardinal number → text in chosen script |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
sub num2jpn_cardinal :Export { |
|
77
|
31
|
|
|
31
|
1
|
204535
|
my $n = shift; |
|
78
|
31
|
|
100
|
|
|
133
|
my $script = shift // 'kanji'; |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
croak "Unknown script '$script' (expected: kanji, hiragana, romaji)" |
|
81
|
31
|
50
|
|
|
|
96
|
unless exists $DIGIT{$script}; |
|
82
|
|
|
|
|
|
|
|
|
83
|
31
|
50
|
33
|
|
|
394
|
croak "Number must be in range [1, 1E16)" |
|
|
|
|
33
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
84
|
|
|
|
|
|
|
if !defined $n || $n !~ m{\A\d+\z}xms || $n < 1 || $n >= 1E16; |
|
85
|
|
|
|
|
|
|
|
|
86
|
31
|
|
|
|
|
85
|
return _render($n, $script); |
|
87
|
2
|
|
|
2
|
|
909
|
} |
|
|
2
|
|
|
|
|
5
|
|
|
|
2
|
|
|
|
|
14
|
|
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# }}} |
|
90
|
|
|
|
|
|
|
# {{{ num2jpn_ordinal number → ordinal text in chosen script |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub num2jpn_ordinal :Export { |
|
93
|
8
|
|
|
8
|
1
|
22
|
my $n = shift; |
|
94
|
8
|
|
100
|
|
|
35
|
my $script = shift // 'kanji'; |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
croak "Unknown script '$script' (expected: kanji, hiragana, romaji)" |
|
97
|
8
|
50
|
|
|
|
27
|
unless exists $DIGIT{$script}; |
|
98
|
|
|
|
|
|
|
|
|
99
|
8
|
50
|
33
|
|
|
126
|
croak "Number must be in range [1, 1E16)" |
|
|
|
|
33
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
100
|
|
|
|
|
|
|
if !defined $n || $n !~ m{\A\d+\z}xms || $n < 1 || $n >= 1E16; |
|
101
|
|
|
|
|
|
|
|
|
102
|
8
|
|
|
|
|
40
|
my $cardinal = _render($n, $script); |
|
103
|
8
|
100
|
|
|
|
28
|
if ($script eq 'romaji') { |
|
104
|
|
|
|
|
|
|
# Conventional ordinal romaji is fully hyphen-joined: spaces between |
|
105
|
|
|
|
|
|
|
# block-tokens become hyphens, and the suffix attaches with a hyphen. |
|
106
|
3
|
|
|
|
|
9
|
$cardinal =~ tr/ /-/; |
|
107
|
3
|
|
|
|
|
25
|
return $cardinal . '-ban-me'; |
|
108
|
|
|
|
|
|
|
} |
|
109
|
5
|
|
|
|
|
18
|
my %suffix = (kanji => '番目', hiragana => 'ばんめ'); |
|
110
|
5
|
|
|
|
|
42
|
return $cardinal . $suffix{$script}; |
|
111
|
2
|
|
|
2
|
|
917
|
} |
|
|
2
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
10
|
|
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# }}} |
|
114
|
|
|
|
|
|
|
# {{{ to_string legacy romaji-list interface (DEPRECATED) |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
# Mike Schilli's 2001 lexicon — preserved verbatim so to_string output is |
|
117
|
|
|
|
|
|
|
# bit-for-bit identical to the historical contract. New code should use |
|
118
|
|
|
|
|
|
|
# num2jpn_cardinal($n, 'romaji') instead. |
|
119
|
|
|
|
|
|
|
my %_LEGACY_N2J = qw( |
|
120
|
|
|
|
|
|
|
1 ichi 2 ni 3 san 4 yon 5 go 6 roku 7 nana |
|
121
|
|
|
|
|
|
|
8 hachi 9 kyu 10 ju 100 hyaku 1000 sen); |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
my %_LEGACY_N2J_EXCP = qw( |
|
124
|
|
|
|
|
|
|
300 san-byaku 600 ro-p-pyaku 800 ha-p-pyaku |
|
125
|
|
|
|
|
|
|
3000 san-zen 8000 ha-s-sen); |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
my @_LEGACY_N2J_BLOCK = ('', 'man', 'oku', 'cho'); |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
my %_LEGACY_N2J_BLOCK_EXCP = qw( 1 i-t-cho 8 ha-t-cho 0 ju-t-cho ); |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub to_string :Export { |
|
132
|
5
|
|
|
5
|
1
|
2204
|
my $n = shift; |
|
133
|
|
|
|
|
|
|
|
|
134
|
5
|
50
|
33
|
|
|
62
|
if (!defined $n || $n < 1 || $n >= 1E16) { |
|
|
|
|
33
|
|
|
|
|
|
135
|
0
|
|
|
|
|
0
|
warn "$n needs to be >=1 and <1E16.\n"; |
|
136
|
0
|
|
|
|
|
0
|
return; |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
5
|
|
|
|
|
9
|
my @result; |
|
140
|
5
|
|
|
|
|
13
|
$n = reverse $n; |
|
141
|
5
|
|
|
|
|
6
|
my $bix = 0; |
|
142
|
|
|
|
|
|
|
|
|
143
|
5
|
|
|
|
|
84
|
while ($n =~ /(\d{1,4})/g) { |
|
144
|
9
|
|
|
|
|
20
|
my $b = scalar reverse($1); |
|
145
|
9
|
|
|
|
|
15
|
my @r = _legacy_blockof4($b); |
|
146
|
|
|
|
|
|
|
|
|
147
|
9
|
100
|
100
|
|
|
22
|
if ($bix && @r) { |
|
148
|
2
|
100
|
66
|
|
|
9
|
if ($bix == 3 && $b =~ /[1-9]0$|[18]$/) { |
|
149
|
1
|
|
|
|
|
4
|
$r[-1] = $_LEGACY_N2J_BLOCK_EXCP{$b % 10}; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
else { |
|
152
|
1
|
|
|
|
|
2
|
push @r, $_LEGACY_N2J_BLOCK[$bix]; |
|
153
|
|
|
|
|
|
|
} |
|
154
|
|
|
|
|
|
|
} |
|
155
|
9
|
|
|
|
|
13
|
unshift @result, @r; |
|
156
|
9
|
|
|
|
|
20
|
$bix++; |
|
157
|
|
|
|
|
|
|
} |
|
158
|
|
|
|
|
|
|
|
|
159
|
5
|
|
|
|
|
30
|
return @result; |
|
160
|
2
|
|
|
2
|
|
1158
|
} |
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
8
|
|
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub _legacy_blockof4 { |
|
163
|
9
|
|
|
9
|
|
12
|
my $n = shift; |
|
164
|
9
|
50
|
33
|
|
|
27
|
return if $n > 9999 or $n < 0; |
|
165
|
9
|
50
|
|
|
|
14
|
return '' unless $n; |
|
166
|
|
|
|
|
|
|
|
|
167
|
9
|
|
|
|
|
11
|
my @result; |
|
168
|
9
|
|
|
|
|
29
|
my @digits = split //, sprintf('%04d', $n); |
|
169
|
9
|
|
|
|
|
15
|
my @weights = (1000, 100, 10, 1); |
|
170
|
|
|
|
|
|
|
|
|
171
|
9
|
|
|
|
|
16
|
for my $i (0..3) { |
|
172
|
36
|
100
|
|
|
|
48
|
next unless $digits[$i]; |
|
173
|
13
|
|
|
|
|
19
|
my $v = $digits[$i] * $weights[$i]; |
|
174
|
|
|
|
|
|
|
push @result, $_LEGACY_N2J_EXCP{$v} |
|
175
|
|
|
|
|
|
|
|| $_LEGACY_N2J{$v} |
|
176
|
13
|
|
66
|
|
|
54
|
|| ($_LEGACY_N2J{$digits[$i]}, $_LEGACY_N2J{$weights[$i]}); |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
|
|
179
|
9
|
|
|
|
|
22
|
return @result; |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# }}} |
|
183
|
|
|
|
|
|
|
# {{{ _render core: number → string in given script |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub _render { |
|
186
|
39
|
|
|
39
|
|
86
|
my ($n, $script) = @_; |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
# Decompose into 4-digit blocks, weighted by 10^(4*k): |
|
189
|
|
|
|
|
|
|
# block 0 → 1 |
|
190
|
|
|
|
|
|
|
# block 1 → 万 (10^4) |
|
191
|
|
|
|
|
|
|
# block 2 → 億 (10^8) |
|
192
|
|
|
|
|
|
|
# block 3 → 兆 (10^12) |
|
193
|
39
|
|
|
|
|
83
|
my @block_scales = (1, 10_000, 100_000_000, 1_000_000_000_000); |
|
194
|
39
|
|
|
|
|
73
|
my @parts; |
|
195
|
39
|
|
|
|
|
58
|
my $bix = 0; |
|
196
|
|
|
|
|
|
|
|
|
197
|
39
|
|
|
|
|
91
|
while ($n > 0) { |
|
198
|
46
|
|
|
|
|
109
|
my $block = $n % 10_000; |
|
199
|
46
|
|
|
|
|
105
|
$n = int($n / 10_000); |
|
200
|
46
|
100
|
|
|
|
86
|
if ($block) { |
|
201
|
39
|
|
|
|
|
56
|
my $piece; |
|
202
|
39
|
100
|
66
|
|
|
113
|
if ($bix == 3 && exists $CHO_IRREGULAR{$script}{$block}) { |
|
203
|
|
|
|
|
|
|
# Whole-block chō irregulars: 1兆, 8兆, 10兆 fuse digit+scale. |
|
204
|
1
|
|
|
|
|
4
|
$piece = $CHO_IRREGULAR{$script}{$block}; |
|
205
|
|
|
|
|
|
|
} |
|
206
|
|
|
|
|
|
|
else { |
|
207
|
38
|
|
|
|
|
76
|
$piece = _render_block4($block, $script); |
|
208
|
38
|
100
|
|
|
|
105
|
$piece .= $SCALE{$script}{$block_scales[$bix]} if $bix > 0; |
|
209
|
|
|
|
|
|
|
} |
|
210
|
39
|
|
|
|
|
91
|
unshift @parts, $piece; |
|
211
|
|
|
|
|
|
|
} |
|
212
|
46
|
|
|
|
|
102
|
$bix++; |
|
213
|
|
|
|
|
|
|
} |
|
214
|
|
|
|
|
|
|
|
|
215
|
39
|
|
|
|
|
103
|
return _join_parts(\@parts, $script); |
|
216
|
|
|
|
|
|
|
} |
|
217
|
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# }}} |
|
219
|
|
|
|
|
|
|
# {{{ _render_block4 render integer 1..9999 in given script |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub _render_block4 { |
|
222
|
38
|
|
|
38
|
|
63
|
my ($n, $script) = @_; |
|
223
|
|
|
|
|
|
|
|
|
224
|
38
|
50
|
|
|
|
74
|
return '' unless $n; |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# In romaji, digit and scale fuse into a single word ("nihyaku", "sanju", |
|
227
|
|
|
|
|
|
|
# "yonsen"). Block boundaries get whitespace ("sen nihyaku sanju yon" |
|
228
|
|
|
|
|
|
|
# for 1234). Kanji and hiragana have no whitespace at all. |
|
229
|
38
|
|
|
|
|
45
|
my @parts; |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# Thousands (1000..9999) |
|
232
|
38
|
100
|
|
|
|
92
|
if (my $th = int($n / 1000)) { |
|
233
|
11
|
100
|
|
|
|
42
|
if (exists $THOUSAND_IRREGULAR{$script}{$th}) { |
|
|
|
50
|
|
|
|
|
|
|
234
|
6
|
|
|
|
|
20
|
push @parts, $THOUSAND_IRREGULAR{$script}{$th}; |
|
235
|
|
|
|
|
|
|
} |
|
236
|
|
|
|
|
|
|
elsif ($th == 1) { |
|
237
|
5
|
|
|
|
|
17
|
push @parts, $SCALE{$script}{1000}; |
|
238
|
|
|
|
|
|
|
} |
|
239
|
|
|
|
|
|
|
else { |
|
240
|
0
|
|
|
|
|
0
|
push @parts, $DIGIT{$script}[$th] . $SCALE{$script}{1000}; |
|
241
|
|
|
|
|
|
|
} |
|
242
|
11
|
|
|
|
|
20
|
$n %= 1000; |
|
243
|
|
|
|
|
|
|
} |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# Hundreds (100..999) |
|
246
|
38
|
100
|
|
|
|
102
|
if (my $h = int($n / 100)) { |
|
247
|
14
|
100
|
|
|
|
44
|
if (exists $HUNDRED_IRREGULAR{$script}{$h}) { |
|
|
|
100
|
|
|
|
|
|
|
248
|
8
|
|
|
|
|
53
|
push @parts, $HUNDRED_IRREGULAR{$script}{$h}; |
|
249
|
|
|
|
|
|
|
} |
|
250
|
|
|
|
|
|
|
elsif ($h == 1) { |
|
251
|
3
|
|
|
|
|
9
|
push @parts, $SCALE{$script}{100}; |
|
252
|
|
|
|
|
|
|
} |
|
253
|
|
|
|
|
|
|
else { |
|
254
|
3
|
|
|
|
|
14
|
push @parts, $DIGIT{$script}[$h] . $SCALE{$script}{100}; |
|
255
|
|
|
|
|
|
|
} |
|
256
|
14
|
|
|
|
|
21
|
$n %= 100; |
|
257
|
|
|
|
|
|
|
} |
|
258
|
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# Tens (10..99) |
|
260
|
38
|
100
|
|
|
|
78
|
if (my $t = int($n / 10)) { |
|
261
|
9
|
100
|
|
|
|
19
|
if ($t == 1) { |
|
262
|
5
|
|
|
|
|
19
|
push @parts, $SCALE{$script}{10}; |
|
263
|
|
|
|
|
|
|
} |
|
264
|
|
|
|
|
|
|
else { |
|
265
|
4
|
|
|
|
|
13
|
push @parts, $DIGIT{$script}[$t] . $SCALE{$script}{10}; |
|
266
|
|
|
|
|
|
|
} |
|
267
|
9
|
|
|
|
|
15
|
$n %= 10; |
|
268
|
|
|
|
|
|
|
} |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
# Units (1..9) |
|
271
|
38
|
100
|
|
|
|
116
|
push @parts, $DIGIT{$script}[$n] if $n; |
|
272
|
|
|
|
|
|
|
|
|
273
|
38
|
|
|
|
|
86
|
return _join_parts(\@parts, $script); |
|
274
|
|
|
|
|
|
|
} |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
# }}} |
|
277
|
|
|
|
|
|
|
# {{{ _join_parts concatenate parts with script-appropriate sep |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
sub _join_parts { |
|
280
|
77
|
|
|
77
|
|
126
|
my ($parts_lr, $script) = @_; |
|
281
|
77
|
50
|
|
|
|
100
|
return '' unless @{$parts_lr}; |
|
|
77
|
|
|
|
|
165
|
|
|
282
|
|
|
|
|
|
|
# Romaji is the only script that uses whitespace as a word separator. |
|
283
|
|
|
|
|
|
|
# Kanji and hiragana are written as a continuous string. |
|
284
|
77
|
100
|
|
|
|
144
|
return $script eq 'romaji' ? join(' ', @{$parts_lr}) : join('', @{$parts_lr}); |
|
|
26
|
|
|
|
|
135
|
|
|
|
51
|
|
|
|
|
279
|
|
|
285
|
|
|
|
|
|
|
} |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
# }}} |
|
288
|
|
|
|
|
|
|
# {{{ capabilities declare supported features |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub capabilities { |
|
291
|
|
|
|
|
|
|
return { |
|
292
|
1
|
|
|
1
|
1
|
5
|
cardinal => 1, |
|
293
|
|
|
|
|
|
|
ordinal => 1, |
|
294
|
|
|
|
|
|
|
scripts => [ 'kanji', 'hiragana', 'romaji' ], |
|
295
|
|
|
|
|
|
|
}; |
|
296
|
|
|
|
|
|
|
} |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
# }}} |
|
299
|
|
|
|
|
|
|
1; |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
__END__ |