File Coverage

blib/lib/Tenjin/Util.pm
Criterion Covered Total %
statement 18 68 26.4
branch 0 16 0.0
condition 0 2 0.0
subroutine 8 20 40.0
pod 13 13 100.0
total 39 119 32.7


line stmt bran cond sub pod time code
1             package Tenjin::Util;
2              
3 7     7   44 use strict;
  7         12  
  7         239  
4 7     7   39 use warnings;
  7         13  
  7         164  
5 7     7   6667 use HTML::Entities;
  7         57735  
  7         10967  
6              
7             our $VERSION = "0.070001";
8             $VERSION = eval $VERSION;
9              
10             =head1 NAME
11              
12             Tenjin::Util - Utility methods for Tenjin.
13              
14             =head1 VERSION
15              
16             version 0.070001
17              
18             =head1 SYNOPSIS
19              
20             # in your templates:
21            
22             # encode a URL
23             [== encode_url('http://www.google.com/search?q=tenjin&ie=utf-8&oe=utf-8&aq=t') =]
24             # returns http%3A//www.google.com/search%3Fq%3Dtenjin%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt
25              
26             # escape a string of lines of HTML code
27             You & Me\n

Me & You

'; ?>
28             [== text2html($string) =]
29             # returns <h1>You & Me</h1>
\n<h2>Me & You</h2>
30              
31             =head1 DESCRIPTION
32              
33             This module provides a few utility functions which can be used in your
34             templates for your convenience. These include functions to (un)escape
35             and (en/de)code URLs.
36              
37             =head1 METHODS
38              
39             =head2 expand_tabs( $str, [$tabwidth] )
40              
41             Receives a string that might contain tabs in it, and replaces those
42             tabs with spaces, each tab with the number of spaces defined by C<$tabwidth>,
43             or, if C<$tabwidth> was not passed, with 8 spaces.
44              
45             =cut
46              
47             sub expand_tabs {
48 0     0 1 0 my ($str, $tabwidth) = @_;
49              
50 0   0     0 $tabwidth ||= 8;
51 0         0 my $s = '';
52 0         0 my $pos = 0;
53 0         0 while ($str =~ /.*?\t/sg) { # /(.*?)\t/ may be slow
54 0         0 my $end = $+[0];
55 0         0 my $text = substr($str, $pos, $end - 1 - $pos);
56 0         0 my $n = rindex($text, "\n");
57 0 0       0 my $col = $n >= 0 ? length($text) - $n - 1 : length($text);
58 0         0 $s .= $text;
59 0         0 $s .= ' ' x ($tabwidth - $col % $tabwidth);
60 0         0 $pos = $end;
61             }
62 0         0 my $rest = substr($str, $pos);
63 0         0 return $s;
64             }
65              
66             =head2 escape_xml( $str )
67              
68             Receives a string of XML (or (x)HTML) code and converts the characters
69             <>&\' to HTML entities. This is the method that is invoked when you use
70             [= $expression =] in your templates.
71              
72             =cut
73              
74             sub escape_xml {
75 1     1 1 28 encode_entities($_[0], '<>&"\'');
76             }
77              
78             =head2 unescape_xml( $str )
79              
80             Receives a string of escaped XML (or (x)HTML) code (for example, a string
81             that was escaped with the L function,
82             and 'unescapes' all HTML entities back to their actual characters.
83              
84             =cut
85              
86             sub unescape_xml {
87 1     1 1 407 decode_entities($_[0]);
88             }
89              
90             =head2 encode_url( $url )
91              
92             Receives a URL and encodes it by escaping 'non-standard' characters.
93              
94             =cut
95              
96             sub encode_url {
97 1     1 1 9 my $url = shift;
98              
99 1         7 $url =~ s/([^-A-Za-z0-9_.\/])/sprintf("%%%02X", ord($1))/sge;
  9         31  
100 1         3 $url =~ tr/ /+/;
101 1         4 return $url;
102             }
103              
104             =head2 decode_url( $url )
105              
106             Does the opposite of L.
107              
108             =cut
109              
110             sub decode_url {
111 0     0 1 0 my $url = shift;
112              
113 0         0 $url =~ s/\%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/sge;
  0         0  
114 0         0 return $url;
115             }
116              
117             =head2 checked( $val )
118              
119             Receives a value of some sort, and if it is a true value, returns the string
120             ' checked="checked"' which can be appended to HTML checkboxes.
121              
122             =cut
123              
124             sub checked {
125 0 0   0 1 0 $_[0] ? ' checked="checked"' : '';
126             }
127              
128             =head2 selected( $val )
129              
130             Receives a value of some sort, and if it is a true value, returns the string
131             ' selected="selected"' which can be used in an option in an HTML select box.
132              
133             =cut
134              
135             sub selected {
136 0 0   0 1 0 $_[0] ? ' selected="selected"' : '';
137             }
138              
139             =head2 disabled( $val )
140              
141             Receives a value of some sort, and if it is a true value, returns the string
142             ' disabled="disabled"' which can be used in an HTML input.
143              
144             =cut
145              
146             sub disabled {
147 0 0   0 1 0 $_[0] ? ' disabled="disabled"' : '';
148             }
149              
150             =head2 nl2br( $text )
151              
152             Receives a string of text containing lines delimited by newline characters
153             (\n, or possibly \r\n) and appends an HTML line break (
) to every
154             line (the newline character is left untouched).
155              
156             =cut
157              
158             sub nl2br {
159 0     0 1 0 my $text = shift;
160              
161 0         0 $text =~ s/(\r?\n)/
$1/g;
162 0         0 return $text;
163             }
164              
165             =head2 text2html( $text )
166              
167             Receives a string of text containing lines delimited by newline characters,
168             and possibly some XML (or (x)HTML) code, escapes that code with
169             L and then appends an HTML line break
170             to every line with L.
171              
172             =cut
173              
174             sub text2html {
175 0     0 1 0 nl2br(escape_xml($_[0]));
176             }
177              
178             =head2 tagattr( $name, $expr, [$value] )
179              
180             =cut
181              
182             sub tagattr {
183 0     0 1 0 my ($name, $expr, $value) = @_;
184              
185 0 0       0 return '' unless $expr;
186 0 0       0 $value = $expr unless defined $value;
187 0         0 return " $name=\"$value\"";
188             }
189              
190             =head2 tagattrs( %attrs )
191              
192             =cut
193              
194             sub tagattrs {
195 0     0 1 0 my (%attrs) = @_;
196              
197 0         0 my $s = '';
198 0         0 while (my ($k, $v) = each %attrs) {
199 0 0       0 $s .= " $k=\"".escape_xml($v)."\"" if defined $v;
200             }
201 0         0 return $s;
202             }
203              
204             =head2 new_cycle( @items )
205              
206             Creates a subroutine reference that can be used for cycling through the
207             items of the C<@items> array. So, for example, you can:
208              
209             my $cycle = new_cycle(qw/red green blue/);
210             print $cycle->(); # prints 'red'
211             print $cycle->(); # prints 'green'
212             print $cycle->(); # prints 'blue'
213             print $cycle->(); # prints 'red' again
214              
215             =cut
216              
217             sub new_cycle {
218 0     0 1 0 my $i = 0;
219 0     0   0 sub { $_[$i++ % scalar @_] }; # returns
  0         0  
220             }
221              
222             =head1 INTERNAL(?) METHODS
223              
224             =head2 _p( $expression )
225              
226             Wraps a Perl expression in a customized wrapper which will be processed
227             by the Tenjin preprocessor and replaced with the standard [== $expression =].
228              
229             =cut
230              
231             sub _p {
232 1     1   19 "<`\#$_[0]\#`>";
233             }
234              
235             =head2 _P( $expression )
236              
237             Wrap a Perl expression in a customized wrapper which will be processed
238             by the Tenjin preprocessor and replaced with the standard [= $expression =],
239             which means the expression will be escaped.
240              
241             =cut
242              
243             sub _P {
244 1     1   6 "<`\$$_[0]\$`>";
245             }
246              
247             =head2 _decode_params( $s )
248              
249             =cut
250              
251             sub _decode_params {
252 0     0     my $s = shift;
253              
254 0 0         return '' unless $s;
255              
256 0           $s =~ s/%3C%60%23(.*?)%23%60%3E/'[=='.decode_url($1).'=]'/ge;
  0            
257 0           $s =~ s/%3C%60%24(.*?)%24%60%3E/'[='.decode_url($1).'=]'/ge;
  0            
258 0           $s =~ s/<`\#(.*?)\#`>/'[=='.unescape_xml($1).'=]'/ge;
  0            
259 0           $s =~ s/<`\$(.*?)\$`>/'[='.unescape_xml($1).'=]'/ge;
  0            
260 0           $s =~ s/<`\#(.*?)\#`>/[==$1=]/g;
261 0           $s =~ s/<`\$(.*?)\$`>/[=$1=]/g;
262              
263 0           return $s;
264             }
265              
266             1;
267              
268             =head1 SEE ALSO
269              
270             L, L, L.
271              
272             =head1 AUTHOR
273              
274             The CPAN version of Tenjin was forked by Ido Perlmuter Eido at ido50.netE
275             from version 0.0.2 of the original plTenjin, which is developed by Makoto Kuwata
276             at L.
277              
278             Development of Tenjin is done with github at L.
279              
280             =head1 LICENSE AND COPYRIGHT
281              
282             Tenjin is licensed under the MIT license.
283              
284             Copyright (c) 2007-2010 the aforementioned authors.
285              
286             Permission is hereby granted, free of charge, to any person obtaining
287             a copy of this software and associated documentation files (the
288             "Software"), to deal in the Software without restriction, including
289             without limitation the rights to use, copy, modify, merge, publish,
290             distribute, sublicense, and/or sell copies of the Software, and to
291             permit persons to whom the Software is furnished to do so, subject to
292             the following conditions:
293              
294             The above copyright notice and this permission notice shall be
295             included in all copies or substantial portions of the Software.
296              
297             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
298             EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
299             MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
300             NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
301             LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
302             OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
303             WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
304              
305             =cut