File Coverage

blib/lib/Pod/Example.pm
Criterion Covered Total %
statement 87 87 100.0
branch 30 32 93.7
condition 3 3 100.0
subroutine 14 14 100.0
pod 2 2 100.0
total 136 138 98.5


line stmt bran cond sub pod time code
1             package Pod::Example;
2              
3 4     4   121305 use base qw(Exporter);
  4         29  
  4         410  
4 4     4   23 use strict;
  4         5  
  4         63  
5 4     4   25 use warnings;
  4         7  
  4         108  
6              
7 4     4   773 use Error::Pure qw(err);
  4         19495  
  4         113  
8 4     4   1858 use Pod::Abstract;
  4         90886  
  4         112  
9 4     4   26 use Pod::Find qw(pod_where);
  4         8  
  4         212  
10 4     4   26 use Readonly;
  4         5  
  4         3259  
11              
12             # Constants.
13             Readonly::Array our @EXPORT_OK => qw(get sections);
14             Readonly::Scalar my $EMPTY_STR => q{};
15              
16             our $VERSION = 0.12;
17              
18             # Get content for file or module.
19             sub get {
20 16     16 1 10391 my ($file_or_module, $section, $number_of_example) = @_;
21              
22             # Get Pod::Abstract object.
23 16         31 my $pod_abstract = _pod_abstract($file_or_module);
24              
25             # Get section pod.
26 15         55302 my ($code, $example_filename) = _get_content($pod_abstract, $section, $number_of_example);
27              
28 15 100       221 return wantarray ? ($code, $example_filename) : $code;
29             }
30              
31             # Get example sections.
32             sub sections {
33 2     2 1 755 my ($file_or_module, $section) = @_;
34              
35             # Get Pod::Abstract object.
36 2         5 my $pod_abstract = _pod_abstract($file_or_module);
37              
38             # Get first section.
39 2         7068 my @pod_sections = _get_sections($pod_abstract, $section);
40              
41             # Get section names.
42 2         1180 my @sections = map { _get_section_name($_) } @pod_sections;
  2         5  
43              
44 2         29 return @sections;
45             }
46              
47             # Get content in Pod::Abstract object.
48             sub _get_content {
49 15     15   32 my ($pod_abstract, $section, $number_of_example) = @_;
50              
51             # Get first section.
52 15         38 my ($pod_section) = _get_sections($pod_abstract, $section,
53             $number_of_example);
54              
55             # No section.
56 15 100       9289 if (! defined $pod_section) {
57 1         3 return;
58             }
59              
60             # Remove #cut.
61 14         68 my @cut = $pod_section->select("//#cut");
62 14         3119 foreach my $cut (@cut) {
63 11         22 $cut->detach;
64             }
65              
66             # Get pod.
67 14         660 my $child_pod = $EMPTY_STR;
68 14         14 my $example_filename;
69 14         26 foreach my $child ($pod_section->children) {
70 18 100       274 if ($child->type eq 'begin') {
    100          
71              
72             # =begin text as commented text.
73 2 100       11 if ($child->body =~ m/^text/ms) {
74             $child_pod .= join "\n",
75 1         10 map { ' #'.$_ }
  6         60  
76             split m/\n/ms,
77             ($child->children)[0]->pod;
78              
79             # Skip =begin html and other unsupported sections.
80             } else {
81 1         9 next;
82             }
83             } elsif ($child->type eq 'for') {
84 1         12 my $body = $child->body;
85 1 50       10 if ($body =~ m/^comment\s*filename=([\w\.]+)\s*$/ms) {
86 1         4 $example_filename = $1;
87             }
88             } else {
89 15         140 $child_pod .= $child->pod;
90             }
91             }
92              
93             # Remove spaces and return.
94 14         531 my $ret = _remove_spaces($child_pod);
95              
96 14 50       65 return wantarray ? ($ret, $example_filename) : $ret;
97             }
98              
99             # Get section name.
100             # XXX Hack to structure.
101             sub _get_section_name {
102 2     2   3 my $pod_abstract_node = shift;
103             return $pod_abstract_node->{'params'}->{'heading'}->{'tree'}
104 2         7 ->{'nodes'}->[0]->{'body'};
105             }
106              
107             # Get sections.
108             sub _get_sections {
109 17     17   27 my ($pod_abstract, $section, $number_of_example) = @_;
110              
111             # Default section.
112 17 100       52 if (! $section) {
113 12         21 $section = 'EXAMPLE';
114             }
115              
116             # Concerete number of example.
117 17 100       54 if ($number_of_example) {
118 2         4 $section .= $number_of_example;
119              
120             # Number of example as potential number.
121             } else {
122 15         21 $section .= '\d*';
123             }
124              
125             # Get and return sections.
126 17         54 return $pod_abstract->select('/head1[@heading =~ {'.$section.'}]');
127             }
128              
129             # Get pod abstract for module.
130             sub _pod_abstract {
131 18     18   25 my $file_or_module = shift;
132              
133             # Module file.
134 18         21 my $file;
135 18 100       321 if (-r $file_or_module) {
136 14         35 $file = $file_or_module;
137              
138             # Module.
139             } else {
140 4         2065 $file = pod_where({ -inc => 1 }, $file_or_module);
141 4 100       23 if (! $file) {
142 1         9 err 'Cannot open pod file or Perl module.';
143             }
144             }
145              
146             # Get and return pod.
147 17         113 return Pod::Abstract->load_file($file);
148             }
149              
150             # Remove spaces from example.
151             sub _remove_spaces {
152 14     14   19 my $string = shift;
153 14         52 my @lines = split /\n/, $string;
154              
155             # Get number of spaces in begin.
156 14         19 my $max = 0;
157 14         20 foreach my $line (@lines) {
158 77 100       104 if (! length $line) {
159 15         21 next;
160             }
161 62         128 $line =~ m/^(\ +)/ms;
162 62         71 my $spaces = $EMPTY_STR;
163 62 100       110 if ($1) {
164 58         66 $spaces = $1;
165             }
166 62 100 100     153 if ($max == 0 || length $spaces < $max) {
167 18         26 $max = length $spaces;
168             }
169             }
170              
171             # Remove spaces.
172 14 100       22 if ($max > 0) {
173 13         15 foreach my $line (@lines) {
174 72 100       99 if (! length $line) {
175 14         19 next;
176             }
177 58         73 $line = substr $line, $max;
178             }
179             }
180              
181             # Return string.
182 14         43 return join "\n", @lines;
183             }
184              
185             1;
186              
187              
188             __END__