#!/usr/local/bin/perl5
#
# copyright (c) 1998 Seth Copen Goldstein and CMU
# 
#  Permission to use, copy, modify, and distribute this
#  software and its documentation for any purpose and without
#  fee is hereby granted, provided that the above copyright
#  notice appear in all copies.  Copyright holder(s) make no
#  representation about the suitability of this software for
#  any purpose. It is provided "as is" without express or
#  implied warranty.
# 
# expects the structure of the index page to include
# <title>...</title> in <head> portion
# first <h1> to be title
# first <h4> to be date
# immediatly followed by <br><h2>
# a center group containing a table with two columns.  First column is slides
# second column is author info etc.
#
# I will zap the <h2> stuff, the second column, the table def, and remake into 
# a two column format
#

#
# define defaults and things
#
($prog) = ($0 =~ m!([^/]+)$!);
$doindex = 1;			# convert the index file
$settitle = 0;
$setdate = 0;
$setdir = 0;
($dir) = (`pwd` =~ m+/([^/]*)$+);
chop $dir;
$ibase = "img";
$iext = "GIF";
$infile = "index.htm";

# set the date the lecture was produce on
($tsec,$tmin,$thour,$tday,$tmon,$year,$twday,$tyday,$tisdst) = localtime(time);
($mon, $day) = unpack("A2 A2", $dir);
$mon =~ s/^0*//;
if (($mon =~ /\d{1,2}/) && ($day =~ /\d{1,2}/)) {
    $date = $mon . "/" . $day . "/" . "98";
    $setdate=1;
} else {
    $date = $tmon+1 . "/" . $tday . "/" . "98";
}

# set the refering home page and name
$referurl = "http://www.cs.cmu.edu/afs/cs/academic/class/15828-s98/www/index.html";
$refername = "Reconfigurable Computing Seminar";

# 
# process options
#

while ($ARGV[0] =~ /^-/) {
    $_ = shift @ARGV;
  option: 
    {
	if (/^-u/) {
	    $referurl = shift @ARGV;
	    last option;
	}
	if (/^-n/) {
	    $refername = shift @ARGV;
	    last option;
	}
	if (/^-t/) {
	    $settitle = 1;
	    $title = shift @ARGV;
	    last option;
	}
	if (/^-d/) {
	    $setdate = 1;
	    $date = shift @ARGV;
	    last option;
	}
	if (/^-p/) {
	    $setdir = 1;
	    $dir = shift @ARGV;
	    last option;
	}
	if (/^-ib/) {
	    $ibase = shift @ARGV;
	    last option;
	}
	if (/^-ie/) {
	    $iext = shift @ARGV;
	    last option;
	}
	if (/^-[hH?]/) {
	    &usage;
	    last option;
	}
	print "Unknown option: ", $_, "\n";
	exit 1;
    }
}

$xx=@ARGV;
if ($xx > 0) {
    ($xx == 1) || die "$prog: Expect zero or one filename\n";
    $infile = $ARGV[0];
}
print "Transforming: $infile\n";
open(IN, $infile) || die "$prog: Can't open index.htm: $!\n";
$outfile=$infile . ".$$";
open(OUT, ">$outfile") || die "$prog: Can't open temporary output file $!\n";
select OUT;

#
# warn about date if it wasn't set
#
(!$setdate) && print STDERR "Date couldn't be determined by directory. Using today's date.\n Use -h for help on setting the date.\n";
 
#
# grab head portion and output
#
$gotmeta=0;
$outmeta=1;
readhead:
while (&getline) {
	if (/<BODY/) {
		last readhead;
	}	
	if ($gotmeta && (!/^<meta/) && $doindex && $outmeta) {
	    # we got the meta lines and now something else, so first 
	    # output a generator line for fix97
	    print "<meta name=\"generator\" content=\"fixindex 97\">\n";
	    $outmeta=0;
	}
	if (! $inbody) {
		print;
	}
	if (/<meta name="generator"/i) {
	    $gotmeta=1;
	    if (/powerpoint/i) {
		/97/ || die "$prog: This index not produced by PowerPoint 97\n";
	    }
	    if (/fixindex 97/i) {
		print STDERR "$prog: index.htm file already converted.  Will only create thumbnails.\n";
		$doindex = 0;
	    }
	}
    }

if ($doindex) {
    &convertindex;
} else {
    close(OUT);
    select STDOUT;
    unlink $outfile;
}
&convertimages;

sub convertindex {
# output last body line and maybe generator line
$outmeta && print "<meta name=\"generator\" content=\"fixindex 97\">\n";
print;

#
# find <h1> and replace with title if necc.
#

while (&getline) {
    /<h1>/ && last;
    print;
}

#
# expect title on its own line
#

chop;
m+^<h1>(.*)</h1>$+ || die "$prog: Unepxected data on first <h1> line\n";
$settitle || ($title = $1);
print "<h1>", $title, "</h1></center>\n\n";

#
# eat the date line
#

&getline;
chop;
m+^<h4>.*</h4>$+ || die "$prog: Unepxected data on first <h4> line\n";

#
# now output our header
#

print <<"EndOfHeader";
<center><table cols=2 width="100%" nosave>
<tr nosave>
<td nosave><font size=+2><A HREF="$referurl">$refername</A></FONT></TD>

<TD ALIGN=RIGHT NOSAVE><FONT SIZE=+2>$date</FONT></TD>
</TR>
</TABLE></CENTER>

<CENTER>
<HR NOSHADE SIZE=4 WIDTH="100%"></CENTER>

<CENTER>
<H4>
The lecture slides can be viewed in <A HREF="$dir.ps">postscript</A>
or read on the web as part of a <A HREF="sld001.htm">slide show</A>.</H4></CENTER>

<CENTER>
<HR NOSHADE SIZE=4 WIDTH="100%"></CENTER>

<TABLE BORDER COLS=3 WIDTH="100%" NOSAVE >

EndOfHeader

#
# now we throw away powerpoints header and table stuff
# - we throw away everything upto and including the tbale of contents line
#

while (&getline) {
    m+<u>Table of Contents</u>+ && last;
}

# 
# now we are at the list of slides.  Expecting <P...><A ...>title</A></P>
#

$num=1;
$needtr=1;
while (&getline) {
    m+</td>+ && last;
    /<P/ || next;
    $needtr && print "<TR VALIGN=BOTTOM NOSAVE>\n";
    $needtr = 0;
    ($sld, $title) = m+<P[^>]*><A HREF="([^"]*)">([^<]*)</A></P>+;
					  /"}/;	# I know this doesn't do anything but 
						# make the program slower, but it 
						# keeps my perl-mode in emacs happy
    ($inum) = $sld =~ /sld(\d+)/;
    $img= $ibase . $inum . "-small." . $iext;
    print "<TD><A HREF='$sld'>$num. $title<BR><IMG SRC='$img'></A></TD>\n";
    if (($num % 3) == 0) {
	print "</TR>";
	$needtr = 1;
    }
    $num++;
}
!$needtr && print "</TR>\n";

#
# ignore rest of input. finish output, close, and rename
#

print "</TABLE><BR><HR><DIV ALIGN=RIGHT>Index page created in part by <A HREF=\"http://www.cs.cmu.edu/~seth/pp97.html\">$prog</A></DIV></BODY></HTML>\n";
close(OUT);
select STDOUT;
opendir(DIR, '.');
$bak="$infile.bak";
if (( $x = grep(/$bak.*/, readdir(DIR)))) {
    $bak = $bak . ".$x";
}
closedir(DIR);

rename($infile, $bak) || die "$prog: Couldn't create backup file: $bak.  $!\n";
rename($outfile, $infile)  || die "$prog: Couldn't rename output file: $outfile.  $!\n";
print STDERR "Created '$infile'.  Old '$infile' in '$bak'.\n";
}

sub convertimages {
#
# now we create the thumbnails if they don't exist
# also make sure img name is what we think it is.
#

if (! -e ($fname = $ibase . "001." . $iext)) {
    print STDERR "Can't find $fname. Are images specified correctly?\n";
    exit 0;
}

# make sure utilities are there for converting images
@utilities = ("giftopnm", "pnmscale", "ppmhist", "ppmquant", "ppmtogif");
@p=split(/:/, $ENV{PATH});
outer:
foreach (@utilities) {
    $u = $_;
    foreach (@p) {
	(-x "$_/$u") && next outer;
    }
    print STDERR "$prog: Can't create thumbnails since '$u' is not on your path.\n";
    exit 1;
}

$orig = "$$.orig";
$half = "$$.half";
unlink($orig, $half);

opendir(DIR, '.');
thumb:
foreach (grep(/$ibase\d+\.$iext/, readdir(DIR))) {
    $fn = $_;
    s/\./-small\./;
    next if -e $_;
    print "Thumbnail of $fn -> $_\n";
    
    # this happens in two stages, first a gif of half size is generated to get
    # a color map that can be used by ppmquant, then we generate the final size 
    # and use the 1/2 size as a color map.
    
    system("giftopnm < $fn > $orig") && die "$prog: Can't create original ppm: $!\n";
    system("pnmscale -xscale .5 -yscale .5 < $orig > $half") 
	&& die "$prog: Can't scale by half: $!\n";
    # make sure half size image has less than 255 colors
    $qline="-floyd -map $half";
    ((`ppmhist $half|wc -l`-2) > 255) && ($qline="-floyd 255");
    # generate the small image
    system("pnmscale -width 250 < $orig | ppmquant $qline | ppmtogif -interlace -sort > $_")
	&& die "$prog: Can't do final scaling: $!\n";
    unlink($orig, $half) || die "$prog: Can't delete tmp files: $orig, $half: $!\n";
}
closedir(DIR);
}

sub getline {
    $_ = <IN>;
    s/\015//g;		# remove trailing ^M
    s/\013/ /g;		# change ^K to space (^K is used for multiline titles)
    $_;
}
    
sub usage {
    print STDERR <<"EndEndEnd";

$prog options [<filename>]

where options are:
    [-t <title>][-d <date>][-p <path>][-ib <image base>]
    [-ie <image extension][-u <url>][-n <name>]
      
Defaults:
	<filename>	index.htm
	<title>		whatever is in <title></title> of <filename>
	<date>		derived from the directory <filename> is found in. 
	    		see below.
	<path>		last component of directory <filename> is found in.
	<image base>	img
	<image ext>	GIF
	<url>		http://www.cs.cmu.edu/afs/cs/..... 
	    		probably not what you want
	<name>		Reconfigurable Computing Seminar
	    		probably not what you want

$prog expects a powerpoint 97 generated index and generates a new
index with thumbnails of the images. See source comments for expected
structure of index.htm if you get errors.  It expects that the current
directory name is mmdd.  If not, use -d to specify a date and -p for a
pointer to the postscript (probably handouts generated 6-up).

After converting the index.htm, it will generate thumbnails of the
original slide images.  It currently expects gifs as the source of the
slide images and generates thumbnails of width 250 pixels.

    -t <title>	is the title you want on the index if is different than the 
	       	one in <filename>.
    -d <date>	the date you want to be put in the index.
    -p <path>	path to a postscript file without the .ps.
    -ib <base>	base name for images (e.g., img for img001.GIF)
    -ie <ext>	extension for images (e.g., GIF for img001.GIF)
    -u <url>	url of refering page
    -n <name>	name you want associated with the refering page

A sample invocation might be:

 $prog -d 1/28/98 -u "http://www.cs.cmu.edu/~seth" -n "Seth's Home Page" \\
       -t "My Favorite Slide Show"

If you want a different structure for the header of the index, you should
modify the code between print <<"EndofHeader"; and EndOfHeader.

problems, suggestions, comments, but certainly no warranty: seth\@cs.cmu.edu.
More info: http://www.cs.cmu.edu/~seth/pp97.html
EndEndEnd
    exit 0;
}
