#===================================================================== # SQL-Ledger Accounting # Copyright (C) 2002 # # Author: Dieter Simader # Email: dsimader@sql-ledger.org # Web: http://www.sql-ledger.org # # Language: Spanish UTF-8 # Contributors: # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #====================================================================== sub init { my $self = shift; %{ $self->{numbername} } = (0 => 'cero', 1 => 'un', '1o' => 'uno', 2 => 'dos', 3 => 'tres', 4 => 'cuatro', 5 => 'cinco', 6 => 'seis', 7 => 'siete', 8 => 'ocho', 9 => 'nueve', 10 => 'diez', 11 => 'once', 12 => 'doce', 13 => 'trece', 14 => 'catorce', 15 => 'quince', 16 => 'dieciséis', 17 => 'diecisiete', 18 => 'dieciocho', 19 => 'diecinueve', 20 => 'veinte', 21 => 'veintiún', '21o' => 'veintiuno', 22 => 'veintidós', 23 => 'veintitrés', 24 => 'veinticuatro', 25 => 'veinticinco', 26 => 'veintiséis', 27 => 'veintisiete', 28 => 'veintiocho', 29 => 'veintinueve', 30 => 'treinta', 40 => 'cuarenta', 50 => 'cincuenta', 60 => 'sesenta', 70 => 'setenta', 80 => 'ochenta', 90 => 'noventa', 500 => 'quinientos', 700 => 'setecientos', 900 => 'novecientos', 10**2 => 'ciento', 10**3 => 'mil', 10**6 => 'millón', 10**12 => 'billón', ); } sub num2text { my ($self, $amount) = @_; return $self->{numbername}{0} unless $amount; my @textnumber = (); # split amount into chunks of 3 my @num = reverse split //, abs($amount); my @numblock = (); my $stripun = 0; my @a = (); my $i; while (@num) { @a = (); for (1 .. 3) { push @a, shift @num; } push @numblock, join / /, reverse @a; } # special case for 1000 if ($numblock[1] eq '1' && $numblock[0] gt '000') { # remove first array element from textnumber $stripun = 1; } while (@numblock) { $i = $#numblock; @num = split //, $numblock[$i]; $numblock[$i] *= 1; if ($numblock[$i] == 0) { pop @numblock; next; } if ($numblock[$i] > 99) { if ($num[0] == 1) { push @textnumber, $self->{numbername}{10**2}; } else { # special case for 500, 700, 900 if (grep /$num[0]/, (5,7,9)) { push @textnumber, $self->{numbername}{"${num[0]}00"}; } else { # the one from hundreds, append cientos push @textnumber, $self->{numbername}{$num[0]}.$self->{numbername}{10**2}.'s'; } } # reduce numblock $numblock[$i] -= $num[0] * 100; } if ($numblock[$i] > 9) { # tens push @textnumber, $self->format_ten($numblock[$i], $i); } elsif ($numblock[$i] > 0) { # ones $num = $numblock[$i]; $num .= 'o' if ($num == 1 && $i == 0); push @textnumber, $self->{numbername}{$num}; } # add thousand, million if ($i) { $num = 10**($i * 3); if ($numblock[$i] > 1) { if ($i == 2 || $i == 4) { $a = $self->{numbername}{$num}."es"; $a =~ s/ó/o/; push @textnumber, $a; } elsif ($i == 3) { $num = 10**($i * 2); $a = "$self->{10**3} $self->{numbername}{$num}"."es"; $a =~ s/ó/o/; push @textnumber, $a; } else { if ($i == 1) { push @textnumber, $self->{numbername}{$num}; } else { push @textnumber, $self->{numbername}{$num}.'s'; } } } else { push @textnumber, $self->{numbername}{$num}; } } pop @numblock; } shift @textnumber if $stripun; join ' ', @textnumber; } sub format_ten { my ($self, $amount, $i) = @_; my $textnumber = ""; my @num = split //, $amount; if ($amount > 30) { $textnumber = $self->{numbername}{$num[0]*10}; $amount = $num[1]; } else { $amount .= 'o' if ($num[1] == 1 && $i == 0); $textnumber = $self->{numbername}{$amount}; $amount = 0; } $textnumber .= " y ".$self->{numbername}{$amount} if $amount; $textnumber; } 1;