#! /usr/local/bin/perl # # slides.pl # # Generate HTML for slides based on a set of images # # Example: # # perl slides.pl -thumbs -slides -template # # Creates thumbnails, html "slides" incorporating captions, and # a template file to copy image links from. # # Slides live in a 'slides' directory at the same level in # the hierarchy as the images directory that they are based on. # # Captions and image order are specified by the file images/idb.txt. # Running slides.pl generates a default version of that file which # can then be edited by the user. Typically, you'll run slides # twice, once to thumbnail and create images/idb.txt, then, after # editing images/idb.txt, once to generate the slides with captions # %options = ( '-thumbs', 0, # generate thumbnails '-template', 0, # generate general purpose HTML template '-gallery', 0, # generate a gallery template '-slides', 0, # generate links to slides instead of image files '-imageDir', 'images', # where to find images '-slideDir', 'slides', # where to put slides '-home', 'index.htm' # start/finish of slide show (in .) ); for ($i = 0; $i < @ARGV; $i++) { die( "Undefined option: $ARGV[$i]" ) unless (defined( $options{$ARGV[$i]} )); if ($ARGV[$i] eq '-imageDir') { $options{'-imageDir'} = $ARGV[++$i]; } elsif ($ARGV[$i] eq '-home') { $options{'-home'} = $ARGV[++$i]; } elsif ($ARGV[$i] eq '-slideDir') { $options{'-slideDir'} = $ARGV[++$i]; } else { $options{$ARGV[$i]} = 1; } } $options{'-template'} = 1 if ($options{'-gallery'}); $ImageDir = $options{'-imageDir'}; $SlideDir = $options{'-slideDir'}; $Home = $options{'-home'}; $DefaultTitle = 'title here'; $IDBFile = "$ImageDir/idb.txt"; LoadFiles(); GenIDB(); GenThumbs() if ($options{'-thumbs'}); GenTemplateHTML() if ($options{'-template'}); GenSlides() if ($options{'-slides'}); exit( 0 ); sub ReadIDB { undef %IDB; # maps name to title undef @IDBFiles; # preserves idb.txt ordering my @filesInOrder; if (-f $IDBFile) { open( T, "<$IDBFile" ) || die( "Unable to open $IDBFile" ); while () { chop; my ($file, $title) = split /\s*\|\s*/; $IDB{$file} = $title; push @filesInOrder, $file; } close( T ); } my $file; my %currentImageFiles; foreach $file (@ImageFiles) # add any new files { if (!defined( $IDB{$file} )) { $IDB{$file} = $DefaultTitle; push @filesInOrder, $file; } $currentImageFiles{$file} = 1; } foreach $file (keys( %IDB )) # remove missing files { delete ( $IDB{$file} ) unless ($currentImageFiles{$file}); } foreach $file (@filesInOrder) { push @IDBFiles, $file if (defined( $IDB{$file} )); } } sub GenIDB { ReadIDB(); open( T, ">$IDBFile" ) || die( "Unable to open: $IDBFile" ); foreach $file (@IDBFiles) { print T $file, " | ", $IDB{$file}, "\n"; } close( T ); } sub ReadImageFiles { my( $dir ) = @_; opendir( D, $dir) || die( "unable to open $dir" ); my @files = readdir( D ); closedir( D ); return grep( /\.([Jj][Pp][Gg])|([Gg][Ii][Ff])$/, sort( @files ) ); } sub LoadFiles { @ImageFiles = ReadImageFiles( $ImageDir ); die ( "No images" ) unless (@ImageFiles); } sub GenThumbs { if (! -d "$ImageDir/thumbs") { mkdir( "$ImageDir/thumbs", 0777 ) || die( "Unable to create thumbs directory" ); } my( $iFile ); foreach $iFile (@ImageFiles) { if (! -f "$ImageDir/thumbs/$iFile") { print STDERR "Thumbnail: $iFile\n"; system( "convert -size 128x128 $ImageDir/$iFile -resize 128x128 $ImageDir/thumbs/$iFile" ); } } } sub imageFileSizeInK { my( $filename ) = @_; my( $dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks ) = stat( $filename ); return int( $size / 1024 ); } sub altOrTitleText { my( $iFile, $iPath ) = @_; my $fileSize = imageFileSizeInK( $iPath ); return $IDB{$iFile} ne $DefaultTitle ? "\"$IDB{$iFile} (${fileSize}K)\"" : "\"$iFile (${fileSize}K)\""; } sub GenTemplateHTML { open( T, ">template.htm" ) || die( "unable to open template HTML file" ); print T <<"End_Of_HTML"; Template HTML Links

Template HTML Links

End_Of_HTML my( $iFile, $tText ); if ($options{'-slides'}) { for ($i = 0; $i < @IDBFiles; $i++) { $iFile = $IDBFiles[$i]; my $iPath = "$ImageDir/$iFile"; my $sFile = "$SlideDir/". slideName( $iFile ); my $tPath = "$ImageDir/thumbs/" . $iFile; my ($tWidth, $tHeight) = GetSize( $tPath ); my ($iWidth, $iHeight ) = GetSize( $iPath ); $tText = altOrTitleText( $iFile, $iPath ); print T "\n"; print T "\t\n"; print T "\t$tText\n\n"; } } else { foreach $iFile (@IDBFiles) { my $iPath = "$ImageDir/$iFile"; my $tPath = "$ImageDir/thumbs/$iFile"; my ($tWidth, $tHeight ) = GetSize( $tPath ) if (-f $tPath ); my ($iWidth, $iHeight ) = GetSize( $iPath ); $tText = altOrTitleText( $iFile, $iPath ); if ($options{'-gallery'}) { print T " "; } else { print T "\n\t"; } print T "\n" if (-f $tPath ); print T "\t$tText\n\n" if (!$options{'-gallery'}) } } print T "\n\n"; close( T ); } sub slideTD { my( $i ) = @_; my $iFile = $IDBFiles[$i]; my $iPath = "$ImageDir/$iFile"; my $sFile = slideName( $iFile ); my $tFile = "$ImageDir/thumbs/" . $iFile; $tText = altOrTitleText( $iFile, $iPath ); my ($width, $height) = GetSize( $tFile ); my $link = ""; return <<"End_of_HTML"; $link End_of_HTML } sub GenSlideIndex { open( S, ">$SlideDir/index.htm" ) || die( "unable to open slide index file" ); print S <<"End_Of_HTML"; Slide Index End_Of_HTML my( $i ); my( $fullRows ) = int( @IDBFiles / 5 ); for ($i = 0; $i < $fullRows; $i++) { print S " \n"; my( $j ); for ($j = 0; $j < 5; $j++) { print S slideTD( $i * 5 + $j ); } print S " \n"; } my( $lastRow ) = @IDBFiles % 5; print S " \n"; for ($j = 0; $j < $lastRow; $j++) { print S slideTD( $i * 5 + $j ); } print S " \n"; print S <<"End_Of_HTML";
End_Of_HTML close( S ); } sub GetSize { my( $fnm ) = @_; die( "invalid image file: $fnm" ) unless (-f $fnm); open( ID, "identify $fnm |" ) || die( "Unable to identify $fnm" ); my $line = ; chop( $line ); close( ID ); my ($name, $type, $size) = split( /\s+/, $line ); return split( /x/, $size ) } sub OutputSlide { my( $sFile, $iFile, $next, $prev, $title ) = @_; my( $width, $height ) = GetSize( "$ImageDir/$iFile" ); open( S, ">$SlideDir/$sFile" ) || die( "unable to open slide HTML file" ); print S <<"End_Of_HTML"; $title

$title

$prev $next

End_Of_HTML close( S ); } sub slideName { my( $fnm ) = @_; $fnm =~ s/(\.[Jj][Pp][Gg])|(\.[Gg][Ii][Ff])$/\.htm/; return $fnm; } sub GenSlides { if (! -d $SlideDir) { mkdir( $SlideDir, 0777 ) || die( "Unable to create $SlideDir directory" ); } my( $i, $sFile, $next, $prev, $title ); if(1 == @IDBFiles) { $title = $IDB{$IDBFiles[0]} ne $DefaultTitle ? $IDB{$IDBFiles[0]} : undef; OutputSlide( slideName( $IDBFiles[0] ), $IDBFiles[0], "Next (home)", "Prev (home)", $title ); } else { $title = $IDB{$IDBFiles[0]} ne $DefaultTitle ? $IDB{$IDBFiles[0]} : undef; $next = slideName( $IDBFiles[1] ); $next = "Next"; OutputSlide( slideName( $IDBFiles[0] ), $IDBFiles[0], $next, "Prev (home)", $title ); for ($i = 1; $i < $#IDBFiles; $i++) { $sFile = slideName( $IDBFiles[$i] ); $title = $IDB{$IDBFiles[$i]} ne $DefaultTitle ? $IDB{$IDBFiles[$i]} : undef; $next = slideName( $IDBFiles[$i + 1] ); $next = "Next"; $prev = slideName( $IDBFiles[$i - 1] ); $prev = "Previous"; OutputSlide( $sFile, $IDBFiles[$i], $next, $prev, $title ); } $prev = slideName( $IDBFiles[$i - 1] ); $prev = "Previous"; $title = $IDB{$IDBFiles[$i]} ne $DefaultTitle ? $IDB{$IDBFiles[$i]} : undef; OutputSlide( slideName( $IDBFiles[$i] ), $IDBFiles[$i], "Next (home)", $prev, $title ); } GenSlideIndex(); }