File Coverage

blib/lib/Lingua/NL/Numbers/GroeneBoekje.pm
Criterion Covered Total %
statement 57 58 98.2
branch 26 28 92.8
condition 1 3 33.3
subroutine 10 10 100.0
pod 0 2 0.0
total 94 101 93.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl --
2              
3             package Lingua::NL::Numbers::GroeneBoekje;
4              
5             # Numbers in words, according to the dutch "Groene Boekje".
6             # http://woordenlijst.org/leidraad/6/9/
7              
8             =head1 NAME
9              
10             Lingua::NL::Numbers::GroeneBoekje - Convert numeric values into their Dutch equivalents
11              
12             =head1 SYNOPSIS
13              
14             use Lingua::NL::Numbers::GroeneBoekje;
15              
16             my $converter = Lingua::NL::Numbers::GroeneBoekje->new;
17              
18             my $text = $converter->parse(124);
19              
20             # prints 'honderdvierentwintig'
21             print $text;
22              
23             =head1 DESCRIPTION
24              
25             Lingua::NL::Numbers::GroeneBoekje converts numeric values to their
26             Dutch written equivalent, according to the guidelines as defined in
27             the "Groene Boekje". For example:
28              
29             twee
30             twintig
31             tweeëntwintig
32             tweehonderd
33             tweehonderdtweeëntwintig
34             tweeëntwintighonderd
35             tweeduizend tweehonderdtwintig
36             twee miljoen tweehonderdtwintigduizend tweehonderdtweeëntwintig
37              
38             =head1 KNOWN BUGS
39              
40             Estimated upper bound is 10**18 - 1, but this is not checked.
41              
42             When "twee" is glued to "en" it will get a dieraesis on the "e" of "en".
43             The result will be a Perl Unicode string.
44              
45             When "drie" is glued to "en" it will get a dieraesis on the "e" of "en".
46             The result will be a Perl Unicode string.
47              
48             =head1 AUTHOR
49              
50             Johan Vromans Ejvromans@squirrel.nlE.
51              
52             =head1 SEE ALSO
53              
54             L
55              
56             http://woordenlijst.org/leidraad/6/9/
57              
58             =cut
59              
60             $VERSION = "0.10";
61              
62 2     2   86582 use strict;
  2         5  
  2         73  
63 2     2   17 use warnings;
  2         3  
  2         947  
64              
65             sub new {
66 2     2 0 31 my ($pkg) = @_;
67 2   33     19 $pkg = ref($pkg) || $pkg;
68 2         14 bless \(my $o), $pkg;
69             }
70              
71             sub parse {
72 36     36 0 12528 my ($self, $n) = @_;
73 36         81 _num_($n);
74             }
75              
76 2     2   12 use constant HOUNDRED => "honderd";
  2         7  
  2         202  
77 2     2   9 use constant THOUSAND => "duizend";
  2         4  
  2         91  
78 2     2   10 use constant TEN6TH => "miljoen";
  2         3  
  2         93  
79 2     2   10 use constant TEN9TH => "miljard";
  2         3  
  2         2606  
80              
81             my @units =
82             ( qw(nul een twee drie vier
83             vijf zes zeven acht negen),
84             qw(tien elf twaalf dertien veertien
85             vijftien zestien zeventien achttien negentien) );
86             my @tens =
87             ( qw(nul tien twintig dertig veertig
88             vijftig zestig zeventig tachtig negentig) );
89              
90             # Regel 6.N
91             # We schrijven een getal in één woord, tot en met het woord duizend.
92              
93             sub _num_ {
94 83     83   100 my ($n) = @_;
95              
96             # Prefab numbers.
97 83 100       247 return $units[$n] if $n < @units;
98              
99             # Small numbers, up to 99.
100 53 100       119 if ( $n < 100 ) {
101 18         43 my $t = int($n / 10);
102 18         24 my $res = "";
103 18 100       46 if ( my $r = $n % 10 ) {
104 12         22 $res = $units[$r] . "en";
105 12         72 $res =~ s/([ie])ee/$1."eë"/e;
  10         37  
106             }
107 18         90 return $res.$tens[$t];
108             }
109              
110             # Up to 1_999.
111 35 100       74 if ( $n < 1999 ) {
112 22         63 my $t = int($n / 100);
113 22         32 my $r = $n % 100;
114 22         21 my $res;
115 22 100       91 if ( $t % 10 == 0 ) {
116 5 50       20 $res = ($t > 10 ? _num_($t/10) : "") . THOUSAND;
117             # Regel 6.N (vervolg)
118             # Na het woord duizend volgt een spatie.
119 5 100       16 $res .= " " if $r;
120             }
121             else {
122 17 100       57 $res = ($t > 1 ? _num_($t) : "") . HOUNDRED;
123             }
124 22 100       66 $res .= _num_($r) if $r;
125 22         100 return $res;
126             }
127              
128             # Up to 999_999.
129 13 100       44 if ( $n < 1000000 ) {
130 10         19 my $t = int($n / 1000);
131 10         15 my $r = $n % 1000;
132 10 50       31 my $res = ($t > 1 ? _num_($t) : "") . THOUSAND;
133             # Regel 6.N (vervolg)
134             # Na het woord duizend volgt een spatie.
135 10 100       30 $res .= " " . _num_($r) if $r;
136 10         50 return $res;
137             }
138              
139             # THe higher ones.
140 3 100       12 return _very_high($n, 1000000, TEN6TH) if $n < 1000000000;
141 1         4 return _very_high($n, 1000000000, TEN9TH);
142 0         0 "ontzettend veel";
143             }
144              
145             # Regel 6.N (vervolg)
146             # De woorden miljoen, miljard, biljoen enz. schrijven we los.
147              
148             sub _very_high {
149 3     3   6 my ($n, $m, $w) = @_;
150 3         8 my $t = int($n / $m);
151 3         4 my $r = $n % $m;
152 3         8 my $res = _num_($t) . " " . $w;
153 3 100       9 $res .= " " . _num_($r) if $r;
154 3         19 return $res;
155             }
156              
157             unless ( caller ) {
158             package main;
159             foreach ( @ARGV ) {
160             printf("%8d: %s\n",
161             $_, Lingua::NL::Numbers::GroeneBoekje->new->parse($_));
162             }
163             }