File Coverage

blib/lib/Text/Context/EitherSide.pm
Criterion Covered Total %
statement 52 55 94.5
branch 14 18 77.7
condition 3 3 100.0
subroutine 11 12 91.6
pod 6 6 100.0
total 86 94 91.4


line stmt bran cond sub pod time code
1             package Text::Context::EitherSide;
2              
3 1     1   1645 use 5.006;
  1         4  
  1         42  
4 1     1   6 use strict;
  1         2  
  1         38  
5 1     1   22 use warnings;
  1         2  
  1         37  
6 1     1   5 use Carp;
  1         2  
  1         112  
7              
8             our $VERSION = '1.4';
9              
10 1     1   6 use base 'Exporter';
  1         1  
  1         129  
11             our @EXPORT_OK = qw(get_context);
12              
13 1     1   4 use constant DEFAULT_WORDS => 2;
  1         2  
  1         687  
14              
15             sub get_context {
16 9     9 1 462 my ($n, $string, @words) = @_;
17 9         34 Text::Context::EitherSide->new($string, context => $n)->as_string(@words);
18             }
19              
20             sub new {
21 9     9 1 15 my $class = shift;
22 9 50       24 my $text = shift or carp "No text supplied for context search";
23 9         21 my %args = @_;
24              
25 9 50       74 return bless {
26             n => exists $args{context} ? $args{context} : DEFAULT_WORDS,
27             text => $text
28             }, $class;
29             }
30              
31             sub context {
32 0     0 1 0 my $self = shift;
33 0 0       0 $self->{n} = shift if @_;
34 0         0 return $self->{n};
35             }
36              
37             sub as_sparse_list {
38 9     9 1 12 my $self = shift;
39 9         19 my @words = @_;
40 19         62 my %keywords = map { lc $_ => 1 }
  17         43  
41 9         15 map { split /\s+/, $_ } @words; # Decouple phrases
42              
43             # First, split the string into words
44 9         49 my @split_s = split /\s+/, $self->{text};
45              
46             # Now, locate keywords and "mark" the indices we want.
47 9         28 my @marks = (undef) x @split_s;
48 9         15 my $ok = 0;
49 9         22 for (0 .. $#split_s) {
50 72         3500 my $word = lc $split_s[$_];
51 72         167 for my $subword (split /\W+/, $word) {
52 69 100       383 if (exists $keywords{$subword}) {
53 23         27 $ok++;
54              
55             # Mark it and its $n neighbours.
56 91 100       546 $marks[$_] = $split_s[$_]
57 23         67 for grep { $_ >= 0 and $_ <= $#split_s }
58             $_ - $self->{n} .. $_ + $self->{n};
59 23         55 last;
60             }
61             }
62             }
63              
64 9 100       1226 return $ok ? @marks : ();
65             }
66              
67             sub as_list {
68 9     9 1 12 my $self = shift;
69 9         19 my @sparse = $self->as_sparse_list(@_);
70 9 100       368 return () unless @sparse;
71 8         11 my @ret;
72 8         19 for (0 .. $#sparse) {
73 69 100       108 if (defined $sparse[$_]) {
74 46         84 push @ret, $sparse[$_];
75             } else {
76 23 100 100     174 push @ret, "..." unless @ret and $ret[-1] eq "...";
77             }
78             }
79 8         82 return @ret;
80             }
81              
82             sub as_string {
83 9     9 1 16 my $self = shift;
84 9         21 return join " ", $self->as_list(@_);
85             }
86              
87             1;
88             __END__