diff --git a/www/rem-default.css b/www/rem-default.css new file mode 100644 index 00000000..df9e9253 --- /dev/null +++ b/www/rem-default.css @@ -0,0 +1,64 @@ +th.rem-cal-hdr { + width: 14%; + border-style: solid; + border-width: 1px; + vertical-align: top; +} +td.rem-empty { + width: 14%; + height: 5em; + border-style: solid; + border-width: 1px; + vertical-align: top; +} +td.rem-cell { + width: 14%; + height: 5em; + border-style: solid; + border-width: 1px; + vertical-align: top; +} +td.rem-small-calendar { + width: 14%; + height: 5em; + border-style: solid; + border-width: 1px; + vertical-align: top; +} +table.rem-cal { + width: 100%; + border-collapse: collapse; +} + +div.rem-daynumber { + float: right; + text-align: right; + vertical-align: top; +} + +div.rem-moon { + float: left; + text-align: left; + vertical-align: top; +} + +th.rem-sc-hdr { + text-align: right; + font-size: x-small; +} + +td.rem-sc-empty-cell { + text-align: right; + font-size: x-small; + width: 14%; +} + +td.rem-sc-cell { + text-align: right; + font-size: x-small; + width: 14%; +} + +caption.rem-sc-caption { + font-size: x-small; +} \ No newline at end of file diff --git a/www/rem2html b/www/rem2html index 2f934868..132ab8f4 100755 --- a/www/rem2html +++ b/www/rem2html @@ -1,102 +1,384 @@ #!/usr/bin/perl -# rem2html -# -# A script to convert from the output of "remind -p" to Hyper-Text Markup -# Language (HTML), the text format used in WWW documents. By default, it -# outputs a stand-alone file which can be fed directly into a web browser. -# The output uses nested blocks, so it will only work in a browser -# which supports tables (Netscape, MSIE, etc, NOT Lynx). -# -# This script works well on my computer (Linux 2.0.27) under Perl 5.003 and -# 5.004. It should work fine on other unices but I have no idea whether -# it will run under VMS, OS/2, Windows, etc. -# -# [Note from David: The REMIND license prohibits you from using REMIND -# under Windows.] -# -# Rem2html puts "normal" CAL or MSG-type reminders in a

pair, -# and escapes any special HTML characters. -# -# If you want to put actual HTML code in the calendar (hyper-links, for -# example), use the "SPECIAL HTML" type. For example: -# -# REM Wed SPECIAL HTML

Meeting at \ -# Linux HQ

-# -# This file is Copyright (C) 1997-8 by Don Schwarz -# and David F. Skoll +use strict; +use warnings; use Getopt::Long; -@months = (January,February,March,April,May,June,July,August,September,October,November,December); +my %Options; - $DefaultImageDir = "%IMAGEBASE%"; -if ($DefaultImageDir =~ m@/$@) { - chop $DefaultImageDir; -} +my $rem2html_version = '2.0'; -$rem2html_version = "1.0"; +my($days, $shades, $moons, $Month, $Year, $Numdays, $Firstwkday, $Mondayfirst, + @Daynames, $Nextmon, $Nextlen, $Prevmon, $Prevlen); -&parse_options(); +# rem2html -- convert the output of "remind -p" to HTML -# Backgound color -- unfortunately, most Web browsers (as of 14 October 1999) -# do not correctly handle transparency in PNG images, so I had to make the -# moon image background white. -$Options{'bgcolor'} ||= "BGCOLOR=\"#FFFFFF\""; +=head1 NAME -if (-t STDIN) { - print STDERR "(Rem2HTML: Input should not come from a terminal.)\n"; - $Options{'help'} = 1; -} +rem2html - Convert the output of "remind -p" to HTML -if ($Options{'help'}) { - &show_usage(); -} elsif ($Options{'version'}) { - print "Rem2HTML Version $rem2html_version.\n"; -} else { - $successes = 0; - while(1) { - last if (!parse_input()); - $successes++; - &output_header(); - &output_data(); - &output_footer(); - } - print STDERR "Rem2HTML: Couldn't find any calendar data.\n" if (!$successes); -} +=head1 SYNOPSIS -exit(0); +remind -p ... | rem2html [options] -sub show_usage { - print STDERR < ---forwurl url Same as --backurl, but with the next month's small calendar ---tableonly Output the results as a
block only, no , etc. ---border,-b size Set the border thickness of the table ---cellspace,-t size Set the line thickness of the table ---bgcolor,-g color Set the background color for the day entries - -EndOfUsage - +--help, -h Print usage information +--version Print version +--stylesheet file.css Specify CSS stylesheet +--backurl url Make the title on the previous month's small calendar + entry a link to +--forwurl url Same as --backurl, but for the next month's small calendar +--tableonly Output results as a
only, no , , etc. +--title What to put in ... tags +--prologue html_text Text to insert at the top of the body +--epilogue html_text Text to insert at the end of the body +EOM + exit(0); } -sub escape_html { +=head2 parse_options + +Parse command-line options + +=cut + +sub parse_options +{ + GetOptions(\%Options, "help|h", + "version", + "stylesheet|s:s", + "backurl|bu:s", + "forwurl|fu:s", + "title|ti:s", + "prologue|pr:s", + "epilogue|ep:s", + "tableonly|to"); + $Options{'title'} ||= 'HTML Calendar'; + $Options{'stylesheet'} ||= "rem-default.css"; +} + +=head2 start_output + +Start the HTML output + +=cut +sub start_output +{ + return if ($Options{'tableonly'}); + + print("\n\n" . $Options{'title'} . "\n"); + if ($Options{'stylesheet'}) { + print('' . "\n"); + } + print("\n\n"); + if ($Options{'prologue'}) { + print $Options{'prologue'} . "\n"; + } +} + +=head2 end_output + +Finish off the calendar + +=cut +sub end_output +{ + return if ($Options{'tableonly'}); + if ($Options{'epilogue'}) { + print $Options{'epilogue'} . "\n"; + } + print("\n\n"); +} + +=head2 parse_input + +Parse off one month's worth of input + +=cut +sub parse_input +{ + undef $days; + undef $shades; + undef $moons; + + my $found_data = 0; + while() { + chomp; + last if /^\# rem2ps begin$/; + } + + my $line; + # Month Year numdays firstday monday_first_flag + $line = ; + return 0 unless $line; + chomp($line); + ($Month, $Year, $Numdays, $Firstwkday, $Mondayfirst) = split(' ', $line); + + # Day names + $line = ; + return 0 unless $line; + chomp($line); + @Daynames = split(' ', $line); + + # Prevmon prevlen + $line = ; + return 0 unless $line; + chomp($line); + ($Prevmon, $Prevlen) = split(' ', $line); + + # Nextmon nextlen + $line = ; + return 0 unless $line; + chomp($line); + ($Nextmon, $Nextlen) = split(' ', $line); + + $found_data = 1; + while() { + chomp; + last if /^\# rem2ps end$/; + next if /^\#/; + next unless m/^(\d*).(\d*).(\d*)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*)$/; + my ($y, $m, $d, $special, $tag, $duration, $time, $body) = + ($1, $2, $3, $4, $5, $6, $7, $8); + if ($special eq 'HTML') { + push(@{$days->[$d]}, $body); + } elsif ($special eq 'MOON') { + if ($body =~ /(\S+)\s+(\S+)\s+(\S+)\s+(.*)$/) { + my ($phase, $moonsize, $fontsize, $msg) = ($1, $2, $3, $4); + $moons->[$d]->{'phase'} = $phase; + $moons->[$d]->{'msg'} = $msg; + } + } elsif ($special eq 'SHADE') { + if ($body =~ /(\d+)\s+(\d+)\s+(\d+)/) { + $shades->[$d] = sprintf("#%02X%02X%02X", + $1 % 255, $2 % 255, $3 % 255); + } + } elsif ($special eq 'COLOR') { + if ($body =~ /(\d+)\s+(\d+)\s+(\d+)\s+(.*)$/) { + my($r, $g, $b, $text) = ($1, $2, $3, $4); + my $color = sprintf("style=\"color: #%02X%02X%02X;\"", + $r % 255, $g % 255, $b % 255); + push(@{$days->[$d]}, '

' . escape_html($text) . '

'); + } + } elsif ($special eq '*') { + push(@{$days->[$d]}, '

' . escape_html($body) . '

'); + } + } + return $found_data; +} + +=head2 small_calendar MONTH, MONLEN, URL, FIRST_COL + +Draw a small calendar + +=cut + +sub small_calendar +{ + my($month, $monlen, $url, $first_col) = @_; + if ($Mondayfirst) { + $first_col--; + if ($first_col < 0) { + $first_col = 6; + } + } + + print "
\n"; +} + +=head2 output_calendar + +Take the parsed input and output a calendar + +=cut + +sub output_calendar +{ + # Which column is 1st of month in? + my $first_col = $Firstwkday; + if ($Mondayfirst) { + $first_col--; + if ($first_col < 0) { + $first_col = 6; + } + } + + # Last column + my $last_col = ($first_col + $Numdays - 1) % 7; + + + # Start the table + print '
\n"; + print "\n"; + print "\n"; + + print ''; + if (!$Mondayfirst) { + print ''; + } + for (my $i=1; $i<7; $i++) { + print ''; + } + if ($Mondayfirst) { + print ''; + } + print("\n"); + my $col = 0; + for (; $col<$first_col; $col++) { + if ($col == 0) { + print("\n"); + } + print("\n"); + } + + for (my $day=1; $day <= $monlen; $day++) { + if ($col == 0) { + print("\n"); + } + $col++; + print("\n"); + if ($col == 7) { + print("\n"); + $col = 0; + } + } + if ($col) { + while ($col < 7) { + print("\n"); + $col++; + } + print("\n"); + } + print("
"; + print "" if ($url); + print $month; + print "" if ($url); + print "
' . substr($Daynames[0], 0, 1) . '' . substr($Daynames[$i], 0, 1) . '' . substr($Daynames[0], 0, 1) . '
 
$day
 
\n"); + print "
' . "\n"; + print ''; + if (!$Mondayfirst) { + print ''; + } + for (my $i=1; $i<7; $i++) { + print ''; + } + if ($Mondayfirst) { + print ''; + } + print "\n"; + + # Start the calendar rows + my $col = 0; + print "\n"; + if ($first_col > 0) { + small_calendar($Prevmon, $Prevlen, $Options{'backurl'}, + ($Firstwkday - $Prevlen + 35) % 7); + $col++; + } + + if ($last_col == 6) { + small_calendar($Nextmon, $Nextlen, $Options{'forwurl'}, + ($Firstwkday + $Numdays) % 7); + $col++; + } + while ($col < $first_col) { + print("\n"); + $col++; + } + + for (my $day=1; $day<=$Numdays; $day++) { + draw_day_cell($day); + $col++; + if ($col == 7) { + $col = 0; + print "\n"; + if ($day < $Numdays) { + print "\n"; + } + } + } + + if ($col) { + while ($col < 7) { + if ($col == 5) { + if ($first_col == 0) { + small_calendar($Prevmon, $Prevlen, $Options{'backurl'}, + ($Firstwkday - $Prevlen + 35) % 7); + } else { + print("\n"); + } + } elsif ($col == 6) { + small_calendar($Nextmon, $Nextlen, $Options{'forwurl'}, + ($Firstwkday + $Numdays) % 7); + } else { + print("\n"); + } + $col++; + } + print "\n"; + } + + # End the table + print "
' . + $Month . ' ' . $Year . '
' . $Daynames[0] . '' . $Daynames[$i] . '' . $Daynames[0] . '
 
  
\n"; +} + +sub draw_day_cell +{ + my($day) = @_; + my $shade = $shades->[$day]; + if ($shade) { + $shade = " style=\"background: $shade;\""; + } else { + $shade = ""; + } + print "\n"; + if ($moons->[$day]) { + my $phase = $moons->[$day]->{'phase'}; + my $msg = $moons->[$day]->{'msg'}; + $msg ||= ''; + if ($msg ne '') { + $msg = ' ' . escape_html($msg); + } + my $img; + if ($phase == 0) { + $img = 'newmoon.png'; + } elsif ($phase == 1) { + $img = 'firstquarter.png'; + } elsif ($phase == 2) { + $img = 'fullmoon.png'; + } else { + $img = 'lastquarter.png'; + } + print("
\"$img\"$msg
"); + } + + print "
$day
\n"; + if ($days->[$day]) { + print(join("\n", @{$days->[$day]})); + } + + print "\n"; +} + +sub escape_html +{ my($in) = @_; $in =~ s/\&/\&/g; $in =~ s/\) { - chomp($_); - if (/rem2(html|ps) begin/) { - } elsif (!$where) { - next; - } elsif ($where == 1) { - local ($month, $year); - ($month, $year, $month_length, $firstday, $mfirst) = split(" "); - $caption = "$month, $year"; - for $i ( 1 .. $month_length) { push(@days, ""); } - } elsif ($where == 2) { - @DayNames = split(" "); - } elsif ($where == 3) { - @prevsc = split(" "); - } elsif ($where == 4) { - @nextsc = split(" "); - } else { - return 1 if /rem2(html|ps) end/; - next if /^\#/; - next unless m/^(\d*).(\d*).(\d*)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*)$/; - $type = $4; - $msg = $8; - $day = $3; - if ($type eq "HTML") { - $days[$day] .= "$msg "; - } elsif ($type eq "MOON") { - my($phase, $text); - if ($msg =~ /^\s*(\d+)\s+\S+\s+\S+\s+(.*)$/) { - $phase = $1; - $text = $2; - } elsif ($msg =~ /^\s*(\d+)/) { - $phase = $1; - $text = ""; - } else { - next; - } - next if ($phase > 3); - if ($phase == 0) { - $text = "\"New " . escape_html($text); - } elsif ($phase == 1) { - $text = "\"First " . escape_html($text); - } elsif ($phase == 2) { - $text = "\"Full " . escape_html($text); - } else { - $text = "\"Last " . escape_html($text); - } - $moons[$day] = $text . " "; - } elsif ($type eq "SHADE") { - my($red, $green, $blue); - if ($msg =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s*$/) { - $red = $1; - $green = $2; - $blue = $3; - } elsif ($msg =~ /^\s*(\d+)\s*$/) { - $red = $1; - $green = $1; - $blue = $1; - } else { - next; - } - next if ($red > 255 || $green > 255 || $blue > 255); - $shades[$day] = sprintf(" BGCOLOR=\"#%02X%02X%02X\"", - $red, $green, $blue); - } elsif ($type eq "COLOR") { - my($red, $green, $blue, $stuff); - if ($msg =~ /^\s*(\d+)\s+(\d+)\s+(\d+)\s*(.*)$/) { - $red = $1; - $green = $2; - $blue = $3; - $stuff = $4; - next if ($red > 255 || $green > 255 || $blue > 255); - $days[$day] .= - sprintf("

", - $red, $green, $blue) . - escape_html($stuff) . "

"; - } else { - next; - } - } elsif ($type eq "*") { - $msg = &escape_html($msg); - $days[$day] .= "

$msg

"; - } - } - $where++; - } - if ($where) { - return 1; - } - return 0; +if (-t STDIN) { + print STDERR "$0: Input should not come from a terminal.\n\n"; + usage(); } -sub output_header { - local ($title, $dayheader); - - if (!$Options{'tableonly'}) { - print < - Reminders for $caption - -EndOfHTML - } - - print <) and Remind (written by David F. Skoll). --> -EndOfHTML - - if ($Options{'prologue'}) { - open(PROLOGUE, "< $Options{'prologue'}"); - print while ( ); - close(PROLOGUE); - } - - $caption = &format_font($caption, $Options{'ft'}, $Options{'st'} || "+1"); - - print < - $caption - -EndOfHTML - - $mfirst || &print_day_header($DayNames[0]); - - for($i=1; $i<7; $i++) { - &print_day_header($DayNames[$i]); - } - - $mfirst && &print_day_header($DayNames[0]); - print " \n"; +my $found_something = 0; +while(1) { + last if (!parse_input()); + start_output() unless $found_something; + $found_something = 1; + output_calendar(); +} +if ($found_something) { + end_output(); + exit(1); +} else { + print STDERR "$0: Could not find any calendar data on STDIN.\n"; + exit(1); } -sub output_footer { - print "\n"; - - if ($Options{'append'}) { - open(EPILOGUE, "< $Options{'append'}"); - print while ( ); - close(EPILOGUE); - } - - unless ($Options{'tableonly'}) { - print < - -EndOfHTML - } -} - -sub output_data { - local ($endday, $prevday, $nextday, $week, $weekday); - local ($element, $day, $msg, $fday); - $firstday -= $mfirst; - if ($firstday < 0) { $firstday += 7; } - $endday = $firstday + $month_length; - $endweek = $endday + (6 - ($endday % 7)); - $endday %= 7; - - if ( $firstday > 1 ) { - $prevday = 0; - $nextday = 1; - } elsif ($endday ? ($endday < 5) : !$firstday) { - $prevday = $endweek - 1; - $nextday = $endweek; - } else { - $prevday = 0; - $nextday = $endweek; - } - - for $week ( 0..5 ) { - print " \n"; - for $weekday ( 0..6 ) { - $element = ($week * 7) + ($weekday * 1); - $day = $element - $firstday + 1; - $msg = $days[$day]; - $msg = $msg ? &format_font($msg, $Options{'fe'}, $Options{'se'}) - : "



"; - - $fday = &format_font($day, $Options{'fd'}, $Options{'sd'} || -1); - if ($day > 0 && $day <= $month_length) { - - print < -

$moons[$day]$fday

- $msg - -EndOfHTML - - } elsif ($element == $prevday) { - &small_calendar(@prevsc, 1, $Options{'backurl'}); - } elsif ($element == $nextday) { - &small_calendar(@nextsc, 2, $Options{'forwurl'}); - } else { - print "
"; - } - } - print " \n"; - last if $day >= $month_length && $element >= $nextday; - } -} - -sub small_calendar { - local ($scname, $scn, $which, $url) = @_; - local ($scstart, $l, $week, $weekday, $tday); - - $scname = "$scname", if $url; - $scname = &format_font($scname, $Options{'fs'}, -2); - - if ($which == 1) { - $scstart = $firstday - ($scn % 7); - if ($scstart < 0) { $scstart += 7; } - } else { - $scstart = $firstday + ($month_length % 7); - if ($scstart > 6) { $scstart -= 7; } - } - - print < - - - -EndOfHTML - - $mfirst || &print_day_header(substr($DayNames[0], 0, 1), 1); - - for ($i=1; $i<7; $i++) { - &print_day_header(substr($DayNames[$i], 0, 1), 1); - } - - $mfirst && &print_day_header(substr($DayNames[0], 0, 1), 1); - - print "\n"; - - for $week ( 0..5 ) { - print " \n"; - for $weekday ( 0..6 ) { - $tday = ($week * 7) + ($weekday * 1) - $scstart + 1; - $tday = "", if $tday <= 0 || $tday > $scn; - print " \n"; - } - print " \n"; - last if $tday >= $scn; - } - - print < - -EndOfHTML - -} - -sub format_font { - local ($text, $font, $size) = @_; - - if (!$text) { - return ""; - } elsif ($font && $size) { - return "$text"; - } elsif ($font) { - return "$text"; - } elsif ($size) { - return "$text"; - } else { - return $text; - } -} - -sub print_day_header { - local ($dheader, $small) = @_; - - if ($small) { - $dheader = &format_font($dheader, $Options{'fs'}, -2); - } else { - $dheader = &format_font($dheader, $Options{'fh'}, $Options{'sh'}); - } - - print " \n"; -}
$scname
$tday
$dheader