wrv@ihlpm.UUCP (Vogel) (04/19/88)
comp.sources.misc: Volume 2, Issue 98 Submitted-By: "Vogel" <wrv@ihlpm.UUCP> Archive-Name: cal.bs It prints fancy postscript calendars, however, it allows you to put your own appointments, etc. in for a given day. In addition, it keeps track of changes you've made to your calendar file, and prints only updated calendar months. You can run this program nightly or weekly with a cron or at job. 8<-----8<-----8<-----8<----- < CUT HERE >----->8----->8----->8----->8 # # cal.bs -> bs program to print personal calendars on postscript printers. # # This program looks in your home directory for your calendar file, # comparing it to a previously hidden copy. Any months with items # changed will result in a calendar page being printed for that month. # It is possible and reasonable to run this program once a day/week # at 2:00am. This first time you run it, it will print all calendar # pages for the current year. The format of the .calendar file is # as follows: # # first line should contain: # year <whitespace> nnnn # # subsequent lines contain entries as follows: # MM/DD <whitespace> text of something happenning on that day. # # example .calendar file: # year 1988 # 04/15 Tax day # 04/16 Darcie's birthday # 05/30 Memorial Day, party! # 07/01 My birthday # 07/04 Fourth of July, party! # # rules: # 1) blank lines are ignored, but no whitespace allowed at beginning of line. # 2) there can be more than one entry for a single day # 3) if there is more than one entry for a single day, they MUST # appear sequentially in the file. It is a good idea to keep the # entries for a given month sorted. Months should go sequentially too. # 4) If there are no entries for a given month, it won't be printed. # 5) You can specify months into the next year, however you can not # specify more than a twelve month span. I.E., if your first # month's entry in the .calendar file is April, then you can fill every # month until March of the next year. # # To run this program, first see instructions below on modifying the # thing to work in your environment (very easy). Then type: # # bs cal.bs # # Thats it! If you're system doesn't have bs, complain! After all, # its been in UNIX since v7 and is a great language for this kind of # stuff. # # There may be bugs, I threw this together in a real hurry. Please # let me know if you find any, and I'll try to fix 'em. # # Bill Vogel, AT&T BL, ...ihnp4!ihlpm!wrv # ######################################## # # Here is the copyright on the original part of the postscript # code which is included in a modified form within this program. # # PostScript portion of this program to draw calendar -> # # Copyright (C) 1987 by Pipeline Associates, Inc. # Permission is granted to modify and distribute this free of charge. # ######################################## # # Things you need to modify: # # home -> your home directory. # lpcmd -> the command line used which will accept standard input as # raw postscript and print it on the local printer. # ######################################## # # # BEGIN LINES WHICH NEED MODIFICATION # # # ######################################## home = "/x1/wrv" # -> your home directory lpcmd = "!lp -or" # -> your local printer command for printing raw # postscript. Note that the '!' MUST be there. ######################################## # # # END LINES WHICH NEED MODIFICATION # # # ######################################## # # # You can change these if you insist on changing the name of the # calendar file. # cf = home_"/.calendar" ci = home_"/.calendar.bak" # # pattern strings. don't muckety-muck with these. # pstr1 = "\([0-9]*\)/\([0-9]*\)[ ]*\(.*\)" pstr2 = "year[ ]\([0-9]*\)" # # initialize month counters # for j = 1 12 mthcnt[j] = 0 altcnt[j] = 0 next frstmo = -1 # # parse the calendar file, break it up into an array # open("fdc", cf, "r") while ?(i = fdc) if match(i, pstr1) month = mstring(1) if ( frstmo == -1 ) frstmo = month x = mthcnt[month] mdata[month, x, 1] = mstring(2) mdata[month, x, 2] = mstring(3) mthcnt[month] = x + 1 elif match(i, pstr2) year = mstring(1) fi next close("fdc") # # parse the backup calendar file. # if ?eval("open(\"fdi\", ci, \"r\")") while ?(i = fdi) if match(i, pstr1) month = mstring(1) x = altcnt[month] altdata[month, x, 1] = mstring(2) altdata[month, x, 2] = mstring(3) altcnt[month] = x + 1 elif match(i, pstr2) altyear = mstring(1) fi next close("fdi") else for j = 1 12 domonth[j] = 2 next fi # # now, go thru and compare months # for i = 1 12 if (altcnt[i] != mthcnt[i]) | (altyear != year) domonth[i] = 1 continue fi if mthcnt[i] for j = 0 mthcnt[i] -1 if mdata[i, j, 1] != altdata[i, j, 1] domonth[i] = 1 continue fi if mdata[i, j, 2] != altdata[i, j, 2] domonth[i] = 1 continue fi next fi next # # make backup copy of the .calendar file. This may do # weird stuff if you don't keep your .calendar writeable or # if you run with a funny umask. # open("command", "!cp "_cf_" "_ci, "w") close("command") # # now, generate the postscript commands for each # entry in the file. # beginm = frstmo header = 0 for j = 1 12 if (domonth[beginm] == 2) | (domonth[beginm] & mthcnt[beginm]) put = "printing month "_beginm_", year "_year if (header == 0) header = 1 open("lpout", lpcmd, "w") pheader() fi pmonth(beginm) fi beginm = beginm + 1 if beginm > 12 beginm = 1 year = year + 1 fi next # # close the output file # if ( header ) close("lpout") # # print the postscript commands for one month # fun pmonth(m) lpout = "/year "_year_" def" lpout = "/month "_m_" def" lpout = "printmonth" oldday = -1 if ( mthcnt[m] == 0 ) lpout = "showpage" return 0 fi for i = 0 mthcnt[m] - 1 day = mdata[m, i, 1] # day if day != oldday if oldday == -1 lpout = day_" [ " else lpout = " ] daytext "_day_" [ " fi oldday = day else lpout = "(.p)" fi nb = 0 s = mdata[m, i, 2] # text while (n = match(s, "[ ]*\([^ ][^ ]*\)")) lpout = "("_mstring(1)_")" s = substr(s, n+1, 900) next next lpout = "] daytext showpage clear" nuf fun pheader() lpout = "/titlefont /Times-Bold def" lpout = "/dayfont /Helvetica-Bold def" lpout = "/month_names [ (January) (February) (March) (April) (May) (June) (July)" lpout = " (August) (September) (October) (November) (December) ] def" lpout = "/prtnum { 3 string cvs show} def" lpout = "/drawgrid { % draw calendar boxes" lpout = " dayfont findfont 10 scalefont setfont" lpout = " 0 1 6 {" lpout = " dup dup 100 mul 40 moveto" lpout = " [ (Sunday) (Monday) (Tuesday) (Wednesday) (Thursday) (Friday) (Saturday) ] exch get" lpout = " 100 center" lpout = " 100 mul 35 moveto" lpout = " 1.0 setlinewidth" lpout = " 0 1 5 {" lpout = " gsave" lpout = " 100 0 rlineto " lpout = " 0 -80 rlineto" lpout = " -100 0 rlineto" lpout = " closepath stroke" lpout = " grestore" lpout = " 0 -80 rmoveto" lpout = " } for" lpout = " } for" lpout = "} def" lpout = "/drawnums { % place day numbers on calendar" lpout = " dayfont findfont 30 scalefont setfont" lpout = " /start startday def" lpout = " /days ndays def" lpout = " start 100 mul 5 add 10 rmoveto" lpout = " 1 1 days {" lpout = " /day exch def" lpout = " gsave" lpout = " day start add 7 mod 1 eq" lpout = " {" lpout = " submonth 0 eq" lpout = " {" lpout = " .8 setgray" lpout = " } if" lpout = " } if" lpout = " day prtnum" lpout = " grestore" lpout = " day start add 7 mod 0 eq" lpout = " {" lpout = " currentpoint exch pop 80 sub 5 exch moveto" lpout = " }" lpout = " {" lpout = " 100 0 rmoveto" lpout = " } ifelse" lpout = " } for" lpout = "} def" lpout = "/drawfill { % place fill squares on calendar" lpout = " /start startday def" lpout = " /days ndays def" lpout = " 0 35 rmoveto" lpout = " 1.0 setlinewidth" lpout = " 0 1 start 1 sub {" lpout = " gsave" lpout = " .9 setgray" lpout = " 100 0 rlineto " lpout = " 0 -80 rlineto" lpout = " -100 0 rlineto" lpout = " closepath fill" lpout = " grestore" lpout = " 100 0 rmoveto" lpout = " } for" lpout = " submonth 1 eq" lpout = " {" lpout = " /lastday 42 def" lpout = " 600 -365 moveto" lpout = " }" lpout = " {" lpout = " /lastday 40 def" lpout = " 400 -365 moveto" lpout = " } ifelse" lpout = " lastday -1 ndays start 1 add add" lpout = " {" lpout = " /day exch def" lpout = " gsave" lpout = " .9 setgray" lpout = " 100 0 rlineto " lpout = " 0 -80 rlineto" lpout = " -100 0 rlineto" lpout = " closepath fill" lpout = " grestore" lpout = " day 7 mod 1 eq" lpout = " {" lpout = " 600 -365 80 add moveto" lpout = " }" lpout = " {" lpout = " -100 0 rmoveto" lpout = " } ifelse" lpout = " } for" lpout = "} def" lpout = "/isleap { % is this a leap year?" lpout = " year 4 mod 0 eq % multiple of 4" lpout = " year 100 mod 0 ne % not century" lpout = " year 1000 mod 0 eq or and % unless it's a millenia" lpout = "} def" lpout = "/days_month [ 31 28 31 30 31 30 31 31 30 31 30 31 ] def" lpout = "/ndays { % number of days in this month" lpout = " days_month month 1 sub get" lpout = " month 2 eq % Feb" lpout = " isleap and" lpout = " {" lpout = " 1 add" lpout = " } if" lpout = "} def" lpout = "/startday { % starting day-of-week for this month" lpout = " /off year 2000 sub def % offset from start of epoch" lpout = " off" lpout = " off 4 idiv add % number of leap years" lpout = " off 100 idiv sub % number of centuries" lpout = " off 1000 idiv add % number of millenia" lpout = " 6 add 7 mod 7 add % offset from Jan 1 2000" lpout = " /off exch def" lpout = " 1 1 month 1 sub {" lpout = " /idx exch def" lpout = " days_month idx 1 sub get" lpout = " idx 2 eq" lpout = " isleap and" lpout = " {" lpout = " 1 add" lpout = " } if" lpout = " /off exch off add def" lpout = " } for" lpout = " off 7 mod % 0--Sunday, 1--monday, etc." lpout = "} def" lpout = "/center { % center string in given width" lpout = " /width exch def" lpout = " /str exch def width str " lpout = " stringwidth pop sub 2 div 0 rmoveto str show" lpout = "} def" lpout = "/calendar" lpout = "{" lpout = " titlefont findfont 48 scalefont setfont" lpout = " 0 60 moveto" lpout = " /month_name month_names month 1 sub get def" lpout = " month_name show" lpout = " /yearstring year 10 string cvs def" lpout = " 700 yearstring stringwidth pop sub 60 moveto" lpout = " yearstring show" lpout = " 0 0 moveto" lpout = " drawnums" lpout = " 0 0 moveto" lpout = " drawfill" lpout = " 0 0 moveto" lpout = " drawgrid" lpout = "} def" lpout = "/daytext {" lpout = " /Helvetica-Narrow findfont 6 scalefont setfont" lpout = " /mytext exch def /myday exch def" lpout = " startday myday 1 sub add dup 7 mod 100 mul 5 add % gives column" lpout = " exch 7 idiv -80 mul % gives row" lpout = " dup /ypos exch def moveto" lpout = " /LM currentpoint pop def /RM LM 95 add def" lpout = " mytext { dup (.p) eq { crlf pop} {prstr ( ) show} ifelse } forall" lpout = "} def" lpout = "/crlf {" lpout = " ypos 8 sub /ypos exch def LM ypos moveto" lpout = "} def" lpout = "/prstr {" lpout = " dup stringwidth pop currentpoint pop" lpout = " add RM gt {crlf} if show" lpout = "} def" lpout = "/printmonth {" lpout = " 90 rotate" lpout = " 50 -120 translate" lpout = " /submonth 0 def" lpout = " calendar" lpout = " month 1 sub 0 eq" lpout = " {" lpout = " /lmonth 12 def" lpout = " /lyear year 1 sub def" lpout = " }" lpout = " {" lpout = " /lmonth month 1 sub def" lpout = " /lyear year def" lpout = " } ifelse" lpout = " month 1 add 13 eq" lpout = " {" lpout = " /nmonth 1 def" lpout = " /nyear year 1 add def" lpout = " } " lpout = " {" lpout = " /nmonth month 1 add def" lpout = " /nyear year def" lpout = " } ifelse" lpout = " /savemonth month def" lpout = " /saveyear year def" lpout = " /submonth 1 def" lpout = " /year lyear def" lpout = " /month lmonth def" lpout = " gsave" lpout = " 500 -365 translate" lpout = " gsave" lpout = " .138 .138 scale" lpout = " 10 -120 translate" lpout = " calendar" lpout = " grestore" lpout = " /submonth 1 def" lpout = " /year nyear def" lpout = " /month nmonth def" lpout = " 100 0 translate" lpout = " gsave" lpout = " .138 .138 scale" lpout = " 10 -120 translate" lpout = " calendar" lpout = " grestore" lpout = " /month savemonth def" lpout = " /year saveyear def" lpout = " /submonth 0 def" lpout = " grestore" lpout = "} def" nuf run exit