home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2000 February
/
PCWorld_2000-02_cd.bin
/
live
/
usr
/
X11R6
/
bin
/
pscal
< prev
next >
Wrap
Text File
|
1997-10-12
|
13KB
|
638 lines
#!/bin/sh
#+
#
# 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 6
# 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.
# 12/89 - The holiday checking has been loosened up in that the
# following takes place:
# 1. The Shell Variable EFILE is used preferentially
# 2. Then the file Events in the current directory is used
# 3. Finally the $HOME/.holiday file is used.
# The whole process can be turned off by setting EFILE=/dev/null.
#
# OPTIONS:
# Any argument whose first character is '-' is passed on to lpr.
# The shell variables BANNER, LFOOT, CFOOT, and RFOOT become a
# top centered banner, and left, centered, or right justified
# footers respectively. As in:
#
# BANNER="Schedule 1" CFOOT=Preliminary pscal 4 90
#
# 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
# @Used the better looking version with 5 rows of days rather than 6
# @ hacked together with holiday and banner/footnotes added
# @ by Joe (No Relation) Wood, 12/89, jlw@lzga.ATT.COM
# @Fixed "-R" (didn't work at all; now it at least works on 8.5x11)
# @Also fixed handling of unrecognized arguments
# @ by Jeff Mogul, 1/90, mogul@decwrl.dec.com
#
# 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).
#
#
# PostScript program to print calendars.
# Doesn't deal well with September 1752 or before.
#
USAGE="Usage: pscal [ -Rrt ] [ -F hfont ] [ -f font ] [-d directory] [ month [ year ] ]"
TFONT=Times-Bold
DFONT=Helvetica-Bold
EFONT=Times-Roman
Calendar=$HOME/Calendar
ROTATE=90
SCALE="1.0 1.0"
# Was 50 -120 - changed to 71 -120 for A4 Use
TRANSLATE="71 -120"
LPR="lpr"
while test $# != 0
do
case $1 in
-P) test $# -lt 2 && { echo "$USAGE" 1>&2; exit 1; }
eval ENVAR="$1$2"; shift; shift;;
-P*) eval ENVAR=$1; shift;;
-F) test $# -lt 2 && { echo "$USAGE" 1>&2; exit 1; }
TFONT="$2"; shift; shift;;
-F*) TFONT=`echo $1 | sed -n 1s/-.//p`; shift;;
-f) test $# -lt 2 && { echo "$USAGE" 1>&2; exit 1; }
DFONT="$2"; shift; shift;;
-f*) DFONT=`echo $1 | sed -n 1s/-.//p`; shift;;
-t) LPR=cat; shift;;
-r) ROTATE=90; shift;;
-R) ROTATE=0; SCALE="0.75 0.75"; TRANSLATE="50 900"; shift;;
-d) test $# -lt 2 && { echo "$USAGE" 1>&2; exit 1; }
Calendar="$2"; shift; shift;;
--|-) break;;
-*) eval ENVAR=\"$ENVAR $1\"; shift;;
*) break
esac
done
test $# -gt 2 && { echo "$USAGE" 1>&2; exit 1; }
case $# in
0) set `date`; YEAR=$6; MONTH=$2;;
1) MONTH=$1; set `date`; YEAR=$6;;
2) MONTH=$1 YEAR=$2;;
esac
MONTH=`case $MONTH in Jan|jan) echo 1;;Feb|feb) echo 2;;Mar|mar) echo 3;;Apr|apr) echo 4;;
May|may) echo 5;;Jun|jun) echo 6;;Jul|jul) echo 7;;Aug|aug) echo 8;;
Sep|sep) echo 9;;Oct|oct) echo 10;;Nov|nov) echo 11;;Dec|dec) echo 12;;
1|2|3|4|5|6|7|8|9|10|11|12) echo $MONTH;;esac`
MONTHNAME=`sed -n ${MONTH}p <<END-monthlist
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec
END-monthlist`
test $YEAR -lt 100 && YEAR=`expr $YEAR + 1900`
if [ -n "$EFILE" -a -r "$EFILE" ]
then
Files=$EFILE
monthday=yes
elif [ -r Events ]
then
Files=Events
monthday=yes
elif [ -r $HOME/.holiday ]
then
Files=$HOME/.holiday
monthday=yes
elif [ -d $Calendar ]
then
cd $Calendar
if [ -d xy$YEAR ]
then
cd xy$YEAR
fi
list=`echo xc*$MONTHNAME$YEAR`
case "$list" in
xc\*$MONTHNAME$YEAR)
;;
*)
for file in $list
do
day=`expr $file : 'xc\([0-9]*\)'`
(cat $file;echo) | sed '/^$/d
s/^/./' | fmt -25 |
sed -n "7q
s/^\.//
s/^/$day ( /
s/\$/ )/
p"
done > /tmp/pscal$$
holidays=`cat /tmp/pscal$$`
rm -f /tmp/pscal$$
esac
fi
case "$monthday" in
yes)
holidays=`cat $Files | grep \^$MONTH: | awk -F: '{printf("%s ( %s",$2,$3);\
for(i = 4; i <= NF; i++) printf(":%s", $i);printf(")\n"); }'`
esac
$LPR $ENVAR <<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.
% The number after /month should be set to a number from 1 to 12.
% The number after /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.
% This program won't produce valid calendars before 1800 due to the switch
% from Julian to Gregorian calendars in September of 1752 wherever English
% was spoken.
/month $MONTH def
/year $YEAR def
/titlefont /$TFONT def
/dayfont /$DFONT def
/eventfont /$EFONT def
/holidays [ $holidays ] def
/Bannerstring ($BANNER) def
/Lfootstring ($LFOOT) def
/Rfootstring ($RFOOT) def
/Cfootstring ($CFOOT) def
% calendar names - change these if you don't speak english
% "August", "April" and "February" could stand to be kerned even if you do
/month_names
[ (January) (February) (March) (April) (May) (June) (July)
(August) (September) (October) (November) (December) ]
def
/day_names
[ (Sunday) (Monday) (Tuesday) (Wednesday) (Thursday) (Friday) (Saturday) ]
def
% layout parameters - you can change these, but things may not look nice
/daywidth 100 def
/dayheight 95 def
/titlefontsize 48 def
/weekdayfontsize 10 def
/datefontsize 30 def
/footfontsize 20 def
/topgridmarg 35 def
/leftmarg 35 def
/daytopmarg 10 def
/dayleftmarg 5 def
% layout constants - don't change these, things probably won't work
/rows 5 def
/subrows 6 def
% calendar constants - change these if you want a French revolutionary calendar
/days_week 7 def
/days_month [ 31 28 31 30 31 30 31 31 30 31 30 31 ] 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
/ndays { % number of days in this month
days_month month 1 sub get
month 2 eq % February
isleap and
{
1 add
} if
} def
/weekday { % weekday (range 0-6) for integer date
days_week mod
} 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 weekday days_week 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 weekday % 0--Sunday, 1--monday, etc.
} def
/prtevent { % event-string day prtevent
% print out an event
/start startday def
/day 2 1 roll def
day start add 1 sub 7 mod daywidth mul
day start add 1 sub 7 div truncate dayheight neg 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
% ------------------------------------------------------------------------
/prtnum { 3 string cvs show } 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
/centernum { exch 3 string cvs exch center } def
/drawgrid { % draw calendar boxes
titlefont findfont weekdayfontsize scalefont setfont
currentpoint /y0 exch def /x0 exch def
0 1 days_week 1 sub {
submonth 0 eq
{
x0 y0 moveto
dup dup daywidth mul 40 rmoveto
day_names exch get
daywidth center
} if
x0 y0 moveto
daywidth mul topgridmarg rmoveto
1.0 setlinewidth
submonth 0 eq
{
/rowsused rows 1 sub def
}
{
/rowsused rows def
}
ifelse
0 1 rowsused {
gsave
daywidth 0 rlineto
0 dayheight neg rlineto
daywidth neg 0 rlineto
closepath stroke
grestore
0 dayheight neg rmoveto
} for
} for
} def
/drawnums { % place day numbers on calendar
dayfont findfont datefontsize
submonth 0 ne
{
2.5 mul
} if scalefont setfont
/start startday def
/days ndays def
start daywidth mul dayleftmarg add daytopmarg rmoveto
submonth 0 ne
{
dayleftmarg neg dayheight -2 div rmoveto
} if
1 1 days {
/day exch def
gsave
day start add weekday 0 eq
{
submonth 0 eq
{
.7 setgray
} if
} if
day start add weekday 1 eq
{
submonth 0 eq
{
.7 setgray
} if
} if
submonth 0 eq
{
isdouble
{
day prtdouble
}
{
day prtnum
} ifelse
}
{
day daywidth centernum
} ifelse
grestore
day start add weekday 0 eq
{
currentpoint exch pop dayheight sub 0 exch moveto
submonth 0 eq
{
dayleftmarg 0 rmoveto
} if
}
{
daywidth 0 rmoveto
} ifelse
} for
} def
/isdouble { % overlay today with next/last week?
days start add rows days_week mul gt
{
day start add rows days_week mul gt
{
true true
}
{
day start add rows 1 sub days_week mul gt
day days_week add days le and
{
false true
}
{
false
} ifelse
} ifelse
}
{
false
} ifelse
} def
/prtdouble {
gsave
dayfont findfont datefontsize 2 mul 3 div scalefont setfont
exch
{
(23/) stringwidth pop dayheight rmoveto
prtnum
}
{
0 datefontsize 5 div rmoveto
prtnum
0 datefontsize -5 div rmoveto
gsave
dayfont findfont datefontsize scalefont setfont
(/) show
grestore
} ifelse
grestore
} def
/drawfill { % place fill squares on calendar
/start startday def
/days ndays def
currentpoint /y0 exch def /x0 exch def
submonth 0 eq
{
usefirst
{
/fillstart 2 def
}
{
/fillstart 0 def
}
ifelse
}
{
/fillstart 0 def
}
ifelse
fillstart daywidth mul topgridmarg rmoveto
1.0 setlinewidth
fillstart 1 start 1 sub {
gsave
.9 setgray
daywidth 0 rlineto
0 dayheight neg rlineto
daywidth neg 0 rlineto
closepath fill
grestore
daywidth 0 rmoveto
} for
x0 y0 moveto
submonth 0 ne
{
/lastday rows 1 add days_week mul def
days_week 1 sub daywidth mul -440 rmoveto
}
{
/lastday rows days_week mul 2 sub fillstart add def
days_week 3 sub fillstart add daywidth mul
-440 dayheight add rmoveto
} ifelse
lastday -1 ndays start 1 add add
{
/day exch def
gsave
.9 setgray
daywidth 0 rlineto
0 dayheight neg rlineto
daywidth neg 0 rlineto
closepath fill
grestore
day weekday 1 eq
{
x0 y0 moveto
days_week 1 sub daywidth mul -440 dayheight add rmoveto
}
{
daywidth neg 0 rmoveto
} ifelse
} for
} def
/usefirst { % are last two boxes used by days?
start ndays add rows days_week mul 3 sub gt
start 2 ge and
} def
/calendar
{
titlefont findfont titlefontsize scalefont setfont
0 60 moveto
/month_name month_names month 1 sub get def
month_name show
/yearstring year 10 string cvs def
daywidth days_week mul yearstring stringwidth pop sub 60 moveto
yearstring show
eventflag {
% Show a centered Banner if any at the Top
daywidth days_week mul 2 div
Bannerstring stringwidth pop 2 div sub
60 moveto
Bannerstring show
% Show footnotes left-center-right
eventfont findfont footfontsize scalefont setfont
/bottomrow { dayheight rows mul 5 sub neg } def
0 bottomrow moveto
Lfootstring show
daywidth days_week mul Rfootstring stringwidth pop sub
bottomrow moveto
Rfootstring show
daywidth days_week mul Cfootstring stringwidth pop sub 2 div
bottomrow moveto
Cfootstring show
} if
0 -5 moveto
drawnums
0 -5 moveto
drawfill
eventflag {
0 0 moveto
drawevents
} if
0 -5 moveto
drawgrid
} def
/eventflag true def
$SCALE scale
$ROTATE rotate
$TRANSLATE 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
usefirst
{
0 30 translate
}
{
days_week 2 sub daywidth mul -350 translate
}
ifelse
/submonth 1 def
/year lyear def
/month lmonth def
gsave
.138 .138 scale
12 -120 translate
calendar
grestore
/submonth 1 def
/year nyear def
/month nmonth def
daywidth 0 translate
gsave
.138 .138 scale
12 -120 translate
calendar
grestore
showpage
END-OF-CALENDAR