home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / a2ps30.zoo / a2ps30 / a2ps.c < prev    next >
C/C++ Source or Header  |  1990-02-23  |  18KB  |  725 lines

  1. /************************************************************************/
  2. /*                                    */
  3. /* Description: Ascii to PostScript printer program.            */
  4. /* File: imag:/users/local/a2ps/a2ps.c                    */
  5. /* Created: Mon Nov 28 15:22:15 1988 by miguel@imag (Miguel Santana)    */
  6. /* Version: 2.0                                */
  7. /*                                    */
  8. /* Edit history:                            */
  9. /* 1) Derived of shell program written by evan@csli (Evan Kirshenbaum).    */
  10. /*    Written in C for improve speed execution and portability. Many    */
  11. /*    improvements have been added.                    */
  12. /* Fixes by Oscar Nierstrasz @ cui.uucp:                */
  13. /* 2) Fixed incorrect handling of stdin (removed error if no file names)*/
  14. /* 3) Added start_page variable to eliminate blank pages printed for    */
  15. /*    files that are exactly multiples of 132 lines (e.g., man pages)    */
  16. /* Modified by miguel@imag:                        */
  17. /* 4) Added new options at installation : sheet format (height/width in    */
  18. /*    inches), page format (number of columns per line and of lines per    */
  19. /*    page).                                */
  20. /* Modified by miguel@imag:                        */
  21. /* 5) Added new option to print n copies of a same document.        */
  22. /* 6) Cut long filenames if don't fit in the page header.        */
  23. /* Modified by Tim Clark (T.Clark@warwick.ac.uk):            */
  24. /* 7) Two additional modes of printing (portrait and wide format modes)    */
  25. /* 8) Fixed to cope with filenames which contain a character which must    */
  26. /*    be escaped in a PostScript string.                */
  27. /* Modified by miguel@imag.fr to                    */
  28. /* 9) Add new option to suppress heading printing.            */
  29. /* 10) Add new option to suppress page surrounding border printing.    */
  30. /* 11) Add new option to change font size. Number of lines and columns    */
  31. /*     are now automatically adjusted, depending on font size and    */
  32. /*     printing mode used.                        */
  33. /* 12) Minor changes (best layout, usage message, etc).            */
  34. /*                                    */
  35. /************************************************************************/
  36.  
  37. /*
  38.  * Copyright (c) 1988, Miguel Santana, miguel@imag.imag.fr
  39.  *
  40.  * Permission is granted to copy and distribute this file in modified
  41.  * or unmodified form, for noncommercial use, provided (a) this copyright
  42.  * notice is preserved, (b) no attempt is made to restrict redistribution
  43.  * of this file, and (c) this file is not distributed as part of any
  44.  * collection whose redistribution is restricted by a compilation copyright.
  45. */
  46.  
  47.  
  48. #include <stdio.h>
  49. #include <ctype.h>
  50. #ifdef ANSIC
  51. #include <sys/types.h>
  52. #include <time.h>
  53. #else
  54. #ifdef BSD
  55. #include <sys/time.h>
  56. #else
  57. #ifdef SYSV
  58. #include <sys/types.h>
  59. #include <sys/timeb.h>
  60. #include <time.h>
  61. #else
  62. error !
  63. #endif
  64. #endif
  65. #endif
  66.  
  67. #ifndef    HEADER_PS
  68. #define    HEADER_PS    "./header.ps"
  69. #endif
  70.  
  71. #ifndef WIDTH
  72. #define    WIDTH    8.27
  73. #endif
  74.  
  75. #ifndef HEIGHT
  76. #define    HEIGHT    11.64
  77. #endif
  78.  
  79. #ifndef MARGIN
  80. #define    MARGIN    1.2
  81. #endif
  82.  
  83. #ifndef DIR_SEP
  84. #define    DIR_SEP    '/'
  85. #endif
  86.  
  87. #define    PORTRAIT_HEADER        0.29
  88. #define    LANDSCAPE_HEADER    0.22
  89. #define    PIXELS_INCH        72
  90. #define MAXFILENAME        20
  91. #define    FALSE            0
  92. #define    TRUE            1
  93.  
  94. int fold_line();
  95. void print_file();
  96. char cut_line();
  97. int printchar();
  98. void skip_page();
  99.  
  100.  
  101. int column = 0;            /* Column number (in current line) */
  102. int line = 0;            /* Line number (in current page) */
  103. int line_number = 0;        /* Source line number */
  104. int first_page;            /* First page for a file */
  105. int nonprinting_chars, chars;    /* Number of nonprinting and total chars */
  106. int prefix_width;        /* Width in characters for line prefix */
  107. int pages = 0;            /* Number of logical pages printed */
  108. int sheets = 0;            /* Number of physical pages printed */
  109. int linesperpage;        /* Lines per page */
  110. int columnsperline;        /* Characters per output line */
  111.  
  112. double font_size = 0.0;        /* Size of a char for body font */
  113. int numbering = TRUE;        /* Line numbering option */
  114. int folding = TRUE;        /* Line folding option */
  115. int restart = TRUE;        /* Restart page number at each file option */
  116. int only_printable = FALSE;    /* Replace non printable char by space option */
  117. int interpret = TRUE;        /* Interpret TAB, FF and BS chars option */
  118. int print_binaries = FALSE;    /* Force printing for binary files */ 
  119. int copies_number = 1;        /* Number of copies to print */
  120. int landscape = TRUE;        /* Otherwise portrait format sheets */
  121. int wide_pages = FALSE;         /* TRUE implies landscape, not twinpage */
  122. int twinpage = TRUE;        /* 2 pages per sheet if true, 1 otherwise */
  123. int no_border = FALSE;        /* TRUE if user don't want the border */
  124. int no_header = FALSE;        /* TRUE if user don't want the header */
  125. int column_width = 8;            /* default column tab width (8) */
  126.  
  127. main(argc, argv)
  128. int argc;
  129. char *argv[];
  130. {
  131.    register int narg;
  132.    register char *arg;
  133.    double char_width, header_size;
  134.    double page_height, page_width;
  135.    int i;
  136.    extern double atof();
  137.  
  138.    /* Option processing */
  139.    arg = argv[narg = 1];
  140.    while (narg < argc && arg[0] == '-')
  141.    {
  142.       switch (arg[1])
  143.       {
  144.       case '?':                    /* help */
  145.      goto usage;
  146.       case '#':                    /* n copies */
  147.      copies_number = 0;
  148.      arg += 2;
  149.      while (*arg != NULL && isdigit(*arg))
  150.         copies_number = copies_number*10 + (*arg++ - '0');
  151.      if (*arg != NULL || copies_number <= 0)
  152.         goto usage;
  153.      break;
  154.       case 'b':                    /* print binary files */
  155.      if (arg[2] != NULL)
  156.         goto usage;
  157.      print_binaries = TRUE;
  158.      break;
  159.       case 'f':                    /* change font size */
  160.      if (arg[2] == NULL) {
  161.         folding = TRUE;
  162.         break;
  163.      }
  164.      if ((font_size = atof(&arg[2])) == 0.0) {
  165.         fprintf(stderr, "Wrong value for option -s\n");
  166.         exit(1);
  167.      }
  168.      break;
  169.       case 'h':                    /* help */
  170.      goto usage;
  171.       case 'i':                    /* interpret control chars */
  172.      if (arg[2] != NULL)
  173.         goto usage;
  174.      interpret = TRUE;
  175.      break;
  176.       case 'n':                    /* number file lines */
  177.      if (arg[2] == NULL)
  178.      {
  179.         numbering = TRUE;
  180.         break;
  181.      }
  182.      if (arg[3] != NULL)
  183.         goto usage;
  184.      switch (arg[2])
  185.      {
  186.      case 'b':                /* don't print binaries */
  187.         print_binaries = FALSE;
  188.         break;
  189.      case 'f':                /* cut lines too long */
  190.         folding = FALSE;
  191.         break;
  192.      case 'h':                /* don't print header */
  193.         no_header = TRUE;
  194.         break;
  195.      case 'i':                /* don't interpret ctrl chars */
  196.         interpret = FALSE;
  197.         break;
  198.      case 'n':                /* don't number lines */
  199.         numbering = FALSE;
  200.         break;
  201.      case 'p':                /* landscape format */
  202.         landscape = TRUE;
  203.         break;
  204.      case 'r':                /* don't restart sheet number */
  205.         restart = FALSE;
  206.         break;
  207.      case 's':                /* no surrounding border */
  208.         no_border = TRUE;
  209.         break;
  210.      case 'v':                /* only printable chars */
  211.         only_printable = TRUE;
  212.         break;
  213.      case 'w':                /* twin pages */
  214.         wide_pages = FALSE;
  215.         break;
  216.      default:
  217.         goto usage;
  218.      }
  219.      break;
  220.       case 'p':                    /* portrait format */
  221.      if (arg[2] != NULL)
  222.         goto usage;
  223.      if (wide_pages) {
  224.         fprintf(stderr, "a2ps: options -p and -w are incompatible\n");
  225.         exit(1);
  226.      }
  227.      landscape = FALSE;
  228.      break;
  229.       case 'r':                    /* restart sheet number */
  230.      if (arg[2] != NULL)
  231.         goto usage;
  232.      restart = TRUE;
  233.      break;
  234.       case 't':                    /* set tab size */
  235.      if (arg[2] == NULL || (column_width = atoi(arg+2)) <= 0)
  236.         goto usage;
  237.      break;
  238.       case 'v':                    /* print control chars */
  239.      if (arg[2] != NULL)
  240.         goto usage;
  241.      only_printable = FALSE;
  242.      break;
  243.       case 'w':                    /* wide format */
  244.      if (arg[2] != NULL)
  245.         goto usage;
  246.      if (!landscape) {
  247.         fprintf(stderr, "a2ps: options -p and -w are incompatible\n");
  248.         exit(1);
  249.      }
  250.      wide_pages = TRUE;
  251.      break;
  252.       default:
  253.       usage:
  254.      fprintf(stderr,"Usage: %s [options] [f1 f2 ... fn]\n", argv[0]);
  255.      fprintf(stderr,"options = -#num\t(number of copies to print)\n");
  256.      fprintf(stderr,"          -?\t(print this information)\n");
  257.      fprintf(stderr,"          -f\t(fold lines too large)\n");
  258.      fprintf(stderr,"          -fnum\t(font size, num is a float number)\n");
  259.      fprintf(stderr,"          -h\t(print this information)\n");
  260.      fprintf(stderr,"          -i\t(interpret tab, bs and ff chars)\n");
  261.      fprintf(stderr,"          -n\t(number line files)\n");
  262.      fprintf(stderr,"          -p\t(print in portrait mode)\n");
  263.      fprintf(stderr,"          -r\t(restart page number after each file)\n");
  264.      fprintf(stderr,"          -tn\t(set tab size to n)\n");
  265.      fprintf(stderr,"          -v\t(show non-printing chars in a clear form)\n");
  266.      fprintf(stderr,"          -w\t(print in wide format)\n");
  267.      fprintf(stderr,"          -nb\t(don't force printing binary files)\n");
  268.      fprintf(stderr,"          -nf\t(don't fold lines)\n");
  269.      fprintf(stderr,"          -nh\t(don't print the header)\n");
  270.      fprintf(stderr,"          -ni\t(don't interpret special chars)\n");
  271.      fprintf(stderr,"          -nn\t(don't number output lines)\n");
  272.      fprintf(stderr,"          -np\t(don't print in portrait format)\n");
  273.      fprintf(stderr,"          -nr\t(don't restart page number)\n");
  274.      fprintf(stderr,"          -ns\t(don't print surrounding borders)\n");
  275.      fprintf(stderr,"          -nv\t(replace non-printing chars by space)\n");
  276.      fprintf(stderr,"          -nw\t(don't print in wide format)\n");
  277.      exit(1);
  278.       }
  279.       arg = argv[++narg];
  280.    }
  281.    if (arg != NULL && strcmp(arg, "?") == 0)
  282.       goto usage;
  283.  
  284.    twinpage = landscape && !wide_pages;
  285.    if (font_size == 0.0)
  286.       font_size = landscape ? 6.8 : 9.0;
  287.    page_height = (HEIGHT - MARGIN) * PIXELS_INCH;
  288.    page_width = (WIDTH - MARGIN) * PIXELS_INCH;
  289.    char_width = 0.6 * font_size;
  290.    if (landscape) {
  291.       header_size = no_header ? 0.0 : LANDSCAPE_HEADER * PIXELS_INCH;
  292.       linesperpage = ((page_width - header_size) / font_size) - 1;
  293.       if (wide_pages)
  294.      columnsperline = (page_height / char_width) - 1;
  295.       else
  296.      columnsperline = ((page_height / 2) / char_width) - 1;
  297.    }
  298.    else {
  299.       header_size = no_header ? 0.0 : PORTRAIT_HEADER * PIXELS_INCH;
  300.       linesperpage = ((page_height - header_size) / font_size) - 1;
  301.       columnsperline = (page_width / char_width) - 1;
  302.    }
  303.    if (linesperpage <= 0 || columnsperline <= 0) {
  304.       fprintf(stderr, "Font %g too big !!\n", font_size);
  305.       exit(1);
  306.    }
  307.  
  308.    /* Header printing (postcript prolog) */
  309.    print_header();
  310.  
  311.    /* Print files designated or standard input */
  312.    prefix_width = numbering ? 6 : 1;
  313.    if (narg >= argc)
  314.       print_file("stdin");
  315.    else
  316.    {
  317.       while (narg < argc)
  318.       {
  319.      if (freopen(arg, "r", stdin) == NULL)
  320.      {
  321.         fprintf(stderr, "Error opening %s\n", arg);
  322.         printf("\n%%%%Trailer\ncleanup\ndocsave restore end\n");
  323.         exit(1);
  324.      }
  325.      print_file(arg);
  326.      arg = argv[++narg];
  327.       }
  328.    }
  329.  
  330.    printf("\n%%%%Trailer\ncleanup\ndocsave restore end\n");
  331. }
  332.  
  333. void print_file(name)
  334. char *name;
  335. {
  336.    register int c;
  337.    int start_line, continue_exit;
  338.    int char_width;
  339.    int start_page;
  340.    char new_name[MAXFILENAME+1];
  341.    char *p;
  342.  
  343.    /*
  344.     * Boolean to indicates that previous char is \n (or interpreted \f)
  345.     * and a new page would be started, if more text follows
  346.     */
  347.    start_page = FALSE;
  348.  
  349.    /*
  350.     * Printing binary files is not very useful. We stop printing
  351.     * if we detect one of these files. Our heuristic to detect them:
  352.     * if 50% characters of first page are non-printing characters,
  353.     * the file is a binary file.
  354.     * Option -b force binary files impression.
  355.     */
  356.    first_page = TRUE;
  357.    nonprinting_chars = chars = 0;
  358.  
  359.    /*
  360.     * Preprocessing (before printing):
  361.     * - TABs expansion (see interpret option)
  362.     * - FF and BS interpretation
  363.     * - replace non printable characters by a space or a char sequence
  364.     *   like:
  365.     *     ^X for ascii codes < 0x20 (X = [@, A, B, ...])
  366.     *     ^? for del char
  367.     *     M-c for ascii codes > 0x3f
  368.     * - prefix parents and backslash ['(', ')', '\'] by backslash
  369.     *   (escape character in postcript)
  370.     */
  371.    column = 0;
  372.    line = line_number = 0;
  373.    start_line = TRUE;
  374.  
  375.    if (strlen(name) > MAXFILENAME) {
  376.       cut_filename(name, new_name);
  377.       name = new_name;
  378.    }
  379.    putchar('(');
  380.    for (p = name; *p != NULL;)
  381.       printchar(*p++);
  382.    printf(") newfile\n");
  383.  
  384.    if (restart)
  385.       printf("/sheet 1 def\n");
  386.  
  387.    pages = 0;
  388.    skip_page();
  389.  
  390.    c = getchar();
  391.    while (c != EOF)
  392.    {
  393.       /* Form feed */
  394.       if (c == '\f' && interpret)
  395.       {
  396.      /* Close current line */
  397.      if (!start_line)
  398.      {
  399.         printf(") s\n");
  400.         start_line = TRUE;
  401.      }
  402.      /* start a new page ? */
  403.      if (start_page)
  404.         skip_page();
  405.      /* Close current page and begin another */
  406.      printf("endpage\n") ;
  407.      start_page = TRUE;
  408.      /* Verification for binary files */
  409.      if (first_page && is_binaryfile(name))
  410.         return;
  411.      line = 0;
  412.      if ((c = getchar()) == EOF)
  413.         break;
  414.       }
  415.  
  416.       /* Start a new line? */
  417.       if (start_line)
  418.       {
  419.      if (start_page)
  420.      {     /* only if there is something to print! */
  421.         skip_page();
  422.         start_page = FALSE ;
  423.      }
  424.      if (numbering)
  425.         printf("(%-5d ", ++line_number);
  426.      else
  427.         printf("( ");
  428.      start_line = FALSE;
  429.       }
  430.  
  431.       /* Interpret each character */
  432.       switch (c)
  433.       {
  434.       case '\b':
  435.      if (!interpret)
  436.         goto print;
  437.      if (column)
  438.         column--;
  439.      putchar(c);
  440.      break;
  441.       case '\n':
  442.      column = 0;
  443.      start_line = TRUE;
  444.      printf(") s\n");
  445.      if (++line >= linesperpage)
  446.      {
  447.         printf("endpage\n");
  448.         start_page = TRUE ;
  449.         if (first_page && is_binaryfile(name))
  450.            return;
  451.         line = 0;
  452.      }
  453.      break;
  454.       case '\t':
  455.      if (interpret)
  456.      {
  457.         continue_exit = FALSE;
  458.         do
  459.         {
  460.            if (++column + prefix_width > columnsperline)
  461.           if (folding)
  462.           {
  463.              if (fold_line(name) == FALSE)
  464.             return;
  465.           }
  466.           else
  467.           {
  468.              c = cut_line();
  469.              continue_exit = TRUE;
  470.              break;
  471.           }
  472.            putchar(' ');
  473.         } while (column % column_width);
  474.         if (continue_exit)
  475.            continue;
  476.         break;
  477.         }
  478.       default:
  479.       print:
  480.      if (only_printable)
  481.         char_width = 1;
  482.      else
  483.      {
  484.         char_width = c > 0177 ? 2 : 0;
  485.         char_width += c < ' ' || c == 0177 ? 2 : 1;
  486.      }
  487.      if (prefix_width + (column += char_width) > columnsperline)
  488.         if (folding)
  489.         {
  490.            if (fold_line(name) == FALSE)
  491.           return;
  492.         }
  493.         else
  494.         {
  495.            c = cut_line();
  496.            continue;
  497.         }
  498.      nonprinting_chars += printchar(c);
  499.      chars++;
  500.      break;
  501.       }
  502.       c = getchar();
  503.    }
  504.  
  505.    if (!start_line)
  506.       printf(") s\n");
  507.    if (!start_page)
  508.       printf("endpage\n");
  509. }
  510.  
  511. /*
  512.  * Cut long filenames.
  513.  */
  514. int cut_filename(old_name, new_name)
  515. char *old_name, *new_name;
  516. {
  517.    register char *p;
  518.    register int i;
  519.  
  520.    p = old_name + (strlen(old_name)-1);
  521.    while (p >= old_name && *p != DIR_SEP) p--;
  522.  
  523.    for (i = 0, p++; *p != NULL && i < MAXFILENAME; i++)
  524.       *new_name++ = *p++;
  525.    *new_name = NULL;
  526. }
  527.  
  528. /*
  529.  * Fold a line too long.
  530.  */
  531. int fold_line(name)
  532. char *name;
  533. {
  534.    column = 0;
  535.    printf(") s\n");
  536.    if (++line >= linesperpage)
  537.    {
  538.       printf("endpage\n");
  539.       skip_page();
  540.       if (first_page && is_binaryfile(name))
  541.      return FALSE;
  542.       line = 0;
  543.    }
  544.    if (numbering)
  545.       printf("(      ");
  546.    else
  547.       printf("( ");
  548.  
  549.    return TRUE;
  550. }
  551.  
  552. /*
  553.  * Cut a textline too long to the size of a page line.
  554.  */
  555. char cut_line()
  556. {
  557.    char c;
  558.  
  559.    while ((c = getchar()) != EOF && c != '\n' && c != '\f');
  560.    return c;
  561. }
  562.  
  563. /*
  564.  * Print a char in a form accept by postscript printers.
  565.  */
  566. int printchar(c)
  567. unsigned char c;
  568. {
  569.    if (c >= ' ' && c < 0177)
  570.    {
  571.       if (c == '(' || c == ')' || c == '\\')
  572.          putchar('\\');
  573.       putchar(c);
  574.       return 0;
  575.    }
  576.  
  577.    if (only_printable)
  578.    {
  579.       putchar(' ');
  580.       return 1;
  581.    }
  582.  
  583.    if (c > 0177)
  584.    {
  585.       printf("M-");
  586.       c &= 0177;
  587.    }
  588.    if (c < ' ')
  589.    {
  590.       putchar('^');
  591.       if ((c = c + '@') == '(' || c == ')' || c == '\\')
  592.      putchar('\\');
  593.       putchar(c);
  594.    }
  595.    else if (c == 0177)
  596.       printf("^?");
  597.    else
  598.       putchar(c);
  599.  
  600.    return 1;
  601. }
  602.  
  603. /*
  604.  * Begins a new physical page.
  605.  */
  606. void skip_page()
  607. {
  608.    pages++;
  609.    if (twinpage == FALSE || (pages & 0x1))
  610.    {
  611.       sheets++;
  612.       printf("%%%%Page: %d %d\n", sheets, sheets);
  613.    }
  614.    printf("startpage\n");
  615. }
  616.  
  617. /*
  618.  * Test if we have a binary file.
  619.  */
  620. is_binaryfile(name)
  621. char *name;
  622. {
  623.    first_page = FALSE;
  624.    if (!print_binaries && (nonprinting_chars*100 / chars) >= 75)
  625.    {
  626.       fprintf(stderr, "%s is a binary file: printing aborted\n", name);
  627.       return TRUE;
  628.    }
  629.    return FALSE;
  630. }
  631.  
  632. print_header()
  633. {
  634.    register int c;
  635.    FILE *f;
  636.    char *string;
  637. #ifdef ANSIC
  638.    time_t date;
  639. #else
  640. #ifdef BSD
  641.    struct timeval date;
  642.    struct tm *p;
  643. #else
  644. #ifdef SYSV
  645.     struct timeb date;
  646. #endif
  647. #endif
  648. #endif
  649.  
  650.    if ((f = fopen(HEADER_PS, "r")) == NULL)
  651.    {
  652.       fprintf(stderr, "Poscript header missing\n");
  653.       exit(1);
  654.    }
  655.  
  656.    /* Initialize some postcript variables */
  657.    printf("%%! a2ps 3.0\n\n");
  658.    printf("/$a2psdict 100 dict def\n");
  659.    printf("$a2psdict begin\n");
  660.    printf("%% Initialize page description variables.\n");
  661.    printf("/inch {72 mul} bind def\n");
  662.    printf("/landscape %s def\n", landscape ? "true" : "false");
  663.    printf("/twinpage %s def\n", twinpage ? "true" : "false");
  664.    printf("/sheetheight %g inch def\n", HEIGHT);
  665.    printf("/sheetwidth %g inch def\n", WIDTH);
  666.    printf("/margin %g inch def\n", MARGIN);
  667.    printf("/noborder %s def\n", no_border ? "true" : "false");
  668.    if (no_header) {
  669.       printf("/noheader true def\n");
  670.       printf("/headersize 0.0 def\n");
  671.    }
  672.    else {
  673.       printf("/noheader false def\n");
  674.       printf("/headersize %g inch def\n",
  675.          landscape ? LANDSCAPE_HEADER : PORTRAIT_HEADER);
  676.    }
  677.    printf("/bodyfontsize %g def\n", font_size);
  678.    printf("/lines %d def\n", linesperpage);
  679.    printf("/columns %d def\n", columnsperline);
  680.  
  681.    /* Retrieve date and hour */
  682. #ifdef ANSIC
  683.    if (time(&date) == -1)
  684.    {
  685.       fprintf(stderr, "Error calculing time\n");
  686.       exit(1);
  687.    }
  688.    string = ctime(&date);
  689.  
  690.    /* and print them */
  691.    printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11);
  692. #else
  693. #ifdef BSD
  694.    (void) gettimeofday(&date, (struct timezone *)0);
  695.    p = localtime(&date.tv_sec);
  696.    string = asctime(p);
  697.  
  698.    /* and print them */
  699.    printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11);
  700. #else
  701. #ifdef SYSV
  702.    (void)ftime(&date);
  703.    string = ctime(&date.time);
  704.    printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11);
  705. #endif
  706. #endif
  707. #endif
  708.  
  709.    /* Header file printing */
  710.    while ((c = getc(f)) != EOF)
  711.       putchar(c);
  712.  
  713.  
  714.    /* Close prolog */
  715.    printf("%%%%EndProlog\n\n");
  716.  
  717.    /* Ask for printing n copies */
  718.    if (copies_number > 1)
  719.       printf("/#copies %d def\n", copies_number);
  720.  
  721.    /* Go on */
  722.    printf("/docsave save def\n");
  723.    printf("startdoc\n");
  724. }
  725.