home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume13 / xcal / part01 / pscal / pscal.script < prev   
Text File  |  1991-05-12  |  13KB  |  624 lines

  1. #!/bin/sh
  2. #+
  3. #
  4. # NAME:
  5. #    pscal
  6. #
  7. # SYNOPSIS:
  8. #    pscal [-Pprinter] [other printer flags] month year
  9. #
  10. # DESCRIPTION:
  11. #    `Pscal' is a PostScript program to print calendars.
  12. #
  13. #    The file $HOME/.holiday is read and used to print short messages
  14. #    on specified days.  The .holiday file should consist of lines of
  15. #    the form 
  16. #        month:day:message string
  17. #    Messages should be 20 characters or less, with no more than 6
  18. #    messages per day.  No spaces should appear from the beginning
  19. #    of a line until after the second colon.
  20. #    Month and day should be numbers in the obvious ranges.
  21. #    12/89 - The holiday checking has been loosened up in that the
  22. #    following takes place:
  23. #        1. The Shell Variable EFILE is used preferentially
  24. #        2. Then the file Events in the current directory is used
  25. #        3. Finally the $HOME/.holiday file is used.
  26. #    The whole process can be turned off by setting EFILE=/dev/null.
  27. #
  28. # OPTIONS:
  29. #    Any argument whose first character is '-' is passed on to lpr.
  30. #    The shell variables BANNER, LFOOT, CFOOT, and RFOOT become a
  31. #    top centered banner, and left, centered, or right justified
  32. #    footers respectively.  As in:
  33. #
  34. #        BANNER="Schedule 1" CFOOT=Preliminary pscal 4 90
  35. #
  36. # AUTHOR:
  37. #    Patrick Wood
  38. #    Copyright (C) 1987 by Pipeline Associates, Inc.
  39. #    Permission is granted to modify and distribute this free of charge.
  40. # HISTORY:
  41. #    @Original From: patwood@unirot.UUCP (Patrick Wood)
  42. #    @Shell stuff added 3/9/87 by King Ables
  43. #    @Made pretty by tjt 1988
  44. #    @Holiday and printer flag passing hacks added Dec 1988 
  45. #    @ by smann@june.cs.washington.edu 
  46. #    @Used the better looking version with 5 rows of days rather than 6
  47. #    @ hacked together with holiday and banner/footnotes added
  48. #    @ by Joe (No Relation) Wood, 12/89, jlw@lzga.ATT.COM
  49. #    @Fixed "-R" (didn't work at all; now it at least works on 8.5x11)
  50. #    @Also fixed handling of unrecognized arguments
  51. #    @ by Jeff Mogul, 1/90, mogul@decwrl.dec.com
  52. #
  53. # BUGS:
  54. #    `Pscal' doesn't work for months before 1753 (weird stuff happened
  55. #    in September, 1752).
  56. #
  57. #    A better format for the dates of holidays would be nice.
  58. #    An escape to allow holiday messages to be raw PostScript would
  59. #    also be nice.
  60. #    The holiday messages should be handled more intelligently (ie,
  61. #    the messages should be clipped to the day).
  62. #
  63.  
  64. # PostScript program to print calendars.
  65. # Doesn't deal well with September 1752 or before.
  66.  
  67. USAGE="Usage: pscal [ -Rrt ] [ -F hfont ] [ -f font ] [ month [ year ] ]"
  68.  
  69. TFONT=Times-Bold
  70. DFONT=Helvetica-Bold
  71. EFONT=Times-Roman
  72.  
  73. Calendar=$HOME/Calendar
  74.  
  75. ROTATE=90
  76. SCALE="1.0 1.0"
  77. #    Was 50 -120 - changed to 71 -120 for A4 Use
  78. TRANSLATE="71 -120"
  79.  
  80. LPR="lpr"
  81.  
  82. while test $# != 0
  83. do
  84.     case $1 in
  85.     -P) test $# -lt 2 && { echo "$USAGE" 1>&2; exit 1; }
  86.         eval ENVAR="$1$2"; shift 2;;
  87.     -P*) eval ENVAR=$1; shift 1;;
  88.     -F) test $# -lt 2 && { echo "$USAGE" 1>&2; exit 1; }
  89.         TFONT="$2"; shift 2;;
  90.     -F*) TFONT=`echo $1 | sed -n 1s/-.//p`; shift 1;;
  91.     -f) test $# -lt 2 && { echo "$USAGE" 1>&2; exit 1; }
  92.         DFONT="$2"; shift 2;;
  93.     -f*) DFONT=`echo $1 | sed -n 1s/-.//p`; shift 1;;
  94.     -t) LPR=cat; shift 1;;
  95.     -r) ROTATE=90; shift 1;;
  96.     -R) ROTATE=0; SCALE="0.75 0.75"; TRANSLATE="50 900"; shift 1;;
  97.     --|-) break;;
  98.     -*) eval ENVAR=\"$ENVAR $1\"; shift 1;;
  99.     *) break
  100.     esac
  101. done
  102.  
  103. test $# -gt 2 && { echo "$USAGE" 1>&2; exit 1; }
  104.  
  105. case $# in
  106.     0)    set `date`; YEAR=$6; MONTH=$2;;
  107.     1)    MONTH=$1; set `date`; YEAR=$6;;
  108.     2)    MONTH=$1 YEAR=$2;;
  109. esac
  110.  
  111. MONTH=`case $MONTH in Jan|jan) echo 1;;Feb|feb) echo 2;;Mar|mar) echo 3;;Apr|apr) echo 4;;
  112.     May|may) echo 5;;Jun|jun) echo 6;;Jul|jul) echo 7;;Aug|aug) echo 8;;
  113.     Sep|sep) echo 9;;Oct|oct) echo 10;;Nov|nov) echo 11;;Dec|dec) echo 12;;
  114.     1|2|3|4|5|6|7|8|9|10|11|12) echo $MONTH;;esac`
  115.  
  116. test $YEAR -lt 100 && YEAR=`expr $YEAR + 1900`
  117.  
  118. if [ -n "$EFILE" -a -r "$EFILE" ]
  119. then
  120.     Files=$EFILE
  121.     monthday=yes
  122. elif [ -r Events ]
  123. then
  124.     Files=Events
  125.     monthday=yes
  126. elif [ -r $HOME/.holiday ]
  127. then
  128.     Files=$HOME/.holiday
  129.     monthday=yes
  130. elif [ -d $Calendar ]
  131. then
  132.     cd $Calendar
  133.     if [ -d xy$YEAR ]
  134.     then
  135.         cd xy$YEAR
  136.     fi
  137.     set 'dummy' 'Jan' 'Feb' 'Mar' 'Apr' 'May' 'Jun' 'Jul' 'Aug' 'Sep' 'Oct' 'Nov' 'Dec'
  138.     shift $MONTH
  139.     list=`echo xc*$1$YEAR`
  140.     case "$list" in
  141.     xc\*$1$YEAR)
  142.             ;;
  143.     *)
  144.         for file in $list
  145.         do
  146.             day=`expr $file : 'xc\([0-9]*\)'`
  147.             (cat $file;echo) | sed '/^$/d
  148.                     s/^/./' | fmt -25 |
  149.                      sed -n "7q
  150.                     s/^\.//
  151.                     s/^/$day ( /
  152.                     s/\$/ )/
  153.                     p"
  154.         done > /tmp/pscal$$
  155.         holidays=`cat /tmp/pscal$$`
  156.         rm -f /tmp/pscal$$    
  157.     esac
  158. fi
  159.  
  160. case "$monthday" in
  161. yes)
  162.     holidays=`cat $Files | grep \^$MONTH: | awk -F: '{printf("%s ( %s",$2,$3);\
  163.         for(i = 4; i <= NF; i++) printf(":%s", $i);printf(")\n"); }'`
  164. esac
  165.  
  166.  
  167. $LPR $ENVAR <<END-OF-CALENDAR
  168. %!
  169. % PostScript program to draw calendar
  170. % Copyright (C) 1987 by Pipeline Associates, Inc.
  171. % Permission is granted to modify and distribute this free of charge.
  172.  
  173. % The number after /month should be set to a number from 1 to 12.
  174. % The number after /year should be set to the year you want.
  175. % You can change the title and date fonts, if you want.
  176. % We figure out the rest.
  177. % This program won't produce valid calendars before 1800 due to the switch
  178. % from Julian to Gregorian calendars in September of 1752 wherever English
  179. % was spoken.
  180.  
  181. /month $MONTH def
  182. /year $YEAR def
  183. /titlefont /$TFONT def
  184. /dayfont /$DFONT def
  185. /eventfont /$EFONT def
  186. /holidays [ $holidays ] def
  187. /Bannerstring ($BANNER) def
  188. /Lfootstring ($LFOOT) def
  189. /Rfootstring ($RFOOT) def
  190. /Cfootstring ($CFOOT) def
  191.  
  192. % calendar names - change these if you don't speak english
  193. % "August", "April" and "February" could stand to be kerned even if you do
  194.  
  195. /month_names
  196. [ (January) (February) (March) (April) (May) (June) (July)
  197. (August) (September) (October) (November) (December) ]
  198. def
  199.  
  200. /day_names
  201. [ (Sunday) (Monday) (Tuesday) (Wednesday) (Thursday) (Friday) (Saturday) ]
  202. def
  203.  
  204. % layout parameters - you can change these, but things may not look nice
  205.  
  206. /daywidth 100 def
  207. /dayheight 95 def
  208.  
  209. /titlefontsize 48 def
  210. /weekdayfontsize 10 def
  211. /datefontsize 30 def
  212. /footfontsize 20 def
  213.  
  214. /topgridmarg 35 def
  215. /leftmarg 35 def
  216. /daytopmarg 10 def
  217. /dayleftmarg 5 def
  218.  
  219. % layout constants - don't change these, things probably won't work
  220.  
  221. /rows 5 def
  222. /subrows 6 def
  223.  
  224. % calendar constants - change these if you want a French revolutionary calendar
  225.  
  226. /days_week 7 def
  227.  
  228. /days_month [ 31 28 31 30 31 30 31 31 30 31 30 31 ] def
  229.  
  230. /isleap {                % is this a leap year?
  231.     year 4 mod 0 eq            % multiple of 4
  232.     year 100 mod 0 ne         % not century
  233.     year 1000 mod 0 eq or and    % unless it's a millenia
  234. } def
  235.  
  236. /ndays {                % number of days in this month
  237.     days_month month 1 sub get
  238.     month 2 eq            % February
  239.     isleap and
  240.     {
  241.         1 add
  242.     } if
  243. } def
  244.  
  245. /weekday {                % weekday (range 0-6) for integer date
  246.     days_week mod
  247. } def
  248.  
  249. /startday {                % starting day-of-week for this month
  250.     /off year 2000 sub def        % offset from start of "epoch"
  251.     off
  252.     off 4 idiv add            % number of leap years
  253.     off 100 idiv sub        % number of centuries
  254.     off 1000 idiv add        % number of millenia
  255.     6 add weekday days_week add     % offset from Jan 1 2000
  256.     /off exch def
  257.     1 1 month 1 sub {
  258.         /idx exch def
  259.         days_month idx 1 sub get
  260.         idx 2 eq
  261.         isleap and
  262.         {
  263.             1 add
  264.         } if
  265.         /off exch off add def
  266.     } for
  267.     off weekday            % 0--Sunday, 1--monday, etc.
  268. } def
  269.  
  270. /prtevent {        % event-string day prtevent
  271.             %  print out an event
  272.     /start startday def
  273.     /day 2 1 roll def
  274.     day start add 1 sub 7 mod daywidth mul
  275.     day start add 1 sub 7 div truncate dayheight neg mul 
  276.     -5 
  277.     numevents day start add get -10 mul add
  278.     numevents
  279.     day start add 
  280.     numevents day start add get 1 add
  281.     put
  282.     add moveto
  283.     show
  284. } def
  285.  
  286. /drawevents {        % read in a file full of events; print
  287.             %  the events for this month
  288.     /numevents
  289.     [0 0 0 0 0 0 0
  290.      0 0 0 0 0 0 0
  291.      0 0 0 0 0 0 0
  292.      0 0 0 0 0 0 0
  293.      0 0 0 0 0 0 0
  294.      0 0 0 0 0 0 0] def 
  295.      eventfont findfont 9 scalefont setfont
  296.      0 2 holidays length 2 sub {
  297.         dup
  298.         1 add holidays 2 1 roll get
  299.         2 1 roll holidays 2 1 roll get
  300.         prtevent
  301.     } for
  302.         
  303. } def
  304.  
  305. % ------------------------------------------------------------------------
  306.  
  307. /prtnum { 3 string cvs show } def
  308.  
  309. /center {                % center string in given width
  310.     /width exch def
  311.     /str exch def width str 
  312.     stringwidth pop sub 2 div 0 rmoveto str show
  313. } def
  314.  
  315. /centernum { exch 3 string cvs exch center } def
  316.  
  317. /drawgrid {                % draw calendar boxes
  318.     titlefont findfont weekdayfontsize scalefont setfont
  319.     currentpoint /y0 exch def /x0 exch def
  320.     0 1 days_week 1 sub {
  321.         submonth 0 eq
  322.         {
  323.             x0 y0 moveto
  324.             dup dup daywidth mul 40 rmoveto
  325.             day_names exch get
  326.             daywidth center
  327.         } if
  328.         x0 y0 moveto
  329.         daywidth mul topgridmarg rmoveto
  330.         1.0 setlinewidth
  331.         submonth 0 eq
  332.         {
  333.             /rowsused rows 1 sub def
  334.         }
  335.         {
  336.             /rowsused rows def
  337.         }
  338.         ifelse
  339.         0 1 rowsused {
  340.             gsave
  341.             daywidth 0 rlineto 
  342.             0 dayheight neg rlineto
  343.             daywidth neg 0 rlineto
  344.             closepath stroke
  345.             grestore
  346.             0 dayheight neg rmoveto
  347.         } for
  348.     } for
  349. } def
  350.  
  351. /drawnums {                % place day numbers on calendar
  352.     dayfont findfont datefontsize
  353.     submonth 0 ne
  354.     {
  355.         2.5 mul
  356.     } if scalefont setfont
  357.     /start startday def
  358.     /days ndays def
  359.     start daywidth mul dayleftmarg add daytopmarg rmoveto
  360.     submonth 0 ne
  361.     {
  362.         dayleftmarg neg dayheight -2 div rmoveto
  363.     } if
  364.     1 1 days {
  365.         /day exch def
  366.         gsave
  367.         day start add weekday 0 eq
  368.         {
  369.             submonth 0 eq
  370.             {
  371.                 .7 setgray
  372.             } if
  373.         } if
  374.         day start add weekday 1 eq
  375.         {
  376.             submonth 0 eq
  377.             {
  378.                 .7 setgray
  379.             } if
  380.         } if
  381.         submonth 0 eq
  382.         {
  383.             isdouble
  384.             {
  385.                 day prtdouble
  386.             }
  387.             {
  388.                 day prtnum
  389.             } ifelse
  390.         }
  391.         {
  392.             day daywidth centernum
  393.         } ifelse
  394.         grestore
  395.         day start add weekday 0 eq
  396.         {
  397.             currentpoint exch pop dayheight sub 0 exch moveto
  398.             submonth 0 eq
  399.             {
  400.                 dayleftmarg 0 rmoveto
  401.             } if
  402.         }
  403.         {
  404.             daywidth 0 rmoveto
  405.         } ifelse
  406.     } for
  407. } def
  408. /isdouble {                % overlay today with next/last week?
  409.     days start add rows days_week mul gt
  410.     {
  411.         day start add rows days_week mul gt
  412.         {
  413.             true true
  414.         }
  415.         {
  416.             day start add rows 1 sub days_week mul gt
  417.             day days_week add days le and
  418.             {
  419.                 false true
  420.             }
  421.             {
  422.                 false
  423.             } ifelse
  424.         } ifelse
  425.     }
  426.     {
  427.         false
  428.     } ifelse
  429. } def
  430.  
  431. /prtdouble {
  432.     gsave
  433.       dayfont findfont datefontsize 2 mul 3 div scalefont setfont
  434.       exch
  435.       {
  436.         (23/) stringwidth pop dayheight rmoveto
  437.         prtnum
  438.       }
  439.       {
  440.         0 datefontsize 5 div rmoveto
  441.         prtnum
  442.         0 datefontsize -5 div rmoveto
  443.         gsave
  444.           dayfont findfont datefontsize scalefont setfont
  445.           (/) show
  446.         grestore
  447.       } ifelse
  448.     grestore
  449. } def
  450.  
  451. /drawfill {                % place fill squares on calendar
  452.     /start startday def
  453.     /days ndays def
  454.     currentpoint /y0 exch def /x0 exch def
  455.     submonth 0 eq
  456.     {
  457.         usefirst
  458.         {
  459.             /fillstart 2 def
  460.         }
  461.         {
  462.             /fillstart 0 def
  463.         }
  464.         ifelse
  465.     }
  466.     {
  467.         /fillstart 0 def
  468.     }
  469.     ifelse
  470.     fillstart daywidth mul topgridmarg rmoveto
  471.     1.0 setlinewidth
  472.     fillstart 1 start 1 sub {
  473.         gsave
  474.         .9 setgray
  475.         daywidth 0 rlineto 
  476.         0 dayheight neg rlineto
  477.         daywidth neg 0 rlineto
  478.         closepath fill
  479.         grestore
  480.         daywidth 0 rmoveto
  481.     } for
  482.     x0 y0 moveto
  483.     submonth 0 ne
  484.     {
  485.         /lastday rows 1 add days_week mul def
  486.         days_week 1 sub daywidth mul -440 rmoveto
  487.     }
  488.     {
  489.         /lastday rows days_week mul 2 sub fillstart add def
  490.         days_week 3 sub fillstart add daywidth mul
  491.         -440 dayheight add rmoveto
  492.     } ifelse
  493.     lastday -1 ndays start 1 add add
  494.     {
  495.         /day exch def
  496.         gsave
  497.         .9 setgray
  498.         daywidth 0 rlineto 
  499.         0 dayheight neg rlineto
  500.         daywidth neg 0 rlineto
  501.         closepath fill
  502.         grestore
  503.         day weekday 1 eq
  504.         {
  505.             x0 y0 moveto
  506.             days_week 1 sub daywidth mul -440 dayheight add rmoveto
  507.         }
  508.         {
  509.             daywidth neg 0 rmoveto
  510.         } ifelse
  511.     } for
  512. } def
  513.  
  514. /usefirst {                % are last two boxes used by days?
  515.     start ndays add rows days_week mul 3 sub gt
  516.     start 2 ge and
  517.     
  518. } def
  519.  
  520. /calendar
  521. {
  522.     titlefont findfont titlefontsize scalefont setfont
  523.     0 60 moveto
  524.     /month_name month_names month 1 sub get def
  525.     month_name show
  526.     /yearstring year 10 string cvs def
  527.     daywidth days_week mul yearstring stringwidth pop sub 60 moveto
  528.     yearstring show
  529.  
  530.     eventflag {
  531.         % Show a centered Banner if any at the Top
  532.         daywidth days_week mul 2 div
  533.         Bannerstring stringwidth pop 2 div sub
  534.         60 moveto
  535.         Bannerstring show
  536.         % Show footnotes left-center-right
  537.         eventfont findfont footfontsize scalefont setfont
  538.         /bottomrow { dayheight rows mul 5 sub neg } def
  539.         0 bottomrow moveto
  540.         Lfootstring show
  541.         daywidth days_week mul Rfootstring stringwidth pop sub
  542.         bottomrow moveto
  543.         Rfootstring show
  544.         daywidth days_week mul Cfootstring stringwidth pop sub 2 div
  545.         bottomrow moveto
  546.         Cfootstring show
  547.         
  548.     } if
  549.  
  550.     0 -5 moveto
  551.     drawnums
  552.  
  553.     0 -5 moveto
  554.     drawfill
  555.  
  556.     eventflag {
  557.         0 0 moveto
  558.         drawevents
  559.     } if
  560.  
  561.     0 -5 moveto
  562.     drawgrid
  563. } def
  564.  
  565. /eventflag true def
  566.  
  567. $SCALE scale
  568. $ROTATE rotate
  569. $TRANSLATE translate
  570. /submonth 0 def
  571. calendar
  572. /eventflag false def
  573. month 1 sub 0 eq
  574. {
  575.     /lmonth 12 def
  576.     /lyear year 1 sub def
  577. }
  578. {
  579.     /lmonth month 1 sub def
  580.     /lyear year def
  581. } ifelse
  582. month 1 add 13 eq
  583. {
  584.     /nmonth 1 def
  585.     /nyear year 1 add def
  586. {
  587.     /nmonth month 1 add def
  588.     /nyear year def
  589. } ifelse
  590. usefirst
  591. {
  592.     0 30 translate
  593. }
  594. {
  595.     days_week 2 sub daywidth mul -350 translate
  596. }
  597. ifelse
  598. /submonth 1 def
  599. /year lyear def
  600. /month lmonth def
  601. gsave
  602. .138 .138 scale
  603. 12 -120 translate
  604. calendar
  605. grestore
  606. /submonth 1 def
  607. /year nyear def
  608. /month nmonth def
  609. daywidth 0 translate
  610. gsave
  611. .138 .138 scale
  612. 12 -120 translate
  613. calendar
  614. grestore
  615.  
  616. showpage
  617.  
  618. END-OF-CALENDAR
  619.  
  620.