File Coverage

blib/lib/Lingua/JPN/Num2Word.pm
Criterion Covered Total %
statement 46 57 80.7
branch 9 16 56.2
condition 9 21 42.8
subroutine 9 12 75.0
pod 2 5 40.0
total 75 111 67.5


line stmt bran cond sub pod time code
1             # For Emacs: -*- mode:cperl; eval: (folding-mode 1); coding:utf-8; -*-
2             #
3             # Mike Schilli, 2001 (m@perlmeister.com)
4             #
5              
6             package Lingua::JPN::Num2Word;
7             # ABSTRACT: Translate Numbers into Japanese
8              
9 2     2   10819 use 5.16.0;
  2         7  
10 2     2   1029 use utf8;
  2         589  
  2         35  
11 2     2   70 use warnings;
  2         3  
  2         108  
12              
13             # {{{ use block
14              
15 2     2   1133 use Export::Attrs;
  2         21916  
  2         13  
16              
17             # }}}
18             # {{{ variables declaration
19             our $VERSION = '0.2603300';
20              
21             my %N2J = qw(
22             1 ichi 2 ni 3 san 4 yon 5 go 6 roku 7 nana
23             8 hachi 9 kyu 10 ju 100 hyaku 1000 sen);
24              
25             my %N2J_EXCP = qw(
26             300 san-byaku 600 ro-p-pyaku 800 ha-p-pyaku
27             3000 san-zen 8000 ha-s-sen);
28              
29             my @N2J_BLOCK = ("", "man", "oku", "cho");
30              
31             my %N2J_BLOCK_EXCP = qw( 1 i-t-cho 8 ha-t-cho
32             0 ju-t-cho);
33              
34             # }}}
35              
36             # {{{ to_string
37 2     2 0 388 sub num2jpn_cardinal :Export { goto &to_string }
  2     0   3  
  2         14  
  0         0  
38              
39             sub to_string :Export {
40 4     4 0 153373 my $n = shift;
41              
42 4 50 33     19 if($n < 1 || $n >= 1E16) {
43 0         0 warn "$n needs to be >=1 and <1E16.\n";
44 0         0 return;
45             }
46              
47 4         5 my @result = ();
48 4         7 $n = reverse $n;
49 4         5 my $bix = 0;
50              
51 4         30 while($n =~ /(\d{1,4})/g) {
52 8         16 my $b = scalar reverse($1);
53 8         10 my @r = blockof4_to_string($b);
54              
55 8 100 100     19 if($bix && @r) {
56 2 100 66     11 if($bix == 3 &&
57             $b =~ /[1-9]0$|[18]$/) {
58 1         4 $r[-1] = $N2J_BLOCK_EXCP{$b%10};
59             } else {
60 1         3 push @r, $N2J_BLOCK[$bix];
61             }
62             }
63 8         12 unshift @result, @r;
64 8         17 $bix++;
65             }
66              
67 4         16 return @result;
68 2     2   1137 }
  2         5  
  2         10  
69              
70             # }}}
71             # {{{ blockof4_to_string
72              
73             sub blockof4_to_string {
74 8     8 0 10 my $n = shift;
75              
76 8 50 33     18 return if $n > 9999 or $n < 0;
77 8 50       11 return "" unless $n;
78              
79 8         9 my @result = ();
80 8         17 my @digits = split //, sprintf("%04d", $n);
81 8         10 my @weights = (1000, 100, 10, 1);
82              
83 8         18 for my $i (0..3) {
84 32 100       51 next unless $digits[$i];
85 9         11 my $v = $digits[$i] * $weights[$i];
86             push @result, $N2J_EXCP{$v} ||
87             $N2J{$v} ||
88             ($N2J{$digits[$i]},
89 9   66     40 $N2J{$weights[$i]});
90             }
91              
92 8         18 return @result;
93             }
94              
95             # }}}
96              
97              
98             # {{{ num2jpn_ordinal convert number to ordinal text
99              
100             sub num2jpn_ordinal :Export {
101 0     0 1   my $number = shift;
102              
103 0 0 0       if (!defined $number || $number < 1 || $number >= 1E16) {
      0        
104 0           warn "ordinal needs to be >=1 and <1E16.\n";
105 0           return;
106             }
107              
108             # Japanese ordinals: cardinal + 番目 (ban-me)
109 0           my @parts = to_string($number);
110 0 0         return unless @parts;
111              
112 0           return join('-', @parts) . '-ban-me';
113 2     2   1037 }
  2         5  
  2         9  
114              
115             # }}}
116              
117             # {{{ capabilities declare supported features
118              
119             sub capabilities {
120             return {
121 0     0 1   cardinal => 1,
122             ordinal => 1,
123             };
124             }
125              
126             # }}}
127             1;
128              
129             __END__