1#=====================================================================
2# LedgerSMB
3# Small Medium Business Accounting software
4# http://www.ledgersmb.org/
5#
6# Copyright (C) 2006
7# This work contains copyrighted information from a number of sources all used
8# with permission.
9#
10# This file contains source code included with or based on SQL-Ledger which
11# is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
12# under the GNU General Public License version 2 or, at your option, any later
13# version.  For a full list including contact information of contributors,
14# maintainers, and copyright holders, see the CONTRIBUTORS file.
15#
16# Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
17# Copyright (C) 2002
18#
19#  Author: DWS Systems Inc.
20#     Web: http://www.sql-ledger.org
21#
22#  Contributors:
23#
24#======================================================================
25#
26# This file has undergone whitespace cleanup.
27#
28#======================================================================
29#
30# this is the default code for the Check package
31#
32#=====================================================================
33
34# The conversion routines can be tested with for example:
35# perl <<EOF
36#   use LedgerSMB::CP;
37#   my $c = CP->new('da');
38#   $c->init;
39#   for(0 .. 202, 999 .. 1002, 1999 .. 2002, 999999 .. 1000002, 999999999 .. 1000000002)
40#     {print $_.":".$c->num2text($_)."\n";};'
41# EOF
42
43use utf8;
44
45sub init {
46    my $self    = shift;
47    my $locale  = $self->{'locale'};
48    my $langtag = substr( $locale->language_tag, 0, 2 );
49    $self->{'numrules'} = 'en';
50    $self->{'numrules'} = $langtag
51      if grep { /$langtag/ } (qw/ca de es et fr hu it nl ru da/);
52    $self->{'numrules'} = 'es' if $self->{'numrules'} eq 'ca';
53    $self->{'numrules'} = 'de' if $self->{'numrules'} eq 'ru';
54
55    %{ $self->{numbername} } = (
56        0      => $locale->text('Zero'),
57        1      => $locale->text('One'),
58        '1o'   => $locale->text('One-o'),
59        2      => $locale->text('Two'),
60        3      => $locale->text('Three'),
61        4      => $locale->text('Four'),
62        5      => $locale->text('Five'),
63        6      => $locale->text('Six'),
64        7      => $locale->text('Seven'),
65        8      => $locale->text('Eight'),
66        9      => $locale->text('Nine'),
67        10     => $locale->text('Ten'),
68        11     => $locale->text('Eleven'),
69        '11o'  => $locale->text('Eleven-o'),
70        12     => $locale->text('Twelve'),
71        13     => $locale->text('Thirteen'),
72        14     => $locale->text('Fourteen'),
73        15     => $locale->text('Fifteen'),
74        16     => $locale->text('Sixteen'),
75        17     => $locale->text('Seventeen'),
76        18     => $locale->text('Eighteen'),
77        19     => $locale->text('Nineteen'),
78        20     => $locale->text('Twenty'),
79        21     => $locale->text('Twenty One'),
80        '21o'  => $locale->text('Twenty One-o'),
81        22     => $locale->text('Twenty Two'),
82        23     => $locale->text('Twenty Three'),
83        24     => $locale->text('Twenty Four'),
84        25     => $locale->text('Twenty Five'),
85        26     => $locale->text('Twenty Six'),
86        27     => $locale->text('Twenty Seven'),
87        28     => $locale->text('Twenty Eight'),
88        29     => $locale->text('Twenty Nine'),
89        30     => $locale->text('Thirty'),
90        40     => $locale->text('Forty'),
91        50     => $locale->text('Fifty'),
92        60     => $locale->text('Sixty'),
93        70     => $locale->text('Seventy'),
94        80     => $locale->text('Eighty'),
95        90     => $locale->text('Ninety'),
96        10**2  => $locale->text('Hundred'),
97        500    => $locale->text('Five Hundred'),
98        700    => $locale->text('Seven Hundred'),
99        900    => $locale->text('Nine Hundred'),
100        10**3  => $locale->text('Thousand'),
101        10**6  => $locale->text('Million'),
102        10**9  => $locale->text('Billion'),
103        10**12 => $locale->text('Trillion'),
104    );
105
106}
107
108sub num2text {
109    my ( $self, $amount ) = @_;
110
111    return $self->num2text_de($amount) if $self->{'numrules'} eq 'de';
112    return $self->num2text_es($amount) if $self->{'numrules'} eq 'es';
113    return $self->num2text_nl($amount) if $self->{'numrules'} eq 'nl';
114    return $self->num2text_hu($amount) if $self->{'numrules'} eq 'hu';
115    return $self->num2text_et($amount) if $self->{'numrules'} eq 'et';
116    return $self->num2text_fr($amount) if $self->{'numrules'} eq 'fr';
117    return $self->num2text_it($amount) if $self->{'numrules'} eq 'it';
118    return $self->num2text_da($amount) if $self->{'numrules'} eq 'da';
119    return $self->num2text_en($amount);
120}
121
122sub num2text_en {
123    my ( $self, $amount ) = @_;
124
125    return $self->{numbername}{0} unless $amount;
126
127    my @textnumber = ();
128
129    # split amount into chunks of 3
130    my @num = reverse split //, abs($amount);
131    my @numblock = ();
132    my @a;
133    my $i;
134
135    while (@num) {
136        @a = ();
137        for ( 1 .. 3 ) {
138            push @a, shift @num;
139        }
140        push @numblock, join / /, reverse @a;
141    }
142
143    while (@numblock) {
144
145        $i = $#numblock;
146        @num = split //, $numblock[$i];
147
148        if ( $numblock[$i] == 0 ) {
149            pop @numblock;
150            next;
151        }
152
153        if ( $numblock[$i] > 99 ) {
154
155            # the one from hundreds
156            push @textnumber, $self->{numbername}{ $num[0] };
157
158            # add hundred designation
159            push @textnumber, $self->{numbername}{ 10**2 };
160
161            # reduce numblock
162            $numblock[$i] -= $num[0] * 100;
163
164        }
165
166        $numblock[$i] *= 1;
167
168        if ( $numblock[$i] > 9 ) {
169
170            # tens
171            push @textnumber, $self->format_ten_en( $numblock[$i] );
172        }
173        elsif ( $numblock[$i] > 0 ) {
174
175            # ones
176            push @textnumber, $self->{numbername}{ $numblock[$i] };
177        }
178
179        # add thousand, million
180        if ($i) {
181            $num = 10**( $i * 3 );
182            push @textnumber, $self->{numbername}{$num};
183        }
184
185        pop @numblock;
186
187    }
188
189    join ' ', @textnumber;
190
191}
192
193sub format_ten_en {
194    my ( $self, $amount ) = @_;
195
196    my $textnumber = "";
197    my @num = split //, $amount;
198
199    if ( $amount > 20 ) {
200        $textnumber = $self->{numbername}{ $num[0] * 10 };
201        $amount     = $num[1];
202    }
203    else {
204        $textnumber = $self->{numbername}{$amount};
205        $amount     = 0;
206    }
207
208    $textnumber .= " " . $self->{numbername}{$amount} if $amount;
209
210    $textnumber;
211
212}
213
214sub num2text_de {
215    my ( $self, $amount ) = @_;
216
217    return $self->{numbername}{0} unless $amount;
218
219    my @textnumber = ();
220
221    # split amount into chunks of 3
222    my @num = reverse split //, abs($amount);
223    my @numblock = ();
224    my ( $i, $appendn );
225    my @a = ();
226
227    while (@num) {
228        @a = ();
229        for ( 1 .. 3 ) {
230            push @a, shift @num;
231        }
232        push @numblock, join / /, reverse @a;
233    }
234
235    my $belowhundred = !$#numblock;
236
237    while (@numblock) {
238
239        $i       = $#numblock;
240        @num     = split //, $numblock[$i];
241        $appendn = "";
242
243        $numblock[$i] *= 1;
244
245        if ( $numblock[$i] == 0 ) {
246            pop @numblock;
247            next;
248        }
249
250        if ( $numblock[$i] > 99 ) {
251
252            # the one from hundreds
253            push @textnumber, $self->{numbername}{ $num[0] };
254
255            # add hundred designation
256            push @textnumber, $self->{numbername}{ 10**2 };
257
258            # reduce numblock
259            $numblock[$i] -= $num[0] * 100;
260        }
261
262        $appendn = 'en' if ( $i == 2 );
263        $appendn = 'n'  if ( $i > 2 );
264
265        if ( $numblock[$i] > 9 ) {
266
267            # tens
268            push @textnumber,
269              $self->format_ten_de( $numblock[$i], $belowhundred );
270        }
271        elsif ( $numblock[$i] > 1 ) {
272
273            # ones
274            push @textnumber, $self->{numbername}{ $numblock[$i] };
275        }
276        elsif ( $numblock[$i] == 1 ) {
277            if ( $i == 0 ) {
278                push @textnumber, $self->{numbername}{ $numblock[$i] } . 's';
279            }
280            else {
281                if ( $i >= 2 ) {
282                    push @textnumber,
283                      $self->{numbername}{ $numblock[$i] } . 'e';
284                }
285                else {
286                    push @textnumber, $self->{numbername}{ $numblock[$i] };
287                }
288            }
289            $appendn = "";
290        }
291
292        # add thousand, million
293        if ($i) {
294            $amount = 10**( $i * 3 );
295            push @textnumber, $self->{numbername}{$amount} . $appendn;
296        }
297
298        pop @numblock;
299
300    }
301
302    join '', @textnumber;
303
304}
305
306sub format_ten_de {
307    my ( $self, $amount, $belowhundred ) = @_;
308
309    my $textnumber = "";
310    my @num = split //, $amount;
311
312    if ( $amount > 20 ) {
313        if ( $num[1] == 0 ) {
314            $textnumber = $self->{numbername}{$amount};
315        }
316        else {
317            if ($belowhundred) {
318                $amount = $num[0] * 10;
319                $textnumber =
320                    $self->{numbername}{ $num[1] } . 'und'
321                  . $self->{numbername}{$amount};
322            }
323            else {
324                $amount = $num[0] * 10;
325                $textnumber =
326                  $self->{numbername}{$amount} . $self->{numbername}{ $num[1] };
327                $textnumber .= 's' if ( $num[1] == 1 );
328            }
329        }
330    }
331    else {
332        $textnumber = $self->{numbername}{$amount};
333    }
334
335    $textnumber;
336
337}
338
339sub num2text_et {
340    my ( $self, $amount ) = @_;
341
342    return $self->{numbername}{0} unless $amount;
343
344    my @textnumber = ();
345
346    # split amount into chunks of 3
347    my @num = reverse split //, abs($amount);
348    my @numblock = ();
349    my ( $i, $appendit );
350    my @a = ();
351
352    while (@num) {
353        @a = ();
354        for ( 1 .. 3 ) {
355            push @a, shift @num;
356        }
357        push @numblock, join / /, reverse @a;
358    }
359
360    while (@numblock) {
361
362        $i = $#numblock;
363        $numblock[$i] *= 1;
364        @num = split //, $numblock[$i];
365
366        $appendit = "it";
367        $hundred  = 0;
368
369        if ( $numblock[$i] == 0 ) {
370            pop @numblock;
371            next;
372        }
373
374        if ( $numblock[$i] > 99 ) {
375
376            # the one from hundreds
377            push @textnumber,
378              "$self->{numbername}{$num[0]}$self->{numbername}{10**2}";
379
380            # reduce numblock
381            $numblock[$i] -= $num[0] * 100;
382            @num = split //, $numblock[$i];
383            $hundred = 1;
384        }
385
386        if ( $numblock[$i] > 19 ) {
387
388            # 20 - 99
389            push @textnumber, "$self->{numbername}{$num[0]}kümmend";
390            @num = split //, $numblock[$i];
391            push @textnumber, $self->{numbername}{ $num[1] } if $num[1] > 0;
392
393        }
394        elsif ( $numblock[$i] > 10 ) {
395
396            # 11 - 19
397            if ($hundred) {
398                @num = split //, $numblock[$i];
399            }
400            $num = $num[1];
401
402            push @textnumber, "$self->{numbername}{$num}teist";
403
404        }
405        elsif ( $numblock[$i] > 1 ) {
406
407            # ones
408            push @textnumber, $self->{numbername}{ $numblock[$i] };
409
410        }
411        elsif ( $numblock[$i] == 1 ) {
412            push @textnumber, $self->{numbername}{ $num[0] };
413            $appendit = "";
414
415        }
416
417        # add thousand, million
418        if ($i) {
419            $amount = 10**( $i * 3 );
420            $appendit = ( $i == 1 ) ? "" : $appendit;
421            push @textnumber, "$self->{numbername}{$amount}$appendit";
422        }
423
424        pop @numblock;
425
426    }
427
428    join ' ', @textnumber;
429
430}
431
432sub num2text_es {
433    my ( $self, $amount ) = @_;
434
435    return $self->{numbername}{0} unless $amount;
436
437    my @textnumber = ();
438
439    # split amount into chunks of 3
440    my @num      = reverse split //, abs($amount);
441    my @numblock = ();
442    my $stripun  = 0;
443    my @a        = ();
444    my $i;
445
446    while (@num) {
447        @a = ();
448        for ( 1 .. 3 ) {
449            push @a, shift @num;
450        }
451        push @numblock, join / /, reverse @a;
452    }
453
454    # special case for 1000
455    if ( $numblock[1] eq '1' && $numblock[0] gt '000' ) {
456
457        # remove first array element from textnumber
458        $stripun = 1;
459    }
460
461    while (@numblock) {
462
463        $i = $#numblock;
464        @num = split //, $numblock[$i];
465
466        $numblock[$i] *= 1;
467
468        if ( $numblock[$i] == 0 ) {
469            pop @numblock;
470            next;
471        }
472
473        if ( $numblock[$i] > 99 ) {
474            if ( $num[0] == 1 ) {
475                push @textnumber, $self->{numbername}{ 10**2 };
476            }
477            else {
478
479                # special case for 500, 700, 900
480                if ( grep /$num[0]/, ( 5, 7, 9 ) ) {
481                    push @textnumber, $self->{numbername}{"${num[0]}00"};
482
483                }
484                else {
485
486                    # the one from hundreds, append cientos
487                    push @textnumber,
488                      $self->{numbername}{ $num[0] }
489                      . $self->{numbername}{ 10**2 } . 's';
490
491                }
492            }
493
494            # reduce numblock
495            $numblock[$i] -= $num[0] * 100;
496        }
497
498        if ( $numblock[$i] > 9 ) {
499
500            # tens
501            push @textnumber, $self->format_ten_es( $numblock[$i], $i );
502        }
503        elsif ( $numblock[$i] > 0 ) {
504
505            # ones
506            $num = $numblock[$i];
507            $num .= 'o' if ( $num == 1 && $i == 0 );
508            push @textnumber, $self->{numbername}{$num};
509        }
510
511        # add thousand, million
512        if ($i) {
513            $num = 10**( $i * 3 );
514            if ( $numblock[$i] > 1 ) {
515                if ( $i == 2 || $i == 4 ) {
516                    $a = $self->{numbername}{$num} . "es";
517                    $a =~ s/ó/o/;
518                    push @textnumber, $a;
519                }
520                elsif ( $i == 3 ) {
521                    $num = 10**( $i * 2 );
522                    $a   = "$self->{10**3} $self->{numbername}{$num}" . "es";
523                    $a =~ s/ó/o/;
524                    push @textnumber, $a;
525                }
526                else {
527                    if ( $i == 1 ) {
528                        push @textnumber, $self->{numbername}{$num};
529                    }
530                    else {
531                        push @textnumber, $self->{numbername}{$num} . 's';
532                    }
533                }
534            }
535            else {
536                push @textnumber, $self->{numbername}{$num};
537            }
538        }
539
540        pop @numblock;
541
542    }
543
544    shift @textnumber if $stripun;
545
546    join ' ', @textnumber;
547
548}
549
550sub format_ten_es {
551    my ( $self, $amount, $i ) = @_;
552
553    my $textnumber = "";
554    my @num = split //, $amount;
555
556    if ( $amount > 30 ) {
557        $textnumber = $self->{numbername}{ $num[0] * 10 };
558        $amount     = $num[1];
559    }
560    else {
561        $amount .= 'o' if ( $num[1] == 1 && $i == 0 );
562        $textnumber = $self->{numbername}{$amount};
563        $amount     = 0;
564    }
565
566    $textnumber .= " y " . $self->{numbername}{$amount} if $amount;
567
568    $textnumber;
569
570}
571
572sub num2text_fr {
573    my ( $self, $amount ) = @_;
574
575    return $self->{numbername}{0} unless $amount;
576
577    my @textnumber = ();
578
579    # split amount into chunks of 3
580    my @num = reverse split //, abs($amount);
581    my @numblock = ();
582    my @a;
583    my $i;
584
585    while (@num) {
586        @a = ();
587        for ( 1 .. 3 ) {
588            push @a, shift @num;
589        }
590        push @numblock, join / /, reverse @a;
591    }
592
593    my $cent = 0;
594
595    while (@numblock) {
596
597        $i = $#numblock;
598        @num = split //, $numblock[$i];
599
600        if ( $numblock[$i] == 0 ) {
601            pop @numblock;
602            next;
603        }
604
605        if ( $numblock[$i] > 99 ) {
606            $cent = 1;
607
608            # the one from hundreds
609
610            if ( $num[0] > 1 ) {
611                push @textnumber, $self->{numbername}{ $num[0] };
612            }
613
614            # reduce numblock
615            $numblock[$i] -= $num[0] * 100;
616
617            # add hundred designation
618            if ( $num[0] > 1 ) {
619                if ( $numblock[$i] > 0 ) {
620                    push @textnumber, $self->{numbername}{ 10**2 };
621                }
622                else {
623                    push @textnumber, "$self->{numbername}{10**2}s";
624                }
625            }
626            else {
627                push @textnumber, $self->{numbername}{ 10**2 };
628            }
629
630        }
631
632        $numblock[$i] *= 1;
633
634        if ( $numblock[$i] > 9 ) {
635
636            # tens
637            push @textnumber, $self->format_ten_fr( $numblock[$i] );
638        }
639        elsif ( $numblock[$i] > 0 ) {
640
641            # ones
642            if ( $i == 1 ) {
643                if ( $cent == 1 ) {
644                    push @textnumber, $self->{numbername}{ $numblock[$i] };
645                }
646                $cent = 0;
647            }
648            else {
649                push @textnumber, $self->{numbername}{ $numblock[$i] };
650            }
651        }
652
653        # add thousand, million
654        if ($i) {
655            $num = 10**( $i * 3 );
656            if ( $i == 1 ) {
657                push @textnumber, $self->{numbername}{$num};
658            }
659            elsif ( $numblock[$i] > 1 ) {
660                push @textnumber, "$self->{numbername}{$num}s";
661            }
662            else {
663                push @textnumber, "$self->{numbername}{$num}";
664            }
665        }
666
667        pop @numblock;
668
669    }
670
671    join ' ', @textnumber;
672
673}
674
675sub format_ten_fr {
676    my ( $self, $amount ) = @_;
677
678    my $textnumber = "";
679    my @num = split //, $amount;
680
681    if ( $amount > 20 ) {
682        if ( $num[0] == 8 ) {
683            if ( $num[1] > 0 ) {
684                $textnumber = $self->{numbername}{ $num[0] * 10 };
685            }
686            else {
687                $textnumber = "$self->{numbername}{$num[0]*10}s";
688            }
689            $amount = $num[1];
690        }
691        elsif ( $num[0] == 7 || $num[0] == 9 ) {
692            if ( $num[1] > 0 ) {
693                $textnumber = $self->{numbername}{ ( $num[0] - 1 ) * 10 };
694
695                $textnumber .= " et" if ( $num[1] == 1 && $num[0] == 7 );
696
697                $amount -= ( $num[0] - 1 ) * 10;
698            }
699            else {
700                $textnumber = $self->{numbername}{ $num[0] * 10 };
701                $amount     = $num[1];
702            }
703        }
704        else {
705            $textnumber = $self->{numbername}{ $num[0] * 10 };
706            $textnumber .= " et" if ( $num[1] == 1 );
707            $amount = $num[1];
708        }
709    }
710    else {
711        $textnumber = "$self->{numbername}{$amount}";
712        $amount     = 0;
713    }
714
715    $textnumber .= " " . $self->{numbername}{$amount} if $amount;
716
717    $textnumber;
718
719}
720
721sub num2text_hu {
722    my ( $self, $amount ) = @_;
723
724    return $self->{numbername}{0} unless $amount;
725
726    my @textnumber = ();
727
728    # split amount into chunks of 3
729    my @num = reverse split //, abs($amount);
730    my @numblock = ();
731    my @a;
732    my $i;
733    my $res;
734    while (@num) {
735        @a = ();
736        for ( 1 .. 3 ) {
737            push @a, shift @num;
738        }
739        push @numblock, join / /, reverse @a;
740    }
741    while (@numblock) {
742        $i = $#numblock;
743        @num = split //, $numblock[$i];
744
745        if ( $numblock[$i] == 0 ) {
746            pop @numblock;
747            next;
748        }
749        if ( $numblock[$i] > 99 ) {
750            push @textnumber, $self->{numbername}{ $num[0] };
751
752            # add hundred designation
753            push @textnumber, $self->{numbername}{ 10**2 };
754
755            # reduce numblock
756            $numblock[$i] -= $num[0] * 100;
757
758        }
759
760        $numblock[$i] *= 1;
761        if ( $numblock[$i] > 9 ) {
762
763            # tens
764            push @textnumber, $self->format_ten_hu( $numblock[$i] );
765        }
766        elsif ( $numblock[$i] > 0 ) {
767
768            # ones
769            push @textnumber, $self->{numbername}{ $numblock[$i] };
770        }
771
772        # add thousand, million
773        if ($i) {
774            if ( $i == 1 && $amount < 2000 ) {
775
776                $num = 10**( $i * 3 );
777                push @textnumber, $self->{numbername}{$num};
778            }
779            else {
780
781                $num = 10**( $i * 3 );
782                push @textnumber, $self->{numbername}{$num} . "-";
783            }
784        }
785
786        pop @numblock;
787
788    }
789    $res = ucfirst join '', @textnumber;
790    $res =~ s/(\-)$//;
791    return $res;
792}
793
794sub format_ten_hu {
795    my ( $self, $amount ) = @_;
796
797    my $textnumber = "";
798    my @num = split //, $amount;
799    if ( $amount > 30 ) {
800        $textnumber = $self->{numbername}{ $num[0] * 10 };
801        $amount     = $num[1];
802    }
803    else {
804        $textnumber = $self->{numbername}{$amount};
805        $amount     = 0;
806    }
807
808    $textnumber .= "" . $self->{numbername}{$amount} if $amount;
809
810    $textnumber;
811
812}
813
814sub num2text_nl {
815    my ( $self, $amount ) = @_;
816
817    return $self->{numbername}{0} unless $amount;
818
819    my @textnumber = ('**');
820
821    # split amount into chunks of 3
822    my @num = reverse split //, abs($amount);
823    my @numblock = ();
824    my ( $i, $appendn );
825    my @a = ();
826
827    while (@num) {
828        @a = ();
829        for ( 1 .. 3 ) {
830            push @a, shift @num;
831        }
832        push @numblock, join / /, reverse @a;
833    }
834
835    while (@numblock) {
836
837        $i = $#numblock;
838        @num = split //, $numblock[$i];
839
840        $numblock[$i] *= 1;
841
842        if ( $numblock[$i] == 0 ) {
843            pop @numblock;
844            next;
845        }
846
847        if ( $numblock[$i] > 99 ) {
848
849            # the one from hundreds
850            push @textnumber, $self->{numbername}{ $num[0] };
851
852            # add hundred designation
853            push @textnumber, $self->{numbername}{ 10**2 };
854
855            # reduce numblock
856            $numblock[$i] -= $num[0] * 100;
857        }
858
859        if ( $numblock[$i] > 9 ) {
860
861            # tens
862            push @textnumber, $self->format_ten_nl( $numblock[$i] );
863        }
864        else {
865
866            # ones
867            push @textnumber, $self->{numbername}{ $numblock[$i] };
868        }
869
870        # add thousand, million
871        if ($i) {
872            $amount = 10**( $i * 3 );
873            push @textnumber, $self->{numbername}{$amount};
874        }
875
876        pop @numblock;
877
878    }
879
880    push @textnumber, '**';
881    join '', @textnumber;
882
883}
884
885sub format_ten_nl {
886    my ( $self, $amount ) = @_;
887
888    my $textnumber = "";
889    my @num = split //, $amount;
890
891    if ( $amount > 20 ) {
892
893        # reverse one and ten and glue together with 'en'
894        $amount = $num[0] * 10;
895        $textnumber =
896          $self->{numbername}{ $num[1] } . 'en' . $self->{numbername}{$amount};
897    }
898    else {
899        $textnumber = $self->{numbername}{$amount};
900    }
901
902    $textnumber;
903
904}
905
906sub num2text_it {
907    my ( $self, $amount ) = @_;
908
909    return $self->{numbername}{0} unless $amount;
910
911    my @textnumber = ();
912
913    # split amount into chunks of 3
914    my @num = reverse split //, abs($amount);
915    my @numblock = ();
916    my ( $i, $appendn );
917    my @a = ();
918
919    while (@num) {
920        @a = ();
921        for ( 1 .. 3 ) {
922            push @a, shift @num;
923        }
924        push @numblock, join / /, reverse @a;
925    }
926
927    while (@numblock) {
928
929        $i = $#numblock;
930        @num = split //, $numblock[$i];
931
932        $numblock[$i] *= 1;
933
934        if ( $numblock[$i] == 0 ) {
935            pop @numblock;
936            next;
937        }
938
939        if ( $numblock[$i] > 99 ) {
940
941            # the one from hundreds
942            push @textnumber, $self->{numbername}{ $num[0] };
943
944            # add hundred designation
945            push @textnumber, $self->{numbername}{ 10**2 };
946
947            # reduce numblock
948            $numblock[$i] -= $num[0] * 100;
949        }
950
951        if ( $numblock[$i] > 9 ) {
952
953            # tens
954            push @textnumber, $self->format_ten_it( $numblock[$i] );
955        }
956        elsif ( $numblock[$i] > 1 ) {
957
958            # ones
959            push @textnumber, $self->{numbername}{ $numblock[$i] };
960        }
961
962        # add thousand, million
963        if ($i) {
964            $amount = 10**( $i * 3 );
965            push @textnumber, $self->{numbername}{$amount};
966        }
967
968        pop @numblock;
969
970    }
971
972    join '', @textnumber;
973
974}
975
976sub format_ten_it {
977    my ( $self, $amount ) = @_;
978
979    my $textnumber = "";
980    my @num = split //, $amount;
981
982    if ( $amount > 20 ) {
983        if ( $num[1] == 0 ) {
984            $textnumber = $self->{numbername}{$amount};
985        }
986        else {
987            $amount = $num[0] * 10;
988            $textnumber =
989              $self->{numbername}{$amount} . $self->{numbername}{ $num[1] };
990        }
991    }
992    else {
993        $textnumber = $self->{numbername}{$amount};
994    }
995
996    $textnumber;
997
998}
999
1000# A special (swedish-like) spelling of danish check numbers
1001sub num2text_da {
1002    my ( $self, $amount ) = @_;
1003
1004    # Handle 0
1005    return $self->{numbername}{0} unless $amount;
1006
1007    # List of collected digits
1008    my @textnumber = ();
1009
1010    # split amount into chunks of 3
1011    my @num      = reverse split //, abs($amount);
1012    my @numblock = ();
1013    my @a        = ();
1014    while (@num) {
1015        @a = ();
1016        for ( 1 .. 3 ) {
1017            push @a, shift @num;
1018        }
1019        push @numblock, join / /, reverse @a;
1020    }
1021
1022    my $i;
1023    my $bigplural;
1024    while (@numblock) {
1025        $i = $#numblock;
1026        $numblock[$i] *= 1;
1027
1028        if ( $numblock[$i] == 0 ) {
1029            pop @numblock;
1030            next;
1031        }
1032
1033        # Plural suffix "er" for million and up, not for tusinde
1034        $bigpluralsuffix = "";
1035        $bigpluralsuffix = "er" if ( $i > 1 && $numblock[$i] > 1 );
1036
1037        if ( $numblock[$i] > 99 ) {
1038            @num = split //, $numblock[$i];
1039
1040            # the one from hundreds
1041            push @textnumber, $self->{numbername}{ $num[0] };
1042
1043            # add hundred designation
1044            push @textnumber, $self->{numbername}{100};
1045
1046            # reduce numblock
1047            $numblock[$i] -= $num[0] * 100;
1048        }
1049
1050        if ( $numblock[$i] > 9 ) {
1051            @num = split //, $numblock[$i];
1052
1053            # the one from tens
1054            push @textnumber, $self->{numbername}{ $num[0] };
1055
1056            # add ten designation
1057            push @textnumber, $self->{numbername}{10};
1058
1059            # reduce numblock
1060            $numblock[$i] -= $num[0] * 10;
1061        }
1062
1063        if ( $numblock[$i] > 0 ) {
1064
1065            # the ones left in the block
1066            if ( $numblock[$i] == 1 && $i != 1 ) {
1067                push @textnumber,
1068                  $self->{numbername}{'1o'};    # Special case for "Et" tusinde
1069            }
1070            else {
1071                push @textnumber, $self->{numbername}{ $numblock[$i] };
1072            }
1073        }
1074
1075        # add thousand, million, etc
1076        if ($i) {
1077            $amount = 10**( $i * 3 );
1078            push @textnumber, $self->{numbername}{$amount} . $bigpluralsuffix;
1079        }
1080
1081        pop @numblock;
1082    }
1083
1084    join '', @textnumber;
1085
1086}
1087
1088
1089sub num2text_sl {
1090  my ($self, $amount) = @_;
1091
1092  return $self->{numbername}{0} unless $amount;
1093
1094  my @textnumber = ();
1095
1096  # split amount into chunks of 3
1097  my @num = reverse split //, abs($amount);
1098  my @numblock = ();
1099  my ($i, $appendn);
1100  my @a = ();
1101
1102  my $skip1k = 0;
1103  my $skip1m = 0;
1104  my $skip1b = 0;
1105
1106  my $checkvalue = abs($amount) % 10**6;
1107  $checkvalue /= 1000;
1108  if (1 <= $checkvalue && $checkvalue <= 2) {
1109    $skip1k = 1;
1110  }
1111
1112  $checkvalue = abs($amount) % 10**9;
1113  $checkvalue /= 10**6;
1114  if (1 <= $checkvalue && $checkvalue <= 2) {
1115    $skip1m = 1;
1116  }
1117
1118  $checkvalue = abs($amount) % 10**15;
1119  $checkvalue /= 10**12;
1120  if (1 <= $checkvalue && $checkvalue <= 2) {
1121    $skip1b = 1;
1122  }
1123
1124  my $check1m = abs($amount) % 10**8;
1125  my $check1md = abs($amount) % 10**11;
1126  my $check1b = abs($amount) % 10**14;
1127
1128  while (@num) {
1129    @a = ();
1130    for (1 .. 3) {
1131      push @a, shift @num;
1132    }
1133    push @numblock, join / /, reverse @a;
1134  }
1135
1136  my $belowhundred = !$#numblock;
1137
1138  while (@numblock) {
1139
1140    $i = $#numblock;
1141    @num = split //, $numblock[$i];
1142    $appendn = "";
1143
1144    $numblock[$i] *= 1;
1145
1146    if ($numblock[$i] == 0) {
1147      pop @numblock;
1148      next;
1149    }
1150
1151    if ($numblock[$i] > 99) {
1152      # the one from hundreds
1153      if ( $num[0] > 2 ) {
1154	push @textnumber, $self->{numbername}{$num[0]};
1155      } elsif ( $num[0] > 1 ) {
1156	push @textnumber, 'dve';
1157      }
1158
1159      # add hundred designation
1160      push @textnumber, $self->{numbername}{10**2};
1161
1162      # reduce numblock
1163      $numblock[$i] -= $num[0] * 100;
1164    }
1165
1166# Appends, where for 1 they shall be eliminated later below:
1167    if ($i == 2) {
1168      if (2*10**6 <= $check1m && $check1m < 3*10**6) {
1169        $appendn = 'a';
1170      } elsif (3*10**6 <= $check1m && $check1m < 5*10**6) {
1171        $appendn = 'e';
1172      } else {
1173        $appendn = 'ov';
1174      }
1175    }
1176    if ($i == 4) {
1177      if (2*10**12 <= $check1b && $check1b < 3*10**12) {
1178        $appendn = 'a';
1179      } elsif (3*10**12 <= $check1b && $check1b < 5*10**12) {
1180        $appendn = 'e';
1181      } else {
1182        $appendn = 'ov';
1183      }
1184    }
1185
1186    if ($numblock[$i] > 9) {
1187      # tens
1188      push @textnumber, $self->format_ten($numblock[$i], $belowhundred);
1189    } elsif ($numblock[$i] > 1) {
1190      # ones
1191      if (2*10**9 <= $check1md && $check1md < 3*10**9) {
1192	push @textnumber, 'dve';
1193      } else {
1194	push @textnumber, $self->{numbername}{$numblock[$i]};
1195      }
1196    } elsif ($numblock[$i] == 1) {
1197      if ($i == 0) {
1198	push @textnumber, $self->{numbername}{$numblock[$i]};
1199      } else {
1200	if ($i >= 5) {
1201	    push @textnumber, $self->{numbername}{$numblock[$i]}.'-!-too big number-!-?!';
1202	} elsif ($i == 4) {
1203	  if ($skip1b == 0) {
1204	    push @textnumber, $self->{numbername}{$numblock[$i]};
1205	  }
1206	} elsif ($i == 3) {
1207	  if (1*10**9 <= $check1md && $check1md < 2*10**9) {
1208	    push @textnumber, 'ena';
1209	  } else {
1210	    push @textnumber, $self->{numbername}{$numblock[$i]};
1211	  }
1212	} elsif ($i == 2) {
1213	  if ($skip1m == 0) {
1214	    push @textnumber, $self->{numbername}{$numblock[$i]};
1215	  }
1216	} elsif ($i == 1) {
1217	  if ($skip1k == 0) {
1218	    push @textnumber, $self->{numbername}{$numblock[$i]};
1219	  }
1220	} else {
1221	  push @textnumber, $self->{numbername}{$numblock[$i]};
1222	}
1223      }
1224      $appendn = "";
1225    }
1226
1227# Appends, where also for 1 they shall be considered as below;
1228# if specified above with the others, they would be eliminated
1229# by a command just a few lines above...
1230#
1231    if ($i == 3) {
1232      if (1*10**9 <= $check1md && $check1md < 2*10**9) {
1233        $appendn = 'a';
1234      } elsif (2*10**9 <= $check1md && $check1md < 3*10**9) {
1235        $appendn = 'i';
1236      } elsif (3*10**9 <= $check1md && $check1md < 5*10**9) {
1237        $appendn = 'e';
1238      }
1239    }
1240
1241    # add thousand, million
1242    if ($i) {
1243      $amount = 10**($i * 3);
1244      push @textnumber, $self->{numbername}{$amount}.$appendn;
1245    }
1246
1247    pop @numblock;
1248
1249    @textnumber = 'NAPAKA! ¿TEVILKA JE PREVELIKA!' if ($i > 4);
1250
1251  }
1252
1253  join '', @textnumber;
1254
1255}
1256
1257
1258sub format_ten_sl {
1259  my ($self, $amount, $belowhundred) = @_;
1260
1261  my $textnumber = "";
1262  my @num = split //, $amount;
1263
1264  if ($amount > 20) {
1265    if ($num[1] == 0) {
1266      $textnumber = $self->{numbername}{$amount};
1267    } elsif ($num[1] == 1) {
1268      $amount = $num[0] * 10;
1269      $textnumber = $self->{numbername}{$num[1]}.'ain'.$self->{numbername}{$amount};
1270    } else {
1271      $amount = $num[0] * 10;
1272      $textnumber = $self->{numbername}{$num[1]}.'in'.$self->{numbername}{$amount};
1273    }
1274  } else {
1275    $textnumber = $self->{numbername}{$amount};
1276  }
1277
1278  $textnumber;
1279
1280}
1281
1282
12831;
1284
1285
1286