blib/lib/WWW/Slides/SlideShow.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 109 | 154 | 70.7 |
branch | 28 | 50 | 56.0 |
condition | 3 | 3 | 100.0 |
subroutine | 20 | 25 | 80.0 |
pod | 0 | 13 | 0.0 |
total | 160 | 245 | 65.3 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package WWW::Slides::SlideShow; | ||||||
2 | { | ||||||
3 | 6 | 6 | 39433 | use version; our $VERSION = qv('0.0.7'); | |||
6 | 13684 | ||||||
6 | 37 | ||||||
4 | |||||||
5 | 6 | 6 | 584 | use warnings; | |||
6 | 12 | ||||||
6 | 196 | ||||||
6 | 6 | 6 | 36 | use strict; | |||
6 | 11 | ||||||
6 | 175 | ||||||
7 | 6 | 6 | 662 | use Carp; | |||
6 | 10 | ||||||
6 | 562 | ||||||
8 | 6 | 6 | 4554 | use English qw( -no_match_vars ); | |||
6 | 15443 | ||||||
6 | 44 | ||||||
9 | |||||||
10 | 6 | 6 | 11352 | use Object::InsideOut; | |||
6 | 349795 | ||||||
6 | 45 | ||||||
11 | |||||||
12 | # Other recommended modules (uncomment to use): | ||||||
13 | # use IO::Prompt; | ||||||
14 | # use Perl6::Export; | ||||||
15 | # use Perl6::Slurp; | ||||||
16 | # use Perl6::Say; | ||||||
17 | # use Regexp::Autoflags; | ||||||
18 | # use Readonly; | ||||||
19 | |||||||
20 | # Module implementation here | ||||||
21 | my @filename : Field # File to read for slides | ||||||
22 | : Get(Name => 'filename') # Public getter | ||||||
23 | : Std(Name => 'filename', Private => 1); | ||||||
24 | |||||||
25 | my @preamble : Field # HTML/whatever preamble | ||||||
26 | : Std(Name => 'preamble'); | ||||||
27 | my @slides : Field # slide repository | ||||||
28 | : Std(Name => 'slides', Private => 1); | ||||||
29 | my @postamble : Field # HTML/whatever postamble | ||||||
30 | : Std(Name => 'postamble'); | ||||||
31 | |||||||
32 | sub read_line_by_line : Private { | ||||||
33 | 5 | 203 | my $self = shift; | ||||
34 | 5 | 9 | my ($iterator) = @_; | ||||
35 | |||||||
36 | 5 | 9 | my $preamble; | ||||
37 | 5 | 17 | while (defined $iterator->()) { | ||||
38 | 97 | 136 | $preamble .= $_; | ||||
39 | 97 | 100 | 259 | last if / | |||
40 | } | ||||||
41 | 5 | 162 | $self->set_preamble($preamble); | ||||
42 | |||||||
43 | 5 | 280 | my @slides; | ||||
44 | 5 | 14 | my $slide = ''; | ||||
45 | 5 | 8 | my $div_id = ''; | ||||
46 | 5 | 10 | my $div_depth = 0; | ||||
47 | 5 | 8 | my $div_mark = 0; | ||||
48 | 5 | 10 | my $postamble = ''; | ||||
49 | 5 | 15 | while (defined $iterator->()) { | ||||
50 | 12 | 50 | 36 | if (m{}mxsi) { | |||
51 | 0 | 0 | $postamble = $_; | ||||
52 | 0 | 0 | last; | ||||
53 | } | ||||||
54 | 12 | 19 | $slide .= $_; | ||||
55 | 12 | 100 | 60 | if (m{ ]*\sid="([^"]*)"}mxsi) { |
|||
50 | |||||||
56 | 6 | 16 | $div_id = $1; | ||||
57 | 6 | 12 | $div_mark = $div_depth++; | ||||
58 | } | ||||||
59 | elsif (m{ | ||||||
60 | 0 | 0 | ++$div_depth; | ||||
61 | } | ||||||
62 | 12 | 100 | 39 | if (m{}mxsi) { | |||
63 | 6 | 50 | 18 | if (--$div_depth == $div_mark) { | |||
64 | 6 | 22 | push @slides, {div_id => $div_id, slide => $slide}; | ||||
65 | 6 | 10 | $slide = ''; | ||||
66 | 6 | 15 | $div_id = ''; | ||||
67 | } | ||||||
68 | } ## end if (m{}mxsi) | ||||||
69 | } ## end while (defined $iterator->... | ||||||
70 | 5 | 163 | $self->set_slides(\@slides); | ||||
71 | |||||||
72 | 5 | 337 | $self->set_postamble($postamble . join('', $iterator->())); | ||||
73 | |||||||
74 | 5 | 48 | return; | ||||
75 | 6 | 6 | 2857 | } ## end sub read_line_by_line : | |||
6 | 13 | ||||||
6 | 36 | ||||||
76 | |||||||
77 | sub read_fh : Private { | ||||||
78 | 5 | 245 | my $self = shift; | ||||
79 | 5 | 11 | my ($fh) = @_; | ||||
80 | |||||||
81 | return $self->read_line_by_line( | ||||||
82 | sub { | ||||||
83 | 122 | 100 | 457 | return <$fh> if wantarray; | |||
84 | 117 | 443 | return $_ = <$fh>; | ||||
85 | } | ||||||
86 | 5 | 44 | ); | ||||
87 | 6 | 6 | 1844 | } ## end sub read_fh : | |||
6 | 15 | ||||||
6 | 30 | ||||||
88 | |||||||
89 | sub read { | ||||||
90 | 5 | 5 | 0 | 58840 | my $self = shift; | ||
91 | 5 | 17 | my ($what) = @_; | ||||
92 | |||||||
93 | 5 | 50 | 29 | croak "undefined file to read slide show" unless defined $what; | |||
94 | |||||||
95 | 5 | 11 | my ($fh, $was_mine); | ||||
96 | 5 | 100 | 30 | if (ref $what eq 'SCALAR') { # Straight string, in-memory handle | |||
100 | |||||||
50 | |||||||
97 | 3 | 97 | $self->set_filename(' |
||||
98 | 3 | 50 | 3 | 226 | eval { open $fh, '<', $what or die }; # The perl 5.8 way... | ||
3 | 118 | ||||||
3 | 29 | ||||||
3 | 7 | ||||||
3 | 26 | ||||||
99 | |||||||
100 | 3 | 50 | 4982 | if ($EVAL_ERROR) { # Try to use IO::String, if available... | |||
101 | 0 | 0 | eval { | ||||
102 | 0 | 0 | require IO::String; | ||||
103 | 0 | 0 | $fh = IO::String->new($$what); | ||||
104 | }; | ||||||
105 | } ## end if ($EVAL_ERROR) | ||||||
106 | |||||||
107 | # I really wouldn't fall back to this, because I've to | ||||||
108 | # split it all in advance, but this is the best I can think | ||||||
109 | # at the moment | ||||||
110 | 3 | 50 | 15 | if ($EVAL_ERROR) { | |||
111 | |||||||
112 | # split and re-insert newlines. I don't really mind that | ||||||
113 | # I could potentially add a newline to the final line. | ||||||
114 | 0 | 0 | my @lines = map { "$_\n" } split /\n/, $$what; | ||||
0 | 0 | ||||||
115 | return $self->read_line_by_line( | ||||||
116 | sub { | ||||||
117 | 0 | 0 | 0 | 0 | return splice @lines if wantarray; | ||
118 | 0 | 0 | return $_ = shift @lines; | ||||
119 | } | ||||||
120 | 0 | 0 | ); | ||||
121 | } ## end if ($EVAL_ERROR) | ||||||
122 | |||||||
123 | 3 | 9 | $was_mine = 1; | ||||
124 | } ## end if (ref $what eq 'SCALAR') | ||||||
125 | elsif (ref $what eq 'GLOB') { | ||||||
126 | 1 | 33 | $self->set_filename(' |
||||
127 | 1 | 77 | $fh = $what; | ||||
128 | } | ||||||
129 | elsif (ref $what eq 'ARRAY') { # One file per slide | ||||||
130 | 0 | 0 | $self->set_filename(' |
||||
131 | 0 | 0 | return $self->read_slides(@$what); | ||||
132 | } | ||||||
133 | else { | ||||||
134 | 1 | 37 | $self->set_filename($what); | ||||
135 | 1 | 50 | 125 | open $fh, '<', $what | |||
136 | or croak "can't open('$what'): $OS_ERROR"; | ||||||
137 | 1 | 3 | $was_mine = 1; | ||||
138 | } ## end else [ if (ref $what eq 'SCALAR') | ||||||
139 | |||||||
140 | 5 | 31 | my $retval = $self->read_fh($fh); | ||||
141 | 5 | 100 | 44 | close $fh if $was_mine; | |||
142 | |||||||
143 | 5 | 33 | return $retval; | ||||
144 | } ## end sub read | ||||||
145 | |||||||
146 | sub read_slides { | ||||||
147 | 0 | 0 | 0 | 0 | my $self = shift; | ||
148 | |||||||
149 | 0 | 0 | $self->set_preamble(' | ||||
150 | |||||||
151 | "http://www.w3.org/TR/html4/loose.dtd"> | ||||||
152 | |||||||
153 | |||||||
154 | |
||||||
155 | |||||||
156 | |||||||
157 | '); | ||||||
158 | |||||||
159 | 0 | 0 | $self->set_postamble("\n\n"); | ||||
160 | |||||||
161 | 0 | 0 | my @slides; | ||||
162 | 0 | 0 | for my $filename (@_) { | ||||
163 | 0 | 0 | my $text = $self->read_slide($filename); | ||||
164 | 0 | 0 | my $div_id = 'slide' . scalar @slides; | ||||
165 | 0 | 0 | push @slides, | ||||
166 | { | ||||||
167 | div_id => $div_id, | ||||||
168 | slide => qq{\n \n" |
||||||
169 | }; | ||||||
170 | } ## end for my $filename (@_) | ||||||
171 | 0 | 0 | $self->set_slides(\@slides); | ||||
172 | 0 | 0 | return 1; | ||||
173 | } ## end sub read_slides | ||||||
174 | |||||||
175 | sub read_slide { # append a slide | ||||||
176 | 0 | 0 | 0 | 0 | my $self = shift; | ||
177 | 0 | 0 | my ($filename) = @_; | ||||
178 | 0 | 0 | require HTML::Parser; | ||||
179 | 0 | 0 | 0 | my $parser = HTML::Parser->new(api_version => 3) or die $!; | |||
180 | |||||||
181 | 0 | 0 | my $text = ''; | ||||
182 | my $start_handler = sub { | ||||||
183 | 0 | 0 | 0 | my ($tag, $self) = @_; | |||
184 | 0 | 0 | 0 | return unless lc($tag) eq 'body'; | |||
185 | 0 | 0 | $self->handler(default => sub { $text .= shift }, 'text'); | ||||
0 | 0 | ||||||
186 | 0 | 0 | $self->handler(start => sub { $text .= shift }, 'text'); | ||||
0 | 0 | ||||||
187 | $self->handler( | ||||||
188 | end => sub { | ||||||
189 | 0 | 0 | my ($tagname, $self, $newtext) = @_; | ||||
190 | 0 | 0 | 0 | if (lc($tagname) eq 'body') { | |||
191 | 0 | 0 | $self->eof(); | ||||
192 | } | ||||||
193 | else { | ||||||
194 | 0 | 0 | 0 | $text .= $newtext if defined $newtext; | |||
195 | } | ||||||
196 | }, | ||||||
197 | 0 | 0 | 'tagname,self,text' | ||||
198 | ); | ||||||
199 | 0 | 0 | }; | ||||
200 | 0 | 0 | $parser->handler(start => $start_handler, 'tagname,self'); | ||||
201 | |||||||
202 | 0 | 0 | 0 | $parser->parse_file($filename) | |||
203 | or die "could not parse '$filename': $OS_ERROR"; | ||||||
204 | 0 | 0 | return $text; | ||||
205 | } ## end sub read_slide | ||||||
206 | |||||||
207 | sub add_headers { # Headers are ok for the moment | ||||||
208 | 0 | 0 | 0 | 0 | my $self = shift; | ||
209 | 0 | 0 | return; | ||||
210 | } | ||||||
211 | |||||||
212 | sub get_ping { | ||||||
213 | 1 | 1 | 0 | 1225 | return "\n"; | ||
214 | } | ||||||
215 | |||||||
216 | sub get_show_div { | ||||||
217 | 3 | 3 | 0 | 1990 | my $self = shift; | ||
218 | 3 | 6 | my ($slide_no) = @_; | ||||
219 | 3 | 8 | my $div_id = $self->_get_slide($slide_no)->{div_id}; | ||||
220 | 3 | 219 | return "\n"; | ||||
221 | } ## end sub get_show_div | ||||||
222 | |||||||
223 | sub get_hide_div { | ||||||
224 | 3 | 3 | 0 | 5 | my $self = shift; | ||
225 | 3 | 7 | my ($slide_no) = @_; | ||||
226 | 3 | 7 | my $div_id = $self->_get_slide($slide_no)->{div_id}; | ||||
227 | 3 | 204 | return "\n"; | ||||
228 | } ## end sub get_hide_div | ||||||
229 | |||||||
230 | sub get_slide { | ||||||
231 | 3 | 3 | 0 | 645 | my $self = shift; | ||
232 | 3 | 5 | my ($slide_no) = @_; | ||||
233 | 3 | 9 | return $self->_get_slide($slide_no)->{slide}; | ||||
234 | } | ||||||
235 | |||||||
236 | sub _get_slide { | ||||||
237 | 9 | 9 | 13 | my $self = shift; | |||
238 | 9 | 13 | my ($n) = @_; | ||||
239 | 9 | 255 | return $self->get_slides()->[$n - 1]; | ||||
240 | } | ||||||
241 | |||||||
242 | sub id_first { | ||||||
243 | 4 | 4 | 0 | 1425 | return 1; | ||
244 | } | ||||||
245 | |||||||
246 | sub id_last { | ||||||
247 | 2 | 2 | 0 | 592 | my $self = shift; | ||
248 | 2 | 5 | return scalar @{$self->get_slides()}; | ||||
2 | 54 | ||||||
249 | } | ||||||
250 | |||||||
251 | sub id_next { | ||||||
252 | 6 | 6 | 0 | 2275 | my $self = shift; | ||
253 | 6 | 9 | my ($id) = @_; | ||||
254 | 6 | 100 | 21 | return ($id + 1) if $self->validate_slide_id($id + 1); | |||
255 | 2 | 105 | return $id; | ||||
256 | } ## end sub id_next | ||||||
257 | |||||||
258 | sub id_previous { | ||||||
259 | 3 | 3 | 0 | 1679 | my $self = shift; | ||
260 | 3 | 6 | my ($id) = @_; | ||||
261 | 3 | 100 | 8 | return ($id - 1) if $self->validate_slide_id($id - 1); | |||
262 | 1 | 3 | return $id; | ||||
263 | } ## end sub id_previous | ||||||
264 | |||||||
265 | sub validate_slide_id { | ||||||
266 | 9 | 9 | 0 | 12 | my $self = shift; | ||
267 | 9 | 11 | my ($id) = @_; | ||||
268 | 9 | 50 | 51 | return if $id !~ /\A\d+\z/; | |||
269 | 9 | 100 | 35 | return ($id > 0) && ($id <= @{$self->get_slides()}); | |||
270 | } ## end sub validate_slide_id | ||||||
271 | |||||||
272 | } | ||||||
273 | |||||||
274 | 1; # Magic true value required at end of module | ||||||
275 | __END__ |