home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume5 / a2ps.c < prev    next >
Encoding:
Internet Message Format  |  1989-02-03  |  23.9 KB

  1. Path: xanth!nic.MR.NET!hal!ncoast!allbery
  2. From: miguel@imag.imag.fr.UUCP (Miguel Santana)
  3. Newsgroups: comp.sources.misc
  4. Subject: v05i090: a2ps
  5. Message-ID: <4068@imag.imag.fr>
  6. Date: 23 Dec 88 01:24:15 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: miguel@imag.imag.fr.UUCP (Miguel Santana)
  9. Organization: IMAG, University of Grenoble, France
  10. Lines: 923
  11. Approved: allbery@ncoast.UUCP
  12.  
  13. Posting-number: Volume 5, Issue 90
  14. Submitted-by: "Miguel Santana" <miguel@imag.imag.fr.UUCP>
  15. Archive-name: a2ps.c
  16.  
  17. [Let's see now:  "UNIX" != "SYSV", and somewhere SYSV picked up <sys/timeb.h>.
  18. Somehow that doesn't agree with what I know... beware of the #ifdef's, people,
  19. they don't appear to be accurate in all cases.  (Actually, it looks more like
  20. "UNIX != XENIX", which is generally true.  Sigh.)  ++bsa]
  21.  
  22. This is a new version of a2ps, a program to format an ascii file for
  23. printing in a postcript printer. Initial version was a shell program
  24. written by evan@csli (Evan Kirshenbaum). It was very slow and contained
  25. many bugs. The new version was written in C for improve speed execution
  26. and portability. New features and improvements have been added (see
  27. README and a2ps.1).
  28.  
  29. Format used to print files is very nice and compact: two pages on each
  30. physical page, borders surrounding pages, headers with useful information
  31. (page number, printing date, file name), line numbering, etc. Very useful
  32. to archive listings of programs.
  33.  
  34. The a2ps distribution consists of the following files:
  35.  
  36.     README
  37.     Makefile
  38.     a2ps.c        a2ps source
  39.     a2ps.1        a troff manual (man file)
  40.     header.ps    postcript header used by a2ps
  41.  
  42. Please send problems and feedback to:
  43.  
  44.     miguel@imag.fr or miguel@imag.UUCP (uunet.uu.net!imag!miguel)
  45.  
  46.     Miguel SANTANA
  47.     LGI
  48.     IMAG-Campus
  49.     BP 53X
  50.     38041 Grenoble Cedex
  51.  
  52. ---- Cut Here and unpack ----
  53. #!/bin/sh
  54. # shar:    Shell Archiver  (v1.22)
  55. #
  56. #    Run the following text with /bin/sh to create:
  57. #      README
  58. #      Makefile
  59. #      a2ps.1
  60. #      a2ps.c
  61. #      header.ps
  62. #
  63. if test -f README; then echo "File README exists"; else
  64. echo "x - extracting README (Text)"
  65. sed 's/^X//' << 'SHAR_EOF' > README &&
  66. XThis is a new version of a2ps, a program to format an ascii file for
  67. Xprinting in a postcript printer. As the copyright indicates, this
  68. Xdistribution can be freely redistributed.
  69. X
  70. XInitial version was a shell program written by evan@csli (Evan
  71. XKirshenbaum). It was very slow and contained many bugs. The new
  72. Xversion was written in C for improve speed execution and portability.
  73. XNew features and improvements have been added.
  74. X
  75. X
  76. XSome notes on the distribution:
  77. X
  78. X    Installation is done by modifying and executing Makefile included
  79. X    in this distribution. You must give your own values to two variables:
  80. X    - HEADER_PS   a2ps will search there the file header.ps at execution
  81. X          time.
  82. X    - compiler      compiler name, actually one of UNIX, SYSV, ANSIC. Turbo
  83. X          C and Microsoft C are considered ANSIC compilers.
  84. X
  85. X    a2ps has been successfully ported to Unix 4.3BSD, Unix SystemV and
  86. X    MSDOS.
  87. X
  88. X
  89. XThe a2ps distribution consists of the following files:
  90. X
  91. X    README        This message
  92. X    Makefile
  93. X    a2ps.c        a2ps source
  94. X    a2ps.1        a troff manual (man file)
  95. X    header.ps    postcript header used by a2ps
  96. X
  97. XDecide where you want to keep these files and move it there.
  98. XEdit "Makefile" and change the definition of HEADER_PS (to
  99. Xreflect the full pathname of header.ps) and of compiler name.
  100. XTo make a2ps do:
  101. X
  102. X    make a2ps
  103. X
  104. XTo install it, do:
  105. X
  106. X    make install
  107. X
  108. XFormat the manual entry using
  109. X
  110. X    nroff -man a2ps.1
  111. X
  112. X
  113. XPlease send problems and feedback to:
  114. X
  115. X    miguel@imag.fr or miguel@imag.UUCP (uunet.uu.net!imag!miguel)
  116. X
  117. X    Miguel SANTANA
  118. X    LGI
  119. X    IMAG-Campus
  120. X    BP 53X
  121. X    38041 Grenoble Cedex
  122. SHAR_EOF
  123. chmod 0664 README || echo "restore of README fails"
  124. set `wc -c README`;Sum=$1
  125. if test "$Sum" != "1575"
  126. then echo original size 1575, current size $Sum;fi
  127. fi
  128. if test -f Makefile; then echo "File Makefile exists"; else
  129. echo "x - extracting Makefile (Text)"
  130. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  131. X#
  132. X# Description: Makefile to construct and install a2ps. Don't forget
  133. X# to give your own values to define variables HEADER_PS and name of
  134. X# compiler (see OPTIONS).
  135. X#
  136. X# File: imag:/users/local/a2ps/Makefile
  137. X# Created: Mon Nov 29 14:05:39 1988 by miguel@imag (Miguel Santana)
  138. X# Version: 2.0
  139. X#
  140. X
  141. X# Copyright (c) 1988, Miguel Santana, miguel@imag.imag.fr
  142. X#
  143. X# Permission is granted to copy and distribute this file in modified
  144. X# or unmodified form, whether for noncommercial or commercial use,
  145. X# provided (a) this copyright notice is preserved, (b) no attempt is
  146. X# made to restrict redistribution of this file, and (c) this file is
  147. X# not distributed as part of any collection whose redistribution is
  148. X# restricted by a compilation copyright.
  149. X#
  150. X
  151. XD    =.
  152. X
  153. XO    =.
  154. X
  155. XI    =/users/local/a2ps
  156. X
  157. XOPTIONS    =-DHEADER_PS="\"$I/header.ps\"" -DUNIX -O
  158. X
  159. XOBJS          = a2ps.o
  160. X
  161. Xall:        a2ps install
  162. X
  163. Xa2ps:        a2ps.o
  164. X        @echo -n "Compiling and linking a2ps ... "
  165. X        @cc -o $D/xa2ps a2ps.o
  166. X        @echo "done"
  167. X
  168. Xinstall:;    @echo -n "Installing a2ps ... "
  169. X        @cp xa2ps $I/a2ps
  170. X        @cp header.ps $I/header.ps
  171. X        @echo "done"
  172. X
  173. Xclean:;        @rm -f $(OBJS)
  174. X
  175. Xa2ps.o:;
  176. X        cc -c $(OPTIONS) a2ps.c
  177. X
  178. SHAR_EOF
  179. chmod 0664 Makefile || echo "restore of Makefile fails"
  180. set `wc -c Makefile`;Sum=$1
  181. if test "$Sum" != "1132"
  182. then echo original size 1132, current size $Sum;fi
  183. fi
  184. if test -f a2ps.1; then echo "File a2ps.1 exists"; else
  185. echo "x - extracting a2ps.1 (Text)"
  186. sed 's/^X//' << 'SHAR_EOF' > a2ps.1 &&
  187. X.\" @(#)a2ps.man.1 2.0 11/29/88
  188. X.\"
  189. X.TH A2PS 1L "November 29 1988"
  190. X.UC 4
  191. X.SH NAME
  192. Xa2ps \- formats an ascii file for printing in a postscript printer;
  193. Xvery nice and compact format for program listings.
  194. X.SH SYNOPSIS
  195. X.B a2ps
  196. X[ -b ] [ -f ] [ -i ] [ -n ] [ -n{bfinrv} ] [ -r ] [ -v ] [
  197. X.B file1
  198. X] [
  199. X.B file2
  200. X] [...]
  201. X.SH DESCRIPTION
  202. X.B a2ps
  203. Xformats files "file1", "file2", ... for printing in a postscript printer;
  204. Xif no file is given,
  205. X.B a2ps
  206. Xreads from the standard input.
  207. XFormat used is very nice and compact: two pages on each physical page,
  208. Xborders surrounding pages, headers with useful information (page number,
  209. Xprinting date, file name), line numbering, etc. Very useful to
  210. Xarchive listings of programs.
  211. X.PP
  212. XOptions offered by
  213. X.B a2ps
  214. Xare the following:
  215. X.TP 0.6i
  216. X.B -b
  217. XForce printing binary files. By default, binary files printing is
  218. Xstopped before second page (see -nb option).
  219. X.TP 0.6i
  220. X.B -f
  221. XFold lines too large to be printed inside the borders (default option).
  222. XMax size is actually 86 characters.
  223. X.TP 0.6i
  224. X.B -i
  225. XInterpret TAB, BS and FF characters (default option). TAB is replaced by
  226. Xenough spaces to reach next tab stop while BS and FF have their meanings.
  227. X.TP 0.6i
  228. X.B -n
  229. XOutput lines are preceded by line numbers, numbered sequentially from 1
  230. X(default option).
  231. X.TP 0.6i
  232. X.B -nb
  233. XDon't print binary files. To detect such a file we make use of a
  234. Xvery simple heuristic: if the first page of the file contains at
  235. Xless 75% of non-printing characters, it's a binary file. First page
  236. Xis always printed.
  237. X.TP 0.6i
  238. X.B -nf
  239. XCut lines too large (don't fold).
  240. X.TP 0.6i
  241. X.B -ni
  242. XDon't interpret TAB, BS and FF characters. They will be printed
  243. Xaccording to -v option.
  244. X.TP 0.6i
  245. X.B -nn
  246. XDon't number output lines.
  247. X.TP 0.6i
  248. X.B -nr
  249. XSheet numbering (see -r option) must be continue for all files (don't
  250. Xreset on new file).
  251. X.TP 0.6i
  252. X.B -nv
  253. XReplace non-printing characters by a space.
  254. X.TP 0.6i
  255. X.B -r
  256. XReset sheet numbering for each new file (default option). Sheet numbering
  257. Xis used to number physical pages (sheets printed) and is placed
  258. Xin the bottom of each physical page. It differs from page numbering: logical
  259. Xpages of file been printed.
  260. X.TP 0.6i
  261. X.B -v
  262. XReplace non-printing characters so that they are lisible and easy to identify
  263. X(default option). Control characters (ascii codes lower than 0x20) are
  264. Xprinted like ^X for ctrl-x; the delete character (hex 0x3f) is printed
  265. Xas ^?. Non ascii characters (with the high bit set) are printed as M-
  266. X(for meta) followed by the character of the low 7 bits. TAB, BS and FF are
  267. Xhandled like non-printing characters if -ni option was taked.
  268. X.SH USAGE
  269. X.PP
  270. X.B a2ps
  271. Xsends formatted file to standard output. User could redirect this output
  272. Xto a file or pipe it directly to a print command, like lpr in UNIX:
  273. X
  274. X.ti +0.5i
  275. Xa2ps file1 > file2
  276. X
  277. X.ti +0.5i
  278. Xa2ps file1 | lpr -l
  279. X.PP
  280. XDon't forget
  281. X.B -l
  282. Xoption in last line, if you want that 
  283. X.B lpr
  284. Xinterprets your postscript program.
  285. X.PP
  286. XThis filter must be used only with text files. Avoid specially output from
  287. XTeX, troff or any other text formatter.
  288. X.SH "SEE ALSO"
  289. Xpprps(1L) tgrind(1) lpr(1)
  290. X.SH AUTHORS
  291. XEvan Kirshenbaum (evan@csli) for the initial version.
  292. X.br
  293. XMiguel Santana (miguel@imag.imag.fr) for 2.0 version.
  294. SHAR_EOF
  295. chmod 0664 a2ps.1 || echo "restore of a2ps.1 fails"
  296. set `wc -c a2ps.1`;Sum=$1
  297. if test "$Sum" != "3182"
  298. then echo original size 3182, current size $Sum;fi
  299. fi
  300. if test -f a2ps.c; then echo "File a2ps.c exists"; else
  301. echo "x - extracting a2ps.c (Text)"
  302. sed 's/^X//' << 'SHAR_EOF' > a2ps.c &&
  303. X/************************************************************************/
  304. X/*                                    */
  305. X/* Description: Ascii to PostScript printer program.            */
  306. X/* File: imag:/users/local/a2ps/a2ps.c                    */
  307. X/* Created: Mon Nov 28 15:22:15 1988 by miguel@imag (Miguel Santana)    */
  308. X/* Version: 2.0                                */
  309. X/*                                    */
  310. X/* Edit history:                            */
  311. X/* 1) Derived of shell program written by evan@csli (Evan Kirshenbaum).    */
  312. X/*    Written in C for improve speed execution and portability. Many    */
  313. X/*    improvements have been added.                    */
  314. X/*                                    */
  315. X/************************************************************************/
  316. X
  317. X/*
  318. X * Copyright (c) 1988, Miguel Santana, miguel@imag.imag.fr
  319. X *
  320. X * Permission is granted to copy and distribute this file in modified
  321. X * or unmodified form, for noncommercial use, provided (a) this copyright
  322. X * notice is preserved, (b) no attempt is made to restrict redistribution
  323. X * of this file, and (c) this file is not distributed as part of any
  324. X * collection whose redistribution is restricted by a compilation copyright.
  325. X*/
  326. X
  327. X
  328. X#include <stdio.h>
  329. X#ifdef ANSIC
  330. X#include <time.h>
  331. X#else
  332. X#ifdef UNIX
  333. X#include <sys/time.h>
  334. X#else
  335. X#ifdef SYSV
  336. X#include <sys/types.h>
  337. X#include <sys/timeb.h>
  338. X#include <time.h>
  339. X#else
  340. Xerror !
  341. X#endif
  342. X#endif
  343. X#endif
  344. X
  345. X#ifndef    HEADER_PS
  346. X#define    HEADER_PS    "./header.ps"
  347. X#endif
  348. X#define    LINESPERPAGE    66
  349. X#define    COLUMNSPERLINE    86
  350. X
  351. X#define    FALSE        0
  352. X#define    TRUE        1
  353. X
  354. Xint fold_line();
  355. Xvoid print_file();
  356. Xchar cut_line();
  357. X
  358. X
  359. Xint column = 0;            /* Column number (in current line) */
  360. Xint line = 0;            /* Line number (in current page) */
  361. Xint line_number = 0;        /* Source line number */
  362. Xint first_page;            /* First page for a file */
  363. Xint nonprinting_chars, chars;    /* Number of nonprinting and total chars */
  364. Xint prefix_width;        /* Width in characters for line prefix */
  365. Xint numbering = TRUE;        /* Line numbering option */
  366. Xint folding = TRUE;        /* Line folding option */
  367. Xint restart = TRUE;        /* Restart page number at each file option */
  368. Xint only_printable = FALSE;    /* Replace non printable char by space option */
  369. Xint interpret = TRUE;        /* Interpret TAB, FF and BS chars option */
  370. Xint print_binaries = FALSE;    /* Force printing for binary files */ 
  371. X
  372. Xmain(argc, argv)
  373. Xint argc;
  374. Xchar *argv[];
  375. X{
  376. X   int narg;
  377. X   char *arg;
  378. X
  379. X   /* Option processing */
  380. X   arg = argv[narg = 1];
  381. X   while (narg < argc && arg[0] == '-')
  382. X   {
  383. X      switch (arg[1])
  384. X      {
  385. X      case 'b':
  386. X     if (arg[2] != NULL)
  387. X        goto usage;
  388. X     print_binaries = TRUE;
  389. X     break;
  390. X      case 'f':
  391. X     if (arg[2] != NULL)
  392. X        goto usage;
  393. X     folding = TRUE;
  394. X     break;
  395. X      case 'i':
  396. X     if (arg[2] != NULL)
  397. X        goto usage;
  398. X     interpret = TRUE;
  399. X     break;
  400. X      case 'n':
  401. X     if (arg[2] == NULL)
  402. X     {
  403. X        numbering = TRUE;
  404. X        break;
  405. X     }
  406. X     if (arg[3] != NULL)
  407. X        goto usage;
  408. X     switch (arg[2])
  409. X     {
  410. X     case 'b':
  411. X        print_binaries = FALSE;
  412. X        break;
  413. X     case 'f':
  414. X        folding = FALSE;
  415. X        break;
  416. X     case 'i':
  417. X        interpret = FALSE;
  418. X        break;
  419. X     case 'n':
  420. X        numbering = FALSE;
  421. X        break;
  422. X     case 'r':
  423. X        restart = FALSE;
  424. X        break;
  425. X     case 'v':
  426. X        only_printable = TRUE;
  427. X        break;
  428. X     default:
  429. X        goto usage;
  430. X     }
  431. X     break;
  432. X      case 'r':
  433. X     if (arg[2] != NULL)
  434. X        goto usage;
  435. X     restart = TRUE;
  436. X     break;
  437. X      case 'v':
  438. X     if (arg[2] != NULL)
  439. X        goto usage;
  440. X     only_printable = FALSE;
  441. X     break;
  442. X      default:
  443. X      usage:
  444. X     fprintf(stderr,
  445. X         "usage: a2ps [-n{bfinrv}] [-b] [-f] [-i] [-n] [-r] [-v] [f1 f2 ... fn]");
  446. X     exit(1);
  447. X      }
  448. X      arg = argv[++narg];
  449. X   }
  450. X   if (narg >= argc)
  451. X      goto usage;
  452. X
  453. X   /* Header printing (postcript prolog) */
  454. X   print_header();
  455. X
  456. X   /* Print files designated or standard input */
  457. X   prefix_width = numbering ? 6 : 1;
  458. X   if (narg >= argc)
  459. X      print_file("stdin");
  460. X   else
  461. X   {
  462. X      while (narg < argc)
  463. X      {
  464. X     if (freopen(arg, "r", stdin) == NULL)
  465. X     {
  466. X        fprintf(stderr, "Error opening %s\n", arg);
  467. X        printf("cleanup\n");
  468. X        exit(1);
  469. X     }
  470. X     print_file(arg);
  471. X     arg = argv[++narg];
  472. X      }
  473. X   }
  474. X
  475. X   printf("cleanup\n");
  476. X}
  477. X
  478. Xvoid print_file(name)
  479. Xchar *name;
  480. X{
  481. X   register int c;
  482. X   int start_line, continue_exit;
  483. X   int char_width;
  484. X
  485. X   /*
  486. X    * Printing binary files is not very useful. We stop printing
  487. X    * if we detect one of these files. Our heuristic to detect them:
  488. X    * if 50% characters of first page are non-printing characters,
  489. X    * the file is a binary file.
  490. X    * Option -b force binary files impression.
  491. X    */
  492. X   first_page = TRUE;
  493. X   nonprinting_chars = chars = 0;
  494. X
  495. X   /*
  496. X    * Preprocessing (before printing):
  497. X    * - TABs expansion (see interpret option)
  498. X    * - FF and BS interpretation
  499. X    * - replace non printable characters by a space or a char sequence
  500. X    *   like:
  501. X    *     ^X for ascii codes < 0x20 (X = [@, A, B, ...])
  502. X    *     ^? for del char
  503. X    *     M-c for ascii codes > 0x3f
  504. X    * - prefix parents and backslash ['(', ')', '\'] by backslash
  505. X    *   (escape character in postcript)
  506. X    */
  507. X   column = 0;
  508. X   line = line_number = 0;
  509. X   start_line = TRUE;
  510. X   printf("(%s) newfile\n", name);
  511. X   if (restart)
  512. X      printf("/sheet 1 def\n");
  513. X   printf("startpage\n");
  514. X
  515. X   c = getchar();
  516. X   while (c != EOF)
  517. X   {
  518. X      /* Form feed */
  519. X      if (c == '\f' && interpret)
  520. X      {
  521. X     if (!start_line)
  522. X        printf(") s\n");
  523. X     start_line = TRUE;
  524. X     printf("endpage startpage\n");
  525. X     if (first_page && is_binaryfile(name))
  526. X        return;
  527. X     line = 0;
  528. X     if ((c = getchar()) == EOF)
  529. X        break;
  530. X      }
  531. X
  532. X      /* Start a new line? */
  533. X      if (start_line)
  534. X      {
  535. X     if (numbering)
  536. X        printf("(%-5d ", ++line_number);
  537. X     else
  538. X        printf("( ");
  539. X     start_line = FALSE;
  540. X      }
  541. X
  542. X      /* Interpret each character */
  543. X      switch (c)
  544. X      {
  545. X      case '\b':
  546. X     if (!interpret)
  547. X        goto print;
  548. X     if (column)
  549. X        column--;
  550. X     putchar(c);
  551. X     break;
  552. X      case '\n':
  553. X     column = 0;
  554. X     start_line = TRUE;
  555. X     printf(") s\n");
  556. X     if (++line >= LINESPERPAGE)
  557. X     {
  558. X        printf("endpage startpage\n");
  559. X        if (first_page && is_binaryfile(name))
  560. X           return;
  561. X        line = 0;
  562. X     }
  563. X     break;
  564. X      case '\t':
  565. X     if (interpret)
  566. X     {
  567. X        continue_exit = FALSE;
  568. X        do
  569. X        {
  570. X           if (++column + prefix_width > COLUMNSPERLINE)
  571. X          if (folding)
  572. X          {
  573. X             if (fold_line(name) == FALSE)
  574. X            return;
  575. X          }
  576. X          else
  577. X          {
  578. X             c = cut_line();
  579. X             continue_exit = TRUE;
  580. X             break;
  581. X          }
  582. X           putchar(' ');
  583. X        } while (column & 0x7);
  584. X        if (continue_exit)
  585. X           continue;
  586. X        break;
  587. X        }
  588. X      default:
  589. X      print:
  590. X     if (only_printable)
  591. X        char_width = 1;
  592. X     else
  593. X     {
  594. X        char_width = c > 0177 ? 2 : 0;
  595. X        char_width += c < ' ' || c == 0177 ? 2 : 1;
  596. X     }
  597. X     if (prefix_width + (column += char_width) > COLUMNSPERLINE)
  598. X        if (folding)
  599. X        {
  600. X           if (fold_line(name) == FALSE)
  601. X          return;
  602. X        }
  603. X        else
  604. X        {
  605. X           c = cut_line();
  606. X           continue;
  607. X        }
  608. X     if (c == '(' || c == ')' || c == '\\')
  609. X        putchar('\\');
  610. X     if (c >= ' ' && c < 0177)
  611. X        putchar(c);
  612. X     else
  613. X     {
  614. X        nonprinting_chars++;
  615. X        if (only_printable)
  616. X           putchar(' ');
  617. X        else
  618. X        {
  619. X           if (c > 0177)
  620. X           {
  621. X          printf("M-");
  622. X          c &= 0177;
  623. X           }
  624. X           if (c < ' ')
  625. X          printf("^%c", c+'@');
  626. X           else if (c == 0177)
  627. X          printf("^?");
  628. X           else
  629. X          putchar(c);
  630. X        }
  631. X     }
  632. X     chars++;
  633. X     break;
  634. X      }
  635. X      c = getchar();
  636. X   }
  637. X
  638. X   if (!start_line)
  639. X      printf(") s\n");
  640. X   printf("endpage\n");
  641. X}
  642. X
  643. Xint fold_line(name)
  644. Xchar *name;
  645. X{
  646. X   column = 0;
  647. X   printf(") s\n");
  648. X   if (++line >= LINESPERPAGE)
  649. X   {
  650. X      printf("endpage startpage\n");
  651. X      if (first_page && is_binaryfile(name))
  652. X     return FALSE;
  653. X      line = 0;
  654. X   }
  655. X   if (numbering)
  656. X      printf("(      ");
  657. X   else
  658. X      printf("( ");
  659. X
  660. X   return TRUE;
  661. X}
  662. X
  663. Xchar cut_line()
  664. X{
  665. X   char c;
  666. X
  667. X   while ((c = getchar()) != EOF && c != '\n' && c != '\f');
  668. X   return c;
  669. X}
  670. X
  671. Xis_binaryfile(name)
  672. Xchar *name;
  673. X{
  674. X   first_page = FALSE;
  675. X   if (!print_binaries && (nonprinting_chars*100 / chars) >= 75)
  676. X   {
  677. X      fprintf(stderr, "%s is a binary file: printing aborted\n", name);
  678. X      return TRUE;
  679. X   }
  680. X   return FALSE;
  681. X}
  682. X
  683. Xprint_header()
  684. X{
  685. X   register int c;
  686. X   FILE *f;
  687. X   char *string;
  688. X#ifdef ANSIC
  689. X   time_t date;
  690. X#else
  691. X#ifdef UNIX
  692. X   struct timeval date;
  693. X   struct tm *p;
  694. X#else
  695. X#ifdef SYSV
  696. X    struct timeb date;
  697. X#endif
  698. X#endif
  699. X#endif
  700. X
  701. X   if ((f = fopen(HEADER_PS, "r")) == NULL)
  702. X   {
  703. X      fprintf(stderr, "Poscript header missing\n");
  704. X      exit(1);
  705. X   }
  706. X
  707. X   /* Header file printing */
  708. X   while ((c = getc(f)) != EOF)
  709. X      putchar(c);
  710. X
  711. X   /* Retrieve date and hour */
  712. X#ifdef ANSIC
  713. X   if (time(&date) == -1)
  714. X   {
  715. X      fprintf(stderr, "Error calculing time\n");
  716. X      exit(1);
  717. X   }
  718. X   string = ctime(&date);
  719. X
  720. X   /* and print them */
  721. X   printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11);
  722. X#else
  723. X#ifdef UNIX
  724. X   (void) gettimeofday(&date, (struct timezone *)0);
  725. X   p = localtime(&date.tv_sec);
  726. X   string = asctime(p);
  727. X
  728. X   /* and print them */
  729. X   printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11);
  730. X#else
  731. X#ifdef SYSV
  732. X   (void)ftime(&date);
  733. X   string = ctime(&date.time);
  734. X   printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11);
  735. X#endif
  736. X#endif
  737. X#endif
  738. X
  739. X   /* Go on */
  740. X   printf("startdoc\n");
  741. X}
  742. SHAR_EOF
  743. chmod 0664 a2ps.c || echo "restore of a2ps.c fails"
  744. set `wc -c a2ps.c`;Sum=$1
  745. if test "$Sum" != "9038"
  746. then echo original size 9038, current size $Sum;fi
  747. fi
  748. if test -f header.ps; then echo "File header.ps exists"; else
  749. echo "x - extracting header.ps (Text)"
  750. sed 's/^X//' << 'SHAR_EOF' > header.ps &&
  751. X%!  PostScript Source Code
  752. X%
  753. X%  File: imag:/users/local/a2ps/header.ps
  754. X%  Created: Tue Nov 29 12:14:02 1988 by miguel@imag (Miguel Santana)
  755. X%  Version: 2.0
  756. X%  Description: PostScript prolog for a2ps ascii to PostScript program.
  757. X% 
  758. X%  Edit History:
  759. X%  - Original version by evan@csli (Evan Kirshenbaum).
  760. X%  - Modified by miguel@imag to:
  761. X%    1) Correct an overflow bug when printing page number 10 (operator
  762. X%    cvs).
  763. X%    2) Define two other variables (sheetwidth, sheetheight) describing
  764. X%    the physical page (actually A4 format).
  765. X%    3) Minor changes (reorganization, comments, etc).
  766. X%
  767. X
  768. X% Copyright (c) 1988, Miguel Santana, miguel@imag.imag.fr
  769. X%
  770. X% Permission is granted to copy and distribute this file in modified
  771. X% or unmodified form, for noncommercial use, provided (a) this copyright
  772. X% notice is preserved, (b) no attempt is made to restrict redistribution
  773. X% of this file, and (c) this file is not distributed as part of any
  774. X% collection whose redistribution is restricted by a compilation copyright.
  775. X%
  776. X
  777. X
  778. X% General macros.
  779. X/xdef {exch def} bind def
  780. X/inch {72 mul} bind def
  781. X/getfont {exch findfont exch scalefont} bind def
  782. X
  783. X% Dimensions of a physical page.
  784. X/sheetwidth 11.7 inch def
  785. X/sheetheight 8.25 inch def
  786. X
  787. X% Character size for differents fonts.
  788. X/filenamefontsize 12 def
  789. X/datefontsize filenamefontsize 2 sub def
  790. X/headerfontsize filenamefontsize 4 add def
  791. X/bodyfontsize 6.8 def
  792. X
  793. X% Font assignment to differents kinds of "objects"
  794. X/filenamefont /Helvetica-Bold filenamefontsize getfont def
  795. X/datefont /Helvetica datefontsize getfont def
  796. X/bodyfont /Courier bodyfontsize getfont def
  797. X
  798. X
  799. X% Logical page attributs (a half of a real page or sheet).
  800. X/linesperpage 66 def
  801. X/sidemargin 4 def
  802. X/topmargin 4 def
  803. X/pagewidth 
  804. X   bodyfont setfont (0) stringwidth pop 86 mul sidemargin dup add add
  805. X   def
  806. X/pageheight
  807. X   bodyfontsize linesperpage mul topmargin dup add add headerfontsize add
  808. X   def
  809. X
  810. X% Upper corner for a logical page. Coordinate x is not the same for left
  811. X% and right pages: upperx is an array of two elements, indexed by sheetside.
  812. X/uppery sheetheight pageheight add 2 div def
  813. X/upperx [ sheetwidth pagewidth 2 mul sub 3 div    % upperx for left page
  814. X          dup 2 mul pagewidth add        % upperx for right page
  815. X        ] def
  816. X
  817. X% String used to make easy printing numbers
  818. X/pnum 12 string def
  819. X/empty 12 string def
  820. X
  821. X
  822. X% Function startdoc: initializes printer and global variables.
  823. X/startdoc
  824. X    { sheetheight 0 inch translate    % new origin for the coordinate system
  825. X      90 rotate                % landscape format
  826. X      /sheetside 0 def            % sheet side that contains current page
  827. X      /sheet 1 def            % sheet number
  828. X    } bind def
  829. X
  830. X% Function newfile: init file name and reset page number for each new file.
  831. X/newfile
  832. X    { /filename xdef
  833. X      /pagenum 1 def 
  834. X      cleanup
  835. X    } bind def
  836. X
  837. X% Function cleanup: terminates printing, flushing last page if necessary.
  838. X/cleanup
  839. X    { sheetside 1 eq
  840. X         { /sheetside 0 def
  841. X           sheetnumber
  842. X           /sheet sheet 1 add def
  843. X           copypage
  844. X           erasepage
  845. X         }
  846. X      if
  847. X    } bind def
  848. X
  849. X%
  850. X% Function startpage: prints page header and page border and initializes
  851. X% printing of the file lines.
  852. X/startpage
  853. X    { printheader
  854. X      printborder
  855. X      upperx sheetside get  sidemargin  add
  856. X      uppery topmargin sub  bodyfontsize  sub  headerfontsize  sub
  857. X         moveto
  858. X      bodyfont setfont
  859. X    } bind def
  860. X
  861. X% Function printheader: prints page header.
  862. X/printheader
  863. X    { upperx sheetside get  uppery headerfontsize sub 1 add  moveto
  864. X      datefont setfont
  865. X      gsave
  866. X        sidemargin 2 rmoveto date show                % date/hour
  867. X      grestore
  868. X      gsave
  869. X        pagenum pnum cvs
  870. X        pagewidth sidemargin sub pnum stringwidth pop sub
  871. X        (Page ) stringwidth pop sub 3 rmoveto
  872. X        (Page ) show pnum show                    % page number
  873. X      grestore
  874. X      empty pnum copy
  875. X      gsave
  876. X        filenamefont setfont
  877. X        pagewidth filename stringwidth pop sub 2 div 2 rmoveto
  878. X        filename show                        % file name
  879. X      grestore
  880. X    } bind def
  881. X
  882. X% Function printborder: prints border page.
  883. X/printborder 
  884. X    { upperx sheetside get uppery moveto
  885. X      gsave                    % print the four sides
  886. X        pagewidth 0 rlineto            % of the square
  887. X        0 pageheight neg rlineto
  888. X        pagewidth neg 0 rlineto
  889. X        closepath stroke
  890. X      grestore
  891. X      0 headerfontsize neg rmoveto pagewidth 0 rlineto stroke
  892. X    } bind def
  893. X
  894. X%
  895. X% Function endpage: adds a sheet number to the page (footnote) and prints
  896. X% the formatted page (physical impression). Activated at the end of each
  897. X% source page (linesperpage reached or FF character).
  898. X/endpage
  899. X   { sheetside 1 eq
  900. X        { /sheetside 0 def
  901. X          sheetnumber
  902. X          copypage
  903. X          erasepage 
  904. X          /sheet sheet 1 add def
  905. X        }
  906. X        { /sheetside 1 def }
  907. X     ifelse
  908. X     /pagenum pagenum 1 add def
  909. X    } bind def
  910. X
  911. X% Function sheetnumber: prints the sheet number.
  912. X/sheetnumber
  913. X    { sheetwidth  upperx 0 get  sub  sidemargin  add
  914. X      sheetheight  uppery  sub  headerfontsize  sub
  915. X         moveto
  916. X      datefont setfont
  917. X      sheet pnum cvs show
  918. X      empty pnum copy
  919. X    } bind def
  920. X
  921. X% Function s: print a source line
  922. X/s  { gsave
  923. X        show
  924. X      grestore
  925. X      0 bodyfontsize neg rmoveto
  926. X    } bind def
  927. SHAR_EOF
  928. chmod 0664 header.ps || echo "restore of header.ps fails"
  929. set `wc -c header.ps`;Sum=$1
  930. if test "$Sum" != "5200"
  931. then echo original size 5200, current size $Sum;fi
  932. fi
  933. exit 0
  934. -- 
  935. Miguel SANTANA   miguel@imag.fr or miguel@imag.UUCP (uunet.uu.net!imag!miguel)
  936.