Path: utzoo!utgpu!watserv1!watmath!att!att!linac!uwm.edu!rpi!zaphod.mps.ohio-state.edu!samsung!olivea!apple!well!shiva From: shiva@well.sf.ca.us (Kenneth Porter) Newsgroups: comp.lang.postscript Subject: Re: A question about //add Summary: Nesting systemdict replacements Message-ID: <21858@well.sf.ca.us> Date: 29 Nov 90 05:55:40 GMT References: <1990Nov12.195235.13908@light.uucp> <321@heaven.woodside.ca.us> <3294@exodus.Eng.Sun.COM> Lines: 123 flar@bendenweyr.Eng.Sun.COM (Jim Graham) writes: > A robust method for performing this overriding behaviour would be the > following (assuming you are writing a package referred to as "AA"): > > /preAAshowpage /showpage load def > > /showpage {stuff preAAshowpage morestuff} bind def > > If showpage were an operator prior to this code, then bind would > still bind the operator into the procedure (in which case > "/preAAshowpage" would be wasted"). If it were not an operator, > then the new showpage procedure would still execute correctly. This doesn't work if you nest the same file twice and the original showpage has been redefined before: % (in exit-server job) /showpage {{sysop stuff} original-showpage} def % (in user job) /preAAshowpage /showpage load def /showpage {stuff preAAshowpage morestuff} bind def /preAAshowpage /showpage load def /showpage {stuff preAAshowpage morestuff} bind def The new showpage is now recursive: {stuff {stuff ... preAAshowpage ... morestuff} morestuff} Here's an nup script that illustrates a case where nesting is necessary: ------------------------------nup.sh------------------------------ #!/bin/csh -f # change following line to point to correct path for next file set twoup=/home/ken/psfonts/ps/twoup.ps set n=$argv[1] set logn=0 while ($n > 1) @ logn++ @ n /= 2 end echo logn = $logn cp /dev/null /tmp/nup.$$ while ($logn > 0) cat $twoup >> /tmp/nup.$$ @ logn-- end foreach i ($argv[2-]) echo $i cat /tmp/nup.$$ $i | lpr end ----------------------------twoup.ps---------------------------- %! Two-up filter % Redefine showpage to collect two pages per page. % Make showpage a procedure if it's an operator. % This allows us to use // unconditionally to replace % showpage below with "//showpage exec". /showpage load type /operatortype eq { /showpage { //showpage } bind def } if % Support routines in private dictionary /twoupdict 6 dict def twoupdict begin /inch { 72 mul } bind def /rightpage false def % doing right half of page /twoupscale 5.5 8.5 div def /offset % fudge factor to center on half page 11 4 div % half page width 8.5 twoupscale mul 2 div % half scaled page width sub inch def /setup { % This does the real work grestore % matrix currentmatrix == flush % observe previous transform for debugging gsave % restore initial coords 90 rotate -8.25 inch translate % this eats argument offset 0 translate twoupscale dup scale 0 0 moveto 8.5 inch 0 lineto 8.5 inch 11 inch lineto 0 11 inch lineto closepath clip newpath } bind def /dofile { % init and cleanup code gsave //twoupdict begin 0 setup end % this is how to do an end-of-file handler currentfile cvx exec % process client file % issue paper for last page if necessary //twoupdict begin rightpage { //showpage exec } if end } bind def end % close dictionary before running % new two-up showpage /showpage { //twoupdict begin /rightpage rightpage dup { grestore //showpage exec gsave 0 setup } { 5.5 inch setup } ifelse not def end } def twoupdict /dofile get exec ---------------------------------------------------------------- Ken (shiva@well.sf.ca.us) P.S. Mention my name and email address when you distribute this -- my ego needs it :-)