Locale::MakePhrase::Numeric - Numeric translation/stringification


Locale-MakePhrase documentation Contained in the Locale-MakePhrase distribution.

Index


Code Index:

NAME

Top

Locale::MakePhrase::Numeric - Numeric translation/stringification

SYNOPSIS

Top

This module provides the functionality to translate and/or stringify a numeric, into something suitable for the string being translated.

API

Top

The following class-functions are provided:

$string stringify($number,$options)

This class-function implements the stringification of a number to a suitable output format. The $options parameter is used to control the formatting behaviour:

numeric_format

The formatting appled to the number; this must be an array reference containing 4 elements:

1.

decimal seperator

2.

thousand's seperator

3.

when the value is negative, the symbol shown to the left of the number

4.

when the value is negative, the symbol shown to the right of the number

width

Set the number of characters used in the output.

precision

Set the maximum number of decimal places processed.

fixed

Set this to true to make the output use a fixed number of decimal places, irrespective if the values are all zeros. Use this in conjunction with the precision setting.

scientific

Set this value to true to make the number show exponential notation.

leading_zeros

Set this to true to make the output display zeros; combine this with the width setting.

NOTES

Top

If the number is purely an integer, you have not set the fixed or scientific settings, we try to keep the number from turning into its scientific notation (ie: we try to stop big numbers turning into something like 1.04E+09).


Locale-MakePhrase documentation Contained in the Locale-MakePhrase distribution.
package Locale::MakePhrase::Numeric;
our $VERSION = 0.1;
our $DEBUG = 0;

use strict;
use warnings;
use base qw(Exporter);
use Data::Dumper;
use vars qw(@EXPORT_OK);
@EXPORT_OK = qw( stringify);
local $Data::Dumper::Indent = 1 if $DEBUG;

# Common formatting types
sub DOT       { return [ '.','' ,'-','' ]; }
sub COMMA     { return [ ',','' ,'-','' ]; }
sub DOT_COMMA { return [ '.',',','-','' ]; }
sub COMMA_DOT { return [ ',','.','-','' ]; }

#--------------------------------------------------------------------------

sub stringify {
  shift if (@_ == 3);
  my ($number,$options) = @_;
  my $format = $options->{numeric_format};
  $format = DOT unless $format;
  print STDERR "Stringify format: '".join("' '",@$format)."'\n" if $DEBUG > 3;
  my $negative = $number < 0 ? 1 : 0;
  $number = abs($number);

  # Don't let the %G of sprintf, turn ten million (or bigger) into something like 1E+007
  # Otherwise, try to apply various formatting options.
  if (!$options->{fixed} and !$options->{scientific} and $number < 10_000_000_000 and $number == int($number)) {
    $number += 0;  # Just use normal integer stringification.
  } else {
    my $mode = "%";
    $mode .= $options->{width} if (exists $options->{width});
    if (exists $options->{precision}) {
      $mode .= ".".$options->{precision};
    } else {
      $mode .= ".15";
    }
    if ($options->{fixed}) {
      $mode .= "F";
    } else {
      $mode .= "G";
    }
    $number = CORE::sprintf($mode,$number);
    if(!$options->{fixed} and !$options->{scientific} and $number < 10_000_000_000 and $number == int($number)) {
      $number += 0;  # Just use normal integer stringification.
    }
  }

  # We optionally apply numeric formatting (eg: put comma's into big numbers)
  if ($format) {

    # has the format defined a seperator, we add them
    if ($format->[1]) {
      # The initial \d+ gobbles as many digits as it can, and then we
      # backtrack so it un-eats the rightmost three, and then we
      # insert the comma there.
      while( $number =~ s/^(\d+)(\d{3})/$1_$2/s ) {1}

      my $t = $format->[0];
      if ($t eq '_') {
        $number =~ s/_/#/g;
        $number =~ s/\./_/;
        $t = $format->[1];
        $number =~ s/#/$t/g;
      } else {
        $number =~ s/\./$t/;
        $t = $format->[1];
        $number =~ s/_/$t/g;
      }
    } else {
      my $t = $format->[0];
      $number =~ s/\./$t/ if ($t ne '.');
    }
  }

  # do we want leading zero's
  $number = tr< ><0> if ($options->{leading_zeros});

  # apply negative-formatting
  $number = $format->[2].$number.$format->[3] if $negative;

  return $number;
}

1;
__END__
#--------------------------------------------------------------------------