File Coverage

blib/lib/Pod/Example.pm
Criterion Covered Total %
statement 88 88 100.0
branch 30 30 100.0
condition 5 6 83.3
subroutine 14 14 100.0
pod 2 2 100.0
total 139 140 99.2


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