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