File Coverage

blib/lib/Text/Decorator/Filter/URIFind.pm
Criterion Covered Total %
statement 50 52 96.1
branch 4 8 50.0
condition 1 2 50.0
subroutine 9 10 90.0
pod 1 1 100.0
total 65 73 89.0


line stmt bran cond sub pod time code
1             package Text::Decorator::Filter::URIFind;
2              
3 1     1   6 use strict;
  1         3  
  1         42  
4              
5 1     1   6 use base 'Text::Decorator::Filter';
  1         2  
  1         198  
6              
7 1     1   6 use Carp;
  1         2  
  1         81  
8 1     1   7 use Text::Decorator::Group;
  1         2  
  1         8  
9 1     1   22 use Text::Decorator::Node;
  1         2  
  1         11  
10              
11             =head1 NAME
12              
13             Text::Decorator::Filter::URIFind - Turn URLs into links
14              
15             =head1 DESCRIPTION
16              
17             =head2 filter_node
18              
19             This filter uses the L module to mark up URLs as links.
20             You can also pass a classname as an argument to this filter, if you
21             prefer using C or whatever.
22              
23             =cut
24              
25             sub filter_node {
26 2     2 1 4 my ($class, $args, $node) = @_;
27              
28 2   50     11 my $urifind = shift(@$args) || "URI::Find";
29 2 50       14 $urifind->require or croak "Couldn't load $urifind";
30              
31 2         9058 my $uriRe = sprintf '(?:%s|%s)', $urifind->uri_re,
32             $urifind->schemeless_uri_re;
33              
34 2         58 my $orig = $node->format_as("html");
35 1 50   1   1174 return $node unless $orig =~ /$uriRe/;
  1         9  
  1         13  
  2         89  
36              
37 2         30752 my $group = Text::Decorator::Group->new();
38 2         11 $group->{representations}{text}{pre} = $node->format_as("text");
39 2         7 $group->{representations}{html}{pre} = "";
40 2         5 $group->{representations}{text}{post} = "";
41 2     0   22 $urifind = $urifind->new(sub {});
  0         0  
42 2         93 while ($orig =~ s{(.*?)(<$uriRe>|$uriRe)}{}sm) {
43 2         447 my $orig_match = $urifind->decruft($2);
44 2         60 $class->_add_text_node($group, $1 . $urifind->{start_cruft});
45 2 50       10 if (my $uri = $urifind->_is_uri(\$orig_match)) { # Its a URI.
46 2         11356 $class->_add_uri_group($group, $uri, $orig_match);
47             } else { # False alarm.
48 0         0 $class->_add_text_node($group, $orig_match);
49             }
50 2 50       58 $class->_add_text_node($group, $urifind->{end_cruft})
51             if $urifind->{end_cruft};
52             }
53 2         8 $class->_add_text_node($group, $orig);
54              
55 2         27 return $group;
56             }
57              
58             sub _add_text_node {
59 4     4   11 my ($class, $group, $text) = @_;
60 4         16 my $node = Text::Decorator::Node->new("");
61              
62             # Text representation is provided by group
63 4         12 $node->{representations}{html} = $text;
64 4         7 push @{ $group->{nodes} }, $node;
  4         11  
65             }
66              
67             sub _add_uri_group {
68 2     2   8 my ($class, $group, $uri, $text) = @_;
69 2         19 my $node = Text::Decorator::Node->new("");
70 2         8 $node->{representations}{html} = $text;
71              
72 2         12 my $subgroup = Text::Decorator::Group->new($node);
73 2         9 $subgroup->{representations}{html}{pre} = "";
74 2         20 $subgroup->{representations}{html}{post} = "";
75 2         4 push @{ $group->{nodes} }, $subgroup;
  2         7  
76             }
77              
78             1;