#!/usr/bin/perl
#
# get a list, one per line, of whitespace-separated token pairs.
# default: first is row, second is column.
# column labels are rotated for size reduction clarity.
# _ as an empty token doesn't produce an intersection but does produce
# a column header.

%label_row = ();
%label_col = ();
%items = ();

while(<>) {
    chomp; @_ = split;
    $label_row{$_[0]}++;
    $label_col{$_[1]}++;
    $items{"$_[0] $_[1]"}++;
}

# debug stuff
if (0) {
for $i (sort keys label_row) {
    print "$i: |";
    for $j (sort keys label_col) {
	printf "%1s|",($items{"$i $j"}?"X":" ");
    }
    print "\n";
}
}

print "%!PS\n";
# column size is probably the limit
# so take page size, give margins, then divide
$p_h = 11.0 * 72;
$p_w = 8.5 * 72;

$rowlabel_w = 1.5 * 72;
$slantmarg = 0.5 * 72;		# calc this for real later
$slantlen = 1 * 72;		# calc later
$cols_w = $p_w - $rowlabel_w - $slantmarg;
$col_w = $cols_w / scalar keys label_col;

$header_h = 2.5 * 72;		# calc later

$corner_x = $rowlabel_w;
$corner_y = $p_h - $header_h;

$angle = 60;

print "$corner_x $corner_y moveto\n";
print "$cols_w 0 rlineto stroke\n";
for $x (0..scalar keys label_col) {
    $off_x = $corner_x + $x * $col_w;
    $off_y = $corner_y;
    print "gsave $off_x $off_y translate $angle rotate\n";
    print "0 0 moveto $slantmarg 0 lineto stroke\n";
    print "grestore\n";
}

print "showpage\n";
