All,
The format() filter accepts sprintf() style format strings.
Almost. It doesn't accept format strings where the minimum width is
calculated, and provided as a separate argument. I.e., you can't do the
equivalent of this Perl:
$out = sprintf("<%*s>\n", 6, "foo");
print $out; # Prints '< foo>'
The TT equivalent:
[% "foo" | format("<%*s>", 6) %]
Gives:
Argument "foo" isn't numeric in sprintf at
.../Template/Filters.pm line 418.
Use of uninitialized value in sprintf at
.../Template/Filters.pm line 418.
I'm aware of the
[% USE padleft = format('%-*s') %]
[% USE padright = format('%*s') %]
[% padleft(10, a) %]-[% padright(10, b) %]
trick, but it's a bit of a hack.
Attached are two patches (against 2.15) -- one that adds this functionality
to format(), along with associated documentation, the other that adds a test
for the functionality.
N
--- Filters.pm.org Wed Feb 7 17:32:59 2007
+++ Filters.pm Wed Feb 7 17:32:08 2007
@@ -409,17 +409,30 @@
#------------------------------------------------------------------------
sub format_filter_factory {
- my ($context, $format) = @_;
- $format = '%s' unless defined $format;
+ my ($context, @format) = @_;
+ $format[0] = '%s' unless @format;
return sub {
my $text = shift;
$text = '' unless defined $text;
- return join("\n", map{ sprintf($format, $_) } split(/\n/, $text));
+
+ # If the format string contains args (e.g., to specify the width
+ # with %*s) then we need to pass the args explicitly as separate
+ # arguments. This is because sprintf() is prototyped as '$@',
+ # so passing an array of format args as the first parameter will
+ # simply convert the array to a scalar (giving the size of the
+ # array), rather than using the array contents.
+
+ if(@format > 1) {
+ return join("\n", map{ sprintf($format[0], @format[1 .. $#format],
+ $_) } split(/\n/, $text));
+ } else {
+ return join("\n", map{ sprintf($format[0], $_) } split(/\n/,
$text))
+;
+ }
}
}
-
#------------------------------------------------------------------------
# repeat_filter_factory($n) [% FILTER repeat(n) %]
#
@@ -980,6 +993,15 @@
<!-- This is a block of text filtered -->
<!-- through the above format. -->
+
+If the printf() format expects extra parameters (e.g., C<%*s>) provide
+them in the argument list.
+
+ [% "foo" FILTER format('<%*s>', 6) %]
+
+output:
+
+ < foo>
=head2 upper
--- format.t.org Wed Feb 7 17:34:31 2007
+++ format.t Wed Feb 7 17:35:01 2007
@@ -84,4 +84,7 @@
-- expect --
alpha - bravo
-
+-- test --
+[% "foo" | format('<%*s>', 6) %]
+-- expect --
+< foo>