home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / ps / pscal.zoo / pscal.shar
Text File  |  1990-05-23  |  17KB  |  721 lines

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