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