File Coverage

blib/lib/Data/Page/Set.pm
Criterion Covered Total %
statement 9 51 17.6
branch 0 20 0.0
condition 0 8 0.0
subroutine 3 13 23.0
pod 1 6 16.6
total 13 98 13.2


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package Data::Page::Set;
4              
5             =head1 NAME
6              
7             Data::Page::Set - Print page indexes
8              
9             =head1 SYNOPSIS
10              
11             use Data::Page;
12             use Data::Page::Set;
13              
14             my @data = 0 .. 300;
15             my $page = Data::Page->new( scalar @data, 5, shift );
16             my $pageset = Data::Page::Set->new( $page, 6, {} );
17              
18             print $pageset->show;
19              
20             =head1 DESCRIPTION
21              
22             =head2 Data::Page::Set->new( $page, $setsize, $showhash );
23              
24             =head4 Arguments
25              
26             =over 4
27              
28             =item C<$page> [Required]
29              
30             A Data::Page object.
31              
32             =item C<$setsize> [Required]
33              
34             The size of the pageset:
35             If you have a page object with 20 pages,
36             but you only want to show
37              
38             BE> B> B<4> B<5> 6 B<7> B<8> B> BE>
39              
40             Then setsize should be 5 because we're only
41             showing 5 page indexes.
42              
43             =item C<$showhash>
44              
45             A hash with zero or more of the following keys,
46             with a coderef as value wich is executed when we are about to print:
47              
48             =over 4
49              
50             =item show_first
51              
52             link to the first page
53              
54             =item show_no_first
55              
56             no link to the first page
57              
58             =item show_prev
59              
60             previous page link
61              
62             =item show_no_prev
63              
64             no link to the previous
65              
66             =item show_next
67              
68             next page link
69              
70             =item show_no_next
71              
72             No next page link
73              
74             =item show_last
75              
76             Last page link
77              
78             =item show_no_last
79              
80             No last page link
81              
82             =item show_page
83              
84             A link to another page
85              
86             =item show_current_page
87              
88             The current page
89              
90             =item grepper
91              
92             Executed in grep { $code->($_) } before the result is joined
93              
94             =item joiner
95              
96             Executed and used as the first argument to join
97              
98             =back
99              
100             =cut
101              
102 1     1   3180 use strict;
  1         3  
  1         37  
103 1     1   5 use warnings;
  1         2  
  1         34  
104 1     1   16 use vars qw($VERSION);
  1         2  
  1         1256  
105              
106             $VERSION = '0.04';
107              
108             my $code = {
109             show_first => sub { qq(<<First) },
110             show_no_first => sub { qq() },
111             show_prev => sub { qq(<Previous) },
112             show_no_prev => sub { qq() },
113             show_next => sub { qq(>Next) },
114             show_no_next => sub { qq() },
115             show_last => sub { qq(>>Last) },
116             show_no_last => sub { qq() },
117             show_page => sub { qq($_[0]) },
118             show_current_page => sub { qq($_[0]) },
119             joiner => sub { qq( \n) },
120             grepper => sub { length $_[0] },
121             };
122              
123             sub new {
124 0     0 1   my $class = shift;
125 0           my $pager = shift;
126 0   0       my $setsize = shift || 10;
127 0           my $show = shift;
128              
129 0           for my $key ( keys %$code ) {
130 0 0 0       $show->{$key} = $code->{$key}
131             unless exists $show->{$key}
132             and ref $show->{$key} eq 'CODE';
133             }
134              
135 0           my $self = bless {
136             pager => $pager,
137             show => $show,
138             setsize => $setsize,
139             }, $class;
140              
141 0           return $self;
142             }
143              
144             sub show {
145 0     0 0   my $self = shift;
146 0   0       my $show = shift || $self->{show};
147 0           my $pager = $self->{pager};
148              
149 0           return join $show->{joiner}->(),
150 0 0         grep( { $show->{grepper}->($_) } (
151             $self->page_in_set($pager->first_page)
152             ? $show->{show_no_first}->($pager->first_page, $pager)
153             : $show->{show_first}->($pager->first_page, $pager),
154             $pager->current_page == $pager->first_page
155             ? $show->{show_no_prev}-> ($pager->previous_page, $pager)
156             : $show->{show_prev}->($pager->previous_page, $pager),
157             (map
158             {
159 0 0         $_ == $pager->current_page
    0          
    0          
    0          
160             ? $show->{show_current_page}->( $_, $pager )
161             : $show->{show_page}->( $_, $pager )
162             } $self->pages_in_set()
163             ),
164             $pager->current_page == $pager->last_page
165             ? $show->{show_no_next}->($pager->next_page, $pager)
166             : $show->{show_next}->($pager->next_page, $pager),
167             $self->page_in_set($pager->last_page)
168             ? $show->{show_no_last}->($pager->last_page, $pager)
169             : $show->{show_last}->($pager->last_page, $pager),
170             ));
171             }
172              
173             sub pages_in_set {
174 0     0 0   my $self = shift;
175              
176 0           my $cur = $self->{pager}->current_page;
177 0           my $len = $self->{setsize};
178 0           my $first = $self->{pager}->first_page;
179 0           my $last = $self->{pager}->last_page;
180              
181 0           my $pre;
182 0     0     my $post = sub { $len - $pre - 1 };
  0            
183 0     0     my $size = sub { $last - $first };
  0            
184 0     0     my $first_show = sub { $cur - $pre };
  0            
185 0     0     my $last_show = sub { $cur + $post->() };
  0            
186              
187 0 0         return $first .. $last if $len > $size->();
188              
189 0 0         $pre = $len % 2 ? int $len / 2 : int( ($len - 1) / 2 );
190              
191 0 0         $pre = $last_show->() > $last ? -$last + $cur + $len - 1
    0          
192             : $first_show->() < $first ? -$first + $cur
193             : $pre;
194              
195 0           return $first_show->() .. $last_show->();
196             }
197              
198             sub page_in_set {
199 0     0 0   my $self = shift;
200 0           my $page = shift;
201              
202 0           return scalar grep
203 0           { $_ == $page }
204             $self->pages_in_set;
205             }
206              
207             sub page_before_view {
208 0     0 0   my $self = shift;
209 0           my @in_view = $self->pages_in_set;
210              
211 0           return $in_view[0] - 1;
212             }
213              
214             sub page_after_view {
215 0     0 0   my $self = shift;
216 0           my @in_view = $self->pages_in_set;
217              
218 0           return $in_view[-1] + 1;
219             }
220              
221             =head1 HISTORY
222              
223             0.02: Previous and next are show when current page
224             not is first and last resp.
225              
226             0.04: perl-5.6.1 compatible, tests added
227              
228             =head1 TODO
229              
230             =over 4
231              
232             =item * Improve joiner/grepper
233              
234             Joiner and grepper could be replaced with one routine that
235             constructs the return value.
236              
237             =item * Generic backend
238              
239             Data::Page is atm the only pager supported, but we could
240             do better than that.
241              
242             =back
243              
244             =head1 AUTHOR
245              
246             Berik Visschers
247              
248             =head1 COPYRIGHT
249              
250             Copyright 2005 by Berik Visschers Eberikv@xs4all.nlE.
251              
252             This program is free software; you can redistribute it and/or
253             modify it under the same terms as Perl itself.
254              
255             See F
256              
257             =cut
258              
259             1