#!/usr/bin/perl -w # htmlcal # Produces a calendar for the four weeks in HTML format, including # appointments and WHY, and a todo list. Also prints it all out as # plain text on stdout. # Files: # events # Contains events in format "yyyy/m/d descriptive text", # one per line. Lines beginning # are comments. # Year or month set to zero means "every". # todo # Contains things to do, one per line. Web and mail addresses # complete with http:// or mailto: will be made active in the # output. # calendar.html # contains the spiffy output for the next 28 days. # These all live in $workingdir, which is ~/.htmlcal by default. # (c) rfbooth, 2001. http://rfbooth.com/ use strict ; sub mil_day ; # mday = mil_day(day, month, year) sub make_document_opening ; my $version = 1.02 ; my $workingdir = "$ENV{HOME}/.htmlcal/" ; ###################################################################### my @month_offsets=(0,31,59,90,120,151,181,212,243,273,304,334); my @wdays=("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat") ; my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) ; my $wday ; # day of the week today, 0-6 my $month ; # month, 0-11 my $mday ; # date, 1-31 (possibly) my $year ; # year (since 1900) my @events ; # to hold everything for the next four weeks $#events = 27 ; my $today ; # will be today as a mil_day my $event ; # event, read from file. my $eday ; # my $emonth ; # when the event is my $eyear ; # my $delta_day ; # days from today for event ($mday, $month, $year, $wday ) = (localtime)[3,4,5,6] ; $today = mil_day($mday, $month, $year) ; ############################################################ # read the events open ( EVENTS, "${workingdir}events" ) or die "Can't open ${workingdir}events: $!" ; while ($event = ) { next if $event =~ /^\s*$/ ; next if $event =~ /^\#/ ; chomp $event ; ($event =~ s{^([0-9]+)/([0-9]+)/([0-9]+)\s*}{}) or die "Bad or no date in events:\n $event" ; ($eyear, $emonth, $eday) = ( $1-1900, $2-1 , $3 ) ; if ( $emonth == -1 ) { for ( $emonth = 0 ; $emonth < 12 ; ++$emonth ) { make_event( $eyear, $emonth, $eday ) ; } } else { make_event( $eyear, $emonth, $eday ) ; } } ############################################################ # Write the htmldoc and so on. open ( CAL, "> ${workingdir}calendar.html" ) or die "Can't open ${workingdir}calendar.html: $!" ; make_document_opening ; my $loopv ; for ( $loopv = 0 ; $loopv < 28 ; ++$loopv ) { if ( ($loopv % 7) == 0 ) { print CAL " \n"; } if ( defined($events[$loopv]) ) { print $events[$loopv][0], ":\n" ; print CAL " \n" ; print CAL " $events[$loopv][0]\n" ; foreach (@{$events[$loopv][1]}) { print " $_\n" ; print CAL "
$_\n" ; } print CAL " \n" ; } else { print CAL "  \n" ; } if ( ($loopv % 7) == 6 ) { print CAL " \n"; } } $ year += 1900 ; print CAL "\n\n

\n Generated on $months[$month] $mday $year ", "by htmlcal version $version.", "\n Copyright © rfbooth 2001.\n", "

\n\n" ; #--------------------------------------------------------------------- ###################################################################### # make_event( $eyear, $emonth, $eday ) # # generates the actual event value. sub make_event { my $eyear = shift ; my $emonth = shift ; my $eday = shift ; if ( $eyear == -1900 ) { $eyear = $year ; if ( ($emonth < $month ) or ( ($emonth == $month) and ($eday < $mday) ) ) { # then look at next year ++$eyear ; } } $delta_day = mil_day( $eday, $emonth , $eyear ) - $today ; if ( ($delta_day >= 0) and ( $delta_day < 28 ) ) { if ( !(defined($events[$delta_day])) ) { $events[$delta_day] = [ "$eday $months[$emonth]", [ $event ] ] ; } else { # slightly heavy referencing voodoo. Here # $events[$delta_day][1] is a reference to a # list of events. push(@{$events[$delta_day][1]}, $event) ; } } } #--------------------------------------------------------------------- ###################################################################### # mday = mil_day(day, month, year) # # Takes date as (day_of_month (1-whatever), month (0-11), year-1900) # and returns days since 1900/1/0 (so 1 Jan 1900 is 1). # # the mil is for millenium (ie days since the millenium), but I # changed my mind. Leave me alone! sub mil_day { my $lday = shift ; my $lmonth = shift ; my $lyear = shift ; # first ignore leap years my $answer = $lday + $month_offsets[$lmonth] + 365 * $lyear ; # it's not a leap year yet until we pass February: --$lyear if ( $lmonth < 2 ); # every 4 years unless divisible by 100, unless div by 400. $answer += int($lyear/4) - int($lyear/100) + int(($lyear+300)/400) ; return $answer ; } #--------------------------------------------------------------------- ###################################################################### # make_document_opening sub make_document_opening { print CAL "\n", "\n\n", "\n", " Upcoming commitments \n", "\n", "\n\n\n\n", " \n" ; my $loopvar ; for ( $loopvar = 0 ; $loopvar < 7 ; ++$loopvar ) { print CAL " \n"; } print CAL " \n" } #--------------------------------------------------------------------- # EOF ######################################################################
\n ", $wdays[($loopvar+$wday) % 7], "\n