smann@june.cs.washington.edu (Stephen Mann) (05/12/89)
Here's a version of Pscal that has holidays hacked in. The program
is a Unix C-shell script that sends PostScript directly to a printer.
Documentation appears in the header comments of the script.
Steve
--------
#!/bin/csh -f
#+
#
# NAME:
# pscal
#
# SYNOPSIS:
# pscal [-Pprinter] [other printer flags] month year
#
# DESCRIPTION:
# `Pscal' is a PostScript program to print calendars.
#
# The file $home/.holiday is read and used to print short messages
# on specified days. The .holiday file should consist of lines of
# the form
# month:day:message string
# Messages should be 20 characters or less, with no more than 4
# messages per day. No spaces should appear from the beginning
# of a line until after the second colon.
# Month and day should be numbers in the obvious ranges.
#
# OPTIONS:
# Any argument whose first character is '-' is passed on to lpr.
#
# AUTHOR:
# Patrick Wood
# Copyright (C) 1987 by Pipeline Associates, Inc.
# Permission is granted to modify and distribute this free of charge.
#
# HISTORY:
# @Original From: patwood@unirot.UUCP (Patrick Wood)
# @Shell stuff added 3/9/87 by King Ables
# @Made pretty by tjt 1988
# @Holiday and printer flag passing hacks added Dec 1988
# @ by smann@june.cs.washington.edu
#
# BUGS:
# `Pscal' doesn't work for months before 1753 (weird stuff happened
# in September, 1752).
#
# A better format for the dates of holidays would be nice.
# An escape to allow holiday messages to be raw PostScript would
# also be nice.
# The holiday messages should be handled more intelligently (ie,
# the messages should be clipped to the day).
#
set printer="-Pps" # set default printer
set flags
top:
if ($#argv > 0) then
switch ("$argv[1]")
case -P*:
set printer="$argv[1]"
shift argv
goto top
case -*:
set flags = ($flags $argv[1])
shift argv
goto top
case *:
if ($?month) then
set year="$argv[1]"
else if ($?year) then
echo "usage: $0 [-Pprinter] month year"
exit 1
else
set month="$argv[1]"
endif
shift argv
goto top
endsw
endif
if ($?year) then
else
echo "usage: $0 [-Pprinter] [-flag1 -flag2 ...] month year"
exit 1
endif
if ( -e $home/.holiday ) then
set noglob
set holidays = \
( \[ `grep ^$month\: $home/.holiday | awk -F: '{print $2,"(",$3,")" }'` ] )
else
set noglob
set holidays = (\[ ] )
endif
lpr $printer $flags <<END-OF-CALENDAR
%!
% PostScript program to draw calendar
% Copyright (C) 1987 by Pipeline Associates, Inc.
% Permission is granted to modify and distribute this free of charge.
% /month should be set to a number from 1 to 12
% /year should be set to the year you want
% you can change the title and date fonts, if you want
% we figure out the rest
% won't produce valid calendars before 1800 (weird stuff happened
% in September of 1752)
/month $month def
/year $year def
/titlefont /Times-Bold def
/dayfont /Helvetica-Bold def
/eventfont /Times-Roman def
/holidays $holidays def
/month_names [ (January) (February) (March) (April) (May) (June) (July)
(August) (September) (October) (November) (December) ] def
/prtnum { 3 string cvs show} def
/drawgrid { % draw calendar boxes
dayfont findfont 10 scalefont setfont
0 1 6 {
dup dup 100 mul 40 moveto
[ (Sunday) (Monday) (Tuesday) (Wednesday) (Thursday) (Friday) (Saturday) ] exch get
100 center
100 mul 35 moveto
1.0 setlinewidth
0 1 5 {
gsave
100 0 rlineto
0 -80 rlineto
-100 0 rlineto
closepath stroke
grestore
0 -80 rmoveto
} for
} for
} def
/drawnums { % place day numbers on calendar
dayfont findfont 30 scalefont setfont
/start startday def
/days ndays def
start 100 mul 5 add 10 rmoveto
1 1 days {
/day exch def
gsave
day start add 7 mod 0 eq
{
submonth 0 eq
{
.8 setgray
} if
} if
day start add 7 mod 1 eq
{
submonth 0 eq
{
.8 setgray
} if
} if
day prtnum
grestore
day start add 7 mod 0 eq
{
currentpoint exch pop 80 sub 5 exch moveto
}
{
100 0 rmoveto
} ifelse
} for
} def
/drawfill { % place fill squares on calendar
/start startday def
/days ndays def
0 35 rmoveto
1.0 setlinewidth
0 1 start 1 sub {
gsave
.9 setgray
100 0 rlineto
0 -80 rlineto
-100 0 rlineto
closepath fill
grestore
100 0 rmoveto
} for
submonth 1 eq
{
/lastday 42 def
600 -365 moveto
}
{
/lastday 40 def
400 -365 moveto
} ifelse
lastday -1 ndays start 1 add add
{
/day exch def
gsave
.9 setgray
100 0 rlineto
0 -80 rlineto
-100 0 rlineto
closepath fill
grestore
day 7 mod 1 eq
{
600 -365 80 add moveto
}
{
-100 0 rmoveto
} ifelse
} for
} def
/isleap { % is this a leap year?
year 4 mod 0 eq % multiple of 4
year 100 mod 0 ne % not century
year 1000 mod 0 eq or and % unless it's a millenia
} def
/days_month [ 31 28 31 30 31 30 31 31 30 31 30 31 ] def
/ndays { % number of days in this month
days_month month 1 sub get
month 2 eq % Feb
isleap and
{
1 add
} if
} def
/startday { % starting day-of-week for this month
/off year 2000 sub def % offset from start of "epoch"
off
off 4 idiv add % number of leap years
off 100 idiv sub % number of centuries
off 1000 idiv add % number of millenia
6 add 7 mod 7 add % offset from Jan 1 2000
/off exch def
1 1 month 1 sub {
/idx exch def
days_month idx 1 sub get
idx 2 eq
isleap and
{
1 add
} if
/off exch off add def
} for
off 7 mod % 0--Sunday, 1--monday, etc.
} def
/prtevent { % event-string day prtevent
% print out an event
/day 2 1 roll def
day start add 1 sub 7 mod 100 mul
day start add 1 sub 7 div truncate -80 mul
-5
numevents day start add get -10 mul add
numevents
day start add
numevents day start add get 1 add
put
add moveto
show
} def
/drawevents { % read in a file full of events; print
% the events for this month
/numevents
[0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0] def
eventfont findfont 9 scalefont setfont
0 2 holidays length 2 sub {
dup
1 add holidays 2 1 roll get
2 1 roll holidays 2 1 roll get
prtevent
} for
} def
/center { % center string in given width
/width exch def
/str exch def width str
stringwidth pop sub 2 div 0 rmoveto str show
} def
/calendar
{
titlefont findfont 48 scalefont setfont
0 60 moveto
/month_name month_names month 1 sub get def
month_name show
/yearstring year 10 string cvs def
700 yearstring stringwidth pop sub 60 moveto
yearstring show
0 0 moveto
drawnums
0 0 moveto
drawfill
eventflag {
0 0 moveto
drawevents
} if
0 0 moveto
drawgrid
} def
/eventflag true def
90 rotate
50 -120 translate
/submonth 0 def
calendar
/eventflag false def
month 1 sub 0 eq
{
/lmonth 12 def
/lyear year 1 sub def
}
{
/lmonth month 1 sub def
/lyear year def
} ifelse
month 1 add 13 eq
{
/nmonth 1 def
/nyear year 1 add def
}
{
/nmonth month 1 add def
/nyear year def
} ifelse
/submonth 1 def
/year lyear def
/month lmonth def
500 -365 translate
gsave
.138 .138 scale
10 -120 translate
calendar
grestore
/submonth 1 def
/year nyear def
/month nmonth def
100 0 translate
gsave
.138 .138 scale
10 -120 translate
calendar
grestore
showpage
END-OF-CALENDARsmann@cs.washington.edu (Stephen Mann) (11/14/90)
I modified a version of pscal to put the day of the year at the top center of each day. If you'd like a copy, send me email (if enough people request it, I'll go ahead and post it). Note the following, however: 1) This is a csh version of pscal 2) It uses the 6 weeks per month format (and not the 5 weeks/month) Steve
schuster@cup.portal.com (Michael Alan Schuster) (11/15/90)
Here is a calendar program I just found on GEnie:
%!PS-Adobe-2.0
%% Title: CALENDAR.PS
%% Creator: C.FOSSETT
%% CreationDate: November 10, 1990
%------------------------------ CALENDAR.PS ----------------------------------
% Copyright (c) 1990
% Chad Fossett Commercial use is absolutely prohibited.
% 8026 Nightingale Way Personal use is permitted as long as this
% San Diego, CA 92123 copyright notice remains present and intact.
% All Rights Reserved.
% CALENDAR.PS produces a wall-style monthly calendar for December, 1990.
% It can be easily modified to print any month. It can also be tailored
% to individual tastes by adjusting the calendar size and aspect-ratio,
% and by adding personalized special events to any date.
%----------------------------------------------------------------------------
%
% The calendar is laid out as follows:
%
% columns on the x-axis
% 0 1 2 3 4 5 6
% 0 Each cell is
% 0 0 1 0 2 0 3 0 designated as
% 1 the intersection
% 0 1 of the two lines
% rows 2 at its upper
% on the 0 2 5 2 left corner
% y-axis 3 (see the x,y
% 2 3 notation in
% 4 the cells to
% 3 4 the left for
% examples).
%
%-----------------------------------------------------------------------------
% As it is set up below, it prints in landscape orientation on an 8 x11 page.
% The aspect ratio can be changed by adjusting CH and CW below, or by
% xy scaling the whole calendar at print time.
% If the size and aspect ratio are OK, then the only things needing
% attention are the top three definitions (month, startday, and numdays),
% and any special events, holidays, etc. (enumerated near the end).
%------------------------------- PROLOGUE ------------------------------------
/month (DECEMBER 1990) def % This gets centered at the top
/startday 6 def % day of the week the month starts on 0=sun, 1=mon etc.
/numdays 31 def % number of days in the month
/monthsize 36 def % Point size for month (JANUARY 1990),
/datesize 30 def % date (1 2 3 4 etc.),
/daysize 14 def % and day (SUNDAY, MONDAY etc.).
/monthfont {/AvantGarde-Demi findfont monthsize scalefont setfont} def
/datefont {/AvantGarde-Demi findfont datesize scalefont setfont} def
/dayfont {/AvantGarde-Book findfont daysize scalefont setfont} def
/CH -82 def % Cell Height (y-axis value of 1)
/CW 105 def % Cell Width (x-axis value of 1)
/cellcoord {CH mul exch CW mul exch} def % scaling for 1x1 cells
/monthshow {monthfont % set the font
month dup stringwidth pop CW 7 mul % and print the month
exch sub 2 div % centered
70 monthsize sub rmoveto show} def % above the line
/daynames {[(SUNDAY) (MONDAY) % 7-element array
(TUESDAY) (WEDNESDAY) % of the names of
(THURSDAY) (FRIDAY) % the days of
(SATURDAY)]} def % the week
/dayshow { dayfont % display the daynames
0 1 6 % start the loop (0-6)
{dup 0 cellcoord moveto % move to a cell 0
daynames exch get % get the array element
dup stringwidth pop CW exch sub 2 div % center it left-right
26 daysize sub 2 div % and up-down
gsave rmoveto show grestore % show it
0 25 rlineto CW 0 rlineto % and draw a line
0 -25 rlineto stroke % around it (on 3 sides)
} for % end of the loop
} def
/bestgray {106 45 % the Guru's
{dup mul exch dup % (Don Lancaster's)
mul add 1.0 exch sub} % best gray half-tone
setscreen} def % setscreen
/box {1 setlinewidth gsave % draw a box
CW 0 rlineto 0 CH rlineto % CH high by
CW neg 0 rlineto closepath % CW wide
stroke grestore
} def
/datecalc {7 mul add startday sub 1 add} def % calculate date (- OK)
/gtcheck {dup 0 gt % if greater than 0,
{lecheck} % do lecheck
{pop pop pop} ifelse} def % if not, pop off
/lecheck {dup numdays le % if numdays,
{row5check} % do row5check
{pop pop pop} ifelse} def % if not, pop off
/row5check {2 copy pop 5 eq % if row equals 5,
{xsundaycheck} % do x(tra)sundatecheck
{sundaycheck} ifelse} def % if not, sundaycheck
/xsundaycheck {3 copy pop pop 0 eq % if col equals 0,
{xsundateshow pop pop} % do x(tra)sundateshow
{xdateshow pop pop} ifelse} def % if not, x(tra)dateshow
/sundaycheck {3 copy pop pop 0 eq % if col equals 0,
{sundateshow pop pop} % do sundateshow
{dateshow pop pop} ifelse} def % if not, dateshow
/dateshow {datefont
2 string cvs dup stringwidth % prints date towards
pop CW 4 sub exch sub 0 datesize % the upper-right
.9 mul sub rmoveto % corner of the cell
show } def
/sundateshow {datefont
2 string cvs dup stringwidth % same as dateshow
pop CW 4 sub exch sub 0 datesize % but
.9 mul sub rmoveto 0 setlinewidth
true charpath gsave % instead of black,
bestgray .96 setgray fill % filled with gray
grestore stroke } def % and outlined
/xdateshow {0 CH -2 div rmoveto gsave % moves *up* a half
CW 0 rlineto % cell, and prints
1 setlinewidth stroke grestore % a line across;
dateshow} def % then dateshow
/xsundateshow {0 CH -2 div rmoveto gsave % moves *up* a half
CW 0 rlineto % cell, and prints
1 setlinewidth stroke grestore % a line across;
sundateshow} def % then sundateshow
/docell {dup 5 lt {box} if % print a box if lt row 5
2 copy % col row col row on stack
datecalc % col row datenum after datecalc
gtcheck % start a series of checks for
} def % a printable number
/calendar {gsave % start calendar definition
1 setlinewidth % set stroke line width to 1
0 0 cellcoord moveto monthshow % show the month
dayshow % show the days
0 1 5 { dup % do dates; loop for rows (nb *6* rows)
0 1 6 { % nested loop for columns (7)
exch 2 copy % col row col row on stack
cellcoord moveto docell dup % go to the cell and do it
} for pop pop % end of nested loop
} for % end of outer loop
grestore} def % end calendar definition
/littlecal {cellcoord gsave translate % prints a small calendar.
4.5 -20 translate % 0 0, then fudge a bit
.13 .13 scale % reduce the size
calendar grestore} def % and do calendar
/specialfont {/AvantGarde-Book findfont 8 scalefont setfont} def
/specialevent {specialfont % prints special events
cellcoord moveto gsave % towards the bottom right
dup stringwidth pop CW 4 sub % of a cell
exch sub CH 4 add rmoveto
show grestore} def
/holiday {specialevent % print specialevent,
sundateshow} def % then gray date
%-------------------------------- SCRIPT -------------------------------------
-90 rotate % landscape mode
-763.5 472.5 translate % 0 0 at the UL corner of UL cell
calendar % and print it - this is the basic calendar
% Then print any special days & events, holidays, small calendars, etc.
% This is done manually to facilitate month-to-month changes, and
% to avoid the "clunky stuff" that shows up if they're displayed in
% the small calendars (at least at 300 dpi on my H-P LaserJet II).
(Pearl Harbor Day, 1941) 5 1 specialevent % a special day in cell 5 1
(Winter begins) 6 3 specialevent % onset of winter in 6 3
(full moon) 0 1 specialevent % full moon in 0 1
(Chanukah) 3 2 specialevent % a religious celebration in 3 2
(Grandma's Birthday) 1 3.5 specialevent % a birthday reminder in cell 1 3.5
% (the upper "half" cell above 1 4)
(New Year's Eve) 1 4 specialevent % New Year's Eve in cell 1 4
(25) (Christmas) 2 4 holiday % make the 25th (Christmas)
% look like a holiday in 2 4
% (note *2* strings for holidays)
/month (NOVEMBER 1990) def % print the previous month's calendar
/startday 4 def % which starts on Thursday (4)
/numdays 30 def % and has 30 days
1 0 littlecal % as a small calendar in 1 0
/month (JANUARY 1991) def % print the next month's calendar
/startday 2 def % which starts on Tuesday (2)
/numdays 30 def % and has 30 days
5 0 littlecal % as a small calendar in 5 0
showpage % and finally, show what's there
quit % and quit
%---------------------------- END CALENDAR.PS --------------------------------