#!/usr/bin/perl # wpdf -- view, watch and remake pdf based on Makefile use strict; use warnings; my $alive; # number of children alive my %deptarget; # dependency => target my %depsource; # dependency => source my $parent = $$; # pid of parent $SIG{USR1} = sub { kill 'HUP', 0 if not --$alive }; $SIG{HUP} = sub { exit 0 }; # collect dependencies for given files for my $target (@ARGV) { # if pdf, collect from Makefile if ($target =~ /\.pdf$/) { (my $basename = $target) =~ s/\.pdf$//; open my $f, '<', 'Makefile' or die "could not open Makefile: $!\n"; while (<$f>) { # explicit if (/^\Q$target\E:\s*(.*)/) { $deptarget{$_} = $target for split /\s/, $1; last; } # implicit if (/^\.([^ .]+)\.pdf\s*:\s*(.*)/) { $deptarget{"$basename.$1"} = $target; $deptarget{$_} = $target for split /\s/, $2; last; } } close $f; } # if not pdf, assume target is actually source file and collect from it # (with build(1) syntax) else { my $i = 0; my $source = $target; $target =~ s,\.[^./]*$,,; $target .= '.pdf'; $deptarget{$source} = $target; $depsource{$source} = $source; open my $f, '<', $source; while (<$f>) { last if ++$i > 20; if (/\s% (.*)/) { $deptarget{$_} = $target for split /\s/, $1; $depsource{$_} = $source for split /\s/, $1; last; } } close $f; } if (fork == 0) { system 'xpdf', '-remote', "wpdf-$target", $target; kill 'USR1', $parent; exit; } $alive++; } die "no dependencies found\n" if not keys %deptarget; # make pdf on demand open my $p, '-|', 'watch', keys %deptarget or die "could not start watch: $!\n"; while (<$p>) { chomp; my $cmd = ($_ =~ /\.pdf$/) ? 'make' : 'build'; my $arg = ($_ =~ /\.pdf$/) ? $deptarget{$_} : $depsource{$_}; system($cmd, $arg) == 0 && system('xpdf', '-remote', "wpdf-$deptarget{$_}", '-reload'); } close $p; exit($? != 0);