| Lingua-HU-Numbers documentation | Contained in the Lingua-HU-Numbers distribution. |
Lingua::HU::Numbers - converts numbers into Hungarian language text form
use Lingua::HU::Numbers qw/num2hu num2hu_ordinal/;
my $number = "42";
my $foo = num2hu($number);
print $foo;
prints
negyvenkettő
Lingua::HU::Numbers is a module converting numbers (like "42") into their Hungarian language representation ("negyvenkettő").
The module provides two optionally exported functions that can be exported:
num2hu and num2hu_ordinal.
Please see the README file for details of Hungarian grammar.
It takes a scalar value which currently must be a real number smaller than -+10**66. The return value is a scalar expressing the Hungarian text version of the given number.
This function takes a scalar value which must be a positive integer smaller than 10**66. The return value is a scalar expressing the Hungarian ordinal text form of the specified number.
The module cannot handle numbers larger than -+10**66 at the moment.
Exponential notation, fraction support will be added in the next few releases. Patches (and accompanying tests) are welcome.
The module aims to remain similar in structure to Lingua::EN::Numbers, so that those familiar with that module can use this one easily.
Bálint Szilakszi, <szbalint at cpan.org>
Please report any bugs or feature requests to
bug-lingua-hu-numbers at rt.cpan.org, or through the web interface at
http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Lingua-HU-Numbers.
I will be notified, and then you'll automatically be notified of progress on
your bug as I make changes.
Sean M. Burke for writing Lingua::EN::Numbers, which this module is modelled from.
Copyright 2006-2008 Bálint Szilakszi.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Lingua-HU-Numbers documentation | Contained in the Lingua-HU-Numbers distribution. |
package Lingua::HU::Numbers; use 5.006; use warnings; use strict; use Carp; use utf8; require Exporter; our @ISA = qw(Exporter); our @EXPORT = (); our @EXPORT_OK = qw(num2hu num2hu_ordinal); our $VERSION = '0.07'; my %dig; @dig{ 0..30,40,50,60,70,80,90 } = qw( nulla egy kettÅ három négy öt hat hét nyolc kilenc tÃz tizenegy tizenkettÅ tizenhárom tizennégy tizenöt tizenhat tizenhét tizennyolc tizenkilenc húsz huszonegy huszonkettÅ huszonhárom huszonnégy huszonöt huszonhat huszonhét huszonnyolc huszonkilenc harminc negyven ötven hatvan hetven nyolcvan kilencven ); my %ord; my @tenord = qw ( egyedik kettedik harmadik negyedik ötödik hatodik hetedik nyolcadik kilencedik); my %tenord; @tenord{ 1..9 } = @tenord; my $empty = q{}; my $minus = q{-}; my $space = q{ }; my @desc = ($empty,qw(ezer millió milliárd billió billiárd trillió trilliárd kvadrillió kvadrilliárd kvintillió kvintilliárd szextillió szextilliárd szeptillió szeptilliárd oktillió oktilliárd nonillió nonilliárd decillió decilliárd)); my @frac = ($empty,qw( ezred milliomod milliárdod billiomod billiárdod trilliomod trilliárdod kvadrilliomod kvadrilliárdod kvintilliomod kvintilliárdod szextilliomod szextilliárdod szeptilliomod szeptilliárdod oktilliomod oktilliárdod nonilliomod nonilliárdod decilliomod decilliárdod )); @ord{ 0..10,11..19,20,21..29,30,40,50,60,70,80,90,100 } = (qw(nulladik elsÅ második), @tenord[2..8], 'tizedik',(map { "tizen$_" } @tenord), 'huszadik', (map { "huszon$_" } @tenord), qw( harmincadik negyvenedik ötvenedik hatvanadik hetvenedik nyolcvanadik kilencvenedik századik)); sub num2hu { my $num = $_[0]; return $dig{'0'} if ($num =~ m/^[+-]0+$/sx); return unless defined $num && length $num; croak('Number is not properly formatted!') if ($num !~ m/^[+-]?\d+(\.\d+)?$/sx); my ($int,$frac) = $num =~ m/^[+-]?(\d+)(?:\.(\d+))?$/x; croak('The number is too large, the module can\'t handle it!') if ($int && length($int) > 66 || $frac && length($frac) > 66); my $plusmin = $empty; $num =~ s/^([+-])/$plusmin = $1;$empty/esx; $plusmin = ($plusmin eq $minus) ? 'mÃnusz ':$empty; if ($num =~ m/(\d+)\.(\d+)/x) { if (_frac2hu($2)) { return $plusmin._int2hu($1).' egész '._frac2hu($2) } else { return $plusmin._int2hu($1); } } else { return $plusmin._int2hu($num); } } sub num2hu_ordinal { my $num = $_[0]; return unless defined $num && length($num); croak('You need to specify a positive integer for this function!') if ($num !~ m/^\d+$/sx); croak('The number is too large, the module can\'t handle it!') if (length($num) > 66); return $ord{'0'} if ($num =~ m/^0+$/sx); return _ord2hu($num); } sub _int2hu { my $num = $_[0]; my $recur = $_[1]; return $dig{$num} if ($dig{$num}); my ($hun,$end,$pre); if ($num =~ m/^(\d)(\d)$/x) { return $dig{$1.'0'} . $dig{$2} } elsif ($num =~ m/^(\d)(\d\d)$/x) { ($hun,$end) = ($1,$2); $hun = ($hun eq '1' && !$recur)? 'száz':"$dig{$hun}száz"; return $hun if ($end eq '00'); return $hun._int2hu($2 + 0); } elsif ($num <= 2000 && $num =~ m/^1(\d\d\d)$/x) { return 'ezer' if ($1 eq '000'); return 'ezer'._int2hu($1 + 0,1); } elsif ($num =~ m/^(\d{1,3})((?:000){1,2})$/x) { ($pre,$end) = ($1,(length($2) == 3)? $desc[1]:$desc[2]); return _int2hu($pre + 0).$end; } else { return _bigint2hu($num); } } sub _bigint2hu { my $num = $_[0]; my @parts; my $count = 0; my $part; if ($num =~ m/001(\d{3})$/x) { $num =~ s/00(1\d{3})$//x; $part = $1; unshift @parts, [ $part, $count ]; $count += 2; } while ($num =~ s/(\d{1,3})$//x) { $part = $1 + 0; unshift @parts, [ $part, $count ] if ($part); $count++; } my @out; for (0..$#parts) { push @out, _int2hu($parts[$_]->[0],$_). (($parts[$_]->[1] > 8)? $space:$empty). $desc[$parts[$_]->[1]]; } return join($minus,@out); } sub _frac2hu { my $num = $_[0]; $num =~ s/0+$//x; my $place = length($num); $num =~ s/^0+//x; return if ($num eq $empty); if ($place < 3) { $place = ($place == 1) ? 'tized':'század'; return _int2hu($num).$space.$place; } else { my $rest = $empty; $rest = _int2hu('1'.('0' x ($place % 3))) if ($place % 3); $place = int( $place / 3 ); return _int2hu($num).$space.$rest.$frac[$place]; } } sub _ord2hu { my $num = $_[0]; $num =~ s/^0+//x; return $ord{$num} if $ord{$num}; if ($num =~ m/^(\d)(\d)$/x) { return _int2hu($1.'0').$tenord{$2}; } elsif ($num =~ m/^(\d)(\d\d)$/x) { if ($2 eq '00') { return _int2hu($1.'00').'adik' } else { return _int2hu($1.'00')._ord2hu($2); } } elsif ($num =~ m/^(\d+?)((?:000)+)$/x) { if ($1 eq '1' && $2 eq '000') { return 'ezredik' } else { return _int2hu($1).$frac[(length($2) / 3)].'ik'; } } elsif ($num =~ m/^1(\d\d\d)$/x) { return 'ezer'._ord2hu($1); } elsif ($num =~ m/^(\d+)(\d\d\d)$/x) { return _int2hu($1.'000').$minus._ord2hu($2); } } 1; __END__