;
}
sub ps2png { # Converts postscript to png
my ($psfilename, $pngfilename, $resolution)=@_;
(slurp $psfilename)
=~ m/^%%BoundingBox: ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)/m;
my $translate="-$1 -$2 translate";
my $width=int($resolution*($3-$1)/72);
my $height=int($resolution*($4-$2)/72);
system "$GHOSTSCRIPT -dNOPAUSE -dBATCH -dQUIET -sDEVICE=png256 ".
"-dPARANOIDSAFER -dTextAlphaBits=4 -dGraphicsAlphaBits=4 ".
"-g${width}x$height -r$resolution -sOutputFile=$pngfilename ".
"-c $translate -f $psfilename";
#Compression?
return ($width, $height);
}
sub modifypng { # Writes transparency & mathinhtml$key chunks to $pngfilename
my ($pngfilename, $key)=@_;
my $png=slurp $pngfilename;
substr($png, -12, 0)=createchunk "tEXtmathinhtml\0$key";
my ($k, $len, $palette)=findchunk("PLTE", $png); my $trans="tRNS";
$trans=$trans.($1 eq "\xFF\xFF\xFF" ? "\x00" : "\xFF")
while ($palette =~ m/(...)/g);
substr($png, $k+$len+12, 0)=createchunk $trans;
open FILE, "> $pngfilename"; binmode FILE; print FILE $png; close FILE;
}
my %index;
sub createindex{ # Creates an index of pre-existing image files
foreach my $filename (grep /\.png$/, @_) {
my $imgstuff=slurp $filename;
my ($dummy1, $dummy2, $key)=findchunk("tEXtmathinhtml\0",$imgstuff);
if ($key) {
my $w=unpack 'N', substr $imgstuff, 16, 4;
my $h=unpack 'N', substr $imgstuff, 20, 4;
# print "Indexing $filename\t${width}x$height\t$key\n";
$index{"$key"}={ filename=>$filename, width=>$w, height=>$h };
};
};
}
my $tagnames=join '|', keys %rules; # A list of defined tags
sub translate { # Translates an element into its correcponding image/text
my $key=$_[0];
my ($dummy, $tagname, $contents)=split " ", $key, 3; # $dummy is $OVERSAMPLE
for (my $i=1; defined $rules{$tagname}{"input$i"}; $i++){
my $input=$rules{$tagname}{"input$i"};
$input =~ s/_CONTENTS_/$contents/g;
open FILE, "> tempfile.$i"; print FILE "$input\n"; close FILE;
}
print STDERR "Translating $key\n";
my $output;
for (my $i=1; defined $rules{$tagname}{"action$i"}; $i++){
$output=qx/ $rules{$tagname}{"action$i"} /;
}
if (-s "tempfile.ps"){
my $resolution=72*$OVERSAMPLE*$rules{$tagname}{"scale"};
my ($width, $height)=ps2png("tempfile.ps", "tempfile.png", $resolution);
modifypng("tempfile.png",$key);
my $num=0; while (-s "IMG_$num.png") { $num++ };
my $imgname="IMG_$num.png";
rename "tempfile.png", $imgname;
$index{$key}= {filename=>$imgname, width=>$width, height=>$height };
}
else {
$output =~ s/\s+/ /g; $index{$key}=$output
};
unlink @tempfiles;
}
sub replace { # Replaces a element by its translation
my $qstr=q/(?:"[^"]*?"|'[^']*?')/; # Matches a quoted string
my ($tagname, $attributes, $contents)=
$_[0] =~ m|^<($tagnames)((?:\s+\w+=$qstr)*)\s*>(.*?)\1>$|is;
$contents =~ s/\s+/ /g; $contents =~ s/^ //; $contents =~ s/ $//;
my $key="$OVERSAMPLE $tagname $contents";
if (! exists $index{$key}){ &translate($key) };
if (ref $index{$key}){
for ($contents) {
# replace "forbidden" html characters
s/&/&/g; s/</g; s/>/>/g; s/"/"/g; s/'/'/g;
# replace backslash with space (may make TeX contents more readable)
s/\\/ /g;
};
$attributes=" SRC=\"$index{$key}{'filename'}\"".
" WIDTH=\"".($index{$key}{'width'}/$OVERSAMPLE)."\"".
" HEIGHT=\"".($index{$key}{'height'}/$OVERSAMPLE)."\"".
" ALT=\"$contents\" TITLE=\"$contents\"".
" $rules{$tagname}{'attrib'} $attributes";
while ($attributes =~ s/\s(\w+)=$qstr(.*?)\s\1=($qstr)/ $1=$3 $2 /is){};
for ($attributes){ s/\s+/ /g; s/ $// };
return "
";
}
else { return $index{$key} };
}
#################################################################
# This is the main executable.
print STDERR "\n$programname\nCopyright (C) 2003 Michael J Miller\n".
"This program comes with absolutely no warranty.\n\n";
chdir dirname $ARGV[0];
opendir DIR, dirname $ARGV[0]; my @files=readdir DIR; closedir DIR;
die "Please delete temporary file(s): @_\n" if (@_=grep/^tempfile\./, @files);
createindex @files;
my $filename=basename $ARGV[0];
$_=slurp $filename;
s||\n\n|i;
my @sections= m/(.*?)(|
|
||.$)/igs;
$filename =~ s/\.mih$//;
open(HTMLFILE, "> $filename.html");
foreach (@sections){
s|<($tagnames)[\s>].*?\1>|&replace($&)|iesg;
print HTMLFILE "$_";
}
close HTMLFILE;
|