#!/u/smann/bin/perl
# Copyright 1994 Stephen Mann.
# This program may be freely used for non-profit use.
# This program may be copied and modified as long as this copyright
# notice remains intact. All other rights reserved.
$ht = 600;
$wd = 450;
$tfhc = 0;
$half = 0;
while ( $#ARGV >= 0 ) {
if ( $ARGV[0] =~ /^\-/ ) {
$arg = shift;
if ( $arg =~ /\-height/ ) {
if ( $#ARGV >= 0 ) {
$ht = shift;
} else {
$help = 1;
last;
}
} elsif ( $arg =~ /\-width/ ) {
if ( $#ARGV >= 0 ) {
$wd = shift;
} else {
$help = 1;
last;
}
} elsif ( $arg =~ /\-24/ ) {
$tfhc = 1;
} elsif ( $arg =~ /\-half/ ) {
$half = 1;
} else {
$help = 1;
last;
}
} else {
last;
}
}
if ( $ht > 650 ) {
warn "Warning: height of $ht reduced to 650\n";
$ht = 650;
}
if ( $wd > 450 ) {
warn "Warning: width of $wd reduced to 450\n";
$wd = 450;
}
$minh = 25;
$maxh = -1;
if ($#ARGV >= 0) {
$FILE = pop(@ARGV);
} else {
$FILE = $ENV{'HOME'} . "/.sched";
}
if ( $help ) {
print "format: pssched [-height h] [-width w] [-24] [file] > schedule.ps\n\n";
print "Print a PostScript version of your schedule.\n";
print "Options:\n";
print " -height h : make the schedule be height h (default 600)\n";
print " -width w : make the schedule be width w (default 450)\n";
print " -24 : Assume a 24 hour clock\n";
print " -half : Print half hours on y axis\n";
print "If a file is given as an argument, then the file is used as your schedule\n";
print "input file. If no file is given, then ~/.sched is used.\n\n";
print "The format of the schedule file is:\n";
print " Title:
\n";
print " - \n";
print " Note: \n\n";
print "All items in <> are to be filled in by you.\n";
print "The day can be a number from 1-5, the strings Monday, Tuesday, etc, or \n";
print " short forms of the days (Mon, Tue, etc). The first letter may be \n";
print " either upper or lower case. If the day is \"Daily\", that entry\n";
print " will be duplicated for Monday through Friday\n";
print "The time should be from 0:00 to 24:00. The colon is optional.\n";
print " A twelve hour clock is assumed unless the -24 flag is used. Hours\n";
print " less than 8 are assumed to be in the afternoon and those from 8-11\n";
print " are assumed to be in the morning, and 12 is assumed to be noon.\n";
print " Exception: it's smart enough to know that 1100-100 means from\n";
print " 11 AM to 1 PM.\n";
print "If you wish to force an hour to be AM or PM, then you can specify\n";
print " 'AM' or 'PM' after *both* times for the line.\n";
print "The appointment is the text that you wish to appear in the corresponding \n";
print " time slot. '\\n' should be used to denote a newline in your text string.\n";
print "A Note is a note that you want to appear at the bottom of the page.\n";
print " There is room for about 5 or 6 notes. If you reduce the height,\n";
print " then you'll have more room for notes.\n";
print "Warning: The width and height values are not used to determine\n";
print " the font size. Thus, if you make them too small, the text will\n";
print " start overlapping\n";
exit;
}
%days = ('mon', 1, 'Mon', 1, 'MON', 1,
'monday', 1, 'Monday', 1, 'MONDAY', 1,
'tue', 2, 'Tue', 2, 'TUE', 2,
'tues', 2, 'Tues', 2, 'TUES', 2,
'tuesday', 2, 'Tuesday', 2, 'TUESDAY', 2,
'wed', 3, 'Wed', 3, 'WED', 3,
'wednes', 3, 'Wednes', 3, 'WEDNES', 3,
'wednesday', 3, 'Wednesday', 3, 'WEDNESDAY', 3,
'thu', 4, 'Thu', 4, 'THU', 4,
'thurs', 4, 'Thurs', 4, 'THURS', 4,
'thursday', 4, 'Thursday', 4, 'THURSDAY', 4,
'fri', 5, 'Fri', 5, 'FRI', 5,
'friday', 5, 'Friday', 5, 'FRIDAY', 5,
'1',1, '2',2, '3',3, '4',4, '5',5,);
if (!open(FILE)) {die "Can not open $FILE\n";}
$cur = 0;
@dayname = ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
'Saturday');
@day = ();
@note = ();
$cur = 0;
$nnotes = 0;
$title = "untitled";
while () {
if ( /^(\d+)\s+(\d{1,2}):?(\d\d)\s*([apAP])M?\s*-\s*(\d{1,2}):?(\d\d)\s*([apAP])M?\s+(.+)$/ ) {
$day[$cur] = $days{$1};
$h1[$cur] = $2;
if ( $4 =~ /p/ || $4 =~ /P/ ) {
$h1[$cur] += 12;
}
$m1[$cur] = $3;
$h2[$cur] = $5;
if ( $7 =~ /p/ || $7 =~ /P/ ) {
$h2[$cur] += 12;
}
$m2[$cur] = $6;
$s[$cur] = $8;
&CheckHours($h1[$cur], $h2[$cur], $m2[$cur], $s[$cur]);
$cur++;
} elsif ( /^(\d+)\s+(\d{1,2}):?(\d\d)\s*-\s*(\d{1,2}):?(\d\d)\s+(.+)$/ ) {
$day[$cur] = $days{$1};
$h1[$cur] = $2;
$m1[$cur] = $3;
$h2[$cur] = $4;
$m2[$cur] = $5;
$s[$cur] = $6;
if ( $h1[$cur] > 0 && $h1[$cur] < 8 &&
$h2[$cur] > $h1[$cur] ) {
$h1[$cur] += 12*(1-$tfhc);
}
if ( $h2[$cur] <= 12 && $h2[$cur] < $h1[$cur] ) {
$h2[$cur] += 12*(1-$tfhc);
}
&CheckHours($h1[$cur], $h2[$cur], $m2[$cur], $s[$cur]);
$cur++;
} elsif (/^([SMTWFsmtwf][a-zA-Z]+)\s+(\d{1,2}):?(\d\d)\s*([apAP])M?\s*\s*-\s*(\d{1,2}):?(\d\d)\s*([apAP])M?\s+(.*)/) {
$day[$cur] = $days{$1};
$h1[$cur] = $2;
if ( $4 =~ /p/ || $4 =~ /P/ ) {
$h1[$cur] += 12;
}
$m1[$cur] = $3;
$h2[$cur] = $5;
if ( $7 =~ /p/ || $7 =~ /P/ ) {
$h2[$cur] += 12;
}
$m2[$cur] = $6;
$s[$cur] = $8;
&CheckHours($h1[$cur], $h2[$cur], $m2[$cur], $s[$cur]);
$cur++;
} elsif (/^([SMTWFsmtwf][a-zA-Z]+)\s+(\d{1,2}):?(\d\d)\s*-\s*(\d{1,2}):?(\d\d)\s+(.*)/) {
$day[$cur] = $days{$1};
$h1[$cur] = $2;
$m1[$cur] = $3;
$h2[$cur] = $4;
$m2[$cur] = $5;
$s[$cur] = $6;
if ( $h1[$cur] > 0 && $h1[$cur] < 8 &&
$h2[$cur] > $h1[$cur] ) {
$h1[$cur] += 12*(1-$tfhc);
}
if ( $h2[$cur] <= 12 && $h2[$cur] < $h1[$cur] ) {
$h2[$cur] += 12*(1-$tfhc);
}
&CheckHours($h1[$cur], $h2[$cur], $m2[$cur], $s[$cur]);
$cur++;
} elsif (/^[Dd]aily\s+(\d{1,2}):?(\d\d)\s*([apAP])M?\s*-\s*(\d{1,2}):?(\d\d)\s*([apAP])M?\s+(.*)/) {
for ($i = 1; $i <= 5; $i++) {
$day[$cur] = $i;
$h1[$cur] = $1;
$m1[$cur] = $2;
if ( $3 =~ /p/ || $3 =~ /P/ ) {
$h1[$cur] += 12;
}
$h2[$cur] = $4;
$m2[$cur] = $5;
if ( $6 =~ /p/ || $6 =~ /P/ ) {
$h2[$cur] += 12;
}
$s[$cur] = $7;
$cur++;
}
&CheckHours($h1[$cur-1], $h2[$cur-1], $m2[$cur], $s[$cur-1]);
} elsif (/^[Dd]aily\s+(\d{1,2}):?(\d\d)\s*-\s*(\d{1,2}):?(\d\d)\s+(.*)/) {
for ($i = 1; $i <= 5; $i++) {
$day[$cur] = $i;
$h1[$cur] = $1;
$m1[$cur] = $2;
$h2[$cur] = $3;
$m2[$cur] = $4;
$s[$cur] = $5;
if ( $h1[$cur] > 0 && $h1[$cur] < 8 &&
$h2[$cur] > $h1[$cur] ) {
$h1[$cur] += 12*(1-$tfhc);
}
if ( $h2[$cur] <= 12 && $h2[$cur] < $h1[$cur] ) {
$h2[$cur] += 12*(1-$tfhc);
}
$cur++;
}
&CheckHours($h1[$cur-1], $h2[$cur-1], $m2[$cur], $s[$cur-1]);
} elsif (/^Note: (.*)/ ) {
@note[$nnotes] = $1;
$nnotes++;
} elsif (/^Title: (.*)/ ) {
$title = $1;
} else {
}
}
sub CheckHours {
local($h1,$h2,$m2,$s)=@_;
if ( $h1 > $h2 ) {
warn "$h1 < $h2 for string '$s'\n";
} elsif ( $h1 < 0 || $h1 > 24 ) {
warn "bad hour $h1 for string '$s'\n";
} elsif ( $h2 < 0 || $h2 > 24 ) {
warn "bad hour $h2 for string '$s'\n";
} else {
if ( $h1 < $minh ) {
$minh = $h1;
}
if ( $h2 > $maxh ) {
$maxh = $h2;
}
if ( $h2 == $maxh && $m2 > 0 ) {
$maxh++;
}
}
}
# Convert hours/min into our time scale (1-n+1)
$mint = 25;
$maxt = -1;
for ($i=0; $i<=$#s; $i++) {
$t1[$i] = $h1[$i]-$minh + $m1[$i]/60.0+1.0;
$t2[$i] = $h2[$i]-$minh + $m2[$i]/60.0+1.0;
if ( $t1[$i] < $mint ) {
$mint = $t1[$i];
}
if ( $t2[$i] > $maxt ) {
$maxt = $t2[$i];
}
}
print "%!PS-Adobe-3.0\n";
print "%%Pages: 1\n";
print "%%BoundingBox: 60 15 557 762\n";
print "%%EndComments\n";
print "%%BeginProlog\n";
print "%%EndProlog\n";
print "\n";
print "%%Page: 1 1\n";
# Draw the title
print "/Times-Bold findfont 20 scalefont setfont\n";
print "8.5 36 mul 11 72 mul 50 sub moveto\n";
print "($title) stringwidth pop 2 div neg 0 rmoveto ($title) show\n";
print "/Times-Bold findfont 15 scalefont setfont\n";
# First draw the grid
printf "gsave 100 %f translate\n", 700-$ht;
print ".95 setgray\n";
print "0 0 moveto $wd 0 rlineto 0 $ht rlineto -$wd 0 rlineto fill stroke\n";
print "0 setgray\n";
print "0 0 moveto $wd 0 rlineto 0 $ht rlineto -$wd 0 rlineto closepath\n";
print "stroke\n";
printf "1 1 5 {%f mul 0 moveto 0 $ht rlineto stroke} for\n", $wd/5;
for ($i=1; $i<=5; $i++) {
printf "%d (%s) stringwidth pop 2 div sub $ht 10 add moveto (%s) show\n",
$i*$wd/5 - $wd/10, @dayname[$i], @dayname[$i];
}
print "stroke\n";
$n = $maxh-$minh;
print "1 1 $n {0 exch $ht $n div mul moveto $wd 0 rlineto stroke} for\n";
printf "1 1 %d {0 exch .5 1 $half sub mul sub $ht $n div mul moveto -10 0 rlineto stroke} for\n", $n-$half;
print "1 1 $n {0 exch .25 sub $ht $n div mul moveto -5 0 rlineto stroke} for\n";
print "1 1 $n {0 exch .75 sub $ht $n div mul moveto -5 0 rlineto stroke} for\n";
print "gsave -50 0 translate\n";
for ($i=$minh; $i<=$maxh-$half; $i++) {
if ( $i > 12 && !$tfhc) { $j = $i-12;} else {$j = $i;}
printf "($j:%02d) stringwidth exch 45 exch sub exch $ht $n div $n %f sub mul exch 2 div sub 5 sub moveto ($j:%02d) show\n",
$half*30, $i-$minh+.5*$half, $half*30;
}
printf "grestore\n";
# Now draw the commitments
$lw = 2;
printf "$lw setlinewidth\n";
printf "1 setlinejoin\n";
print "/Times-Bold findfont 10 scalefont setfont\n";
for ($i=0; $i<$cur; $i++) {
printf "1 setgray\n";
printf "%d %d moveto %d %d rlineto ", ($day[$i]-1)*$wd/5+$lw,
($n-$t2[$i]+1)*$ht/$n+$lw,
0, ($t2[$i]-$t1[$i])*$ht/$n-2*$lw;
printf "%d %d rlineto\n", $wd/5-2*$lw, 0;
printf "%d %d rlineto\n", 0, ($t1[$i]-$t2[$i])*$ht/$n+2*$lw;
printf "fill stroke\n";
printf "0 setgray\n";
printf "%d %d moveto %d %d rlineto ", ($day[$i]-1)*$wd/5+$lw,
($n-$t2[$i]+1)*$ht/$n+$lw,
0, ($t2[$i]-$t1[$i])*$ht/$n-2*$lw;
printf "%d %d rlineto\n", $wd/5-2*$lw, 0;
printf "%d %d rlineto\n", 0, ($t1[$i]-$t2[$i])*$ht/$n+2*$lw;
printf "closepath stroke\n";
@t = split(/\\n/, $s[$i]);
$xc = (2*$day[$i]-1)*$wd/10;
# $ys = ($n-$t1[$i]+1)*$ht/$n-$lw-10;
$ys = ($n-($t1[$i]+$t2[$i])/2+1)*$ht/$n-$lw-10+15/2*($#t+1);
print "% Start text\n";
for ($j=0; $j<=$#t; $j++) {
printf "($t[$j]) stringwidth $ys exch pop exch $xc exch 2 div sub exch\n";
printf "moveto ($t[$j]) show\n";
$ys -= 15;
}
}
print "grestore\n";
# Now draw the notes
print "/Times-Bold findfont 15 scalefont setfont\n";
printf "100 %d moveto (NOTES:) show\n", 600-$ht+85;
print "/Times-Bold findfont 10 scalefont setfont\n";
for ($i=0; $i<$nnotes; $i++) {
printf "175 %d moveto (%s) show\n", 700-$ht-$i*12-15, $note[$i];
}
print "showpage\n";
print "%%EOF\n";