#!/usr/bin/perl
use strict;
$!=1;

# script to watch a tex file and if it (or any images in it) changes
# then regenerate it

# this could be improved to deal with cases when latex just stops...
# (very annoying)

my $file='NAC.tex'; # this is your tex file (xyz.tex)

# variables
my $root=$file; $root=~s/\.tex$//o;
my $latex;
my @watchfiles;
my $lasttime;
my @lasttimes;

# infinite loop
while(1)
{
    # check the stat of the file to get modification time
    my $t=(stat($file))[9];
    
    my $rerun=0; # set to 1 to rerun latex 
    
    if($t != $lasttime)
    {
	$rerun=1;
	print "$file has changed\n";
    }
    else
    {
	# check other files (images etc)
	for(my $i=0;$i<=$#watchfiles;$i++)
	{
	    if((stat($watchfiles[$i]))[9] != $lasttimes[$i])
	    {
		print "$watchfiles[$i] has changed\n";
		$rerun=1;
		last;
	    }
	}
    }

    if($rerun==1)
    {
	# rerun latex
	print "Remove old file...";
	unlink "$root.dvi";
	unlink "$root.ps";

	print "Run latex...";
	my $latexerr=`latex -interaction=nonstopmode -file-line-error-style NAC.tex`;

	# check for errors
	if(-s "$root.dvi" < 10)
	{
	    print "ERROR in your latex:\n";
	    my @l=split(/\n/o,$latexerr);
	    my $j=0;
	    for(my $i=0;$i<=$#l;$i++)
	    {
		if($l[$i]=~/$file/)
		{
		    $l[$i],"\n";
		    $j++;
		}
		if($j>20)
		{
		    $i=$#l+1;
		}
	    }@l;
	}
	else
	{
	    print "dvips...";
	    `dvips -o $root.ps $root 2>/tmp/watchmake.dvips.err`;
	    print "resize to A4...";
	    `psresize -W594mm -H841mm -pa4  $root.ps $root.A4.ps 2>/dev/null`;
	    print "done\n";
	}
	$lasttime=$t;

	# watch other files, e.g. images used by the tex file

	# clear arrays
	@watchfiles=(); @lasttimes=();

	# slurp the latex and get the names of .(e)ps images
	$latex=slurp($root.'.tex');
	# remove comments
	$latex=~s/\%.*//go;

	# check for images in the tex, could be improved to check
	# external files, text files etc.
	while($latex=~s/.*\{(\S+\.e?ps)\}//)
	{
	    push(@watchfiles,$1);
	    push(@lasttimes,(stat($1))[9]);
	}
    }

    # non-blocking sleep
    sleep 1;
}

sub slurp
{
    # uber-fast slurper!
    # Stolen from somewhere on the web...
    open(my $fh,'<'.$_[0])||die("cannot open $_[0] in slurp");
    return (do { local( $/ ) ; <$fh> } );
}
