File Coverage

blib/lib/String/Template.pm
Criterion Covered Total %
statement 55 55 100.0
branch 28 28 100.0
condition 8 8 100.0
subroutine 11 11 100.0
pod 4 4 100.0
total 106 106 100.0


line stmt bran cond sub pod time code
1             package String::Template;
2              
3 2     2   472931 use strict;
  2         14  
  2         60  
4 2     2   10 use warnings;
  2         4  
  2         45  
5 2     2   50 use 5.008001;
  2         7  
6 2     2   12 use base 'Exporter';
  2         3  
  2         205  
7 2     2   15 use POSIX ();
  2         4  
  2         34  
8 2     2   1039 use Date::Parse;
  2         15534  
  2         2309  
9              
10             # ABSTRACT: Fills in string templates from hash of fields
11             our $VERSION = '0.22'; # VERSION
12              
13              
14             our @EXPORT = qw(expand_string missing_values expand_stringi);
15             our @EXPORT_OK = qw(expand_hash);
16             our %EXPORT_TAGS = ( all => [@EXPORT, @EXPORT_OK] );
17              
18             my %special =
19             (
20             '%' => sub { sprintf("%$_[0]", $_[1]) },
21              
22             ':' => sub { POSIX::strftime($_[0], localtime(str2time($_[1]))) },
23              
24             '!' => sub { POSIX::strftime($_[0], gmtime(str2time($_[1]))) },
25              
26             '#' => sub { my @args = split(/\s*,\s*/, $_[0]);
27             defined $args[1]
28             ? substr($_[1], $args[0], $args[1])
29             : substr($_[1], $args[0]) }
30             );
31              
32             my $specials = join('', keys %special);
33             my $specialre = qr/^([^{$specials]+)([{$specials])(.+)$/;
34             my $bracketre = qr/^([^$specials]*?)([{$specials])(.*?)(?
35              
36             $special{'{'} = sub {
37             my ($field, $replace) = @_;
38             $field =~ s/\\\}/}/g;
39             my ($pre, $key, $spec, $post) = $field =~ /$bracketre/;
40             $pre . $special{$key}($spec, $replace) . $post;
41             };
42              
43             #
44             # _replace($field, \%fields, $undef_flag)
45             #
46             # replace a single " or ""
47             # or ""
48             #
49             sub _replace
50             {
51 56     56   150 my ($field, $f, $undef_flag, $i_flag) = @_;
52              
53 56 100       332 if ($field =~ $specialre)
54             {
55 23 100       110 return ($undef_flag ? "<$field>" : '') unless defined $f->{($i_flag ? lc($1) : $1)};
    100          
    100          
56 18 100       96 return $special{$2}($3,$f->{($i_flag ? lc($1) : $1)});
57             }
58              
59 33 100       87 my $ifield = $i_flag ? lc $field : $field;
60 33 100       188 return defined $f->{$ifield} ? $f->{$ifield}
    100          
61             : ($undef_flag ? "<$field>" : '');
62             }
63              
64              
65             #
66             # expand_string($string, \%fields, $undef_flag)
67             # find ""
68             #
69             sub expand_string
70             {
71 38     38 1 21207 my ($string, $fields, $undef_flag) = @_;
72              
73 38         196 $string =~ s/<([^>]+)>/_replace($1, $fields, $undef_flag)/ge;
  34         279  
74              
75 38         1757 return $string;
76             }
77              
78              
79             sub expand_stringi
80             {
81 9     9 1 2923 my ($string, $fields, $undef_flag) = @_;
82 9         25 my %ifields = map { lc $_ => $fields->{$_} } keys %$fields;
  19         57  
83              
84 9         65 $string =~ s/<([^>]+)>/_replace($1, \%ifields, $undef_flag, 1)/gie;
  22         559  
85              
86 9         774 return $string;
87             }
88              
89              
90             sub missing_values
91             {
92 5     5 1 3969 my ($string, $fields, $dont_allow_undefs) = @_;
93 5         10 my @missing;
94              
95 5         83 while ($string =~ /<([^>$specials]+)(?:[$specials][^>]+)?>/g) {
96 12 100 100     70 next if exists($fields->{$1}) && (!$dont_allow_undefs || defined($fields->{$1}));
      100        
97 6         34 push @missing, $1;
98             }
99 5 100       21 return unless @missing;
100 3         15 return @missing;
101             }
102              
103              
104             sub expand_hash
105             {
106 4     4 1 6478 my ($hash, $maxdepth) = @_;
107              
108 4   100     21 $maxdepth ||= 10;
109              
110 4         7 my $changeflag = 1;
111 4         6 my $missing = 1;
112              
113 4         10 while ($changeflag)
114             {
115 7         11 $changeflag = 0;
116 7         8 $missing = 0;
117 7         26 foreach my $key (sort keys %$hash)
118             {
119 17         34 my $newstr = expand_string($hash->{$key}, $hash, 1);
120              
121 17 100       40 if ($newstr ne $hash->{$key})
122             {
123 6         9 $hash->{$key} = $newstr;
124 6         10 $changeflag = 1;
125             }
126 17 100       39 $missing++ if $newstr =~ /<[^>]+>/;
127             }
128 7 100       20 last unless --$maxdepth;
129             }
130 4 100       13 return $missing ? undef : 1;
131             }
132              
133             1;
134              
135             __END__