File Coverage

lib/Pod/Definitions/Heuristic.pm
Criterion Covered Total %
statement 61 72 84.7
branch 13 20 65.0
condition 1 2 50.0
subroutine 8 9 88.8
pod 3 3 100.0
total 86 106 81.1


line stmt bran cond sub pod time code
1             package Pod::Definitions::Heuristic;
2              
3 2     2   937 use Pod::Headings;
  2         5  
  2         70  
4             our $VERSION = '0.04';
5              
6 2     2   18 use v5.20;
  2         5  
7              
8 2     2   8 use strict;
  2         4  
  2         29  
9 2     2   8 use warnings;
  2         4  
  2         43  
10 2     2   8 use feature 'signatures';
  2         3  
  2         119  
11 2     2   10 no warnings 'experimental::signatures';
  2         16  
  2         2422  
12              
13             #
14             # Instantiation
15             #
16              
17 18     18 1 5131 sub new ($class, @args) {
  18         22  
  18         32  
  18         20  
18 18         38 my $self = {@args};
19 18         29 bless $self, $class;
20              
21 18         33 return $self;
22             }
23              
24             #
25             # Accessors
26             #
27              
28 0     0 1 0 sub text ($self, $new = undef) {
  0         0  
  0         0  
  0         0  
29 0 0       0 $self->{text} = $new if defined $new;
30 0         0 return $self->{text};
31             }
32              
33 18     18 1 47 sub clean ($self) {
  18         21  
  18         21  
34             # Clean headings for index display
35              
36             #
37             # TODO:
38             #
39             # Rewrite this as a series of filters, in the style of
40             # Mail::Filter, or iptables, where each filter's output is passed
41             # to the next in the chain, with the possibility of:
42             #
43             # - skipping the remainder of the chain with a final result (PASS)
44             # - skipping the remainder of the chain without saving (FAIL)
45             # - modifying the text (as iptables lets you modify a packet)
46             #
47             # TODO:
48             #
49             # - Perhaps an alternate heuristic for 'item' entries?
50             #
51              
52 18         23 my $original = $self->{text};
53 18         47 $original =~ s/^\s+//;
54 18         32 $original =~ s/\s(?:mean|go)\?$//;
55 18         33 $original =~ s/\?$//;
56              
57             # Remove arrows
58 18         33 $original =~ s/\s*=>.*//;
59 18         25 $original =~ s/^\s*\w+\s*->\s*//;
60              
61             # Which versions are supported -> Versions supported
62             # How much does... How well is... How many...
63 18         58 $original =~ s/^(?:(what|which|how|many|much|well|is|are|do)\s+)+(\S.*?)?\s+(?:is|are|do)\s+(.+)\z/\u$2, $3/i;
64 18         29 $original =~ s/\s{2,}/ /g;
65              
66             # What does the error "Oops" mean? -> Oops, error
67 18 100       49 if ($original =~ m/^(?:(?:what|do|does|a|an|the)\s+)+((?:error|message)\s+)"?(.*)\z/i) {
68 1         4 my ($prefix, $main) = ($1, ucfirst($2));
69 1         4 $main =~ s/[?"]//g;
70 1         2 $main =~ s/^\s+//;
71 1         2 $prefix =~ s/[?"]//g;
72 1         2 $prefix =~ s/\s+\z//;
73 1         5 return "$main, $prefix";
74             }
75              
76             # How can I blip the blop? -> Blip the blop, How can I
77             # Why doesn't my socket have a packet? -> Socket have a packet, Why doesn't my
78             # Where are the pockets on the port? -> Pockets on the port, Where are the
79 17 100       56 if ($original =~ m/^((?:(?:who|what|when|where|which|why|how|is|are|did|a|an|the|do|does|don't|doesn't|can|not|I|my|need|to|about|there|much|many)\s+|go\s+for|error\s+"\.*|message\s+"\.*)+)(.*)$/i) {
80 4         16 my ($prefix, $main) = ($1, ucfirst($2));
81 4         7 $main =~ s/[?"]//g;
82 4         6 $main =~ s/^\s+//;
83 4         5 $prefix =~ s/[?"]//g;
84 4         12 $prefix =~ s/\s+\z//;
85 4         69 return "$main, $prefix";
86             }
87             # Nibbling the carrot -> Carrot, nibbling the
88 13 100       40 if ($original =~ m/^(\w+ing(?:\s+and\s+\w+ing)?)\s+(a|an|the|some|any|all|to|from|your)?\b\s*(.*)$/) {
89 1         5 my ($verb, $qualifier, $remainder) = ($1, $2, $3);
90 1   50     2 $qualifier ||= '';
91             # print ucfirst("$remainder, $verb $qualifier\n");
92 1         8 return ucfirst("$remainder, $verb $qualifier");
93             }
94             # $variable=function_name(...) -> function_name
95 12 50       22 if ($original =~ m/^[\$@]\w+\s*=\s*(?:\$\w+\s*->\s*)?(\w+)/) {
96 0         0 return $1;
97             }
98             # $variable->function_name(...) -> function_name
99 12 100       22 if ($original =~ m/^\$?\w+\s*->\s*(\w+)/) {
100 2         15 return $1;
101             }
102             # Module::Module->function_name(...) -> function_name
103 10 50       19 if ($original =~ m/^\w+(?:::\w+)+\s*->\s*(\w+)/) {
104 0         0 return $1;
105             }
106             # function_name($args,...) -> function_name
107 10 50       15 if ($original =~ m/^(\w+)\s*\(\s*[\$@%]\w+/) {
108 0         0 return $1;
109             }
110             # ($var, $var) = function_name(...) -> function_name
111 10 50       15 if ($original =~ m/^\([\$@%][^)]+\)\s*=\s*(?:\$\w+\s*->\s*)?(\w+)/) {
112 0         0 return $1;
113             }
114             # function_name BLOCK LIST [EXPR] -> function_name
115 10 50       34 if ($original =~ m/^((?:\w|_)+)\s+(?:(?:BLOCK|EXPR|LIST|COUNT|ARRAY\d*|VALUE|STRING|ITEM|\.+)\s*)+/) {
116 0         0 return $1;
117             }
118 10         33 return $original;
119             }
120              
121             1;
122              
123             __END__