File Coverage

blib/lib/App/week.pm
Criterion Covered Total %
statement 50 160 31.2
branch 0 42 0.0
condition 0 22 0.0
subroutine 17 31 54.8
pod 0 13 0.0
total 67 268 25.0


line stmt bran cond sub pod time code
1             package App::week;
2             our $VERSION = "1.0303";
3              
4 1     1   743 use v5.14;
  1         3  
5 1     1   6 use warnings;
  1         1  
  1         26  
6              
7 1     1   656 use utf8;
  1         14  
  1         4  
8 1     1   676 use Encode;
  1         10707  
  1         70  
9 1     1   457 use Time::localtime;
  1         4980  
  1         61  
10 1     1   7 use List::Util qw(min max);
  1         2  
  1         94  
11 1     1   571 use Hash::Util qw(lock_keys);
  1         3022  
  1         5  
12 1     1   664 use Pod::Usage;
  1         41037  
  1         100  
13 1     1   593 use Data::Dumper;
  1         6699  
  1         64  
14 1     1   557 use open IO => ':utf8', ':std';
  1         1246  
  1         5  
15 1     1   681 use Getopt::EX::Colormap;
  1         23169  
  1         49  
16              
17 1     1   512 use App::week::Util;
  1         5  
  1         43  
18 1     1   478 use App::week::CalYear qw(@calyear);
  1         3  
  1         161  
19              
20             my @DOW_LABELS = qw(
21             DOW_SU
22             DOW_MO
23             DOW_TU
24             DOW_WE
25             DOW_TH
26             DOW_FR
27             DOW_SA
28             DOW_CW
29             );
30              
31             my %DEFAULT_COLORMAP = (
32             (), DAYS => "L05/335",
33             (), WEEK => "L05/445",
34             (), FRAME => "L05/445",
35             (), MONTH => "L05/335",
36             (), THISDAY => "522/113",
37             (), THISDAYS => "555/113",
38             (), THISWEEK => "L05/445",
39             (), THISMONTH => "555/113",
40             map { $_ => "" } @DOW_LABELS,
41             );
42              
43 1     1   536 use Getopt::EX::Hashed; {
  1         3761  
  1         6  
44              
45             Getopt::EX::Hashed->configure(DEFAULT => [ is => 'rw' ]);
46              
47             has ARGV => default => [];
48             has COLORMAP => ;
49             has CM => ;
50              
51             my($sec, $min, $hour, $mday, $mon, $year) = CORE::localtime(time);
52             has year => default => $year + 1900;
53             has mday => default => $mday;
54             has mon => default => $mon + 1;
55              
56             has cell_width => default => undef;
57             has frame => default => ' ';
58             has frame_height => default => 1;
59              
60             # option params
61             has help => ' h ' ;
62             has version => ' v ' ;
63             has months => ' m =i ' , default => 0;
64             has after => ' A :1 ' , min => 0;
65             has before => ' B :1 ' , min => 0, default => 1;
66             has center => ' C :4 ' , min => 0;
67             has column => ' c =i ' , min => 1, default => 3;
68             has colordump => ' ' ;
69             has colormap => ' =s@ cm ' , default => [];
70             has show_year => ' y ' ;
71             has years => ' Y :1 ' , max => 100;
72             has rgb24 => ' ! ' ;
73             has year_on_all => ' P ' ;
74             has year_on => ' p =i ' , min => 0, max => 12;
75             has config => ' =s% ' , default => {};
76             has weeknumber => ' W :1 ' ;
77              
78             has '+center' => sub {
79             $_->after = $_->before = $_[1];
80             };
81              
82             has '+weeknumber' => sub {
83             App::week::CalYear::Configure $_[0] => $_[1];
84             };
85              
86             has '+rgb24' => sub {
87             $Getopt::EX::Colormap::RGB24 = !!$_[1];
88             };
89              
90             has '+config' => sub {
91             App::week::CalYear::Configure $_[1] => $_[2];
92             };
93              
94             has '+help' => sub {
95             pod2usage
96             -verbose => 99,
97             -sections => [ qw(SYNOPSIS VERSION) ];
98             };
99              
100             has '+version' => sub {
101             print "Version: $VERSION\n";
102             exit;
103             };
104              
105             has "<>" => sub {
106             my $obj = $_;
107             local $_ = $_[0];
108             if (/^-+([0-9]+)$/) {
109             $obj->months = $1;
110             } elsif (/^-/) {
111             die "$_: Option error\n";
112             } else {
113             push @{$obj->ARGV}, $_;
114             }
115             };
116              
117 1     1   743 } no Getopt::EX::Hashed;
  1         2  
  1         5  
118              
119             sub color {
120 0     0 0   (+shift)->CM->color(@_);
121             }
122              
123             sub usage {
124 0     0 0   pod2usage(-verbose => 0, -exitval => "NOEXIT");
125 0           print "Version: $VERSION\n";
126 0           exit 2;
127             }
128              
129             sub run {
130 0     0 0   my $app = shift;
131 0           local @ARGV = decode_argv @_;
132              
133 0           $app->read_option()
134             ->argv()
135             ->deal_option()
136             ->prepare()
137             ->show();
138              
139 0           return 0;
140             }
141              
142             sub read_option {
143 0     0 0   my $app = shift;
144 1     1   776 use Getopt::EX::Long qw(:DEFAULT Configure ExConfigure);
  1         17553  
  1         670  
145 0           ExConfigure BASECLASS => [ "App::week", "Getopt::EX", "" ];
146 0           Configure qw(bundling no_getopt_compat no_ignore_case pass_through);
147 0 0         $app->getopt || usage;
148 0           return $app;
149             }
150              
151             sub argv {
152 0     0 0   my $app = shift;
153 0           for (@{$app->ARGV}) {
  0            
154 0           call \&guess_date,
155             for => $app,
156             with => [ qw(year mon mday show_year) ];
157             }
158 0           return $app;
159             }
160              
161             sub deal_option {
162 0     0 0   my $app = shift;
163              
164             # load --colormap option
165 0           my %colormap = %DEFAULT_COLORMAP;
166 0           $app->COLORMAP(\%colormap);
167             $app->CM(Getopt::EX::Colormap->new(HASH => \%colormap)
168 0           ->load_params(@{$app->colormap}));
  0            
169              
170             # --colordump
171 0 0         if ($app->colordump) {
172 0           print $app->CM->colormap(
173             name => '--changeme',
174             option => '--colormap');
175 0           exit;
176             }
177              
178             # -p, -P
179 0 0 0       $app->year_on //= $app->mon if $app->mday;
180 0 0         if ($app->year_on_all) {
    0          
181 0           App::week::CalYear::Configure show_year => [ 1..12 ];
182             }
183             elsif (defined(my $m = $app->year_on)) {
184 0 0 0       if ($m < 0 or 12 < $m) {
185 0           die "$m: Month must be within 0 to 12\n";
186             }
187             App::week::CalYear::Configure
188 0           show_year => { $app->year => $m, '*' => 1 };
189             } else {
190 0           App::week::CalYear::Configure show_year => 1;
191             }
192              
193             # -y, -Y
194 0 0 0       $app->years //= 1 if $app->show_year;
195              
196 0           return $app;
197             }
198              
199             sub prepare {
200 0     0 0   my $app = shift;
201 0           call \&_prepare,
202             for => $app,
203             with => [ qw(years months before after year mon column) ];
204 0           return $app;
205             }
206              
207             sub _prepare {
208 0     0     my @args = \(
209             my($years, $months, $before, $after, $year, $mon, $column) = @_
210             );
211              
212 1     1   8 use integer;
  1         2  
  1         6  
213 0 0         if ($months == 1) {
    0          
    0          
214 0           $before = $after = 0;
215             }
216             elsif ($months > 1) {
217 0 0         if (defined $before) {
    0          
218 0           $after = $months - $before - 1;
219             } elsif (defined $after) {
220 0           $before = $months - $after - 1;
221             } else {
222 0           $before = ($months - 1) / 2;
223 0           $after = $months - $before - 1;
224             }
225             }
226             elsif ($years) {
227 0   0       $months = 12 * ($years // 1);
228 0           $before = $mon - 1;
229 0           $after = $months - $mon;
230             }
231             else {
232 0   0       $before //= 1;
233 0   0       $after //= max(0, $column - $before - 1);
234 0           $months = $before + $after + 1;
235             }
236              
237 0   0       $before //= 1;
238 0   0       $after //= 1;
239              
240 0 0         $year += $year < 50 ? 2000 : $year < 100 ? 1900 : 0;
    0          
241              
242 0           map ${$_}, @args;
  0            
243             }
244              
245             sub show {
246 0     0 0   my $app = shift;
247             $app->display(
248             map {
249 0 0         $app->cell( $app->year,
  0            
250             $app->mon + $_,
251             $_ ? () : $app->mday )
252             } -$app->before .. $app->after
253             );
254 0           return $app;
255             }
256              
257             ######################################################################
258              
259             sub display {
260 0     0 0   my $obj = shift;
261 0 0         @_ or return;
262 0           $obj->h_rule(min($obj->column, int @_));
263 0           while (@_) {
264 0           my @cell = splice @_, 0, $obj->column;
265 0           for my $row (transpose @cell) {
266 0           $obj->h_line(@{$row});
  0            
267             }
268 0           $obj->h_rule(int @cell);
269             }
270             }
271              
272             sub h_rule {
273 0     0 0   my $obj = shift;
274 0           my $column = shift;
275 0           my $hr1 = " " x $obj->cell_width;
276 0           my $s = join($obj->frame, '', ($hr1) x $column, '');
277 0           my $rule = $obj->color(FRAME => $s) . "\n";
278 0           print $rule x $obj->frame_height;
279             }
280              
281             sub h_line {
282 0     0 0   my $obj = shift;
283 0           my $frame = $obj->color(FRAME => $obj->frame);
284 0           print join($frame, '', @_, '') . "\n";
285             }
286              
287             sub cell {
288 0     0 0   my $obj = shift;
289 0           my($y, $m, $d) = @_;
290              
291 0           while ($m > 12) { $y += 1; $m -= 12 }
  0            
  0            
292 0           while ($m <= 0) { $y -= 1; $m += 12 }
  0            
  0            
293              
294 0           my @cal = @{$calyear[$y][$m]};
  0            
295              
296             # XXX this is not the best place to initialize...
297 0   0       $obj->cell_width //= length $cal[2];
298              
299 0           my %label;
300 0 0         @label{qw(month week days)} = $d
301             ? qw(THISMONTH THISWEEK THISDAYS)
302             : qw( MONTH WEEK DAYS);
303              
304 0           $cal[0] = $obj->color($label{month}, $cal[0]);
305             $cal[1] = $obj->color($label{week},
306 0           state $week = $obj->week_line($cal[1]));
307 0 0         my $day_re = $d ? qr/^(?: [ \d]{2}){0,6} \K(${\(sprintf '%2d', $d)})\b/ : undef;
  0            
308 0           for (@cal[ 2 .. $#cal ]) {
309 0 0         s/$day_re/$obj->color("THISDAY", $1)/e if $day_re;
  0            
310 0           $_ = $obj->color($label{days}, $_);
311             }
312              
313 0           return \@cal;
314             }
315              
316             sub week_line {
317 0     0 0   my $obj = shift;
318 0           my $week = shift;
319 0           my @week = split_week $week;
320 0           for (0..7) {
321 0 0         if (my $color = $obj->COLORMAP->{$DOW_LABELS[$_]}) {
322 0           my $i = $_ * 2 + 1;
323 0 0         $i > $#week and last;
324 0           $week[$i] = $obj->color($color, $week[$i]);
325             }
326             }
327 0           join '', @week;
328             }
329              
330             1;
331              
332             __END__