| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package HTML::Make::Calendar; |
|
2
|
1
|
|
|
1
|
|
762
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
34
|
|
|
3
|
1
|
|
|
1
|
|
6
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
80
|
|
|
4
|
1
|
|
|
1
|
|
7
|
use Carp; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
61
|
|
|
5
|
1
|
|
|
1
|
|
6
|
use utf8; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
5
|
|
|
6
|
|
|
|
|
|
|
require Exporter; |
|
7
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
|
8
|
|
|
|
|
|
|
our @EXPORT_OK = qw/calendar/; |
|
9
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( |
|
10
|
|
|
|
|
|
|
all => \@EXPORT_OK, |
|
11
|
|
|
|
|
|
|
); |
|
12
|
|
|
|
|
|
|
our $VERSION = '0.00_04'; |
|
13
|
|
|
|
|
|
|
|
|
14
|
1
|
|
|
1
|
|
664
|
use Date::Calc ':all'; |
|
|
1
|
|
|
|
|
6542
|
|
|
|
1
|
|
|
|
|
388
|
|
|
15
|
1
|
|
|
1
|
|
601
|
use HTML::Make; |
|
|
1
|
|
|
|
|
15596
|
|
|
|
1
|
|
|
|
|
39
|
|
|
16
|
1
|
|
|
1
|
|
601
|
use Table::Readable 'read_table'; |
|
|
1
|
|
|
|
|
1407
|
|
|
|
1
|
|
|
|
|
1184
|
|
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# Default HTML elements and classes. |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
my @dowclass = (undef, "mon", "tue", "wed", "thu", "fri", "sat", "sun"); |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# Read the configuration file. |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my $html_file = __FILE__; |
|
25
|
|
|
|
|
|
|
$html_file =~ s!\.pm!/html.txt!; |
|
26
|
|
|
|
|
|
|
my @html = read_table ($html_file); |
|
27
|
|
|
|
|
|
|
my %html; |
|
28
|
|
|
|
|
|
|
for (@html) { |
|
29
|
|
|
|
|
|
|
$html{$_->{item}} = $_ |
|
30
|
|
|
|
|
|
|
} |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# Add an HTML element defined by $thing to $parent. |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub add_el |
|
35
|
|
|
|
|
|
|
{ |
|
36
|
0
|
|
|
0
|
0
|
|
my ($parent, $thing) = @_; |
|
37
|
0
|
|
|
|
|
|
my $class = $thing->{class}; |
|
38
|
0
|
|
|
|
|
|
my $type = $thing->{element}; |
|
39
|
0
|
|
|
|
|
|
my $element; |
|
40
|
0
|
0
|
|
|
|
|
if ($class) { |
|
41
|
|
|
|
|
|
|
# HTML::Make should have a class pusher since it is so common |
|
42
|
|
|
|
|
|
|
# http://mikan/bugs/bug/2108 |
|
43
|
0
|
|
|
|
|
|
$element = $parent->push ($type, attr => {class => $class}); |
|
44
|
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
else { |
|
46
|
|
|
|
|
|
|
# Allow non-class elements if the user doesn't want a class. |
|
47
|
0
|
|
|
|
|
|
$element = $parent->push ($type); |
|
48
|
|
|
|
|
|
|
} |
|
49
|
0
|
|
|
|
|
|
return $element; |
|
50
|
|
|
|
|
|
|
} |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub option |
|
53
|
|
|
|
|
|
|
{ |
|
54
|
0
|
|
|
0
|
0
|
|
my ($ref, $options, $what) = @_; |
|
55
|
0
|
0
|
|
|
|
|
if ($options->{$what}) { |
|
56
|
0
|
|
|
|
|
|
$$ref = $options->{$what}; |
|
57
|
0
|
|
|
|
|
|
delete $options->{$what}; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
} |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
sub calendar |
|
62
|
|
|
|
|
|
|
{ |
|
63
|
0
|
|
|
0
|
1
|
|
my (%options) = @_; |
|
64
|
0
|
|
|
|
|
|
option (\my $verbose, \%options, 'verbose'); |
|
65
|
0
|
|
|
|
|
|
my ($year, $month, undef) = Today (); |
|
66
|
0
|
|
|
|
|
|
option (\$year, \%options, 'year'); |
|
67
|
0
|
|
|
|
|
|
option (\$month, \%options, 'month'); |
|
68
|
0
|
|
|
|
|
|
option (\my $dayc, \%options, 'dayc'); |
|
69
|
0
|
|
|
|
|
|
option (\my $cdata, \%options, 'cdata'); |
|
70
|
0
|
|
|
|
|
|
my $html_week = $html{week}{element}; |
|
71
|
0
|
|
|
|
|
|
option (\$html_week, \%options, 'html_week'); |
|
72
|
0
|
|
|
|
|
|
my $first = 1; |
|
73
|
0
|
|
|
|
|
|
option (\$first, \%options, 'first'); |
|
74
|
0
|
0
|
|
|
|
|
if ($first != 1) { |
|
75
|
0
|
0
|
0
|
|
|
|
if (int ($first) != $first || $first < 1 || $first > 7) { |
|
|
|
|
0
|
|
|
|
|
|
76
|
0
|
|
|
|
|
|
carp "Use a number between 1 (Monday) and 7 (Sunday) for first"; |
|
77
|
0
|
|
|
|
|
|
$first = 1; |
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
# To do: Allow the user to use their own HTML tags. |
|
81
|
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
|
for my $k (sort keys %options) { |
|
83
|
0
|
0
|
|
|
|
|
if ($options{$k}) { |
|
84
|
0
|
|
|
|
|
|
carp "Unknown option '$k'"; |
|
85
|
0
|
|
|
|
|
|
delete $options{$k}; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
} |
|
88
|
|
|
|
|
|
|
# Map from columns of the calendar to days of the week, e.g. 1 -> |
|
89
|
|
|
|
|
|
|
# 7 if Sunday is the first day of the week. |
|
90
|
0
|
|
|
|
|
|
my %col2dow; |
|
91
|
0
|
|
|
|
|
|
for (1..7) { |
|
92
|
0
|
|
|
|
|
|
my $col2dow = $_ + $first - 1; |
|
93
|
0
|
0
|
|
|
|
|
if ($col2dow > 7) { |
|
94
|
0
|
|
|
|
|
|
$col2dow -= 7; |
|
95
|
|
|
|
|
|
|
} |
|
96
|
0
|
|
|
|
|
|
$col2dow{$_} = $col2dow; |
|
97
|
|
|
|
|
|
|
} |
|
98
|
0
|
|
|
|
|
|
my %dow2col = reverse %col2dow; |
|
99
|
0
|
|
|
|
|
|
my $dim = Days_in_Month ($year, $month); |
|
100
|
0
|
0
|
|
|
|
|
if ($verbose) { |
|
101
|
|
|
|
|
|
|
# To do: Add a messaging routine with caller line numbers |
|
102
|
|
|
|
|
|
|
# rather than just use print. |
|
103
|
0
|
|
|
|
|
|
print "There are $dim days in month $month of $year.\n"; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
0
|
|
|
|
|
|
my @col; |
|
106
|
|
|
|
|
|
|
# The number of weeks |
|
107
|
0
|
|
|
|
|
|
my $weeks = 1; |
|
108
|
0
|
|
|
|
|
|
my $prev = 0; |
|
109
|
0
|
|
|
|
|
|
for my $day (1..$dim) { |
|
110
|
0
|
|
|
|
|
|
my $dow = Day_of_Week ($year, $month, $day); |
|
111
|
0
|
|
|
|
|
|
my $col = $dow2col{$dow}; |
|
112
|
0
|
|
|
|
|
|
$col[$day] = $col; |
|
113
|
0
|
0
|
|
|
|
|
if ($col < $prev) { |
|
114
|
0
|
|
|
|
|
|
$weeks++; |
|
115
|
|
|
|
|
|
|
} |
|
116
|
0
|
|
|
|
|
|
$prev = $col; |
|
117
|
|
|
|
|
|
|
} |
|
118
|
|
|
|
|
|
|
# The number of empty cells we need at the start of the month. |
|
119
|
0
|
|
|
|
|
|
my $fill_start = $col[1] - 1; |
|
120
|
0
|
|
|
|
|
|
my $fill_end = 7 - $col[-1]; |
|
121
|
0
|
0
|
|
|
|
|
if ($verbose) { |
|
122
|
0
|
|
|
|
|
|
print "Start $fill_start, end $fill_end, weeks $weeks\n"; |
|
123
|
|
|
|
|
|
|
} |
|
124
|
0
|
|
|
|
|
|
my @cells; |
|
125
|
|
|
|
|
|
|
# To do: Allow the user to colour or otherwise alter empty cells, |
|
126
|
|
|
|
|
|
|
# for example with a callback or with a user-defined class. |
|
127
|
0
|
|
|
|
|
|
for (1..$fill_start) { |
|
128
|
0
|
|
|
|
|
|
push @cells, {}; |
|
129
|
|
|
|
|
|
|
} |
|
130
|
0
|
|
|
|
|
|
for (1..$dim) { |
|
131
|
0
|
|
|
|
|
|
my $col = $col[$_]; |
|
132
|
0
|
|
|
|
|
|
push @cells, {dom => $_, col => $col, dow => $col2dow{$col}}; |
|
133
|
|
|
|
|
|
|
} |
|
134
|
0
|
|
|
|
|
|
for (1..$fill_end) { |
|
135
|
0
|
|
|
|
|
|
push @cells, {}; |
|
136
|
|
|
|
|
|
|
} |
|
137
|
0
|
|
|
|
|
|
my $calendar = HTML::Make->new ($html{calendar}{element}); |
|
138
|
|
|
|
|
|
|
# As far as I know, is the correct HTML, although
|
139
|
|
|
|
|
|
|
# nobody really does this. |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
# To do: inspect the type of $html{calendar} and don't add the |
|
142
|
|
|
|
|
|
|
# | unless it is a element.
|
143
|
0
|
|
|
|
|
|
my $tbody = $calendar->push ('tbody'); |
|
144
|
|
|
|
|
|
|
# To do: These should be overridden if the caller doesn't want to |
|
145
|
|
|
|
|
|
|
# use table, tr, td to construct the calendar. |
|
146
|
0
|
|
|
|
|
|
my $titler = $tbody->push ('tr'); |
|
147
|
0
|
|
|
|
|
|
my $titleh = $titler->push ('th', attr => {colspan => 7}); |
|
148
|
|
|
|
|
|
|
# To do: Allow the caller to override this. |
|
149
|
0
|
|
|
|
|
|
my $my = Month_to_Text ($month) . " $year"; |
|
150
|
0
|
|
|
|
|
|
$titleh->add_text ($my); |
|
151
|
|
|
|
|
|
|
# To do: Allow the user to override this. |
|
152
|
0
|
|
|
|
|
|
my $wdr = $tbody->push ('tr'); |
|
153
|
0
|
|
|
|
|
|
for my $col (1..7) { |
|
154
|
|
|
|
|
|
|
# To do: Allow the user to use their own weekdays (possibly |
|
155
|
|
|
|
|
|
|
# allow them to use the language specifier of Date::Calc). |
|
156
|
0
|
|
|
|
|
|
my $dow = $col2dow{$col}; |
|
157
|
0
|
|
|
|
|
|
my $wdt = substr (Day_of_Week_to_Text ($dow), 0, 2); |
|
158
|
0
|
|
|
|
|
|
my $dow_el = add_el ($wdr, $html{dow}); |
|
159
|
0
|
|
|
|
|
|
$dow_el->add_text ($wdt); |
|
160
|
|
|
|
|
|
|
} |
|
161
|
|
|
|
|
|
|
# wom = week of month |
|
162
|
0
|
|
|
|
|
|
for my $wom (1..$weeks) { |
|
163
|
0
|
|
|
|
|
|
my $week = add_el ($tbody, $html{week}); |
|
164
|
0
|
|
|
|
|
|
for my $col (1..7) { |
|
165
|
|
|
|
|
|
|
# dow = day of week |
|
166
|
0
|
|
|
|
|
|
my $dow = $col2dow{$col}; |
|
167
|
0
|
|
|
|
|
|
my $day = add_el ($week, $html{day}); |
|
168
|
0
|
|
|
|
|
|
my $cell = shift @cells; |
|
169
|
|
|
|
|
|
|
# dom = day of month |
|
170
|
0
|
|
|
|
|
|
my $dom = $cell->{dom}; |
|
171
|
0
|
0
|
|
|
|
|
if (defined $dom) { |
|
172
|
0
|
|
|
|
|
|
$day->add_class ('cal-' . $dowclass[$dow]); |
|
173
|
0
|
0
|
|
|
|
|
if ($dayc) { |
|
174
|
0
|
|
|
|
|
|
&{$dayc} ($cdata, |
|
|
0
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
{ |
|
176
|
|
|
|
|
|
|
year => $year, |
|
177
|
|
|
|
|
|
|
month => $month, |
|
178
|
|
|
|
|
|
|
dom => $dom, |
|
179
|
|
|
|
|
|
|
dow => $dow, |
|
180
|
|
|
|
|
|
|
wom => $wom, |
|
181
|
|
|
|
|
|
|
}, |
|
182
|
|
|
|
|
|
|
$day); |
|
183
|
|
|
|
|
|
|
} |
|
184
|
|
|
|
|
|
|
else { |
|
185
|
0
|
|
|
|
|
|
$day->push ('span', text => $dom, |
|
186
|
|
|
|
|
|
|
attr => {class => 'cal-dom'}); |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
} |
|
189
|
|
|
|
|
|
|
else { |
|
190
|
0
|
|
|
|
|
|
$day->add_class ('cal-noday'); |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
# To do: allow a callback on the packing cells |
|
193
|
|
|
|
|
|
|
} |
|
194
|
|
|
|
|
|
|
} |
|
195
|
0
|
|
|
|
|
|
return $calendar; |
|
196
|
|
|
|
|
|
|
} |
|
197
|
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
1; |
|