--- /dev/null
+package Template::Plugin::Number::Format;
+
+# ----------------------------------------------------------------------
+# $Id: Format.pm,v 1.1 2002/07/30 12:13:40 dlc Exp dlc $
+# ----------------------------------------------------------------------
+# Template::Plugin::Number::Format - Plugin/filter interface to Number::Format
+# Copyright (C) 2002 darren chamberlain <darren@cpan.org>
+#
+# 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; version 2.
+#
+# 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., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA
+# -------------------------------------------------------------------
+
+use strict;
+use vars qw($VERSION $DYNAMIC $AUTOLOAD);
+
+$VERSION = '1.02';
+$DYNAMIC = 1;
+
+use Number::Format;
+use base qw(Template::Plugin::Filter);
+
+# ----------------------------------------------------------------------
+# filter($text)
+#
+# The default filter is format_number, i.e., commify.
+# ----------------------------------------------------------------------
+sub filter {
+ my ($self, $text, $args) = @_;
+ $self->{ _NFO }->format_number($text, @$args);
+}
+
+
+# ----------------------------------------------------------------------
+# init($config)
+#
+# Initialize the instance. Creates a Number::Format object, which is
+# used to create closures that implement the filters.
+# ----------------------------------------------------------------------
+sub init {
+ my ($self, $config) = @_;
+ my ($sub, $filter, $nfo);
+ $nfo = Number::Format->new(%$config);
+
+ $self->{ _DYNAMIC } = 1;
+ $self->{ _NFO } = $nfo;
+
+ # ------------------------------------------------------------------
+ # This makes is dependant upon Number::Format not changing the
+ # Exporter interface it advertises, which is unlikely.
+ #
+ # It is likely that each of these subroutines should accept all
+ # the configuration options of the constructor, and instantiate a
+ # new Number::Format instance. This is easier, for now.
+ # ------------------------------------------------------------------
+ for my $sub (@{$Number::Format::EXPORT_TAGS{"subs"}}) {
+ my $filter = sub {
+ my ($context, @args) = @_;
+ return sub {
+ my $text = shift;
+ return $nfo->$sub($text, @args);
+ };
+ };
+ $self->{ _CONTEXT }->define_filter($sub, $filter, 1);
+ }
+
+ return $self;
+}
+
+# ----------------------------------------------------------------------
+# AUTOLOAD
+#
+# Catches method calls; so that the plugin can be used like you'd
+# expect a plugin to work:
+#
+# [% USE nf = Number.Format; nf.format_number(num) %]
+# ----------------------------------------------------------------------
+sub AUTOLOAD {
+ my $self = shift;
+ (my $autoload = $AUTOLOAD) =~ s/.*:://;
+
+ return if $autoload eq 'DESTROY';
+
+ $self->{ _NFO }->$autoload(@_);
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Template::Plugin::Number::Format - Plugin/filter interface to Number::Format
+
+=head1 SYNOPSIS
+
+ [% USE Number.Format %]
+ [% num | format_number %]
+
+=head1 ABSTRACT
+
+Template::Plugin::Number::Format makes the number-munging grooviness
+of Number::Format available to your templates. It is used like a
+plugin, but installs filters into the current context.
+
+=head1 DESCRIPTION
+
+All filters created by Template::Plugin::Number::Format can be
+configured by constructor options and options that can be passed to
+individual filters. See L<Number::Format/"METHODS"> for all the details.
+
+=head2 Constructor Parameters
+
+The USE line accepts the following parameters, all optional, which
+define the default behavior for filters within the current Context:
+
+=over 4
+
+=item THOUSANDS_SEP
+
+character inserted between groups of 3 digits
+
+=item DECIMAL_POINT
+
+character separating integer and fractional parts
+
+=item MON_THOUSANDS_SEP
+
+like THOUSANDS_SEP, but used for format_price
+
+=item MON_DECIMAL_POINT
+
+like DECIMAL_POINT, but used for format_price
+
+=item INT_CURR_SYMBOL
+
+character(s) denoting currency (see format_price())
+
+=item DECIMAL_DIGITS
+
+number of digits to the right of dec point (def 2)
+
+=item DECIMAL_FILL
+
+boolean; whether to add zeroes to fill out decimal
+
+=item NEG_FORMAT
+
+format to display negative numbers (def -x)
+
+=item KILO_SUFFIX
+
+suffix to add when format_bytes formats kilobytes
+
+=item MEGA_SUFFIX
+
+suffix to add when format_bytes formats megabytes
+
+=item GIGA_SUFFIX
+
+suffix to add when format_bytes formats gigabytes
+
+=back
+
+=head1 Using Template::Plugin::Number::Format
+
+When you invoke:
+
+ [% USE Number.Format(option = value) %]
+
+the following filters are installed into the current Context:
+
+=over 4
+
+=item B<round($precision)>
+
+Rounds the number to the specified precision. If "$precision" is
+omitted, the value of the "DECIMAL_DIGITS" parameter is used
+(default value 2).
+
+=item B<format_number($precision, $trailing_zeros)>
+
+Formats a number by adding "THOUSANDS_SEP" between each set of 3
+digits to the left of the decimal point, substituting "DECIMAL_POINT"
+for the decimal point, and rounding to the specified precision using
+"round()". Note that "$precision" is a maximum precision specifier;
+trailing zeroes will only appear in the output if "$trailing_zeroes"
+is provided, or the parameter "DECIMAL_FILL" is set, with a value that
+is true (not zero, undef, or the empty string). If "$precision" is
+omitted, the value of the "DECIMAL_DIGITS" parameter (default value
+of 2) is used.
+
+=item B<format_negative($picture)>
+
+Formats a negative number. Picture should be a string that contains
+the letter "x" where the number should be inserted. For example, for
+standard negative numbers you might use "-x", while for
+accounting purposes you might use "(x)". If the specified number
+begins with a - character, that will be removed before formatting, but
+formatting will occur whether or not the number is negative.
+
+=item B<format_picture($picture)>
+
+Returns a string based on "$picture" with the "#" characters replaced
+by digits from "$number". If the length of the integer part of
+$number is too large to fit, the "#" characters are replaced with
+asterisks ("*") instead.
+
+=item B<format_price($precision)>
+
+Returns a string containing "$number" formatted similarly to
+"format_number()", except that the decimal portion may have trailing
+zeroes added to make it be exactly "$precision" characters long, and
+the currency string will be prefixed.
+
+If the "INT_CURR_SYMBOL" attribute of the object is the empty string,
+no currency will be added.
+
+If "$precision" is not provided, the default of 2 will be used.
+
+=item B<format_bytes($precision)>
+
+Returns a string containing "$number" formatted similarly to
+"format_number()", except that if the number is over 1024, it will be
+divided by 1024 and the value of KILO_SUFFIX appended to the end; or
+if it is over 1048576 (1024*1024), it will be divided by 1048576 and
+MEGA_SUFFIX appended to the end. Negative values will result in an
+error.
+
+If "$precision" is not provided, the default of 2 will be used.
+
+=item B<unformat_number>
+
+Converts a string as returned by "format_number()", "format_price()",
+or "format_picture()", and returns the corresponding value as a
+numeric scalar. Returns "undef" if the number does not contain any
+digits.
+
+=back
+
+=head1 SEE ALSO
+
+L<Template|Template>, L<Number::Format|Number::Format>
+
+=head1 AUTHOR
+
+darren chamberlain E<lt>darren@cpan.orgE<gt>
+