Use Number::Format to format numbers without the help of locales
[deb/packages.git] / lib / Template / Plugin / Number / Format.pm
1 package Template::Plugin::Number::Format;
2
3 # ----------------------------------------------------------------------
4 # $Id: Format.pm,v 1.1 2002/07/30 12:13:40 dlc Exp dlc $
5 # ----------------------------------------------------------------------
6 #  Template::Plugin::Number::Format - Plugin/filter interface to Number::Format
7 #  Copyright (C) 2002 darren chamberlain <darren@cpan.org>
8 #
9 #  This program is free software; you can redistribute it and/or
10 #  modify it under the terms of the GNU General Public License as
11 #  published by the Free Software Foundation; version 2.
12 #
13 #  This program is distributed in the hope that it will be useful, but
14 #  WITHOUT ANY WARRANTY; without even the implied warranty of
15 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 #  General Public License for more details.
17 #
18 #  You should have received a copy of the GNU General Public License
19 #  along with this program; if not, write to the Free Software
20 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 #  02111-1307  USA
22 # -------------------------------------------------------------------
23
24 use strict;
25 use vars qw($VERSION $DYNAMIC $AUTOLOAD);
26
27 $VERSION = '1.02';
28 $DYNAMIC = 1;
29
30 use Number::Format;
31 use base qw(Template::Plugin::Filter);
32
33 # ----------------------------------------------------------------------
34 # filter($text)
35 #
36 # The default filter is format_number, i.e., commify.
37 # ----------------------------------------------------------------------
38 sub filter {
39     my ($self, $text, $args) = @_;
40     $self->{ _NFO }->format_number($text, @$args);
41 }
42
43
44 # ----------------------------------------------------------------------
45 # init($config)
46 #
47 # Initialize the instance.  Creates a Number::Format object, which is
48 # used to create closures that implement the filters.
49 # ----------------------------------------------------------------------
50 sub init {
51     my ($self, $config) = @_;
52     my ($sub, $filter, $nfo);
53     $nfo = Number::Format->new(%$config);
54     
55     $self->{ _DYNAMIC } = 1;
56     $self->{ _NFO } = $nfo;
57
58     # ------------------------------------------------------------------
59     # This makes is dependant upon Number::Format not changing the 
60     # Exporter interface it advertises, which is unlikely.
61     #
62     # It is likely that each of these subroutines should accept all
63     # the configuration options of the constructor, and instantiate a
64     # new Number::Format instance.  This is easier, for now.
65     # ------------------------------------------------------------------
66     for my $sub (@{$Number::Format::EXPORT_TAGS{"subs"}}) {
67         my $filter = sub {
68             my ($context, @args) = @_;
69             return sub {
70                 my $text = shift;
71                 return $nfo->$sub($text, @args);
72             };
73         };
74         $self->{ _CONTEXT }->define_filter($sub, $filter, 1);
75     }
76
77     return $self;
78 }
79
80 # ----------------------------------------------------------------------
81 # AUTOLOAD
82 #
83 # Catches method calls; so that the plugin can be used like you'd
84 # expect a plugin to work:
85 #
86 # [% USE nf = Number.Format; nf.format_number(num) %]
87 # ----------------------------------------------------------------------
88 sub AUTOLOAD {
89     my $self = shift;
90    (my $autoload = $AUTOLOAD) =~ s/.*:://;
91
92     return if $autoload eq 'DESTROY';
93
94     $self->{ _NFO }->$autoload(@_);
95 }
96
97 1;
98
99 __END__
100
101 =head1 NAME
102
103 Template::Plugin::Number::Format - Plugin/filter interface to Number::Format
104
105 =head1 SYNOPSIS
106
107     [% USE Number.Format %]
108     [% num | format_number %]
109
110 =head1 ABSTRACT
111
112 Template::Plugin::Number::Format makes the number-munging grooviness
113 of Number::Format available to your templates.  It is used like a
114 plugin, but installs filters into the current context.
115
116 =head1 DESCRIPTION
117
118 All filters created by Template::Plugin::Number::Format can be
119 configured by constructor options and options that can be passed to
120 individual filters.  See L<Number::Format/"METHODS"> for all the details.
121
122 =head2 Constructor Parameters
123
124 The USE line accepts the following parameters, all optional, which
125 define the default behavior for filters within the current Context:
126
127 =over 4
128
129 =item THOUSANDS_SEP
130
131 character inserted between groups of 3 digits
132
133 =item DECIMAL_POINT
134
135 character separating integer and fractional parts
136
137 =item MON_THOUSANDS_SEP
138
139 like THOUSANDS_SEP, but used for format_price
140
141 =item MON_DECIMAL_POINT
142
143 like DECIMAL_POINT, but used for format_price
144
145 =item INT_CURR_SYMBOL
146
147 character(s) denoting currency (see format_price())
148
149 =item DECIMAL_DIGITS
150
151 number of digits to the right of dec point (def 2)
152
153 =item DECIMAL_FILL
154
155 boolean; whether to add zeroes to fill out decimal
156
157 =item NEG_FORMAT
158
159 format to display negative numbers (def -x)
160
161 =item KILO_SUFFIX
162
163 suffix to add when format_bytes formats kilobytes
164
165 =item MEGA_SUFFIX
166
167 suffix to add when format_bytes formats megabytes
168
169 =item GIGA_SUFFIX
170
171 suffix to add when format_bytes formats gigabytes
172
173 =back
174
175 =head1 Using Template::Plugin::Number::Format
176
177 When you invoke:
178
179     [% USE Number.Format(option = value) %]
180
181 the following filters are installed into the current Context:
182
183 =over 4
184
185 =item B<round($precision)>
186
187 Rounds the number to the specified precision.  If "$precision" is
188 omitted, the value of the "DECIMAL_DIGITS" parameter is used
189 (default value 2).
190
191 =item B<format_number($precision, $trailing_zeros)>
192
193 Formats a number by adding "THOUSANDS_SEP" between each set of 3
194 digits to the left of the decimal point, substituting "DECIMAL_POINT"
195 for the decimal point, and rounding to the specified precision using
196 "round()".  Note that "$precision" is a maximum precision specifier;
197 trailing zeroes will only appear in the output if "$trailing_zeroes"
198 is provided, or the parameter "DECIMAL_FILL" is set, with a value that
199 is true (not zero, undef, or the empty string).  If "$precision" is
200 omitted, the value of the "DECIMAL_DIGITS" parameter (default value
201 of 2) is used.
202
203 =item B<format_negative($picture)>
204
205 Formats a negative number.  Picture should be a string that contains
206 the letter "x" where the number should be inserted.  For example, for
207 standard negative numbers you might use "-x", while for
208 accounting purposes you might use "(x)".  If the specified number
209 begins with a - character, that will be removed before formatting, but
210 formatting will occur whether or not the number is negative.
211
212 =item B<format_picture($picture)>
213
214 Returns a string based on "$picture" with the "#" characters replaced
215 by digits from "$number".  If the length of the integer part of
216 $number is too large to fit, the "#" characters are replaced with
217 asterisks ("*") instead. 
218
219 =item B<format_price($precision)>
220
221 Returns a string containing "$number" formatted similarly to
222 "format_number()", except that the decimal portion may have trailing
223 zeroes added to make it be exactly "$precision" characters long, and
224 the currency string will be prefixed.
225
226 If the "INT_CURR_SYMBOL" attribute of the object is the empty string,
227 no currency will be added.
228
229 If "$precision" is not provided, the default of 2 will be used. 
230
231 =item B<format_bytes($precision)>
232
233 Returns a string containing "$number" formatted similarly to
234 "format_number()", except that if the number is over 1024, it will be
235 divided by 1024 and the value of KILO_SUFFIX appended to the end; or
236 if it is over 1048576 (1024*1024), it will be divided by 1048576 and
237 MEGA_SUFFIX appended to the end.  Negative values will result in an
238 error.
239
240 If "$precision" is not provided, the default of 2 will be used.
241
242 =item B<unformat_number>
243
244 Converts a string as returned by "format_number()", "format_price()",
245 or "format_picture()", and returns the corresponding value as a
246 numeric scalar.  Returns "undef" if the number does not contain any
247 digits.
248
249 =back
250
251 =head1 SEE ALSO
252
253 L<Template|Template>, L<Number::Format|Number::Format>
254
255 =head1 AUTHOR
256
257 darren chamberlain E<lt>darren@cpan.orgE<gt>
258