#!/usr/bin/perl -w

 ###########################################################################
 ##                                                                       ##
 ##                Centre for Speech Technology Research                  ##
 ##                     University of Edinburgh, UK                       ##
 ##                         Copyright (c) 1996                            ##
 ##                        All Rights Reserved.                           ##
 ##                                                                       ##
 ##  Permission is hereby granted, free of charge, to use and distribute  ##
 ##  this software and its documentation without restriction, including   ##
 ##  without limitation the rights to use, copy, modify, merge, publish,  ##
 ##  distribute, sublicense, and/or sell copies of this work, and to      ##
 ##  permit persons to whom this work is furnished to do so, subject to   ##
 ##  the following conditions:                                            ##
 ##   1. The code must retain the above copyright notice, this list of    ##
 ##      conditions and the following disclaimer.                         ##
 ##   2. Any modifications must be clearly marked as such.                ##
 ##   3. Original authors' names are not deleted.                         ##
 ##   4. The authors' names are not used to endorse or promote products   ##
 ##      derived from this software without specific prior written        ##
 ##      permission.                                                      ##
 ##                                                                       ##
 ##  THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK        ##
 ##  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      ##
 ##  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   ##
 ##  SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE     ##
 ##  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    ##
 ##  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   ##
 ##  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          ##
 ##  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       ##
 ##  THIS SOFTWARE.                                                       ##
 ##                                                                       ##
 ########################################################################### 

# /*@name tex_to_images
#  * 
#  * Converts maths (one formula per line) into gifs.
#  *
#  * @author Richard Caley <rjc@cstr.ed.ac.uk>
#  * @version $Id: tex_to_images.prl,v 1.2 2001/04/04 13:11:27 awb Exp $
#  */

sub useage
{
    print <<END;

Convert LaTeX fragments into image files. For instance to include maths in
web pages. Input is either one fragment per line or fragments between \@Start
and \@End lines.

Useage: 
    tex_to_images [-s SCALE] [-u UPSCALE] [-o OUT_PATTERN] [-d DIR] [-f FORMAT] [FILE...]

	-o OUT_PATTERN		Describes the filenames. Should
				contain NNN which is replaced by
				the number of the formula. May contain FFF
				which is replaced by the output format.
				Default 'image_NNN.FFF'.

	-d DIR			Directory to put images in.

	-f FORMAT		Selects output format.
					ppm	  Portable Pixmap
					gif	  Compuserv GIF
					jpg	  JPEG
       				Default 'gif'.

	-s SCALE		Scale factor for output. Default 3.

	-u UPSCALE		Create the image UPSCALE times larger
				than required, then scale it down. This
				improves image quality at the expense of
				time and space. Default 2.


END

    exit($_[0]);
}


if (defined($ENV{LD_LIBRARY_PATH}))
	{
	$ENV{LD_LIBRARY_PATH} = "/usr/lib::$ENV{LD_LIBRARY_PATH}";
	}
else
	{
	$ENV{LD_LIBRARY_PATH} = "/usr/lib";
	} 


$out_pattern="image_NNN.FFF";
$scale=3;
$over=2;
$format='gif';
$dir='';

while ($#ARGV>=0)
    {
    if ($ARGV[0] =~ /-+[h?](elp)?/)
	{
	useage(0);
	}
    elsif ($ARGV[0] =~ /-+o(utput)?/)
	{
	shift @ARGV;
	$out_pattern = $ARGV[0];
	shift @ARGV;
	}
    elsif ($ARGV[0] =~ /-+d(ir)?/)
	{
	shift @ARGV;
	$dir = $ARGV[0];
	shift @ARGV;
	}
    elsif ($ARGV[0] =~ /-+s(cale)?/)
	{
	shift @ARGV;
	$scale = $ARGV[0];
	shift @ARGV;
	}
    elsif ($ARGV[0] =~ /-+u(pscale)?/)
	{
	shift @ARGV;
	$over = $ARGV[0];
	shift @ARGV;
	}
    elsif ($ARGV[0] =~ /-+f(ormat)?/)
	{
	shift @ARGV;
	$format= $ARGV[0];
	shift @ARGV;
	}
    else
	{
	last;
	}
    }

$scale *= $over;

$post_scale = 1.0/$over;

if ($format eq 'gif')
    {
    $conv = 'ppmtogif -i -t 1,1,1';
    }
elsif ($format eq 'ppm')
    {
    $conv = 'cat';
    }
elsif ($format eq 'jpg')
    {
    $conv = 'cjpeg';
    }
elsif ($format eq 'eps')
    {
    $conv = '';
    }
else
    {
    useage(1);
    }

$tmp="mti$$";
$tex="$tmp.tex";
$dvi="$tmp.dvi";
$dvipage="${tmp}_page.dvi";
$ps="$tmp.ps";
$ppm="${tmp}.ppm";
$psres=int(72*$scale+0.5);

open(TEX, ">$tex") ||
    die "can't create $tex - $!";

print TEX <<END ;
\\documentclass{article}

\\pagestyle{empty}

\\begin{document}

END

$n=0;
@out=();
@formula=();
$out=$out_pattern;

while(<>)
    {
    chomp;

    if (/^\@Name\s+([A-Za-z0-9_.\/]+)\s*$/)
	{
	$out=$1;
	}
    elsif (/^\@Start\s*$/)
	{
	$form='';
	}
    elsif (/^\@End\s*$/)
	{
	got_formula($dir, $out, $form);
	$form=undef;
	$out=$out_pattern;
	}
    elsif (defined($form))
	{
	$form .= "\n";
	$form .= $_;
	}
    else
	{
	got_formula($dir, $out, $_);
	$out=$out_pattern;
	}
    }

print TEX <<END;

\\end{document}
END

close(TEX);

execute("latex $tex");

for($i=0; $i<$n; $i++)
    {
    $in=$i+1;
    print "Process Image $in -> $out[$i]\n";
    execute("dviselect -i $dvi -o $dvipage $in", 1);
    execute("dvips -E -o$ps $dvipage");
    ($x, $y, $w, $h) = get_bb($ps);
    $w =  int($w*$scale+0.5);
    $h =  int($h*$scale+0.5);
    if ($conv)
	{
	execute("echo '$x neg $y neg translate'|gs -sDEVICE=ppmraw -sOutputFile=$ppm " . ($w>0?"-g${w}x$h":"") . " -r$psres -dNOPAUSE -dBATCH - $ps");
    
	execute("cat $ppm|pnmscale $post_scale |ppmnorm| ppmquant 255 | $conv > $out[$i]");
	}
    else
	{
	rename($ps, $out[$i]);
	}
    }

while (defined($f=<$tmp*>))
    {
    unlink($f);
    }

exit(0);


sub execute
{
    my ($command, $ignore) = @_;
    
    print "DOING $command\n";
    (system($command)>>8)==0 || defined($ignore) ||
	die "FAILED - $!";
}

sub get_bb
{
    my ($ps) = @_;
    local (*PS);

    open(PS, $ps) ||
	die " can't read $ps - $!";

    while (<PS>)
	{
	if (/%%BoundingBox:\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)/)
	    {
	    close(PS);
	    return ($1, $2, $3-$1, $4-$2);
	    }
	}
    close(PS);

    return (0,0,0,0);
}

sub got_formula
{
    my ($dir, $out, $form) = @_;

    $n++;

    $out =~ s/NNN/$n/;
    $out =~ s/FFF/$format/;

    $out = "$dir/$out"
	if ($dir);

    $form =~ s/&#([0-9]+);/chr(hex($1))/ge;
    
    push(@out, $out);
    push(@formula, $form);

    if ($out =~ m!^(.*)/([^/]*)$!)
	{
	system "mkdir", "-p", $1;
	}

    print TEX "\\[ $form \\] \\pagebreak \n\n";
}
