use strict; use HTML::Parser; use Getopt::Std; use File::Find; use File::Copy; use File::Path; use Cwd; sub handleEmbed; sub handleEnd; sub usage; use vars qw/$opt_v $opt_a $opt_s $opt_c $opt_d $opt_b/; getopts('va:s:cd:b:') or usage(); ($opt_s && $opt_d) or usage(); my $pwd = cwd(); print "pwd is $pwd\n" if $opt_v; my $fullsrcpath = $opt_s; $fullsrcpath =~ s|(\./)+||; $fullsrcpath = $pwd . "/" . $fullsrcpath unless $fullsrcpath =~ m|^/|; $fullsrcpath = $fullsrcpath . "/" unless $fullsrcpath =~ m|/$|; my $fulldstpath = $opt_d; $fulldstpath =~ s|(\./)+||; $fulldstpath = $pwd . "/" . $fulldstpath unless $fulldstpath =~ m|^/|; $fulldstpath = $fulldstpath . "/" unless $fulldstpath =~ m|/$|; print "source directory $fullsrcpath\n" if $opt_v; (-d $fullsrcpath) or die "$fullsrcpath is not a directory"; if ($opt_c) { print "deleting directory tree $fulldstpath\n" if $opt_v; rmtree $fulldstpath; } if (-e $fulldstpath) { print "destination directory $fulldstpath exists\n" if $opt_v; -d $fulldstpath or die "$fulldstpath is not a directory"; } else { print "creating destination directory $fulldstpath\n" if $opt_v; mkdir($fulldstpath) or die "could not make directory $fulldstpath"; } my $archive = "JmolApplet.jar"; $archive = $opt_a if $opt_a; print "archive is $archive\n" if $opt_v; my $codebase = $opt_b; print "codebase is $codebase\n" if $codebase && $opt_v; my $baseDirectory; my @files; my @directories; sub accumulateFilename { if ($baseDirectory) { my $pathname = $File::Find::name; my $name = substr $pathname, length($baseDirectory); if (-f $pathname) { print "$pathname is a file\n"; push @files, $name if -f $pathname; } elsif (-d $pathname) { print "$pathname is a directory\n"; push @directories, $name if -d $pathname; } else { print "$pathname is neither fish nor fowl?\n"; print "but it exists!\n" if -e $pathname; } } else { $baseDirectory = $File::Find::name . "/"; print "baseDirectory=$baseDirectory\n" if $opt_v; } } find(\&accumulateFilename, $fullsrcpath); for my $directory (@directories) { print "mkdir $fulldstpath$directory\n" if $opt_v; mkdir "$fulldstpath$directory"; } for my $file (@files) { next if $file =~ /\~$/; # ignore emacs files print "processing $file\n" if $opt_v; processFile("$baseDirectory$file", "$fulldstpath$file"); } exit(); sub processFile { my ($src, $dst) = @_; if ($src =~ /html?$/i) { processHtmlFile($src, $dst); } else { copyFile($src, $dst); } } sub copyFile { my ($src, $dst) = @_; # print "copyFile $src -> $dst\n"; copy $src, $dst; } sub processHtmlFile { my ($src, $dst) = @_; open OUTPUT, ">$dst" or die "could not open $dst"; my $p = HTML::Parser->new(start_h => [\&handleEmbed, 'skipped_text,text,tokens'], end_document_h => [\&writePrevious, 'skipped_text']); $p->report_tags('embed'); $p->parse_file($src) || die $!; close OUTPUT; } my ($previous, $embed, $tokens); my $tokenCount; # common to both plugins and buttons my ($name, $width, $height, $bgcolor, $src, $script); # plug-in specific my ($preloadscript, $loadStructCallback, $messageCallback, $pauseCallback, $pickCallback); # button-specific my ($type, $button, $buttonCallback, $target, $altscript); sub handleEmbed { ($previous, $embed, $tokens) = @_; $tokenCount = scalar @$tokens; $name = getUnquotedParameter('name'); $width = getUnquotedParameter('width'); $height = getUnquotedParameter('height'); $bgcolor = getUnquotedParameter('bgcolor'); $src = getUnquotedParameter('src'); $loadStructCallback = getUnquotedParameter('LoadStructCallback'); $messageCallback = getUnquotedParameter('MessageCallback'); $pauseCallback = getUnquotedParameter('pauseCallback'); $pickCallback = getUnquotedParameter('pickCallback'); $type = getUnquotedParameter('type'); $button = getUnquotedParameter('button'); $buttonCallback = getUnquotedParameter('ButtonCallBack'); $target = getUnquotedParameter('target'); $preloadscript = checkPreloadScript(); $script = getRawParameter('script'); $script = convertSemicolonNewline($script); $altscript = convertSemicolonNewline(getRawParameter('altscript')); writePrevious($previous); writeCommentedEmbed(); # dumpVars(); writeJmolApplet() unless $button; writeButtonControl() if $button; } sub checkPreloadScript { my $spinX = getUnquotedParameter('spinx'); my $spinY = getUnquotedParameter('spiny'); my $spinZ = getUnquotedParameter('spinz'); my $startspin = getUnquotedParameter('startspin'); my $frank = getUnquotedParameter('frank'); my $debugscript = getUnquotedParameter('debugscript'); my $preloadscript = getUnquotedParameter('preloadscript'); $preloadscript = convertSemicolonNewline($preloadscript); $preloadscript .= "set spin x $spinX;" if $spinX; $preloadscript .= "set spin y $spinY;" if $spinY; $preloadscript .= "set spin z $spinZ;" if $spinZ; $preloadscript .= "set spin on;" if $startspin =~ /true|yes|on/i; $preloadscript .= "set frank $frank;" if $frank; $preloadscript .= "set debugscript $debugscript;" if $debugscript; return $preloadscript; } sub dumpVars { print <\n"; } sub writeJmolApplet { print OUTPUT " \n"; print OUTPUT " \n"; print OUTPUT " \n" if $bgcolor; print OUTPUT " \n" if $src; print OUTPUT " \n" if $preloadscript; print OUTPUT " \n" if $script; print OUTPUT " \n" if $loadStructCallback; print OUTPUT " \n" if $messageCallback; print OUTPUT " \n" if $pauseCallback; print OUTPUT " \n" if $pickCallback; print OUTPUT " \n"; } sub writeButtonControl { my ($controlType, $group); if ($button =~ /push/i) { $controlType = "chimePush"; } elsif ($button =~ /toggle/i) { $controlType = "chimeToggle"; } elsif ($button =~ /radio(\d+)/i) { $controlType = "chimeRadio"; $group = $1; } my $buttonScript = $script || $src; print OUTPUT " \n"; print OUTPUT " \n". " \n"; print OUTPUT " \n" if $group; print OUTPUT " \n" if $buttonScript; print OUTPUT " \n" if $altscript; print OUTPUT " \n" if $buttonCallback; print OUTPUT " \n"; } sub getRawParameter { my ($tag) = @_; for (my $i = 0; $i < $tokenCount; ++$i) { my $token = $tokens->[$i]; return $tokens->[$i + 1] if ($token =~ /$tag/i); } return undef; } sub getUnquotedParameter { my $value = getRawParameter(@_); return undef unless $value; $value =~ s/^[\'\"]//; $value =~ s/[\'\"]$//; return $value; } sub convertNewline { my ($text) = @_; $text =~ s/\r\n/\n/g; $text =~ s/\r/\n/g; return $text; } sub convertSemicolonNewline { my ($text) = @_; $text = convertNewline($text); $text =~ s/\n/;\n/g; return $text; } sub usage { print < -d {-c} {-a } -s -d -c Clear destination directory -a specify alternate archive name -b specify codebase -v Verbose END exit; }