X-Git-Url: https://git.donarmstrong.com/deb_pkgs/libhtml-calendarmonth-perl.git?a=blobdiff_plain;f=lib%2FHTML%2FCalendarMonth.pm;h=5ca73498c7e135449d994c17e108329e73fd9ffb;hb=f3ef12e10123e46a0db95d820bb77f6e6d3225c7;hp=8d4445647c685f787c2780f92630504da2e0f021;hpb=febd0b02136ed777f42c0e2b79d71db21c1805a8;p=deb_pkgs%2Flibhtml-calendarmonth-perl.git diff --git a/lib/HTML/CalendarMonth.pm b/lib/HTML/CalendarMonth.pm index 8d44456..5ca7349 100644 --- a/lib/HTML/CalendarMonth.pm +++ b/lib/HTML/CalendarMonth.pm @@ -1,52 +1,132 @@ package HTML::CalendarMonth; +BEGIN { + $HTML::CalendarMonth::VERSION = '1.25'; +} use strict; -use vars qw($VERSION @ISA); - -$VERSION = '1.19'; - +use warnings; use Carp; -use HTML::ElementTable 1.15; +BEGIN { $HTML::CalendarMonth::VERSION = 1.25 } + +use HTML::ElementTable 1.18; use HTML::CalendarMonth::Locale; use HTML::CalendarMonth::DateTool; -@ISA = qw(HTML::CalendarMonth::Accessor HTML::ElementTable); +use base qw( Class::Accessor HTML::ElementTable ); + +my %Objects; + +# default complex attributes +my %Calmonth_Attrs = ( + head_m => 1, # month heading mode + head_y => 1, # year heading mode + head_dow => 1, # DOW heading mode + head_week => 0, # weak of year + year_span => 2, # default col span of year -# Calmonth attribute method overrides + today => undef, # DOM, if not now + week_begin => 1, # what DOW (1-7) is the 1st DOW? + + historic => 1, # if able to choose, use ncal/cal + # rather than Date::Calc, which + # blindly extrapolates Gregorian + + alias => {}, # what gets displayed if not + # the default item + + month => undef, # these will get initialized + year => undef, + + locale => 'en_US', + full_days => 0, + full_months => 1, -sub row_offset { - # Displace calendar how many rows into table? + datetool => undef, + + enable_css => 1, + semantic_css => 0, + + # internal muckety muck + _cal => undef, + _itoch => {}, + _ctoih => {}, + _caltool => undef, + _weeknums => undef, + _today => undef, + + dow1st => undef, + lastday => undef, + loc => undef, + + # deprecated + row_offset => undef, + col_offset => undef, +); + +__PACKAGE__->mk_accessors(keys %Calmonth_Attrs); + +# Class::Accessor overrides + +sub set { + my($self, $key) = splice(@_, 0, 2); + if (@_ == 1) { + $Objects{$self}{$key} = $_[0]; + } + elsif (@_ > 1) { + $Objects{$self}{$key} = [@_]; + } + else { + Carp::confess("wrong number of arguments received"); + } +} + +sub get { my $self = shift; - if (@_) { - $_[0] >= 0 or croak "Offset must be zero or more"; + if (@_ == 1) { + return $Objects{$self}{$_[0]}; + } + elsif ( @_ > 1 ) { + return @{$Objects{$self}{@_}}; + } + else { + Carp::confess("wrong number of arguments received."); } - $self->SUPER::row_offset(@_); } -sub col_offset { - # Displace calendar how many columns into table? +sub _is_calmonth_attr { shift; exists $Calmonth_Attrs{shift()} } + +sub _set_defaults { my $self = shift; - if (@_) { - $_[0] >= 0 or croak "Offset must be zero or more"; + foreach (keys %Calmonth_Attrs) { + $self->$_($Calmonth_Attrs{$_}); } - $self->SUPER::col_offset(@_); + $self; } +sub DESTROY { delete $Objects{shift()} } + +# last dow col, first week row + +use constant LDC => 6; +use constant FWR => 2; + +# alias + sub item_alias { my($self, $item) = splice(@_, 0, 2); - defined $item or croak "Item name required"; + defined $item or croak "item name required"; $self->alias->{$item} = shift if @_; $self->alias->{$item} || $item; } sub item_aliased { my($self, $item) = splice(@_, 0, 2); - defined $item or croak "Item name required.\n"; + defined $item or croak "item name required.\n"; defined $self->alias->{$item}; } -# Header Toggles +# header toggles sub _head { # Set/test entire heading (month,year,and dow headers) (does not @@ -68,10 +148,10 @@ sub _initialized { @_ ? $self->{_initialized} = shift : $self->{_initialized}; } -# Circa Interface +# circa interface sub _date { - # Set target month, year + # set target month, year my $self = shift; if (@_) { my ($month, $year) = @_; @@ -89,52 +169,42 @@ sub _date { $self->year($year); $month = $self->monthnum($month); - # Trigger _gencal...this should be the only place where this occurs + # trigger _gencal...this should be the only place where this occurs $self->_gencal; } return($self->month, $self->year); } -# locale accessors -sub locales { shift->loc->locales } -sub locale_days { shift->loc->days } -sub locale_daynum { shift->loc->daynum(@_) } -sub locale_months { shift->loc->months } -sub locale_daynums { shift->loc->daynums } -sub locale_minmatch { shift->loc->minmatch } -sub locale_monthnum { shift->loc->monthnum(@_) } -sub locale_monthnums { shift->loc->monthnums } -sub locale_minmatch_pattern { shift->loc->minmatch_pattern } - # class factory access -sub class_element_table { 'HTML::ElementTable' } -sub class_datetool { __PACKAGE__ . '::DateTool' } -sub class_locale { __PACKAGE__ . '::Locale' } +use constant CLASS_HET => 'HTML::ElementTable'; +use constant CLASS_DATETOOL => 'HTML::CalendarMonth::DateTool'; +use constant CLASS_LOCALE => 'HTML::CalendarMonth::Locale'; sub _gencal { - # Generate internal calendar representation + # generate internal calendar representation my $self = shift; - # New calendar...clobber day-specific settings - my $itoc = $self->_itoc({}); + # new calendar...clobber day-specific settings + my $itoc = $self->_itoch({}); + my $ctoi = $self->_ctoih({}); - # Figure out dow of 1st day of the month as well as last day of the + # figure out dow of 1st day of the month as well as last day of the # month (uses date calculator backends) $self->_anchor_month(); # row count for weeks in grid - my ($wcnt) = 0; + my $wcnt = 0; my ($dowc) = $self->dow1st; - my $skips = $self->_caltool->skips; + my $skips = $self->_caltool->_skips; - # For each day + # for each day foreach (1 .. $self->lastday) { next if $skips->{$_}; - my $r = $wcnt + 2 + $self->row_offset; - my $c = $dowc + $self->col_offset; - # This is a bootstrap until we know the number of rows in the month. + my $r = $wcnt + FWR; + my $c = $dowc; + # this is a bootstrap until we know the number of rows in the month. $itoc->{$_} = [$r, $c]; $dowc = ++$dowc % 7; ++$wcnt unless $dowc || $_ == $self->lastday; @@ -142,32 +212,30 @@ sub _gencal { $self->{_week_rows} = $wcnt; - my $row_extent = $wcnt + 2; - my $col_extent = 6; + my $row_extent = $wcnt + FWR; + my $col_extent = LDC; $col_extent += 1 if $self->head_week; - $self->extent($row_extent + $self->row_offset, - $col_extent + $self->col_offset); + $self->SUPER::extent($row_extent, $col_extent); - # Table can contain the days now, so replace our bootstrap coordinates + # table can contain the days now, so replace our bootstrap coordinates # with references to the actual elements. foreach (keys %$itoc) { my $cellref = $self->cell(@{$itoc->{$_}}); - $self->itoc($_, $cellref); - $self->ctoi($cellref, $_); + $self->_itoc($_, $cellref); + $self->_ctoi($cellref, $_); } # week num affects month/year spans my $width = $self->head_week ? 8 : 7; # month/year headers - my $cellref = $self->cell($self->row_offset, $self->col_offset); - $self->itoc($self->month, $cellref); - $self->ctoi($cellref, $self->month); - $cellref = $self->cell($self->row_offset, - $width - $self->year_span + $self->col_offset); - $self->itoc($self->year, $cellref); - $self->ctoi($cellref, $self->year); + my $cellref = $self->cell(0, 0); + $self->_itoc($self->month, $cellref); + $self->_ctoi($cellref, $self->month); + $cellref = $self->cell(0, $width - $self->year_span); + $self->_itoc($self->year, $cellref); + $self->_ctoi($cellref, $self->year); $self->item($self->month)->replace_content($self->item_alias($self->month)); $self->item($self->year)->replace_content($self->item_alias($self->year)); @@ -189,65 +257,152 @@ sub _gencal { } } else { - $self->row($self->first_row)->mask(1); + $self->row(0)->mask(1); } # DOW headers my $trans; - my $days = $self->locale_days; + my $days = $self->loc->days; foreach (0..$#$days) { # Transform for week_begin 1..7 $trans = ($_ + $self->week_begin - 1) % 7; - my $cellref = $self->cell(1 + $self->row_offset, $_ + $self->col_offset); - $self->itoc($days->[$trans], $cellref); - $self->ctoi($cellref, $days->[$trans]); + my $cellref = $self->cell(1, $_); + $self->_itoc($days->[$trans], $cellref); + $self->_ctoi($cellref, $days->[$trans]); } if ($self->head_dow) { grep($self->item($_)->replace_content($self->item_alias($_)), @$days); } else { - $self->row($self->first_row + 1)->mask(1); + $self->row(1)->mask(1); } - # Week number column + # week number column if ($self->head_week) { - # Week nums can collide with days. Use "w" in front of the number + # week nums can collide with days. Use "w" in front of the number # for uniqueness, and automatically alias to just the number (unless # already aliased, of course). $self->_gen_week_nums(); my $ws; - my $row_count = $self->first_week_row; + my $row_count = FWR; foreach ($self->_numeric_week_nums) { $ws = "w$_"; $self->item_alias($ws, $_) unless $self->item_aliased($ws); my $cellref = $self->cell($row_count, $self->last_col); - $self->itoc($ws, $cellref); - $self->ctoi($cellref, $ws); + $self->_itoc($ws, $cellref); + $self->_ctoi($cellref, $ws); $self->item($ws)->replace_content($self->item_alias($ws)); ++$row_count; } } - # Fill in days of the month + # fill in days of the month my $i; - foreach my $r ($self->first_week_row .. $self->last_row) { - foreach my $c ($self->first_col .. $self->last_week_col) { + foreach my $r (FWR .. $self->last_row) { + foreach my $c (0 .. LDC) { $self->cell($r,$c)->replace_content($self->item_alias($i)) if ($i = $self->item_at($r,$c)); } } - # Defaults - $self->table->attr(align => 'center'); - $self->item($self->month)->attr(align => 'left') if $self->head_m; - $self->attr(bgcolor => 'white') unless defined $self->attr('bgcolor'); - $self->attr(border => 1) unless defined $self->attr('border'); - $self->attr(cellspacing => 0) unless defined $self->attr('cellspacing'); - $self->attr(cellpadding => 0) unless defined $self->attr('cellpadding'); + # css classes + if ($self->enable_css) { + $self ->push_attr(class => 'hcm-table' ); + $self->item_row($self->dayheaders)->push_attr(class => 'hcm-day-head' ); + $self->item ($self->year) ->push_attr(class => 'hcm-year-head' ); + $self->item ($self->month) ->push_attr(class => 'hcm-month-head'); + $self->item ($self->week_nums) ->push_attr(class => 'hcm-week-head' ) + if $self->head_week; + } + + if ($self->semantic_css) { + my $today = $self->today; + if ($today < 0) { + $self->item($self->days)->push_attr(class => 'hcm-past'); + } + elsif ($today == 0) { + $self->item($self->days)->push_attr(class => 'hcm-future'); + } + else { + for my $d ($self->days) { + if ($d < $today) { + $self->item($d)->push_attr(class => 'hcm-past'); + } + elsif ($d > $today) { + $self->item($d)->push_attr(class => 'hcm-future'); + } + else { + $self->item($d)->push_attr(class => 'hcm-today'); + } + } + } + } $self; } +sub default_css { + my $hbgc = '#DDDDDD'; + my $bc = '#888888'; + + my $str = <<__CSS; + +__CSS + +} + +sub _datetool { + my $self = shift; + my $ct; + if (! ($ct = $self->_caltool)) { + $ct = $self->_caltool(CLASS_DATETOOL->new( + year => $self->year, + month => $self->month, + weeknum => $self->head_week, + historic => $self->historic, + datetool => $self->datetool, + )); + } + $ct; +} + sub _anchor_month { # Figure out what our month grid looks like. # Let HTML::CalendarMonth::DateTool determine which method is @@ -257,21 +412,12 @@ sub _anchor_month { my $month = $self->monthnum($self->month); my $year = $self->year; - my $tool = $self->_caltool; - if (!$tool) { - $tool = $self->class_datetool->new( - year => $year, - month => $month, - weeknum => $self->head_week, - historic => $self->historic, - datetool => $self->datetool, - ); - $self->_caltool($tool); - } - my $dow1st = $tool->dow1st; + my $tool = $self->_datetool; + + my $dow1st = $tool->dow1st; # 0..6, starting with Sun my $lastday = $tool->lastday; - # If the first day of the week is not Sunday... + # week_begin given as 1..7 starting with Sun $dow1st = ($dow1st - ($self->week_begin - 1)) % 7; $self->dow1st($dow1st); @@ -292,8 +438,8 @@ sub _gen_week_nums { my($year, $month, $lastday) = ($self->year, $self->monthnum, $self->lastday); my $tool = $self->_caltool; - $tool->can('week_of_year') - or croak "Oops. $tool not set up for week of year calculations.\n"; + croak "Oops. " . ref $tool . " not set up for week of year calculations.\n" + unless $tool->can('week_of_year'); my $fdow = $self->dow1st; my $delta = 4 - $fdow; @@ -311,227 +457,225 @@ sub _gen_week_nums { my $fweek = $tool->week_of_year(@ft); my $lweek = $tool->week_of_year(@lt); - my @wnums = $fweek .. $lweek; + my @wnums = $fweek > $lweek ? ($fweek, 1 .. $lweek) : ($fweek .. $lweek); - # Do we have days above our first Thursday? - if ($self->row_of($ft[0]) != $self->first_week_row) { + # do we have days above our first Thursday? + if ($self->row_of($ft[0]) != FWR) { unshift(@wnums, $wnums[0] -1); } - # Do we have days below our last Thursday? + # do we have days below our last Thursday? if ($self->row_of($lt[0]) != $self->last_row) { push(@wnums, $wnums[-1] + 1); } - # First visible week is from last year + # first visible week is from last year if ($wnums[0] == 0) { $wnums[0] = $tool->week_of_year($tool->add_days(-7, $ft[0])); } - # Last visible week is from subsequent year + # last visible week is from subsequent year if ($wnums[-1] > $lweek) { $wnums[-1] = $tool->week_of_year($tool->add_days(7, $lt[0])); } - $self->_weeknums(@wnums); + $self->_weeknums(\@wnums); } -# Month hooks +# month hooks sub row_items { - # Given a list of items, return all items in rows shared by the + # given a list of items, return all items in rows shared by the # provided items. my $self = shift; - my($item,$row,$col,$i,@i,%i); - foreach $item (@_) { - $row = ($self->coords_of($item))[0]; - foreach $col ($self->first_col .. $self->last_col) { - $i = $self->item_at($row,$col) || next; - ++$i{$i}; + my %items; + foreach my $item (@_) { + my $row = ($self->coords_of($item))[0]; + foreach my $col (0 .. $self->last_col) { + my $i = $self->item_at($row, $col) || next; + ++$items{$i}; } } - @i = keys %i; - @i ? @i : $i[0]; + keys %items > 1 ? keys %items : (keys %items)[0]; } sub col_items { - # Return all item cells in the columns occupied by the provided list + # return all item cells in the columns occupied by the provided list # of items. my $self = shift; - $self->_col_items($self->first_row,$self->last_row,@_); + $self->_col_items(0, $self->last_row, @_); } sub daycol_items { - # Same as col_items(), but excludes header cells. + # same as col_items(), but excludes header cells. my $self = shift; - $self->_col_items($self->first_week_row,$self->last_row,@_); + $self->_col_items(FWR, $self->last_row, @_); } sub _col_items { - # Given row bounds and a list of items, return all item elements + # given row bounds and a list of items, return all item elements # in the columns occupied by the provided items. Does not return # empty cells. my($self, $rfirst, $rlast) = splice(@_, 0, 3); + my %items; my($item, $row, $col, %i); - foreach $item (@_) { - $col = ($self->coords_of($item))[1]; - foreach $row ($rfirst .. $rlast) { + foreach my $item (@_) { + my $col = ($self->coords_of($item))[1]; + foreach my $row ($rfirst .. $rlast) { my $i = $self->item_at($row,$col) || next; - ++$i{$i}; + ++$items{$i}; } } - my @i = keys %i; - $#i ? @i : $i[0]; + keys %items > 1 ? keys %items : (keys %items)[0]; } sub daytime { - # Return seconds since epoch for a given day + # return seconds since epoch for a given day my($self, $day) = splice(@_, 0, 2); - $day or croak "Must specify day of month"; - croak "Day does not exist" unless $self->_daycheck($day); + $day or croak "must specify day of month"; + croak "day does not exist" unless $self->_daycheck($day); $self->_caltool->day_epoch($day); } sub week_nums { - # Return list of all week numbers - map("w$_", shift->_numeric_week_nums); + # return list of all week number labels + my @wnums = map("w$_", shift->_numeric_week_nums); + wantarray ? @wnums : \@wnums; } sub _numeric_week_nums { - # Return list of all week numbers as numbers + # return list of all week numbers as numbers my $self = shift; - $self->head_week ? @{$self->_weeknums} : (); + return unless $self->head_week; + wantarray ? @{$self->_weeknums} : $self->_weeknums; } sub days { - # Return list of all days of the month (1..$c->lastday). + # return list of all days of the month (1..$c->lastday). my $self = shift; - my $skips = $self->_caltool->skips; - grep(!$skips->{$_}, (1 .. $self->lastday)); + my $skips = $self->_caltool->_skips; + my @days = grep { !$skips->{$_} } (1 .. $self->lastday); + wantarray ? @days : \@days; } sub dayheaders { - # Return list of all day headers (Su..Sa). - shift->locale_days; + # return list of all day headers (Su..Sa). + shift->loc->days; } sub headers { - # Return list of all headers (month,year,dayheaders) + # return list of all headers (month,year,dayheaders) my $self = shift; - ($self->year, $self->month, $self->dayheaders); + wantarray ? ($self->year, $self->month, $self->dayheaders) + : [$self->year, $self->month, $self->dayheaders]; } sub items { - # Return list of all items (days, headers) + # return list of all items (days, headers) my $self = shift; - ($self->headers, $self->days); + wantarray ? ($self->headers, $self->days) + : [$self->headers, $self->days]; } -sub first_col { - # Where is the first column of the calendar within the table? - shift->col_offset(); +sub last_col { + # what's the max col of the calendar? + my $self = shift; + $self->head_week ? LDC + 1 : LDC; } -sub first_week_col { first_col(@_) } +sub last_day_col { LDC } -sub last_col { - # What's the max col of the calendar? +sub last_row { + # last row of the calendar my $self = shift; - $self->head_week ? $self->last_week_col + 1 : $self->last_week_col; + return ($self->coords_of($self->lastday))[0]; } -sub last_week_col { - # What column does the last DOW fall in? Should be the same as - # last_col unless head_week is activated - shift->first_col + 6; -} +*last_week_row = \&last_row; -sub first_row { - # Where is the first row of the calendar? - shift->row_offset(); -} +sub first_week_row { FWR }; -sub first_week_row { - # Returns the first row containing days of the month. This used to - # take into account whether the header rows were active or not, - # but since masking was implemented this should always be offset 2 - # from the first row (thereby taking into account the month/year - # and DOW rows). - my $w = 2; - shift->first_row + $w; +sub past_days { + my $self = shift; + my $today = $self->_today; + if ($today < 0) { + return $self->days; + } + elsif ($today == 0) { + return; + } + return(1 .. $today); } -sub last_row { - # Last row of the calendar - my $self = shift; - return ($self->coords_of($self->lastday))[0]; +sub future_days { + my $self = shift; + my $today = $self->_today; + if ($today < 0) { + return; + } + elsif ($today == 0) { + return $self->days; + } + return($today .. $self->last_day); } -sub last_week_row { last_row(@_) } - -# Custom glob interfaces +# custom glob interfaces sub item { - # Return TD elements containing items + # return TD elements containing items my $self = shift; - @_ || croak "Item(s) must be provided"; + @_ || croak "item(s) must be provided"; $self->cell(grep(defined $_, map($self->coords_of($_), @_))); } sub item_row { - # Return a glob of the rows of a list of items, including empty cells. + # return a glob of the rows of a list of items, including empty cells. my $self = shift; - $self->_item_row($self->first_col, $self->last_col, @_); + $self->row(map { $self->row_of($_) } @_); } sub item_day_row { - # Same as item_row, but excludes possible week number cells + # same as item_row, but excludes possible week number cells my $self = shift; - $self->_item_row($self->first_col, $self->last_week_col, @_); -} - -sub _item_row { - # Given column bounds and a list of items, return a glob representing - # the cells in the rows occupied by the provided items, including - # empty cells. - my($self, $cfirst, $clast) = splice(@_, 0, 3); - defined $cfirst && defined $clast or croak "No items provided"; - my($row, $col, @coords); - foreach $row (map($self->row_of($_), @_)) { - foreach $col ($cfirst .. $clast) { - push(@coords, $row, $col); + return $self->item_row(@_) unless $self->head_week; + my(%rows, @coords); + for my $r (map { $self->row_of($_) } @_) { + next if ++$rows{$r} > 1; + for my $c (0 .. 6) { + push(@coords, ($r, $c)); } } $self->cell(@coords); } sub item_week_nums { - # Glob of all week numbers + # glob of all week numbers my $self = shift; $self->item($self->week_nums); } sub item_col { - # Return a glob of the cols of a list of items, including empty cells. + # return a glob of the cols of a list of items, including empty cells. my $self = shift; - $self->_item_col($self->first_row, $self->last_row, @_); + $self->_item_col(0, $self->last_row, @_); } sub item_daycol { - # Same as item_col(), but excludes header cells. + # same as item_col(), but excludes header cells. my $self = shift; - $self->_item_col($self->first_week_row, $self->last_row, @_); + $self->_item_col(2, $self->last_row, @_); } sub _item_col { - # Given row bounds and a list of items, return a glob representing + # given row bounds and a list of items, return a glob representing # the cells in the columns occupied by the provided items, including # empty cells. my($self, $rfirst, $rlast) = splice(@_, 0, 3); - defined $rfirst && defined $rlast or croak "No items provided"; - my($row, $col, @coords); - foreach $col (map($self->col_of($_), @_)) { - foreach $row ($rfirst .. $rlast) { + defined $rfirst && defined $rlast or Carp::confess "No items provided"; + my(%seen, @coords); + foreach my $col (map { $self->col_of($_) } @_) { + next if ++$seen{$col} > 1; + foreach my $row ($rfirst .. $rlast) { push(@coords, $row, $col); } } @@ -539,53 +683,52 @@ sub _item_col { } sub item_box { - # Return a glob of the box defined by two items + # return a glob of the box defined by two items my($self, $item1, $item2) = splice(@_, 0, 3); defined $item1 && defined $item2 or croak "Two items required"; $self->box($self->coords_of($item1), $self->coords_of($item2)); } sub all { - # Return a glob of all calendar cells, including empty cells. + # return a glob of all calendar cells, including empty cells. my $self = shift; - $self->box( $self->first_row => $self->first_col, - $self->last_row => $self->last_col ); + $self->box( 0,0 => $self->last_row, $self->last_col ); } sub alldays { - # Return a glob of all cells other than header cells + # return a glob of all cells other than header cells my $self = shift; - $self->box( $self->first_week_row => $self->first_col, - $self->last_row => $self->last_week_col ); + $self->box( 2, 0 => $self->last_row, 6 ); } sub allheaders { - # Return a glob of all header cells + # return a glob of all header cells my $self = shift; $self->item($self->headers); } -# Transformation Methods +# transformation Methods sub coords_of { - # Convert an item into grid coordinates + # convert an item into grid coordinates my $self = shift; - my $ref = $self->itoc(@_); + croak "undefined value passed to coords_of()" if @_ && ! defined $_[0]; + my $ref = $self->_itoc(@_); my @pos = ref $ref ? $ref->position : (); @pos ? (@pos[$#pos - 1, $#pos]) : (); } sub item_at { - # Convert grid coords into item + # convert grid coords into item my $self = shift; - $self->ctoi($self->cell(@_)); + $self->_ctoi($self->cell(@_)); } -sub itoc { - # Item to grid +sub _itoc { + # item to grid my($self, $item, $ref) = splice(@_, 0, 3); defined $item or croak "item required"; - my $itoc = $self->_itoc; + my $itoc = $self->_itoch; if ($ref) { croak "Reference required" unless ref $ref; $itoc->{$item} = $ref; @@ -593,11 +736,11 @@ sub itoc { $itoc->{$item}; } -sub ctoi { - # Cell reference to item +sub _ctoi { + # cell reference to item my($self, $refstring, $item) = splice(@_, 0, 3); defined $refstring or croak "cell id required"; - my $ctoi = $self->_ctoi; + my $ctoi = $self->_ctoih; if (defined $item) { $ctoi->{$refstring} = $item; } @@ -615,117 +758,106 @@ sub col_of { } sub monthname { - # Check/return month...returns name. Accepts 1-12, or Jan..Dec + # check/return month...returns name. Accepts month number or string. my $self = shift; return $self->month unless @_; - my(@mn, $month); - my $months = $self->locale_months; - my $monthnum = $self->locale_monthnums; - my $minmatch = $self->locale_minmatch; - my $mmpat = $self->locale_minmatch_pattern; - - foreach $month (@_) { - if ($month =~ /^\d+$/) { - $month >= 1 && $month <= 12 || return 0; - push(@mn, $months->[$month-1]); - } - else { - if (exists $monthnum->{$month}) { - push(@mn, $month); - } - else { - # Make one last attempt - if ($month =~ /^($mmpat)/) { - push(@mn, $minmatch->{$1}); - } - else { - return undef; - } - } - } + my $loc = $self->loc; + my @names; + for my $m (@_) { + $m = ($m - 1) % 12 if $m && $m =~ /^\d+$/; + $m = $loc->monthname($m) || croak "month not found " . join(', ', @_); + return $m if @_ == 1; + push(@names, $m); } - $#mn > 0 ? @mn : $mn[0]; + @names; } sub monthnum { - # Check/return month, returns number. Accepts 1-12, or Jan..Dec - my $self = shift; - my $monthnum = $self->locale_monthnums; - my @mn; - push(@mn, map(exists $monthnum->{$_} ? - $monthnum->{$_}+1 : undef, $self->monthname(@_))); - $#mn > 0 ? @mn : $mn[0]; + # check/return month, returns number. Accepts month number or string. + my $self = shift; + my @months = @_ ? @_ : $self->month; + my $loc = $self->loc; + my @nums; + for my $m (@months) { + $m = ($m - 1) % 12 if $m && $m =~ /^\d+$/; + $m = $loc->monthnum($m); + croak "month not found ", join(', ', @_) unless defined $m; + $m += 1; + return $m if @_ == 1; + push(@nums, $m); + } + @nums; } sub dayname { - # Check/return day...returns name. Accepts 1..7, or Su..Sa + # check/return day...returns name. Accepts 1..7, or Su..Sa my $self = shift; - @_ || croak "Day must be provided"; - my(@dn, $day); - my $days = $self->locale_days; - my $daynum = $self->locale_daynums; - foreach $day (@_) { - if ($day =~ /^\d+$/) { - $day >= 1 && $day <= 7 || return undef; - # week_begin is at least 1, so skew is automatic - push(@dn, $days->[($day - 1 + $self->week_begin - 1) % 8]); - } - else { - $day = ucfirst(lc($day)); - if (exists $daynum->{$day}) { - push(@dn, $day); - } - else { - return undef; - } + @_ || croak "day string or num required"; + my $loc = $self->loc; + my @names; + for my $d (@_) { + if ($d =~ /^\d+$/) { + $d = (($d - 1) % 7) + $self->week_begin - 1; } + $d = $loc->dayname($d) || croak "day not found ", join(', ', @_); + return $d if @_ == 1; + push(@names, $d); } - $#dn > 0 ? @dn : $dn[0]; + @names; } sub daynum { - # Check/return day number 1..7, returns number. Accepts 1..7, + # check/return day number 1..7, returns number. Accepts 1..7, # or Su..Sa my $self = shift; - my $daynum = $self->locale_daynums; - my @dn; - push(@dn, map(exists $daynum->{$_} ? - $daynum->{$_}+1 : undef,$self->dayname(@_))); - $#dn > 0 ? @dn : $dn[0]; + @_ || croak "day string or num required"; + my $loc = $self->loc; + my @nums; + for my $d (@_) { + if ($d =~ /^\d+$/) { + $d = (($d - 1) % 7) + $self->week_begin - 1; + } + $d = $loc->daynum($d); + croak "day not found ", join(', ', @_) unless defined $d; + $d += 1; + return $d if @_ == 1; + push(@nums, $d); + } + @nums; } -# Tests-n-checks +# tests-n-checks sub _dayheadcheck { - # Test day head names + # test day head names my($self, $name) = splice(@_, 0, 2); - $name or croak "Name missing"; - return undef if $name =~ /^\d+$/; + $name or croak "name missing"; + return if $name =~ /^\d+$/; $self->daynum($name); } sub _daycheck { - # Check if an item is a day of the month (1..31) + # check if an item is a day of the month (1..31) my($self, $item) = splice(@_, 0, 2); - $item = shift or croak "Item required"; - # Can't just invert _headcheck because coords_of() needs _daycheck, + croak "item required" unless $item; + # can't just invert _headcheck because coords_of() needs _daycheck, # and _headcheck uses coords_of() $item =~ /^\d{1,2}$/ && $item <= 31; } sub _headcheck { - # Check if an item is a header + # check if an item is a header !_daycheck(@_); } -# Constructors/Destructors +# constructors/destructors sub new { my $class = shift; my %parms = @_; my(%attrs, %tattrs); foreach (keys %parms) { - if (__PACKAGE__->is_calmonth_attr($_)) { + if (__PACKAGE__->_is_calmonth_attr($_)) { $attrs{$_} = $parms{$_}; } else { @@ -733,15 +865,11 @@ sub new { } } - my $self = __PACKAGE__->class_element_table->new(%tattrs); + my $self = CLASS_HET->new(%tattrs); bless $self, $class; # set defaults - $self->set_defaults; - - # Enable blank cell fill so BGCOLOR shows up by default - # (HTML::ElementTable) - $self->blank_fill(1); + $self->_set_defaults; my $month = delete $attrs{month}; my $year = delete $attrs{year}; @@ -755,220 +883,166 @@ sub new { $self->year($year); # set overrides - $self->$_($attrs{$_}) foreach (keys %attrs); + for my $k (keys %attrs) { + $self->$k($attrs{$k}) if defined $attrs{$k}; + } - $self->loc($self->class_locale->new( + my $loc = CLASS_LOCALE->new( id => $self->locale, full_days => $self->full_days, full_months => $self->full_months, - )) or croak "Problem creating locale " . $self->locale . "\n"; + ) or croak "Problem creating locale " . $self->locale . "\n"; + $self->loc($loc); + + my $dt = CLASS_DATETOOL->new( + year => $self->year, + month => $self->month, + weeknum => $self->head_week, + historic => $self->historic, + datetool => $self->datetool, + ); + $self->_caltool($dt); + + $self->week_begin($loc->first_day_of_week + 1) + unless defined $attrs{week_begin}; + + my $dom_now = defined $attrs{today} ? $dt->_dom_now(delete $attrs{today}) + : $dt->_dom_now; + $self->_today($dom_now); + $self->today($dom_now) if $dom_now > 0; + + my $alias = $attrs{alias} || {}; + if ($self->full_days < 0) { + my @full = $self->loc->days; + my @narrow = $self->loc->narrow_days; + for my $i (0 .. $#narrow) { + $alias->{$full[$i]} = $narrow[$i]; + } + } + if ($self->full_months < 0) { + my @full = $self->loc->months; + my @narrow = $self->loc->narrow_months; + for my $i (0 .. $#narrow) { + $alias->{$full[$i]} = $narrow[$i]; + } + } + $self->alias($alias) if keys %$alias; - # For now, this is the only time this will every happen for this + # for now, this is the only time this will every happen for this # object. It is now 'initialized'. $self->_date($month, $year); $self; } -{ - -package HTML::CalendarMonth::Accessor; - -use strict; -use vars qw($VERSION @ISA); - -$VERSION = '0.01'; - -use Carp; - -use Class::Accessor; - -@ISA = qw(Class::Accessor); - -my %Objects; - -# Default complex attributes -my %Calmonth_Attrs = ( - head_m => 1, # Month heading mode - head_y => 1, # Year heading mode - head_dow => 1, # DOW heading mode - head_week => 0, # European week number mode - year_span => 2, # Default col span of year - - week_begin => 1, # What DOW (1-7) is the 1st DOW? - - historic => 1, # If able to choose, use 'cal' - # rather than Date::Calc, which - # blindly extrapolates Gregorian - - row_offset => 0, # Displacment within table - col_offset => 0, - - alias => {}, # What gets displayed if not - # the default item - - month => '', # These will get initialized - year => '', - - locale => 'en_US', - full_days => 0, - full_months => 1, - - datetool => '', - caltool => '', - - # internal muckety muck - _cal => '', - _itoc => {}, - _ctoi => {}, - _caltool => '', - _weeknums => '', - - dow1st => '', - lastday => '', - loc => '', -); - -__PACKAGE__->mk_accessors(keys %Calmonth_Attrs); - -# Class::Accessor overrides - -sub new { - my $class = shift; - my $self = $class->SUPER::new(@_); - foreach (sort keys %Calmonth_Attrs) { - $self->$_($Calmonth_Attrs{$_}); - } - $self; -} - -sub set { - my($self, $key) = splice(@_, 0, 2); - if (@_ == 1) { - $Objects{$self}{$key} = $_[0]; - } - elsif (@_ > 1) { - $Objects{$self}{$key} = [@_]; - } - else { - Carp::confess("Wrong number of arguments received"); - } -} +### overrides (our table is static) -sub get { - my $self = shift; - if (@_ == 1) { - return $Objects{$self}{$_[0]}; - } - elsif ( @_ > 1 ) { - return @{$Objects{$self}{@_}}; - } - else { - Carp::confess("Wrong number of arguments received."); - } -} +sub extent { } +sub maxrow { shift->SUPER::maxrow } +sub maxcol { shift->SUPER::maxcol } -sub is_calmonth_attr { shift; exists $Calmonth_Attrs{shift()} } +### deprecated -sub set_defaults { - my $self = shift; - foreach (keys %Calmonth_Attrs) { - $self->$_($Calmonth_Attrs{$_}); - } - $self; -} +use constant row_offset => 0; +use constant col_offset => 0; +use constant first_col => 0; +use constant first_row => 0; +use constant first_week_col => 0; +use constant last_week_col => 6; -} # end HTML::CalendarMonth::Accessor +### -# Go forth and prosper. 1; __END__ =head1 NAME -HTML::CalendarMonth - Perl extension for generating and manipulating HTML calendar months +HTML::CalendarMonth - Generate and manipulate HTML calendar months =head1 SYNOPSIS use HTML::CalendarMonth; - use HTML::AsSubs; - # Using HTML::AsSubs - $c = HTML::CalendarMonth->new( month => 3, year => 69 ); - $c->item($c->year, $c->month)->attr(bgcolor => 'wheat'); - $c->item($c->year, $c->month)->wrap_content(font({size => '+2'})); - $c->item(12, 16, 28)->wrap_content(strong()); + # Using regular HTML::Element creation + my $c = HTML::CalendarMonth->new( month => 8, year => 2010 ); print $c->as_HTML; - # Using regular HTML::Element creation - $c2 = HTML::CalendarMonth->new( month => 8, year => 79 ); - $c2->item($c2->year, $c2->month)->attr(bgcolor => 'wheat'); - $f = HTML::Element->new('font', size => '+2'); - $c2->item($c2->year, $c2->month)->wrap_content($f); - $c2->item_daycol('Su', 'Sa')->attr(bgcolor => 'cyan'); + # Full locale support via DateTime::Locale + my $c2 = HTML::CalendarMonth->new( + month => 8, + year => 2010, + locale => 'zu_ZA' + ); print $c2->as_HTML; # Full locale support via DateTime::Locale $c3 = HTML::CalendarMonth->new( month => 8, year => 79, locale => 'fr' ); print $c3->as_HTML + # HTML-Tree integration + my $tree = HTML::TreeBuilder->parse_file('cal.html'); + $tree->find_by_attribute(class => 'hcm-calendar')->replace_with($c); + print $tree->as_HTML; + + # clean up if you're not done, HTML::Element structures must be + # manually destroyed + $c->delete; $c2->delete; + =head1 DESCRIPTION HTML::CalendarMonth is a subclass of HTML::ElementTable. See L for how that class works, for it affects this -module on many levels. Like HTML::ElementTable, HTML::CalendarMonth -behaves as if it were an HTML::ElementSuper, which is a regular -HTML::Element with methods added to easily manipulate the appearance of -the HTML table containing the calendar. - -The primary interaction with HTML::CalendarMonth is through I. An -I is merely a symbol that represents the content of the cell of -interest within the calendar. For instance, the element representing the -14th day of the month would be returned by C<$c-Eitem(14)>. -Similarly, the element representing the header for Monday would be -returned by C<$c-Eitem('Mo')>. If the year happened to by 1984, then -C<$c-Eitem(1984)> would return the cell representing the year. Since +module on many levels. Like HTML::ElementTable, HTML::CalendarMonth is +an enhanced HTML::Element with methods added to facilitate the +manipulation of the calendar table elements as a whole. + +The primary interaction with HTML::CalendarMonth is through I +rather than cell coordinates like HTML::ElementTable uses. An I is +merely a string that represents the content of the cell of interest +within the calendar. For instance, the element representing the 14th day +of the month would be returned by C<$c-Eitem(14)>. Similarly, the +element representing the header for Monday would be returned by C<$c- +Eitem('Mo')>. If the year happened to by 2010, then C<$c- +Eitem(2010)> would return the cell representing the year. Since years and particular months change frequently, it is probably more useful to take advantage of the C and C methods, which -return the respective item symbol for the current calendar. In the prior -example, using 1984, the following is equivalent: C<$c-Eitem($c- -Eyear())>. +return their respective values. The following is therefore the same as +explicitely referencing the year: C<$c-Eitem($c- Eyear())>. Multiple cells of the calendar can be manipulated as if they were a -single element. For instance, C<$c-Eitem(15)-Eattr(bgcolor -=E 'cyan')> would alter the background color of the cell -representing the 15th. By the same token, C<$c-Eitem(15, 16, 17, -23)-Eattr(bgcolor =E 'cyan')> would do the same thing for all -cells containing the item symbols passed to the C method. - -The calendar structure is still nothing more than a table structure; the -same table structure provided by the HTML::ElementTable class. In -addition to the I based access methods above, calendar cells can -still be accessed using row and column grid coordinates using the -C method provided by the table class. All coordinate-based -methods in the table class are accessible to the calendar class. +single element. For instance, C<$c-Eitem(15)-Eattr(class =E +'fancyday')> would alter the class of the cell representing the 15th. By +the same token, C<$c-Eitem(15, 16, 17, +23)-Eattr(class =E 'fancyday')> would do the same thing for all +cells containing the days passed to the C method. + +Underneath, the calendar is still nothing more than a table structure, +the same as provided by the HTML::ElementTable class. In addition to the +I based access methods above, calendar cells can still be accessed +using row and column grid coordinates using the C method +provided by the table class. All coordinate-based methods in the table +class are accessible to the calendar class. The module includes support for week-of-the-year numbering, arbitrary -1st day of the week definitions, and aliasing so that you can express -any element in any language HTML can handle. +1st day of the week definitions, and locale support. Dates that are beyond the range of the built-in time functions of perl -are handled either by the 'cal' command, Date::Calc, or Date::Manip. The -presence of any one of these utilities and modules will suffice for -these far flung date calculations. If you want to use week-of-year -numbering, then either one of the date modules is required. +are handled either by the ncal/cal command, Date::Calc, DateTime, or +Date::Manip. The presence of any one of these utilities and modules will +suffice for these far flung date calculations. One of these utilities +(with the exception of 'cal') is also required if you want to use week-of- +year numbering. Full locale support is offered via DateTime::Locale. For a full list of -supported locale id's, look at HTML::CalendarMonth::Locale->locales() or -DateTime::Locale->ids(). +supported locale id's, look at HTML::CalendarMonth::Locale->locales(). =head1 METHODS All arguments appearing in [brackets] are optional, and do not represent anonymous array references. -B +=head2 Constructor =over @@ -1008,20 +1082,24 @@ Specifies whether to display days of the week header. Default 1. =item locale -Specifies a locale in which to render the calendar. Default is 'en_US'. -See L for more information. If for some -reason you prefer to use different labels than those provided by -C, see the C attribute below. +Specifies the id of the locale in which to render the calendar. Default +is 'en_US'. By default, this will also control determine which day is +considered to be the first day of the week. See +L for more information. If for some reason +you prefer to use different labels than those provided by C, see +the C attribute below. =item full_days Specifies whether or not to use full day names or their abbreviated -names. Default is 0, use abbreviated names. +names. Default is 0, use abbreviated names. Use -1 for 'narrow' mode, +the shortest (not guaranteed to be unique) abbreviations. =item full_months -Specifies whether or not to use full month names or their abbriviated -names. Default is 1, use full names. +Specifies whether or not to use full month names or their abbreviated +names. Default is 1, use full names. Use -1 for 'narrow' mode, the +shortest (not guaranteed to be unique) abbreviations. =item alias @@ -1037,47 +1115,63 @@ Specifies whether to display the week-of-year numbering. Default 0. =item week_begin Specify first day of the week, which can be 1..7, starting with Sunday. -Defaults to 1, or Sunday. In order to specify Monday, set this to 2, -and so on. +In order to specify Monday, set this to 2, and so on. By default, this +is determined based on the locale. + +=item enable_css + +Set some handy CSS class attributes on elements, enabled by default. +Currently the classes are: + + hcm-table Set on the table tag of the calendar + hcm-day-head Set on the day-of-week tr or td tags + hcm-year-head Set on the td tag for the year + hcm-month-head Set on the td tag for the month + hcm-week-head Set on the td tags for the week-of-year -=item row_offset +=item semantic_css -Specifies the offset of the first calendar row within the table -containing the calendar. This is 0 by default, making the first row of -the table the same as the first row of the calendar. +Sets some additional CSS class attributes on elements, disabled by +default. The notion of 'today' is taken either from the system clock +(default) or from the 'today' parameter as provided to new(). Currently +these classes are: -=item col_offset + hcm-today Set on the td tag for today, if present + hcm-past Set on the td tags for prior days, if present + hcm-future Set on the td tags for subsequent days, if present -Specifies the offset of the first calendar column within the table -containing the calendar. This is 0 by default, making the first column -of the table the same as the first row of the calendar. +=item today + +Specify the value for 'today' if different from the local time as +reported by the system clock (the default). If specified as two or less +digits, it is assumed to be one of the days of the month in the current +calendar. If more than two digits, it is assumed to be a epoch time in +seconds. Otherwise it must be given as a string of the form 'YYYY-mm- +dd'. Note that the default value as determined by the system clock uses +localtime rather than gmtime. =item historic This option is ignored for dates that do not exceed the range of the built- in perl time functions. For dates that B exceed these ranges, this -option specifies the default calculation method. When set, if the 'cal' -utility is available on your system, that will be used rather than the -Date::Calc or Date::Manip modules. This can be an issue since the date -modules blindly extrapolate the Gregorian calendar, whereas 'cal' takes -some of these quirks into account. If 'cal' is not available on your -system, this attribute is meaningless. Defaults to 1. +option specifies the default calculation method. When set, if the 'ncal' +or 'cal' command is available on your system, that will be used rather +than the Date::Calc or Date::Manip modules. This can be an issue since +the date modules blindly extrapolate the Gregorian calendar, whereas +ncal/cal will revert to the Julian calendar during September 1752. If +either ncal or cal are not available on your system, this attribute is +meaningless. Defaults to 1. =back =back -B +=head2 Item Query Methods -The following methods return lists of item symbols that are related in -some way to the provided list of items. The returned symbols may then -be used as arguments to the glob methods detailed further below. When -these methods deal with 'rows' and 'columns', they are only concerned -with the cells in the calendar -- not the cells that might be present -in the surrounding table if you have extended it. If you have not set -row or column offsets, or extended the span of the containing table, -then these rows and columns are functionally equivalent to the table -rows and columns. +The following methods return lists of item *symbols* (28, 29, 'Thu', +...) that are related in some way to the provided list of items. The +returned symbols may then be used as arguments to the glob methods +detailed further below. =over @@ -1096,24 +1190,28 @@ that are not header items (month, year, day-of-week). =item row_of(item1, [item2, ...]) -Returns the row numbers of rows containing the provided item symbols. +Returns the row indices of rows containing the provided item symbols. =item col_of(item1, [item2, ...]) -Returns the column numbers of columns containing the provided +Returns the column indices of columns containing the provided item symbols. =item lastday() -Returns the number of the last day of the month. +Returns the day number (symbol) of the last day of the month. =item dow1st() -Returns the column number for the first day of the month. +Returns the column index for the first day of the month. =item days() -Returns a list of all days of the month. +Returns a list of all days of the month as numbers. + +=item week_nums() + +Returns a list of week-of-year numbers for this month. =item dayheaders() @@ -1125,40 +1223,48 @@ Returns a list of all headers (month, year, dayheaders) =item items() -Returns a list of all item symbols in the calendar. - -=item first_col() - -Returns the number of the first column of the calendar. This could be -different from that of the surrounding table if the table was extended, -but otherwise should be identical. +Returns a list of all item symbols (day number, header values) in +the calendar. =item last_col() -Returns the number of the last column of the calendar. This could be -different from that of the surrounding table if the table was extended, -but should otherwise be identical. +Returns the index of the last column of the calendar (note that this +could be the week-of-year column if head_week is enabled). -=item first_row() +=item last_day_col() -Returns the number of the first row of the calendar. This could be -different from that of the surrounding table if offsets were made. +Returns the index of the last column of the calendar containing days of +the month (same as last_col() unless week-of-year is enabled). =item first_week_row() -Returns the number of the first row of the calendar containing day items -(ie, the first week). This could vary depending on table offsets and -header modes. +Returns the index of the first row of the calendar containing day items +(ie, the first week). =item last_row() -Returns the number of the last row of the calendar. This could be -different from that of the surrounding table if the table was extended, -but should otherwise be identical. +Returns the index of the last row of the calendar. + +=item today() + +Returns the day of month for 'today', if present in the current +calendar. + +=item past_days() + +Returns a list of days prior to 'today'. If 'today' is in a future +month, all days are returned. If 'today' is in a past month, no days +are returned. + +=item future_days() + +Returns a list of days after 'today'. If 'today' is in a past +month, all days are returned. If 'today' is in a future month, no +days are returned. =back -B +=head2 Glob Methods Glob methods return references that are functionally equivalent to an individual calendar cell. Mostly, they provide item based analogues to @@ -1181,13 +1287,21 @@ Returns all cells containing the provided item symbols. Returns all cells in all rows occupied by the provided item symbols. +=item item_day_row(item1, [item2, ...]) + +Same as item_row() except excludes week-of-year cells, if present. + =item item_col(item1, [item2, ...]) Returns all cells in all columns occupied by the provided item symbols. =item item_daycol(item1, [item2, ...]) -Same as item_col(), except limits the cells to non header cells. +Same as item_col() except limits the cells to non header cells. + +=item item_week_nums() + +Returns all week-of-year cells, if present. =item item_box(item1a, item1b, [item2a, item2b, ...]) @@ -1207,7 +1321,7 @@ Returns all cells in the calendar, including empty cells. =back -B +=head2 Transformation Methods The following methods provide ways of translating between various item symbols, coordinates, and other representations. @@ -1216,8 +1330,8 @@ symbols, coordinates, and other representations. =item coords_of(item) -Returns the row and column of the provided item symbol, for use with the -grid based methods in HTML::ElementTable. +Returns the row and column coordinates of the provided item symbol, for +use with the grid based methods in HTML::ElementTable. =item item_at(row,column) @@ -1252,30 +1366,17 @@ must be present in the current calendar. =back -=head1 Notes On Dates And Spatial Relationships - -One of the nice things about having a calendar represented as a table -accessible with grid coordinates is that some of the trickier date -calculations become trivial. You can use packages such as I -or I for these sort of things, but the algorithms are often -derived from a common human activity: looking at a calendar on a wall. -Say, for instance, that you are interested in "the third Friday of every -month". If you are using a calendar with Sunday as the first day of the -week, then Fridays will always be in column 5, starting from 0. -Likewise, due to the fact that supressed headers are merely I in -the actual table, the first row with dates in a calendar structure will -B be 2, even if the month, year, or day headers are disabled. -The third friday of every month therefore becomes C<$c-Ecell(2,5)>, -regardless of the particular month. Likewise, the "nth dayname/week of -the month" can always be mapped to table coordinates. - -The particulars of this grid mapping are affected if you have redefined -what the first day of the week is, or if you have tweaked the table -beyond the bounds of the calendar itself. There are methods that can -help under these circumstances, though. For instance, in our example -where we are interested in the 3rd Friday of the month, the row number -is accessed with C<$c-Efirst_week_row + 2>, whereas the column -number could be derived with C<$c-Elast_col - 1>. +=head2 Other Methods + +=over + +=item default_css() + +Returns a simple style sheet as a string that can be used in an HTML +document in conjunction with the classes assigned to elements when css +is enabled. + +=back =head1 REQUIRES @@ -1283,8 +1384,9 @@ HTML::ElementTable =head1 OPTIONAL -Date::Calc or Date::Manip (only if you want week-of-year numbering or -non-contemporary dates on a system without the I command) +Date::Calc, DateTime, or Date::Manip (only if you want week-of- +year numbering or non-contemporary dates on a system without the +I command) =head1 AUTHOR @@ -1292,7 +1394,7 @@ Matthew P. Sisk, EFE =head1 COPYRIGHT -Copyright (c) 1998-2008 Matthew P. Sisk. All rights reserved. All wrongs +Copyright (c) 1998-2010 Matthew P. Sisk. All rights reserved. All wrongs revenged. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. @@ -1306,4 +1408,4 @@ names, see http://www.loc.gov/standards/iso639-2/englangn.html HTML::ElementTable(3), HTML::Element(3), perl(1) -=cut +=for Pod::Coverage col_offset row_offset item_alias item_aliased last_week_row