home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / psutils / part04 < prev    next >
Encoding:
Text File  |  1993-02-03  |  44.2 KB  |  1,697 lines

  1. Newsgroups: comp.sources.misc
  2. From: Angus Duggan <ajcd@dcs.ed.ac.uk>
  3. Subject: v35i011:  psutils - Postscript document manipulation tools, v1.7, Part04/04
  4. Message-ID: <1993Feb2.051908.19185@sparky.imd.sterling.com>
  5. Date: Tue, 2 Feb 1993 05:19:08 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Md4-Signature: 7eda73d1b71d8fd8ecaf90f9134be803
  8.  
  9. Submitted-by: Angus Duggan <ajcd@dcs.ed.ac.uk>
  10. Posting-number: Volume 35, Issue 11
  11. Archive-name: psutils/part04
  12. Environment: UNIX
  13. Supersedes: psutils: Volume 22, Issue 87-88
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # Contents:  LICENSE Manifest epsffit.c fixfmps fixmacps fixpsditps
  20. #   fixpspps fixwfwps getafm patchlevel.h psbook.1 psbook.c psnup.1
  21. #   psselect.1 psselect.c pstops.c psutil.h
  22. # Wrapped by kent@sparky on Mon Feb  1 23:31:46 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 4 (of 4)."'
  26. if test -f 'LICENSE' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'LICENSE'\"
  28. else
  29.   echo shar: Extracting \"'LICENSE'\" \(1668 characters\)
  30.   sed "s/^X//" >'LICENSE' <<'END_OF_FILE'
  31. X
  32. X                        PS Utilities Package
  33. X
  34. XThe constituent files of this package listed below are copyright (C) 1991,1992
  35. XAngus J. C. Duggan.
  36. X
  37. XMakefile        README          buffer.c        epsffit.c       fixfmps
  38. Xfixmacps        fixpspps        getafm          magic.c         psbook.1
  39. Xpsbook.c        psnup           psnup.1         psselect.1      psselect.c
  40. Xpstops.1        pstops.c        psutil.c        psutil.h        showchar
  41. X
  42. XThey may be copied and used for any purpose (including distribution as part of
  43. Xa for-profit product), provided:
  44. X
  45. X1) The original attribution of the programs is clearly displayed in the product
  46. X   and/or documentation, even if the programs are modified and/or renamed as
  47. X   part of the product.
  48. X
  49. X2) The original source code of the programs is provided free of charge (except
  50. X   for reasonable distribution costs). For a definition of reasonable
  51. X   distribution costs, see the Gnu General Public License or Larry Wall's
  52. X   Artistic License (provided with the Perl 4 kit). The GPL and Artistic
  53. X   License in NO WAY affect this license; they are merely used as examples of
  54. X   the spirit in which it is intended.
  55. X
  56. X3) These programs are provided "as-is". No warranty or guarantee of their
  57. X   fitness for any particular task is provided. Use of these programs is
  58. X   completely at your own risk.
  59. X
  60. XBasically, I don't mind how you use the programs so long as you acknowledge
  61. Xthe author, and give people the originals if they want them.
  62. X
  63. XThe included files appledict.ps, md68.0.ps and md71.0.ps are (to the best of my
  64. Xknowledge) copyright Apple Computer, Inc.
  65. X
  66. X                                                                AJCD 25/3/92
  67. END_OF_FILE
  68.   if test 1668 -ne `wc -c <'LICENSE'`; then
  69.     echo shar: \"'LICENSE'\" unpacked with wrong size!
  70.   fi
  71.   # end of 'LICENSE'
  72. fi
  73. if test -f 'Manifest' -a "${1}" != "-c" ; then 
  74.   echo shar: Will not clobber existing file \"'Manifest'\"
  75. else
  76.   echo shar: Extracting \"'Manifest'\" \(249 characters\)
  77.   sed "s/^X//" >'Manifest' <<'END_OF_FILE'
  78. XLICENSE
  79. XMakefile
  80. XManifest
  81. XREADME
  82. Xpatchlevel.h
  83. Xappledict.ps
  84. Xepsffit.c
  85. Xfixfmps
  86. Xfixmacps
  87. Xfixpsditps
  88. Xfixpspps
  89. Xfixwfwps
  90. Xfixwpps
  91. Xgetafm
  92. Xmd68.0.ps
  93. Xmd71.0.ps
  94. Xpsbook.1
  95. Xpsbook.c
  96. Xpsnup
  97. Xpsnup.1
  98. Xpsselect.1
  99. Xpsselect.c
  100. Xpstops.1
  101. Xpstops.c
  102. Xpsutil.c
  103. Xpsutil.h
  104. Xshowchar
  105. END_OF_FILE
  106.   if test 249 -ne `wc -c <'Manifest'`; then
  107.     echo shar: \"'Manifest'\" unpacked with wrong size!
  108.   fi
  109.   # end of 'Manifest'
  110. fi
  111. if test -f 'epsffit.c' -a "${1}" != "-c" ; then 
  112.   echo shar: Will not clobber existing file \"'epsffit.c'\"
  113. else
  114.   echo shar: Extracting \"'epsffit.c'\" \(3793 characters\)
  115.   sed "s/^X//" >'epsffit.c' <<'END_OF_FILE'
  116. X/* epsffit.c
  117. X * AJCD 6 Dec 90
  118. X * fit epsf file into constrained size
  119. X * Usage:
  120. X *       epsffit [-c] [-r] [-a] [-s] llx lly urx ury
  121. X *               -c centres the image in the bounding box given
  122. X *               -r rotates the image by 90 degrees anti-clockwise
  123. X *               -a alters the aspect ratio to fit the bounding box
  124. X *               -s adds a showpage at the end of the image
  125. X */
  126. X
  127. X#include <stdio.h>
  128. X#include <ctype.h>
  129. X#include "patchlevel.h"
  130. X
  131. X#define min(x,y) ((x) > (y) ? (y) : (x))
  132. X#define max(x,y) ((x) > (y) ? (x) : (y))
  133. X
  134. Xstatic char *prog;
  135. X
  136. Xusage()
  137. X{
  138. X   fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  139. X   fprintf(stderr, "Usage: %s [-c] [-r] [-a] [-s] llx lly urx ury\n", prog);
  140. X   exit(1);
  141. X}
  142. X
  143. Xmain(argc, argv)
  144. X     int argc;
  145. X     char **argv;
  146. X{
  147. X   int fit[4], i;
  148. X   int bbfound = 0;              /* %%BoundingBox: found */
  149. X   int urx, ury, llx, lly;
  150. X   int furx, fury, fllx, flly, fwidth, fheight;
  151. X   int showpage = 0, centre = 0, rotate = 0, aspect = 0;
  152. X   char buf[BUFSIZ];
  153. X
  154. X   prog = *argv++; argc--;
  155. X
  156. X   while (argc > 0 && argv[0][0] == '-') {
  157. X      switch (argv[0][1]) {
  158. X      case 'c': centre = 1; break;
  159. X      case 's': showpage = 1; break;
  160. X      case 'r': rotate = 1; break;
  161. X      case 'a': aspect = 1; break;
  162. X      case 'v':
  163. X      default:  usage();
  164. X      }
  165. X      argc--;
  166. X      argv++;
  167. X   }
  168. X
  169. X   if (argc != 4) usage();
  170. X   fllx = atoi(argv[0]);
  171. X   flly = atoi(argv[1]);
  172. X   furx = atoi(argv[2]);
  173. X   fury = atoi(argv[3]);
  174. X   if (rotate) {
  175. X      fwidth = fury - flly;
  176. X      fheight = furx - fllx;
  177. X   } else {
  178. X      fwidth = furx - fllx;
  179. X      fheight = fury - flly;
  180. X   }
  181. X
  182. X   while (fgets(buf, BUFSIZ, stdin)) {
  183. X      if (buf[0] == '%' && (buf[1] == '%' || buf[1] == '!')) {
  184. X     /* still in comment section */
  185. X     if (!strncmp(buf, "%%BoundingBox:", 14)) {
  186. X        if (sscanf(buf, "%%%%BoundingBox:%d %d %d %d\n",
  187. X               &llx, &lly, &urx, &ury) == 4)
  188. X           bbfound = 1;
  189. X     } else if (!strncmp(buf, "%%EndComments", 13)) {
  190. X        strcpy(buf, "\n"); /* don't repeat %%EndComments */
  191. X        break;
  192. X     } else fputs(buf,stdout);
  193. X      } else break;
  194. X   }
  195. X   if (bbfound) { /* put BB, followed by scale&translate */
  196. X      double width = urx-llx, height = ury-lly;
  197. X      double xscale = fwidth/width, yscale = fheight/height;
  198. X      double xoffset = fllx, yoffset = flly;
  199. X      if (!aspect) {       /* preserve aspect ratio ? */
  200. X     xscale = yscale = min(xscale,yscale);
  201. X      }
  202. X      width *= xscale;     /* actual width and height after scaling */
  203. X      height *= yscale;
  204. X      if (centre) {
  205. X     if (rotate) {
  206. X        xoffset += (fheight - height)/2;
  207. X        yoffset += (fwidth - width)/2;
  208. X     } else {
  209. X        xoffset += (fwidth - width)/2;
  210. X        yoffset += (fheight - height)/2;
  211. X     }
  212. X      }
  213. X      printf("%%%%BoundingBox: %d %d %d %d\n", (int)xoffset, (int)yoffset,
  214. X         (int)(xoffset+(rotate ? height : width)),
  215. X         (int)(yoffset+(rotate ? width : height)));
  216. X      if (rotate) {  /* compensate for original image shift */
  217. X     xoffset += height + lly * yscale;  /* displacement for rotation */
  218. X     yoffset -= llx * xscale;
  219. X      } else {
  220. X     xoffset -= llx * xscale;
  221. X     yoffset -= lly * yscale;
  222. X      }
  223. X      puts("%%EndComments");
  224. X      if (showpage)
  225. X     puts("save /showpage{}def /copypage{}def /erasepage{}def");
  226. X      else
  227. X     puts("%%BeginProcSet: epsffit 1 0");
  228. X      puts("gsave");
  229. X      printf("%.3lf %.3lf translate\n", xoffset, yoffset);
  230. X      if (rotate)
  231. X     puts("90 rotate");
  232. X      printf("%.3lf %.3lf scale\n", xscale, yscale);
  233. X      if (!showpage)
  234. X     puts("%%EndProcSet");
  235. X   }
  236. X   do {
  237. X      fputs(buf,stdout);
  238. X   } while (fgets(buf, BUFSIZ, stdin));
  239. X   if (bbfound) {
  240. X      puts("grestore");
  241. X      if (showpage)
  242. X     puts("restore showpage"); /* just in case */
  243. X   } else {
  244. X      fprintf(stderr, "%s: no %%%%BoundingBox:\n", prog);
  245. X      exit(1);
  246. X   }
  247. X   exit(0);
  248. X}
  249. END_OF_FILE
  250.   if test 3793 -ne `wc -c <'epsffit.c'`; then
  251.     echo shar: \"'epsffit.c'\" unpacked with wrong size!
  252.   fi
  253.   # end of 'epsffit.c'
  254. fi
  255. if test -f 'fixfmps' -a "${1}" != "-c" ; then 
  256.   echo shar: Will not clobber existing file \"'fixfmps'\"
  257. else
  258.   echo shar: Extracting \"'fixfmps'\" \(362 characters\)
  259.   sed "s/^X//" >'fixfmps' <<'END_OF_FILE'
  260. X#!/usr/local/bin/perl
  261. X# fixfmps: get conforming PostScript out of FrameMaker file
  262. X# move all FMDEFINEFONTs to start of pages
  263. X
  264. X%fonts=();
  265. X
  266. Xwhile (<>) {
  267. X   if (/^([0-9]+) [0-9]+ .* FMDEFINEFONT$/) {
  268. X      $fonts{$1} = $_;
  269. X   } elsif (/^[0-9]+ [0-9]+ [0-9]+ FMBEGINPAGE$/) {
  270. X      print STDOUT $_, join('',values(%fonts));
  271. X   } else {
  272. X      print STDOUT $_;
  273. X   }
  274. X}
  275. END_OF_FILE
  276.   if test 362 -ne `wc -c <'fixfmps'`; then
  277.     echo shar: \"'fixfmps'\" unpacked with wrong size!
  278.   fi
  279.   chmod +x 'fixfmps'
  280.   # end of 'fixfmps'
  281. fi
  282. if test -f 'fixmacps' -a "${1}" != "-c" ; then 
  283.   echo shar: Will not clobber existing file \"'fixmacps'\"
  284. else
  285.   echo shar: Extracting \"'fixmacps'\" \(1329 characters\)
  286.   sed "s/^X//" >'fixmacps' <<'END_OF_FILE'
  287. X#!/usr/local/bin/perl
  288. X# fixmacps: swap to sanitised appledict
  289. X
  290. X$line = 0;            # keep line count
  291. X$dir = "/usr/local/share/tex/dvips";
  292. X$prefix = "md";
  293. X$default = "appledict.ps";
  294. X
  295. Xwhile ($_ = shift(@ARGV)) {
  296. X   if (/^-d(ir)?$/)   { $dir = shift(@ARGV); }
  297. X   if (/^-n(ame)?$/)   { $prefix = shift(@ARGV); }
  298. X   else {
  299. X      unshift(@ARGV, $_);
  300. X      last;
  301. X   }
  302. X}
  303. X
  304. Xwhile (<>) {
  305. X   if (/^%!/) {
  306. X      if (! $line) {
  307. X     print;
  308. X      }
  309. X   } elsif (/^%%BeginProcSet: "\(AppleDict md\)" ([0-9]+) ([0-9]+)$/) {
  310. X      local($mdv, $mdr) = ($1, $2);
  311. X      if (open(SANE, "<$dir/$prefix$mdv.$mdr.ps") ||
  312. X      open(SANE, "<$dir/$default")) {
  313. X     $sane = <SANE>;
  314. X     local($snv, $snr) =
  315. X        $sane =~ /^%%BeginProcSet: "\(AppleDict md\)" ([0-9]+) ([0-9]+)$/;
  316. X     if ($mdv == $snv && $mdr == $snr) {
  317. X        $ignore = 1;
  318. X     } else {
  319. X        print STDERR "Unrecognised AppleDict version $mdv $mdr\n";
  320. X        print "%!\n" if !$line;
  321. X        print;
  322. X     }
  323. X      } else {
  324. X     print STDERR "Can't find sanitised AppleDict\n";
  325. X     print "%!\n" if !$line;
  326. X     print;
  327. X      }
  328. X   } elsif (/^%%EndProcSet/) {
  329. X      if ($ignore) {
  330. X     $ignore = 0;
  331. X     print "%!\n" if !$line;
  332. X     print $sane;
  333. X     while(<SANE>) {
  334. X        print;
  335. X     }
  336. X     close(SANE);
  337. X      } else {
  338. X     print "%!\n" if !$line;
  339. X     print;
  340. X      }
  341. X   } else {
  342. X      if (! $ignore) {
  343. X     print "%!\n" if !$line;
  344. X     print;
  345. X      }
  346. X   }
  347. X   $line++;
  348. X}
  349. END_OF_FILE
  350.   if test 1329 -ne `wc -c <'fixmacps'`; then
  351.     echo shar: \"'fixmacps'\" unpacked with wrong size!
  352.   fi
  353.   chmod +x 'fixmacps'
  354.   # end of 'fixmacps'
  355. fi
  356. if test -f 'fixpsditps' -a "${1}" != "-c" ; then 
  357.   echo shar: Will not clobber existing file \"'fixpsditps'\"
  358. else
  359.   echo shar: Extracting \"'fixpsditps'\" \(349 characters\)
  360.   sed "s/^X//" >'fixpsditps' <<'END_OF_FILE'
  361. X#!/usr/local/bin/perl
  362. X# fixpsditps: fix psdit output for use in psutils
  363. X
  364. Xwhile (<>) {
  365. X   if (/^\/p{pop showpage pagesave restore \/pagesave save def}def$/) {
  366. X      print STDOUT "/p{pop showpage pagesave restore}def\n";
  367. X   } elsif (/^%%Page:/) {
  368. X      print STDOUT $_;
  369. X      print STDOUT "xi\n";
  370. X   } elsif (! /^xi$/) {
  371. X      print STDOUT $_;
  372. X   }
  373. X}
  374. END_OF_FILE
  375.   if test 349 -ne `wc -c <'fixpsditps'`; then
  376.     echo shar: \"'fixpsditps'\" unpacked with wrong size!
  377.   fi
  378.   chmod +x 'fixpsditps'
  379.   # end of 'fixpsditps'
  380. fi
  381. if test -f 'fixpspps' -a "${1}" != "-c" ; then 
  382.   echo shar: Will not clobber existing file \"'fixpspps'\"
  383. else
  384.   echo shar: Extracting \"'fixpspps'\" \(1165 characters\)
  385.   sed "s/^X//" >'fixpspps' <<'END_OF_FILE'
  386. X#!/usr/local/bin/perl
  387. X# mangle PostScript produced by PSPrint to make it almost conforming
  388. X
  389. X$header = 1; $ignore = 0;
  390. X$verbose = 0;
  391. X@body = ();
  392. X%fonts = (); $font = "";
  393. X$inchar = 0; @char = ();
  394. X
  395. Xwhile (<>) {
  396. X   if (/^@end$/) {
  397. X      $ignore = 1;
  398. X   } elsif (/^[0-9]+ @bop0$/) {
  399. X      $ignore = 0;
  400. X      $header = 1;
  401. X   } elsif ($header) {
  402. X      if (/^\/([a-z.0-9]+) @newfont$/) {
  403. X     if (! defined($fonts{$1})) {
  404. X        $fonts{$1} = 1;
  405. X        print;
  406. X     } elsif ($verbose) {
  407. X        print STDERR "$font already defined\n";
  408. X     }
  409. X      } elsif (/^([a-z.0-9]+) sf$/) {
  410. X     $font = $1;
  411. X     print;
  412. X      } elsif (/^\[</) {
  413. X     $inchar = 1;
  414. X     push (@char, $_);
  415. X      } elsif ($inchar) {
  416. X     push (@char, $_);
  417. X     if (/.*\] ([0-9]+) dc$/) {
  418. X        if (! defined($fonts{$font,$1})) {
  419. X           $fonts{$font,$1} = 1;
  420. X           print (@char);
  421. X        } elsif ($verbose) {
  422. X           print STDERR "$font character $1 already defined\n";
  423. X        }
  424. X        $inchar = 0;
  425. X        @char = ();
  426. X     }
  427. X      } elsif (/^([0-9]+) @bop1$/) {
  428. X     $header = 0;
  429. X     push (@body, "%%Page: ? $1\n");
  430. X     push (@body, $_);
  431. X      } else {
  432. X     print;
  433. X      }
  434. X   } elsif (! $ignore) {
  435. X      push (@body, $_);
  436. X   }
  437. X}
  438. Xprint (@body);
  439. Xprint ("@end\n");
  440. END_OF_FILE
  441.   if test 1165 -ne `wc -c <'fixpspps'`; then
  442.     echo shar: \"'fixpspps'\" unpacked with wrong size!
  443.   fi
  444.   chmod +x 'fixpspps'
  445.   # end of 'fixpspps'
  446. fi
  447. if test -f 'fixwfwps' -a "${1}" != "-c" ; then 
  448.   echo shar: Will not clobber existing file \"'fixwfwps'\"
  449. else
  450.   echo shar: Extracting \"'fixwfwps'\" \(261 characters\)
  451.   sed "s/^X//" >'fixwfwps' <<'END_OF_FILE'
  452. X#!/usr/local/bin/perl
  453. X# fixwfwps: fix Word for windows PostScript for printing.
  454. X
  455. Xwhile (<>) {
  456. X   tr/\000-\011\013-\037//d;
  457. X   if (/^(%!PS-Adobe-[0-9]*\.[0-9]*) EPSF-/) {
  458. X      print STDOUT "$1\n";
  459. X   } elsif (! /^%%BoundingBox/) {
  460. X      print STDOUT $_;
  461. X   }
  462. X}
  463. END_OF_FILE
  464.   if test 261 -ne `wc -c <'fixwfwps'`; then
  465.     echo shar: \"'fixwfwps'\" unpacked with wrong size!
  466.   fi
  467.   chmod +x 'fixwfwps'
  468.   # end of 'fixwfwps'
  469. fi
  470. if test -f 'getafm' -a "${1}" != "-c" ; then 
  471.   echo shar: Will not clobber existing file \"'getafm'\"
  472. else
  473.   echo shar: Extracting \"'getafm'\" \(4706 characters\)
  474.   sed "s/^X//" >'getafm' <<'END_OF_FILE'
  475. X#!/bin/sh
  476. X# getafm: get afm file from printer
  477. X#         Note that the AFM file returned will not have any kerning
  478. X#         information, but it is useful if you can't get the file anywhere else
  479. X# usage:
  480. X#       getafm Font-Name | lpr -Pprinter
  481. X
  482. Xif [ $# != 1 ]; then
  483. X        echo "Usage: `basename $0` Font-Name" >&2
  484. X        exit 1
  485. Xfi
  486. X
  487. Xcat <<EOF
  488. X%!
  489. X% Get character metrics and bounding box for $1
  490. X/ns 30 string def
  491. X/fname /$1 def
  492. X/fn fname findfont 1000 scalefont def
  493. X/en fn /Encoding get def
  494. Xfn setfont
  495. X
  496. X/sp { ( )print } def
  497. X/nl { (\n)print } def
  498. X/pn { ns cvs print } def
  499. X
  500. X/printbb { % llx lly urx ury => -
  501. X   4 -1 roll round cvi pn sp
  502. X   3 -1 roll round cvi pn sp
  503. X   exch round cvi pn sp
  504. X   round cvi pn
  505. X} def
  506. X
  507. X(StartFontMetrics 2.0\n)print
  508. X(Comment Created by `basename $0` 1.00 (c) AJCD `date`\n)print
  509. Xfn /FontName known {
  510. X   (FontName )print fn /FontName get pn nl
  511. X} {
  512. X   (FontName $1\n) print
  513. X} ifelse
  514. Xen StandardEncoding eq {
  515. X   (EncodingScheme AdobeStandardEncoding\n)print
  516. X} {
  517. X   en ISOLatin1Encoding eq {
  518. X      (EncodingScheme ISOLatin1Encoding\n)print
  519. X   } if
  520. X} ifelse
  521. Xfn /FontInfo known {
  522. X   fn /FontInfo get
  523. X   dup /FamilyName known {
  524. X      (FamilyName )print dup /FamilyName get print nl
  525. X   } if
  526. X   dup /FullName known {
  527. X      (FullName )print dup /FullName get print nl
  528. X   } if
  529. X   dup /Notice known {
  530. X      (Notice )print dup /Notice get print nl
  531. X   } if
  532. X   dup /Weight known {
  533. X      (Weight )print dup /Weight get print nl
  534. X   } if
  535. X   dup /Version known {
  536. X      (Version )print dup /Version get print nl
  537. X   } if
  538. X   dup /ItalicAngle known {
  539. X      (ItalicAngle )print dup /ItalicAngle get pn nl
  540. X   } if
  541. X   dup /isFixedPitch known {
  542. X      (IsFixedPitch )print dup /isFixedPitch get {(true)}{(false)}ifelse print
  543. X       nl
  544. X   } {
  545. X      (IsFixedPitch false\n)print
  546. X   } ifelse
  547. X   dup /UnderlinePosition known {
  548. X      (UnderlinePosition )print dup /UnderlinePosition get pn nl
  549. X   } if
  550. X   dup /UnderlineThickness known {
  551. X      (UnderlineThickness )print dup /UnderlineThickness get pn nl
  552. X   } if
  553. X   pop
  554. X} if
  555. X(FontBBox )print fn /FontBBox get aload pop printbb nl
  556. X
  557. X%CapHeight 662
  558. X%XHeight 448
  559. X%Descender -217
  560. X%Ascender 682
  561. X%(PaintType: )print fn /PaintType get pn (\n) print flush
  562. X
  563. X(StartCharMetrics )print
  564. Xfn /CharStrings get length 1 sub pn nl
  565. X
  566. X% check encoded chars
  567. X0 1 255 {
  568. X   dup en exch get 
  569. X   dup /.notdef ne { % C 77 ; WX 889 ; N M ; B 19 0 871 662 ;
  570. X      (C ) print                                % character number
  571. X      exch dup pn exch
  572. X      ( ; WX ) print                            % character width
  573. X      fn /Metrics known {
  574. X         dup fn /Metrics get exch get 
  575. X         dup type /arraytype eq {
  576. X            dup length 2 eq
  577. X            {1 get} {2 get} ifelse
  578. X         } if
  579. X      } {
  580. X         ( ) dup 0 4 index put stringwidth pop round cvi
  581. X      } ifelse
  582. X      pn
  583. X      ( ; N ) print                             % character name
  584. X      pn
  585. X      newpath 0 0 moveto
  586. X      ( ; B ) print                             % BoundingBox
  587. X      ( ) dup 0 4 -1 roll put
  588. X      true charpath flattenpath pathbbox printbb
  589. X      ( ;\n) print                              % finished!
  590. X   } {pop pop} ifelse
  591. X} for
  592. X
  593. X% get unencoded characters into MyEncoding array (problem if >256 unencoded)
  594. X/MyEncoding 256 array def
  595. X/Reverse 256 dict def
  596. XReverse begin
  597. X   en { % reverse encoding dictionary
  598. X      true def
  599. X   } forall
  600. Xend
  601. X
  602. X0 % start at beginning of MyEncoding
  603. Xfn /CharStrings get {
  604. X   pop % discard encrypted string
  605. X   dup Reverse exch known not % test if key is in normal encoding
  606. X   {
  607. X     MyEncoding 2 index 3 -1 roll put 1 add
  608. X   } {pop} ifelse
  609. X} forall
  610. X1 255 { % fill out with notdefs
  611. X   MyEncoding exch /.notdef put
  612. X} for
  613. X
  614. Xfn dup length dict begin
  615. X  {1 index /FID ne {def} {pop pop} ifelse} forall
  616. X  /Encoding MyEncoding def
  617. X  currentdict
  618. Xend /newfont exch definefont
  619. Xdup /fn exch def setfont
  620. X/en MyEncoding def
  621. X
  622. X% check encoded chars
  623. X0 1 255 {
  624. X   dup en exch get
  625. X   dup /.notdef ne { % C -1 ; WX 889 ; N M ; B 19 0 871 662 ;
  626. X      (C -1) print                                % character number
  627. X      ( ; WX ) print                            % character width
  628. X      fn /Metrics known {
  629. X         dup fn /Metrics get exch get 
  630. X         dup type /arraytype eq {
  631. X            dup length 2 eq
  632. X            {1 get} {2 get} ifelse
  633. X         } if
  634. X      } {
  635. X         ( ) dup 0 4 index put stringwidth pop round cvi
  636. X      } ifelse
  637. X      pn
  638. X      ( ; N ) print                             % character name
  639. X      pn
  640. X      newpath 0 0 moveto
  641. X      ( ; B ) print                             % BoundingBox
  642. X      ( ) dup 0 4 -1 roll put
  643. X      true charpath flattenpath pathbbox printbb
  644. X      ( ;\n) print                              % finished!
  645. X   } {pop pop exit} ifelse
  646. X} for
  647. X(EndCharMetrics\n)print
  648. Xflush
  649. XEOF
  650. END_OF_FILE
  651.   if test 4706 -ne `wc -c <'getafm'`; then
  652.     echo shar: \"'getafm'\" unpacked with wrong size!
  653.   fi
  654.   chmod +x 'getafm'
  655.   # end of 'getafm'
  656. fi
  657. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  658.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  659. else
  660.   echo shar: Extracting \"'patchlevel.h'\" \(39 characters\)
  661.   sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  662. X#define RELEASE 1
  663. X#define PATCHLEVEL 7
  664. END_OF_FILE
  665.   if test 39 -ne `wc -c <'patchlevel.h'`; then
  666.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  667.   fi
  668.   # end of 'patchlevel.h'
  669. fi
  670. if test -f 'psbook.1' -a "${1}" != "-c" ; then 
  671.   echo shar: Will not clobber existing file \"'psbook.1'\"
  672. else
  673.   echo shar: Extracting \"'psbook.1'\" \(1066 characters\)
  674.   sed "s/^X//" >'psbook.1' <<'END_OF_FILE'
  675. X.TH PSBOOK 1
  676. X.SH NAME
  677. Xpsbook \- rearrange pages in PostScript file into signatures
  678. X.SH SYNOPSIS
  679. X.B psbook
  680. X[
  681. X.B \-q
  682. X] [
  683. X.B \-s\fIsignature\fR
  684. X] [
  685. X.I infile
  686. X[
  687. X.I outfile
  688. X] ]
  689. X.SH DESCRIPTION
  690. X.I Psbook
  691. Xrearranges pages from a PostScript document into ``signatures'' for
  692. Xprinting books or booklets, creating a new PostScript file. The
  693. Xinput PostScript file should follow the Adobe Document Structuring
  694. XConventions.
  695. X.PP
  696. XThe
  697. X.I \-s
  698. Xoption selects the size of signature which will be used. The signature size is
  699. Xthe number of sides which will be folded and bound together; the number given
  700. Xshould be a multiple of four. The default is to use one signature for the
  701. Xwhole file. Extra blank sides will be added if the file does not contain a
  702. Xmultiple of four pages.
  703. X.PP
  704. XPsbook normally prints the page numbers of the pages rearranged; the
  705. X.I \-q
  706. Xoption suppresses this.
  707. X.SH AUTHOR
  708. XAngus Duggan
  709. X.SH "SEE ALSO"
  710. Xpsselect(1), pstops(1)
  711. X.SH TRADEMARKS
  712. X.B PostScript
  713. Xis a trademark of Adobe Systems Incorporated.
  714. X.SH BUGS
  715. X.I Psbook
  716. Xcannot cope with documents longer than 5000 pages.
  717. END_OF_FILE
  718.   if test 1066 -ne `wc -c <'psbook.1'`; then
  719.     echo shar: \"'psbook.1'\" unpacked with wrong size!
  720.   fi
  721.   # end of 'psbook.1'
  722. fi
  723. if test -f 'psbook.c' -a "${1}" != "-c" ; then 
  724.   echo shar: Will not clobber existing file \"'psbook.c'\"
  725. else
  726.   echo shar: Extracting \"'psbook.c'\" \(2106 characters\)
  727.   sed "s/^X//" >'psbook.c' <<'END_OF_FILE'
  728. X/* psbook.c
  729. X * AJCD 27/1/91
  730. X * rearrange pages in conforming PS file for printing in signatures
  731. X *
  732. X * Usage:
  733. X *       psbook [-q] [-s<signature>] [infile [outfile]]
  734. X */
  735. X
  736. X#include "psutil.h"
  737. X#include "patchlevel.h"
  738. X
  739. Xvoid usage()
  740. X{
  741. X   fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  742. X   fprintf(stderr, "Usage: %s [-q] [-s<signature>] [infile [outfile]]\n",
  743. X       prog);
  744. X   fprintf(stderr, "       <signature> must be positive and divisible by 4\n");
  745. X   fflush(stderr);
  746. X   exit(1);
  747. X}
  748. X
  749. X
  750. Xmain(argc, argv)
  751. X     int argc;
  752. X     char *argv[];
  753. X{
  754. X   int signature = 0;
  755. X   int currentpg, maxpage;
  756. X
  757. X   infile = stdin;
  758. X   outfile = stdout;
  759. X   verbose = 1;
  760. X   for (prog = *argv++; --argc; argv++) {
  761. X      if (argv[0][0] == '-') {
  762. X     switch (argv[0][1]) {
  763. X     case 's':
  764. X        signature = atoi(*argv+2);
  765. X        if (signature < 1 || signature % 4) usage();
  766. X        break;
  767. X     case 'q':
  768. X        verbose = 0;
  769. X        break;
  770. X     case 'v':
  771. X     default:
  772. X        usage();
  773. X     }
  774. X      } else if (infile == stdin) {
  775. X     if ((infile = fopen(*argv, "r")) == NULL) {
  776. X        fprintf(stderr, "%s: can't open input file %s\n", prog, *argv);
  777. X        fflush(stderr);
  778. X        exit(1);
  779. X     }
  780. X      } else if (outfile == stdout) {
  781. X     if ((outfile = fopen(*argv, "w")) == NULL) {
  782. X        fprintf(stderr, "%s: can't open output file %s\n", prog, *argv);
  783. X        fflush(stderr);
  784. X        exit(1);
  785. X     }
  786. X      } else usage();
  787. X   }
  788. X   if ((infile=seekable(infile))==NULL) {
  789. X      fprintf(stderr, "%s: can't seek input\n", prog);
  790. X      fflush(stderr);
  791. X      exit(1);
  792. X   }
  793. X   scanpages();
  794. X
  795. X   maxpage = pages+(4-pages%4)%4;
  796. X
  797. X   if (!signature)
  798. X      signature = maxpage;
  799. X
  800. X   /* rearrange pages */
  801. X   writeheader(maxpage);
  802. X   writeprolog();
  803. X   for (currentpg = 0; currentpg < maxpage; currentpg++) {
  804. X      int actualpg = currentpg - currentpg%signature;
  805. X      switch(currentpg%4) {
  806. X      case 0:
  807. X      case 3:
  808. X     actualpg += signature-1-(currentpg%signature)/2;
  809. X     break;
  810. X      case 1:
  811. X      case 2:
  812. X     actualpg += (currentpg%signature)/2;
  813. X     break;
  814. X      }
  815. X      if (actualpg < pages)
  816. X     writepage(actualpg);
  817. X      else
  818. X     writeemptypage();
  819. X   }
  820. X   writetrailer();
  821. X
  822. X   exit(0);
  823. X}
  824. END_OF_FILE
  825.   if test 2106 -ne `wc -c <'psbook.c'`; then
  826.     echo shar: \"'psbook.c'\" unpacked with wrong size!
  827.   fi
  828.   # end of 'psbook.c'
  829. fi
  830. if test -f 'psnup.1' -a "${1}" != "-c" ; then 
  831.   echo shar: Will not clobber existing file \"'psnup.1'\"
  832. else
  833.   echo shar: Extracting \"'psnup.1'\" \(2283 characters\)
  834.   sed "s/^X//" >'psnup.1' <<'END_OF_FILE'
  835. X.TH PSNUP 1
  836. X.SH NAME
  837. Xpsnup \- uses pstops to merge multiple pages per sheet
  838. X.SH SYNOPSIS
  839. X.B psnup
  840. X[
  841. X.B \-q
  842. X]
  843. X[
  844. X.B \-w\fIwidth\fR
  845. X]
  846. X[
  847. X.B \-h\fIheight\fR
  848. X]
  849. X[
  850. X.B \-p\fIpaper\fR
  851. X]
  852. X.B \-l
  853. X]
  854. X[
  855. X.B \-2 | \-4 | \-8 | \-h
  856. X]
  857. X[
  858. X.I infile
  859. X] ]
  860. X.SH DESCRIPTION
  861. X.I Psnup
  862. Xis a script making the use of 
  863. X.I pstops 
  864. Xeasier.
  865. XIt sets up standard width and height parameters and 
  866. X.I Pstops
  867. Xrearranges pages from a PostScript document, creating a new PostScript file.
  868. XThe input PostScript file should follow the Adobe Document Structuring
  869. XConventions.
  870. X.I Pstops
  871. Xcan be used to perform a large number of arbitrary re-arrangements of
  872. XDocuments, including arranging for printing 2-up, 4-up, booklets, reversing,
  873. Xselecting front or back sides of documents, scaling, etc.
  874. X.PP
  875. XThe
  876. X.I \-w
  877. Xoption gives the width, the default is (21cm),
  878. X.I \-h
  879. Xoption gives the height, the default is (29.7cm), 
  880. Xand are normally specified in
  881. X.B "cm"
  882. Xor
  883. X.B "in"
  884. Xto convert 
  885. XPostScript's points (1/72 of an inch)
  886. Xto centimeters or inches.
  887. XThe 
  888. X.I \-p
  889. Xoption can be used as an alternative, to set the paper size to
  890. X.B a3, a4, a5, letter
  891. Xor
  892. X.B legal.
  893. X.PP
  894. XThe
  895. X.I \-b
  896. Xoption prevents any
  897. X.B bind
  898. Xoperators in the PostScript prolog from binding. This may be needed in cases
  899. Xwhere complex multi-page re-arrangements are being done.
  900. X.PP
  901. XPstops normally prints the page numbers of the pages re-arranged; the
  902. X.I \-q
  903. Xoption suppresses this.
  904. X.SH EXAMPLES
  905. XThe potential use of this utility is varied but one particular 
  906. Xuse is in conjunction with 
  907. X.I psbook(1).
  908. XFor example, using psroff to create a PostScript document and lpr as 
  909. Xthe 
  910. X.SM UNIX 
  911. Xprint spooler a typical command line might look like this: 
  912. X.sp
  913. Xpsroff -ms \fIfile\fP | psbook | psnup -2 | lpr
  914. X.sp
  915. XWhere file is a 4 page document this command will result in a 
  916. Xtwo page document printing two pages of \fIfile\fP per page and
  917. Xrearranges the page order to match the input pages 4 and 1 
  918. Xon the first output page and
  919. Xpages 2 then 3 of the input document 
  920. Xon the second output page.
  921. X.SH AUTHOR
  922. XAngus Duggan
  923. X.br
  924. XBrian Colfer, University of California, San Francisco
  925. X.br
  926. Xbrianc@labmed.ucsf.edu
  927. X.SH "SEE ALSO"
  928. Xpsbook(1), pstops(1), psroff(1)
  929. X.SH TRADEMARKS
  930. X.B PostScript
  931. Xis a trademark of Adobe Systems Incorporated.
  932. X.SH BUGS
  933. X.I Pstops
  934. Xcannot cope with documents longer than 5000 pages.
  935. END_OF_FILE
  936.   if test 2283 -ne `wc -c <'psnup.1'`; then
  937.     echo shar: \"'psnup.1'\" unpacked with wrong size!
  938.   fi
  939.   # end of 'psnup.1'
  940. fi
  941. if test -f 'psselect.1' -a "${1}" != "-c" ; then 
  942.   echo shar: Will not clobber existing file \"'psselect.1'\"
  943. else
  944.   echo shar: Extracting \"'psselect.1'\" \(1776 characters\)
  945.   sed "s/^X//" >'psselect.1' <<'END_OF_FILE'
  946. X.TH PSSELECT 1
  947. X.SH NAME
  948. Xpsselect \- select pages from a PostScript file
  949. X.SH SYNOPSIS
  950. X.B psselect
  951. X[
  952. X.B \-q
  953. X] [
  954. X.B \-e
  955. X] [
  956. X.B \-o
  957. X] [
  958. X.B \-r
  959. X] [
  960. X.B \-p\fIpages\fR
  961. X] [
  962. X.I pages
  963. X] [
  964. X.I infile
  965. X[
  966. X.I outfile
  967. X] ]
  968. X.SH DESCRIPTION
  969. X.I Psselect
  970. Xselects pages from a PostScript document, creating a new PostScript file. The
  971. Xinput PostScript file should follow the Adobe Document Structuring
  972. XConventions.
  973. X.PP
  974. XThe 
  975. X.I \-e
  976. Xoption selects all of the even pages; it may be used in conjunction with the
  977. Xother page selection options to select the even pages from a range of pages.
  978. X.PP
  979. XThe 
  980. X.I \-o
  981. Xoption selects all of the odd pages; it may be used in conjunction with the
  982. Xother page selection options.
  983. X.PP
  984. XThe 
  985. X.I \-p\fIpages\fR
  986. Xoption specifies the pages which are to be selected.
  987. X.I Pages
  988. Xis a comma separated list of page ranges, each of which may be a page number,
  989. Xor a page range of the form \fIfirst\fR-\fIlast\fR. If \fIfirst\fR is omitted,
  990. Xthe
  991. Xfirst page is assumed, and if \fIlast\fR is omitted, the last page is assumed.
  992. X.PP
  993. XThe 
  994. X.I \-r
  995. Xoption causes
  996. X.I psselect
  997. Xto output the selected pages in reverse order.
  998. X.PP
  999. XPsselect normally prints the page numbers of the pages rearranged; the
  1000. X.I \-q
  1001. Xoption suppresses this.
  1002. X.PP
  1003. XIf any of the
  1004. X.I \-r, \-e,
  1005. Xor
  1006. X.I \-o
  1007. Xoptions are specified, the page range must be given with the
  1008. X.I \-p
  1009. Xoption. This is for backwards compatibility with previous versions.
  1010. X
  1011. X.SH NOTES
  1012. XThe page number given to
  1013. X.I psselect
  1014. Xis the number of the page counting from the start of the file, starting at
  1015. Xone. The actual page number in the document may be different.
  1016. X.SH AUTHOR
  1017. XAngus Duggan
  1018. X.SH "SEE ALSO"
  1019. Xpsbook(1), pstops(1)
  1020. X.SH TRADEMARKS
  1021. X.B PostScript
  1022. Xis a trademark of Adobe Systems Incorporated.
  1023. X.SH BUGS
  1024. X.I Psselect
  1025. Xcannot cope with documents longer than 5000 pages.
  1026. END_OF_FILE
  1027.   if test 1776 -ne `wc -c <'psselect.1'`; then
  1028.     echo shar: \"'psselect.1'\" unpacked with wrong size!
  1029.   fi
  1030.   # end of 'psselect.1'
  1031. fi
  1032. if test -f 'psselect.c' -a "${1}" != "-c" ; then 
  1033.   echo shar: Will not clobber existing file \"'psselect.c'\"
  1034. else
  1035.   echo shar: Extracting \"'psselect.c'\" \(4681 characters\)
  1036.   sed "s/^X//" >'psselect.c' <<'END_OF_FILE'
  1037. X/* psselect.c
  1038. X * AJCD 27/1/91
  1039. X * rearrange pages in conforming PS file for printing in signatures
  1040. X *
  1041. X * Usage:
  1042. X *       psselect [-q] [-e] [-o] [-r] [-p<pages>] [infile [outfile]]
  1043. X */
  1044. X
  1045. X#include "psutil.h"
  1046. X#include "patchlevel.h"
  1047. X
  1048. Xvoid usage()
  1049. X{
  1050. X   fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  1051. X   fprintf(stderr,
  1052. X       "Usage: %s [-q] [-e] [-o] [-r] [-p<pages>] [infile [outfile]]\n",
  1053. X       prog);
  1054. X   fflush(stderr);
  1055. X   exit(1);
  1056. X}
  1057. X
  1058. Xstruct pgrange {
  1059. X   int first, last;
  1060. X   struct pgrange *next;
  1061. X};
  1062. X
  1063. Xtypedef struct pgrange range;
  1064. X
  1065. Xrange * makerange(beg, end, next)
  1066. X     int beg, end;
  1067. X     range *next;
  1068. X{
  1069. X   range *new;
  1070. X   if ((new = (range *)malloc(sizeof(range))) == NULL) {
  1071. X      fprintf(stderr, "%s: out of memory\n", prog);
  1072. X      fflush(stderr);
  1073. X      exit(1);
  1074. X   }
  1075. X   new->first = beg;
  1076. X   new->last = end;
  1077. X   new->next = next;
  1078. X   return (new);
  1079. X}
  1080. X
  1081. X
  1082. Xrange * addrange(str, rp)
  1083. X     char *str;
  1084. X     range *rp;
  1085. X{
  1086. X   int first=0;
  1087. X   if (isdigit(*str)) {
  1088. X      first = atoi(str);
  1089. X      while (isdigit(*str)) str++;
  1090. X   }
  1091. X   switch (*str) {
  1092. X   case '\0':
  1093. X      if (first)
  1094. X     return (makerange(first, first, rp));
  1095. X      break;
  1096. X   case ',':
  1097. X      if (first)
  1098. X     return (addrange(str+1, makerange(first, first, rp)));
  1099. X      break;
  1100. X   case '-':
  1101. X   case ':':
  1102. X      str++;
  1103. X      if (isdigit(*str)) {
  1104. X     int last = atoi(str);
  1105. X     while (isdigit(*str)) str++;
  1106. X     if (!first)
  1107. X        first = 1;
  1108. X     if (last >= first) 
  1109. X        switch (*str) {
  1110. X        case '\0':
  1111. X           return (makerange(first, last, rp));
  1112. X        case ',':
  1113. X           return (addrange(str+1, makerange(first, last, rp)));
  1114. X        }
  1115. X      } else if (*str == '\0')
  1116. X     return (makerange(first, MAXPAGES, rp));
  1117. X   }
  1118. X   fprintf(stderr, "%s: invalid page range\n", prog);
  1119. X   fflush(stderr);
  1120. X   exit(1);
  1121. X}
  1122. X
  1123. X
  1124. Xmain(argc, argv)
  1125. X     int argc;
  1126. X     char *argv[];
  1127. X{
  1128. X   int currentpg, maxpage = 0;
  1129. X   int even = 0, odd = 0, reverse = 0;
  1130. X   int pass, all;
  1131. X   range *pagerange = NULL;
  1132. X
  1133. X   infile = stdin;
  1134. X   outfile = stdout;
  1135. X   verbose = 1;
  1136. X   for (prog = *argv++; --argc; argv++) {
  1137. X      if (argv[0][0] == '-') {
  1138. X     switch (argv[0][1]) {
  1139. X     case 'e':
  1140. X        even = 1;
  1141. X        break;
  1142. X     case 'o':
  1143. X        odd = 1;
  1144. X        break;
  1145. X     case 'r':
  1146. X        reverse = 1;
  1147. X        break;
  1148. X     case 'p':
  1149. X        pagerange = addrange(*argv+2, pagerange);
  1150. X        break;
  1151. X     case 'q':
  1152. X        verbose = 0;
  1153. X        break;
  1154. X     case 'v':
  1155. X     default:
  1156. X        usage();
  1157. X     }
  1158. X      } else if (pagerange == NULL && !reverse && !even && !odd) {
  1159. X     pagerange = addrange(*argv, NULL);
  1160. X      } else if (infile == stdin) {
  1161. X     if ((infile = fopen(*argv, "r")) == NULL) {
  1162. X        fprintf(stderr, "%s: can't open input file %s\n", prog, *argv);
  1163. X        fflush(stderr);
  1164. X        exit(1);
  1165. X     }
  1166. X      } else if (outfile == stdout) {
  1167. X     if ((outfile = fopen(*argv, "w")) == NULL) {
  1168. X        fprintf(stderr, "%s: can't open output file %s\n", prog, *argv);
  1169. X        fflush(stderr);
  1170. X        exit(1);
  1171. X     }
  1172. X      } else usage();
  1173. X   }
  1174. X   if ((infile=seekable(infile))==NULL) {
  1175. X      fprintf(stderr, "%s: can't seek input\n", prog);
  1176. X      fflush(stderr);
  1177. X      exit(1);
  1178. X   }
  1179. X   scanpages();
  1180. X
  1181. X   /* reverse page list if not reversing pages (list constructed bottom up) */
  1182. X   if (!reverse) {
  1183. X      range *revlist = NULL;
  1184. X      range *next = NULL;
  1185. X      while (pagerange) {
  1186. X     next = pagerange->next;
  1187. X     pagerange->next = revlist;
  1188. X     revlist = pagerange;
  1189. X     pagerange = next;
  1190. X      }
  1191. X      pagerange = revlist;
  1192. X   }
  1193. X
  1194. X   /* select all pages or all in range if odd or even not set */
  1195. X   all = !(odd || even);
  1196. X
  1197. X   /* count pages on first pass, select pages on second pass */
  1198. X   for (pass = 0; pass < 2; pass++) {
  1199. X      if (pass) {                           /* write header on second pass */
  1200. X     writeheader(maxpage);
  1201. X     writeprolog();
  1202. X      }
  1203. X      if (pagerange) {
  1204. X     range *r;
  1205. X     for (r = pagerange; r; r = r->next) {
  1206. X        if (reverse) {
  1207. X           for (currentpg = r->last; currentpg >= r->first; currentpg--) {
  1208. X          if ((currentpg&1) ? (odd || all) : (even || all)) {
  1209. X             if (pass)
  1210. X            writepage(currentpg-1);
  1211. X             else
  1212. X            maxpage++;
  1213. X          }
  1214. X           }
  1215. X        } else {
  1216. X           for (currentpg = r->first; currentpg <= r->last; currentpg++) {
  1217. X          if ((currentpg&1) ? (odd || all) : (even || all)) {
  1218. X             if (pass)
  1219. X            writepage(currentpg-1);
  1220. X             else
  1221. X            maxpage++;
  1222. X          }
  1223. X           }
  1224. X        }
  1225. X     }
  1226. X      } else if (reverse) {
  1227. X     for (currentpg = pages; currentpg > 0; currentpg--)
  1228. X        if ((currentpg&1) ? (odd || all) : (even || all)) {
  1229. X           if (pass)
  1230. X          writepage(currentpg-1);
  1231. X           else
  1232. X          maxpage++;
  1233. X        }
  1234. X      } else {
  1235. X     for (currentpg = 1; currentpg <= pages; currentpg++)
  1236. X        if ((currentpg&1) ? (odd || all) : (even || all)) {
  1237. X           if (pass)
  1238. X          writepage(currentpg-1);
  1239. X           else
  1240. X          maxpage++;
  1241. X        }
  1242. X      }
  1243. X   }
  1244. X   writetrailer();
  1245. X
  1246. X   exit(0);
  1247. X}
  1248. END_OF_FILE
  1249.   if test 4681 -ne `wc -c <'psselect.c'`; then
  1250.     echo shar: \"'psselect.c'\" unpacked with wrong size!
  1251.   fi
  1252.   # end of 'psselect.c'
  1253. fi
  1254. if test -f 'pstops.c' -a "${1}" != "-c" ; then 
  1255.   echo shar: Will not clobber existing file \"'pstops.c'\"
  1256. else
  1257.   echo shar: Extracting \"'pstops.c'\" \(9511 characters\)
  1258.   sed "s/^X//" >'pstops.c' <<'END_OF_FILE'
  1259. X/* pstops.c
  1260. X * AJCD 27/1/91
  1261. X * rearrange pages in conforming PS file for printing in signatures
  1262. X *
  1263. X * Usage:
  1264. X *       pstops [-q] [-b] [-w<dim>] [-h<dim>] <pagespecs> [infile [outfile]]
  1265. X */
  1266. X
  1267. X#include "psutil.h"
  1268. X#include "patchlevel.h"
  1269. X
  1270. Xvoid usage()
  1271. X{
  1272. X   fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  1273. X   fprintf(stderr, "Usage: %s [-q] [-b] [-w<dim>] [-h<dim] <pagespecs> [infile [outfile]]\n",
  1274. X       prog);
  1275. X   fflush(stderr);
  1276. X   exit(1);
  1277. X}
  1278. X
  1279. Xvoid specusage()
  1280. X{
  1281. X   fprintf(stderr, "%s: page specification error:\n", prog);
  1282. X   fprintf(stderr, "  <pagespecs> = [modulo:]<spec>\n");
  1283. X   fprintf(stderr, "  <spec>      = [-]pageno[@scale][L|R|U][(xoff,yoff)][,spec|+spec]\n");
  1284. X   fprintf(stderr, "                modulo>=1, 0<=pageno<modulo\n");
  1285. X   fflush(stderr);
  1286. X   exit(1);
  1287. X}
  1288. X
  1289. Xstatic int modulo = 1;
  1290. Xstatic int pagesperspec = 1;
  1291. Xstatic double width = -1.0;
  1292. Xstatic double height = -1.0;
  1293. X
  1294. X/* pagespec flags */
  1295. X#define ADD_NEXT (0x01)
  1296. X#define ROTATE   (0x02)
  1297. X#define SCALE    (0x04)
  1298. X#define OFFSET   (0x08)
  1299. X#define GSAVE    (ROTATE|SCALE|OFFSET)
  1300. X
  1301. Xstruct pagespec {
  1302. X   int reversed, pageno, flags, rotate;
  1303. X   double xoff, yoff, scale;
  1304. X   struct pagespec *next;
  1305. X};
  1306. X
  1307. Xstruct pagespec *newspec()
  1308. X{
  1309. X   struct pagespec *temp = (struct pagespec *)malloc(sizeof(struct pagespec));
  1310. X   temp->reversed = temp->pageno = temp->flags = temp->rotate = 0;
  1311. X   temp->scale = 1.0;
  1312. X   temp->xoff = temp->yoff = 0.0;
  1313. X   temp->next = NULL;
  1314. X   return (temp);
  1315. X}
  1316. X
  1317. Xint parseint(sp)
  1318. X     char **sp;
  1319. X{
  1320. X   char *s;
  1321. X   int n = 0;
  1322. X
  1323. X   for (s = *sp; isdigit(*s); s++)
  1324. X      n = n*10 + (*s-'0');
  1325. X   if (*sp == s) specusage();
  1326. X   *sp = s;
  1327. X   return (n);
  1328. X}
  1329. X
  1330. Xdouble parsedouble(sp)
  1331. X     char **sp;
  1332. X{
  1333. X   int n = 0, neg = 1;
  1334. X   char *s = *sp;
  1335. X   int d = 0, frac = 1;
  1336. X
  1337. X   if (*s == '-') {
  1338. X      neg = -1;
  1339. X      *sp = ++s;
  1340. X   }
  1341. X   for (;isdigit(*s); s++)
  1342. X      n = n*10 + (*s-'0');
  1343. X   if (*s == '.') {
  1344. X      *sp = ++s;
  1345. X      for (; isdigit(*s); s++) {
  1346. X     d = d*10 + (*s-'0');
  1347. X     frac *= 10;
  1348. X      }
  1349. X   }
  1350. X   if (*sp == s) specusage();
  1351. X   *sp = s;
  1352. X   return (neg*((double)n+(double)d/frac));
  1353. X}
  1354. X
  1355. Xdouble parsedimen(sp)
  1356. X     char **sp;
  1357. X{
  1358. X   double num = parsedouble(sp);
  1359. X   char *s = *sp;
  1360. X
  1361. X   if (strncmp(s, "pt", 2) == 0) {
  1362. X      s += 2;
  1363. X   } else if (strncmp(s, "in", 2) == 0) {
  1364. X      num *= 72.0;
  1365. X      s += 2;
  1366. X   } else if (strncmp(s, "cm", 2) == 0) {
  1367. X      num *= 28.346456692913385211;
  1368. X      s += 2;
  1369. X   } else if (*s == 'w') {
  1370. X      if (width < 0.0) {
  1371. X     fprintf(stderr, "%s: width not initialised\n", prog);
  1372. X     fflush(stderr);
  1373. X     exit(1);
  1374. X      }
  1375. X      num *= width;
  1376. X      s++;
  1377. X   } else if (*s == 'h') {
  1378. X      if (height < 0.0) {
  1379. X     fprintf(stderr, "%s: height not initialised\n", prog);
  1380. X     fflush(stderr);
  1381. X     exit(1);
  1382. X      }
  1383. X      num *= height;
  1384. X      s++;
  1385. X   }
  1386. X   *sp = s;
  1387. X   return (num);
  1388. X}
  1389. X
  1390. Xstruct pagespec *parsespecs(str)
  1391. X     char *str;
  1392. X{
  1393. X   char *t;
  1394. X   struct pagespec *head, *tail;
  1395. X   int other = 0;
  1396. X   int num = -1;
  1397. X
  1398. X   head = tail = newspec();
  1399. X   while (*str) {
  1400. X      if (isdigit(*str)) {
  1401. X     num = parseint(&str);
  1402. X      } else {
  1403. X     switch (*str++) {
  1404. X     case ':':
  1405. X        if (other || head != tail || num < 1) specusage();
  1406. X        modulo = num;
  1407. X        num = -1;
  1408. X        break;
  1409. X     case '-':
  1410. X        tail->reversed = !tail->reversed;
  1411. X        break;
  1412. X     case '@':
  1413. X        if (num < 0) specusage();
  1414. X        tail->scale *= parsedouble(&str);
  1415. X        tail->flags |= SCALE;
  1416. X        break;
  1417. X     case 'l': case 'L':
  1418. X        tail->rotate += 90;
  1419. X        tail->flags |= ROTATE;
  1420. X        break;
  1421. X     case 'r': case 'R':
  1422. X        tail->rotate -= 90;
  1423. X        tail->flags |= ROTATE;
  1424. X        break;
  1425. X     case 'u': case 'U':
  1426. X        tail->rotate += 180;
  1427. X        tail->flags |= ROTATE;
  1428. X        break;
  1429. X     case '(':
  1430. X        tail->xoff += parsedimen(&str);
  1431. X        if (*str++ != ',') specusage();
  1432. X        tail->yoff += parsedimen(&str);
  1433. X        if (*str++ != ')') specusage();
  1434. X        tail->flags |= OFFSET;
  1435. X        break;
  1436. X     case '+':
  1437. X        tail->flags |= ADD_NEXT;
  1438. X     case ',':
  1439. X        if (num < 0 || num >= modulo) specusage();
  1440. X        if ((tail->flags & ADD_NEXT) == 0)
  1441. X           pagesperspec++;
  1442. X        tail->pageno = num;
  1443. X        tail->next = newspec();
  1444. X        tail = tail->next;
  1445. X        num = -1;
  1446. X        break;
  1447. X     default:
  1448. X        specusage();
  1449. X     }
  1450. X     other = 1;
  1451. X      }
  1452. X   }
  1453. X   if (num >= modulo)
  1454. X      specusage();
  1455. X   else if (num >= 0)
  1456. X      tail->pageno = num;
  1457. X   return (head);
  1458. X}
  1459. X
  1460. Xdouble singledimen(str)
  1461. X     char *str;
  1462. X{
  1463. X   double num = parsedimen(&str);
  1464. X   if (*str) usage();
  1465. X   return (num);
  1466. X}
  1467. X
  1468. X
  1469. Xmain(argc, argv)
  1470. X     int argc;
  1471. X     char *argv[];
  1472. X{
  1473. X   int thispg, maxpage;
  1474. X   int pageindex = 0;
  1475. X   struct pagespec *specs = NULL;
  1476. X   int nobinding = 0;
  1477. X
  1478. X   infile = stdin;
  1479. X   outfile = stdout;
  1480. X   verbose = 1;
  1481. X   for (prog = *argv++; --argc; argv++) {
  1482. X      if (argv[0][0] == '-') {
  1483. X     switch (argv[0][1]) {
  1484. X     case 'q':
  1485. X        verbose = 0;
  1486. X        break;
  1487. X     case 'b':
  1488. X        nobinding = 1;
  1489. X        break;
  1490. X     case 'w':
  1491. X        width = singledimen(*argv+2);
  1492. X        break;
  1493. X     case 'h':
  1494. X        height = singledimen(*argv+2);
  1495. X        break;
  1496. X     case 'v':
  1497. X        usage();
  1498. X     default:
  1499. X        if (specs == NULL)
  1500. X           specs = parsespecs(*argv);
  1501. X        else
  1502. X           usage();
  1503. X     }
  1504. X      } else if (specs == NULL)
  1505. X     specs = parsespecs(*argv);
  1506. X      else if (infile == stdin) {
  1507. X     if ((infile = fopen(*argv, "r")) == NULL) {
  1508. X        fprintf(stderr, "%s: can't open input file %s\n", prog, *argv);
  1509. X        fflush(stderr);
  1510. X        exit(1);
  1511. X     }
  1512. X      } else if (outfile == stdout) {
  1513. X     if ((outfile = fopen(*argv, "w")) == NULL) {
  1514. X        fprintf(stderr, "%s: can't open output file %s\n", prog, *argv);
  1515. X        fflush(stderr);
  1516. X        exit(1);
  1517. X     }
  1518. X      } else usage();
  1519. X   }
  1520. X   if (specs == NULL)
  1521. X      usage();
  1522. X   if ((infile=seekable(infile))==NULL) {
  1523. X      fprintf(stderr, "%s: can't seek input\n", prog);
  1524. X      fflush(stderr);
  1525. X      exit(1);
  1526. X   }
  1527. X   scanpages();
  1528. X
  1529. X   maxpage = ((pages+modulo-1)/modulo)*modulo;
  1530. X
  1531. X   /* rearrange pages: doesn't cope properly with:
  1532. X    * initmatrix, initgraphics, defaultmatrix, grestoreall, initclip */
  1533. X   writeheader((maxpage/modulo)*pagesperspec);
  1534. X   writestring("%%BeginProcSet: pstops 1 0\n");
  1535. X   writestring("[/showpage/erasepage/copypage]{dup where{pop dup load\n");
  1536. X   writestring(" type/operatortype eq{1 array cvx dup 0 3 index cvx put\n");
  1537. X   writestring(" bind def}{pop}ifelse}{pop}ifelse}forall\n");
  1538. X   writestring("[/letter/legal/executivepage/a4/a4small/b5/com10envelope\n");
  1539. X   writestring(" /monarchenvelope/c5envelope/dlenvelope/lettersmall/note\n");
  1540. X   writestring(" /folio/quarto/a5]{dup where{dup wcheck{exch{}put}\n");
  1541. X   writestring(" {pop{}def}ifelse}{pop}ifelse}forall\n");
  1542. X   writestring("/lcvx{dup load dup type dup/operatortype eq{pop exch pop}\n");
  1543. X   writestring(" {/arraytype eq{dup xcheck{exch pop aload pop}\n");
  1544. X   writestring(" {pop cvx}ifelse}{pop cvx}ifelse}ifelse}bind def\n");
  1545. X   writestring("/pstopsmatrix matrix currentmatrix def\n");
  1546. X   writestring("/defaultmatrix{pstopsmatrix exch copy}bind def\n");
  1547. X   writestring("/initmatrix{matrix defaultmatrix setmatrix}bind def\n");
  1548. X   writestring("/pathtoproc{[{currentpoint}stopped{$error/newerror false\n");
  1549. X   writestring(" put{newpath}}{/newpath cvx 3 1 roll/moveto cvx 4 array\n");
  1550. X   writestring(" astore cvx}ifelse]{[/newpath cvx{/moveto cvx}{/lineto cvx}\n");
  1551. X   writestring(" {/curveto cvx}{/closepath cvx}pathforall]cvx exch pop}\n");
  1552. X   writestring(" stopped{$error/errorname get/invalidaccess eq{cleartomark\n");
  1553. X   writestring(" $error/newerror false put cvx exec}{stop}ifelse}if}def\n");
  1554. X   if (width > 0.0 && height > 0.0) {
  1555. X      char buffer[BUFSIZ];
  1556. X      writestring("/initclip[/pathtoproc lcvx/matrix lcvx/currentmatrix lcvx");
  1557. X      writestring("/initmatrix lcvx/initclip lcvx /newpath lcvx\n");
  1558. X      writestring(" 0 0 /moveto lcvx\n");
  1559. X      sprintf(buffer,
  1560. X          " %lf 0/rlineto lcvx 0 %lf/rlineto lcvx -%lf 0/rlineto lcvx\n",
  1561. X          width, height, width);
  1562. X      writestring(buffer);
  1563. X      writestring(" /clip lcvx /newpath lcvx /setmatrix lcvx /exec lcvx]\n");
  1564. X      writestring(" cvx def\n");
  1565. X   }
  1566. X   writestring("/initgraphics{initmatrix newpath initclip 1 setlinewidth\n");
  1567. X   writestring(" 0 setlinecap 0 setlinejoin []0 setdash 0 setgray\n");
  1568. X   writestring(" 10 setmiterlimit}bind def\n");
  1569. X   if (nobinding) /* desperation measures */
  1570. X      writestring("/bind{}def\n");
  1571. X   writestring("%%EndProcSet\n");
  1572. X   writeprolog();
  1573. X   for (thispg = 0; thispg < maxpage; thispg += modulo) {
  1574. X      int add_last = 0;
  1575. X      struct pagespec *ps;
  1576. X      for (ps = specs; ps != NULL; ps = ps->next) {
  1577. X     int actualpg;
  1578. X     int add_next = ((ps->flags & ADD_NEXT) != 0);
  1579. X     if (ps->reversed)
  1580. X        actualpg = maxpage-thispg-modulo+ps->pageno;
  1581. X     else
  1582. X        actualpg = thispg+ps->pageno;
  1583. X     if (actualpg < pages)
  1584. X        seekpage(actualpg);
  1585. X     if (!add_last) {
  1586. X        writepageheader("pstops", ++pageindex);
  1587. X     }
  1588. X     writestring("/pstopssaved save def\n");
  1589. X     if (ps->flags & GSAVE) {
  1590. X        char buffer[BUFSIZ];
  1591. X        if (ps->flags & OFFSET) {
  1592. X           sprintf(buffer, "%lf %lf translate\n", ps->xoff, ps->yoff);
  1593. X           writestring(buffer);
  1594. X        }
  1595. X        if (ps->flags & ROTATE) {
  1596. X           sprintf(buffer, "%d rotate\n", ps->rotate);
  1597. X           writestring(buffer);
  1598. X        }
  1599. X        if (ps->flags & SCALE) {
  1600. X           sprintf(buffer, "%lf dup scale\n", ps->scale);
  1601. X           writestring(buffer);
  1602. X        }
  1603. X        writestring("/pstopsmatrix matrix currentmatrix def\n");
  1604. X     }
  1605. X     if (width > 0.0 && height > 0.0) {
  1606. X        writestring("initclip\n");
  1607. X     }
  1608. X     if (add_next) {
  1609. X        writestring("/showpage{}def/copypage{}def/erasepage{}def\n");
  1610. X     }
  1611. X     if (actualpg < pages)
  1612. X        writepagebody();
  1613. X     else
  1614. X        writestring("showpage\n");
  1615. X     writestring("pstopssaved restore\n");
  1616. X     add_last = add_next;
  1617. X      }
  1618. X   }
  1619. X   writetrailer();
  1620. X
  1621. X   exit(0);
  1622. X}
  1623. END_OF_FILE
  1624.   if test 9511 -ne `wc -c <'pstops.c'`; then
  1625.     echo shar: \"'pstops.c'\" unpacked with wrong size!
  1626.   fi
  1627.   # end of 'pstops.c'
  1628. fi
  1629. if test -f 'psutil.h' -a "${1}" != "-c" ; then 
  1630.   echo shar: Will not clobber existing file \"'psutil.h'\"
  1631. else
  1632.   echo shar: Extracting \"'psutil.h'\" \(682 characters\)
  1633.   sed "s/^X//" >'psutil.h' <<'END_OF_FILE'
  1634. X/* psutil.h
  1635. X * AJCD 29/1/91
  1636. X * utilities for PS programs
  1637. X */
  1638. X
  1639. X#include <stdio.h>
  1640. X#include <ctype.h>
  1641. X
  1642. X#ifndef LOCAL
  1643. X#define LOCAL extern
  1644. X#endif
  1645. X
  1646. X#define TMPDIR "/tmp"
  1647. X#define MAXPAGES 5000 /* max pages in document */
  1648. X
  1649. XLOCAL char *prog;
  1650. XLOCAL long pageptr[MAXPAGES];
  1651. XLOCAL int pages;
  1652. XLOCAL int verbose;
  1653. XLOCAL FILE *infile;
  1654. XLOCAL FILE *outfile;
  1655. X
  1656. XLOCAL FILE *seekable();
  1657. XLOCAL int fcopy();
  1658. XLOCAL writepage();
  1659. XLOCAL seekpage();
  1660. XLOCAL writepageheader();
  1661. XLOCAL writepagebody();
  1662. XLOCAL writeheader();
  1663. XLOCAL writeprolog();
  1664. XLOCAL writetrailer();
  1665. XLOCAL writeemptypage();
  1666. XLOCAL scanpages();
  1667. XLOCAL writestring();
  1668. XLOCAL message();
  1669. X
  1670. Xextern long lseek();
  1671. Xextern long ftell();
  1672. Xextern char *getenv();
  1673. END_OF_FILE
  1674.   if test 682 -ne `wc -c <'psutil.h'`; then
  1675.     echo shar: \"'psutil.h'\" unpacked with wrong size!
  1676.   fi
  1677.   # end of 'psutil.h'
  1678. fi
  1679. echo shar: End of archive 4 \(of 4\).
  1680. cp /dev/null ark4isdone
  1681. MISSING=""
  1682. for I in 1 2 3 4 ; do
  1683.     if test ! -f ark${I}isdone ; then
  1684.     MISSING="${MISSING} ${I}"
  1685.     fi
  1686. done
  1687. if test "${MISSING}" = "" ; then
  1688.     echo You have unpacked all 4 archives.
  1689.     rm -f ark[1-9]isdone
  1690. else
  1691.     echo You still must unpack the following archives:
  1692.     echo "        " ${MISSING}
  1693. fi
  1694. exit 0
  1695.  
  1696. exit 0 # Just in case...
  1697.