aboutsummaryrefslogtreecommitdiff
path: root/etc/wpdf
diff options
context:
space:
mode:
Diffstat (limited to 'etc/wpdf')
-rwxr-xr-xetc/wpdf76
1 files changed, 76 insertions, 0 deletions
diff --git a/etc/wpdf b/etc/wpdf
new file mode 100755
index 0000000..94e5029
--- /dev/null
+++ b/etc/wpdf
@@ -0,0 +1,76 @@
+#!/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 $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;
+
+ open my $f, '<', $source;
+ while (<$f>) {
+ last if ++$i > 20;
+ if (/\s% (.*)/) {
+ $deptarget{$_} = $target 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;
+ system('make', "$deptarget{$_}") == 0
+ && system('xpdf', '-remote', "wpdf-$deptarget{$_}", '-reload');
+}
+close $p;
+exit($? != 0);