#!/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 " <Day> <start> - <end> <appointment>\n"; print " Note: <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 (<FILE>) { 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";