File Coverage

blib/lib/Lingua/FR/Nums2Words.pm
Criterion Covered Total %
statement 63 64 98.4
branch 28 30 93.3
condition 9 9 100.0
subroutine 8 8 100.0
pod 0 1 0.0
total 108 112 96.4


line stmt bran cond sub pod time code
1             package Lingua::FR::Nums2Words;
2              
3 1     1   68848 use strict;
  1         3  
  1         30  
4 1     1   6 use warnings;
  1         2  
  1         23  
5 1     1   5 use Exporter;
  1         2  
  1         49  
6 1     1   6 use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK $VERSION);
  1         2  
  1         774  
7              
8             @ISA = qw(Exporter);
9              
10             %EXPORT_TAGS = ( 'all' => [ qw(
11             num2word
12             ) ] );
13              
14             @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
15              
16             our $VERSION = '1.01';
17              
18             my @major = (
19             "",
20             " mille",
21             " million",
22             " milliard",
23             " trillion",
24             " quadrillion",
25             " quintillion"
26             );
27              
28             my @ten = (
29             "",
30             " dix",
31             " vingt",
32             " trente",
33             " quarante",
34             " cinquante",
35             " soixante",
36             " soixante-dix",
37             " quatre-vingt",
38             " quatre-vingt-dix"
39             );
40              
41             my @num = (
42             "",
43             " un",
44             " deux",
45             " trois",
46             " quatre",
47             " cinq",
48             " six",
49             " sept",
50             " huit",
51             " neuf",
52             " dix",
53             " onze",
54             " douze",
55             " treize",
56             " quatorze",
57             " quinze",
58             " seize",
59             " dix-sept",
60             " dix-huit",
61             " dix-neuf"
62             );
63              
64             sub num2word {
65 12 100   12 0 800 my @numbers = wantarray ? @_ : shift;
66 12 50       30 return () unless (@numbers);
67              
68 12         28 my @results = map { _num2word($_) } @numbers;
  15         31  
69              
70 12 100       63 return wantarray ? @results : $results[0];
71             }
72              
73             sub _num2words_less_1000 {
74 19     19   36 my ($number) = @_;
75              
76 19         26 my $result;
77 19 100       33 if ($number % 100 < 20){
78             # 19 et moins
79 12         22 $result = $num[$number % 100];
80 12         24 $number /= 100;
81             } else {
82             # 9 et moins
83 7         16 $result = $num[$number % 10];
84 7         16 $number /= 10;
85              
86             # 90, 80, ... 20
87 7         23 $result = $ten[$number % 10].$result;
88 7         12 $number /= 10;
89             }
90              
91             # reste les centaines
92             # y'en a pas
93 19 100       44 if (int($number) == 0) { return $result; }
  10         24  
94              
95 9 100       21 if (int($number) == 1) {
96             # on ne retourne "un cent xxxx" mais "cent xxxx"
97 3         8 return " cent$result";
98             } else {
99 6         19 return $num[$number]." cent".$result;
100             }
101             }
102              
103             sub _num2word {
104 15     15   25 my ($number) = @_;
105              
106 15 100       40 return 'zéro' if ($number == 0);
107              
108 14         20 my $prefix = '';
109 14 100       30 if ($number < 0) {
110 2         13 $prefix = 'moins';
111 2         5 $number = -$number;
112             }
113              
114 14         22 my $place = 0;
115 14         21 my $result = '';
116 14         23 my $plural_possible = 1;
117 14         16 my $plural_form = 0;
118 14         32 while ($number > 0) {
119 1530         1971 my $n = ($number % 1000);
120              
121             # par tranche de 1000
122 1530 100       2456 if ($n != 0) {
123 19         33 my $s = _num2words_less_1000($n);
124 19 100 100     79 if (($s =~ /\s*un\s*/) and ($place == 1)) {
125             # on donne pas le un pour mille
126 1         4 $result = $major[$place].$result;
127             } else {
128 18 100       35 if ($place == 0) {
129 13 100 100     84 if (($s =~ /cent\s*$/) and ($s !~ /^\s*cent/)) {
130             # nnn200 ... nnn900 avec "s"
131 1         3 $plural_form = 1;
132             } else {
133             # pas de "s" jamais
134 12         23 $plural_possible = 0;
135             }
136             }
137              
138 18 100 100     49 if (($place > 0) and ($plural_possible)) {
139 1 50       8 if ($s !~ /^\s*un/) {
140             # avec "s"
141 1         3 $plural_form = 1;
142             } else {
143             # jamais de "s"
144 0         0 $plural_possible = 0;
145             }
146             }
147              
148 18         45 $result = $s.$major[$place].$result;
149             }
150             }
151              
152 1530         1850 $place++;
153 1530         2558 $number /= 1000;
154             }
155              
156 14         78 $result = _trim($prefix.$result);
157              
158 14 100       55 return $plural_form ? $result.'s' : $result;
159             }
160              
161             sub _trim {
162 14     14   28 my ($string) = @_;
163              
164 14         54 $string =~ s/^\s+//;
165 14         43 $string =~ s/\s+$//;
166              
167 14         30 return $string;
168             }
169              
170             1;
171              
172             __END__