Lingua-ENG-Inflect

 view release on metacpan or  search on metacpan

lib/Lingua/ENG/Inflect.pm  view on Meta::CPAN

       return $ind<@mill ? $mill[$ind] : ' ???illion'; }

sub unit { return $unit[$_[0]]. mill($_[1]); }

sub ten
{
    return $ten[$_[0]] . ($_[0]&&$_[1]?'-':'') . $unit[$_[1]] . mill($_[2])
        if $_[0] ne '1';
    return $teen[$_[1]]. $mill[$_[2]||0];
}

sub hund
{
    return unit($_[0]) . " hundred" . ($_[1] || $_[2] ? " $_[4] " : '')
         . ten($_[1],$_[2]) . mill($_[3]) . ', ' if $_[0];
    return ten($_[1],$_[2]) . mill($_[3]) . ', ' if $_[1] || $_[2];
    return '';
}

sub enword
{
    my ($num,$group,$zero,$one,$comma,$and) = @_;

    if ($group==1)
    {
        $num =~ s/(\d)/ ($1==1 ? " $one" : $1 ? unit($1) :" $zero")."$comma " /eg;
    }
    elsif ($group==2)
    {
        $num =~ s/(\d)(\d)/ ($1 ? ten($1,$2) : $2 ? " $zero " . unit($2) : " $zero $zero") . "$comma " /eg;
        $num =~ s/(\d)/ ($1 ? unit($1) :" $zero")."$comma " /e;
    }
    elsif ($group==3)
    {
        $num =~ s/(\d)(\d)(\d)/ ($1==1 ? " $one" : $1 ? unit($1) :" $zero")." ".($2 ? ten($2,$3) : $3 ? " $zero " . unit($3) : " $zero $zero") . "$comma " /eg;
        $num =~ s/(\d)(\d)/ ($1 ? ten($1,$2) : $2 ? " $zero " . unit($2) : " $zero $zero") . "$comma " /e;
        $num =~ s/(\d)/ ($1==1 ? " $one" : $1 ? unit($1) :" $zero")."$comma " /e;
    }
    elsif ($num+0==0) {
        $num = $zero;
    }
    elsif ($num+0==1) {
        $num = $one;
    }
    else {
        $num =~ s/\A\s*0+//;
        my $mill = 0;
        1 while $num =~ s/(\d)(\d)(\d)(?=\D*\Z)/ hund($1,$2,$3,$mill++,$and) /e;
        $num =~ s/(\d)(\d)(?=\D*\Z)/ ten($1,$2,$mill)."$comma " /e;
        $num =~ s/(\d)(?=\D*\Z)/ unit($1,$mill) . "$comma "/e;
    }
    return $num;
}

sub NUMWORDS
{
    my $num = shift;

    if (@_ % 2 and require Carp) {
        die "Missing value in option list (odd number of option args) at"
          . join ' line ', (caller)[1,2];
    }

    my %arg = ( %default_args, @_ );
    my $group = $arg{group};

    # Handle "stylistic" conversions (up to a given threshold)...
    if (exists $arg{threshold} && $num > $arg{threshold}) {
        my ($whole, $frac) = split /[.]/, $num;
        while ($arg{comma}) {
            $whole =~ s{ (\d) ( \d{3}(?:,|\z) ) }{$1,$2}xms
                or last;
        }
        return $frac ? "$whole.$frac" : $whole;
    }

    die "Bad chunking option: $group\n" unless $group =~ /\A[0-3]\Z/;
    my $sign = ($num =~ /\A\s*\+/) ? "plus"
         : ($num =~ /\A\s*\-/) ? "minus"
         : '';

    my ($zero, $one) = @arg{'zero','one'};
    my $comma = $arg{comma};
    my $and = $arg{'and'};

    my $ord = $num =~ s/(st|nd|rd|th)\Z//;
    my @chunks = ($arg{decimal})
            ? $group ? split(/\./, $num) : split(/\./, $num, 2)
            : ($num);

    my $first = 1;

    if ($chunks[0] eq '') { $first=0; shift @chunks; }

    foreach ( @chunks )
    {
        s/\D//g;
        $_ = '0' unless $_;

        if (!$group && !$first) { $_ = enword($_,1,$zero,$one,$comma,$and) }
        else                    { $_ = enword($_,$group,$zero,$one,$comma,$and) }

        s/, \Z//;
        s/\s+,/,/g;
        s/, (\S+)\s+\Z/ $and $1/ if !$group and $first;
        s/\s+/ /g;
        s/(\A\s|\s\Z)//g;
        $first = '' if $first;
    }

    my @numchunks = ();
    if ($first =~ /0/)
    {
        unshift @chunks, '';
    }
    else
    {
        @numchunks = split /\Q$comma /, $chunks[0];
    }

    $numchunks[-1] =~ s/($ordinal_suff)\Z/$ordinal{$1}/



( run in 2.852 seconds using v1.01-cache-2.11-cpan-364913b4093 )