Files
remind/www/rem2html
2007-08-22 16:34:35 -04:00

417 lines
11 KiB
Perl
Executable File

#!/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 <TABLE> 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 <P></P> 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 <P> Meeting at \
# <A HREF="http://www.linuxhq.com">Linux HQ</A> </P>
#
# This file is Copyright (C) 1997-8 by Don Schwarz <darkowl@mcs.net>
# and David F. Skoll
use Getopt::Long;
@months = (January,February,March,April,May,June,July,August,September,October,November,December);
$DefaultImageDir = "%IMAGEBASE%";
if ($DefaultImageDir =~ m@/$@) {
chop $DefaultImageDir;
}
$rem2html_version = "1.0";
&parse_options();
# 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\"";
if (-t STDIN) {
print STDERR "(Rem2HTML: Input should not come from a terminal.)\n";
$Options{'help'} = 1;
}
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);
}
exit(0);
sub show_usage {
print STDERR <<EndOfUsage;
Rem2HTML: Produce a HTML calendar from the output of Remind.
Usage: rem2html [options]
Options:
--help, -h Print this information
--version Version information
-p file Prepend the specified HTML file to the beginning of the
output
-a file Append the specified HTML file to the end of the output
-f[shted] font Set font for small cal, hdr, title, cal entries,day numbers
-s[hted] size Set size for header, title, calendar entries and/or day
numbers
--backurl url Make the title on the previous month's small calendar entry
a hyperlink to <url>
--forwurl url Same as --backurl, but with the next month's small calendar
--tableonly Output the results as a <TABLE> block only, no <HTML>, 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
}
sub escape_html {
my($in) = @_;
$in =~ s/\&/\&amp;/g;
$in =~ s/\</\&lt;/g;
$in =~ s/\>/\&gt;/g;
return $in;
}
sub parse_options {
%Options = ();
GetOptions (\%Options, "help|h",
"version",
"border|b=i",
"cellspace|t=i",
"backurl|bu:s", "forwurl|fu:s",
"tableonly|to",
"prologue|p=s",
"append|a=s",
"bgcolor|g=s",
"fs=s", "fh=s", "ft=s", "fe=s", "fd=s",
"sh=i", "st=i", "se=i", "sd=i",
);
$Options{'border'} = "BORDER=" . ($Options{'border'} || 1);
$Options{'cellspace'} &&= "CELLSPACING=$Options{'cellspace'}";
$Options{'bgcolor'} &&= "BGCOLOR=$Options{'bgcolor'}";
}
sub parse_input {
local $where = 0;
local $msg;
local $type;
local $day;
@days = ();
@shades = ();
@moons = ();
while (<>) {
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 = "<IMAGE SRC=\"$DefaultImageDir/newmoon.png\" ALT=\"New Moon\"" .
"WIDTH=16 HEIGHT=16> <FONT SIZE=\"-2\">" . escape_html($text);
} elsif ($phase == 1) {
$text = "<IMAGE SRC=\"$DefaultImageDir/firstquarter.png\" ALT=\"First Quarter\"" .
"WIDTH=16 HEIGHT=16> <FONT SIZE=\"-2\">" . escape_html($text);
} elsif ($phase == 2) {
$text = "<IMAGE SRC=\"$DefaultImageDir/fullmoon.png\" ALT=\"Full Moon\"" .
"WIDTH=16 HEIGHT=16> <FONT SIZE=\"-2\">" . escape_html($text);
} else {
$text = "<IMAGE SRC=\"$DefaultImageDir/lastquarter.png\" ALT=\"Last Quarter\"" .
"WIDTH=16 HEIGHT=16> <FONT SIZE=\"-2\">" . escape_html($text);
}
$moons[$day] = $text . "</FONT> ";
} 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("<P><font color=\"#%02x%02x%02x\">",
$red, $green, $blue) .
escape_html($stuff) . "</font></P>";
} else {
next;
}
} elsif ($type eq "*") {
$msg = &escape_html($msg);
$days[$day] .= "<P>$msg</P>";
}
}
$where++;
}
if ($where) {
return 1;
}
return 0;
}
sub output_header {
local ($title, $dayheader);
if (!$Options{'tableonly'}) {
print <<EndOfHTML;
<HTML>
<HEAD><TITLE>Reminders for $caption</TITLE></HEAD>
<BODY>
EndOfHTML
}
print <<EndOfHTML;
<!-- This output was produced by Rem2HTML $rem2html_version (written by
Don Schwarz <darkowl\@mcs.net>) and Remind (written by David F. Skoll). -->
EndOfHTML
if ($Options{'prologue'}) {
open(PROLOGUE, "< $Options{'prologue'}");
print while ( <PROLOGUE> );
close(PROLOGUE);
}
$caption = &format_font($caption, $Options{'ft'}, $Options{'st'} || "+1");
print <<EndOfHTML;
<TABLE $Options{'border'} $Options{'cellspace'} $Options{'bgcolor'} WIDTH=100%>
<CAPTION><STRONG>$caption</STRONG></CAPTION>
<TR>
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 " </TR>\n";
}
sub output_footer {
print "</TABLE>\n";
if ($Options{'append'}) {
open(EPILOGUE, "< $Options{'append'}");
print while ( <EPILOGUE> );
close(EPILOGUE);
}
unless ($Options{'tableonly'}) {
print <<EndOfHTML;
</BODY>
</HTML>
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 " <TR>\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'})
: " <BR> <BR> <BR> <BR>";
$fday = &format_font($day, $Options{'fd'}, $Options{'sd'} || -1);
if ($day > 0 && $day <= $month_length) {
print <<EndOfHTML;
<TD HEIGHT="120" VALIGN=TOP WIDTH=14%$shades[$day]>
<P ALIGN=RIGHT>$moons[$day]$fday</P>
$msg
</TD>
EndOfHTML
} elsif ($element == $prevday) {
&small_calendar(@prevsc, 1, $Options{'backurl'});
} elsif ($element == $nextday) {
&small_calendar(@nextsc, 2, $Options{'forwurl'});
} else {
print " <TD WIDTH=14%><BR></TD>";
}
}
print " </TR>\n";
last if $day >= $month_length && $element >= $nextday;
}
}
sub small_calendar {
local ($scname, $scn, $which, $url) = @_;
local ($scstart, $l, $week, $weekday, $tday);
$scname = "<A HREF=\"$url\">$scname</A>", 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;
<TD WIDTH=14% VALIGN=TOP>
<TABLE WIDTH=100%>
<CAPTION><STRONG>$scname</STRONG></CAPTION>
<TR>
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 "</TR>\n";
for $week ( 0..5 ) {
print " <TR>\n";
for $weekday ( 0..6 ) {
$tday = ($week * 7) + ($weekday * 1) - $scstart + 1;
$tday = "", if $tday <= 0 || $tday > $scn;
print " <TD WIDTH=14%><FONT SIZE=-2>$tday</FONT></TD>\n";
}
print " </TR>\n";
last if $tday >= $scn;
}
print <<EndOfHTML;
</TABLE>
</TD>
EndOfHTML
}
sub format_font {
local ($text, $font, $size) = @_;
if (!$text) {
return "";
} elsif ($font && $size) {
return "<FONT FACE=$font SIZE=$size>$text</FONT>";
} elsif ($font) {
return "<FONT FACE=$font>$text</FONT>";
} elsif ($size) {
return "<FONT SIZE=$size>$text</FONT>";
} 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 " <TH WIDTH=14%>$dheader</TH>\n";
}