home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2351 / textps.c < prev   
Encoding:
C/C++ Source or Header  |  1990-12-28  |  6.5 KB  |  360 lines

  1. /* textps.c */
  2.  
  3. #ifndef lint
  4. static char rcsid[] = "$Header: /usr/jjc/lprps/RCS/textps.c,v 1.2 90/12/18 10:01:58 jjc Rel $";
  5. #endif
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9.  
  10. extern char *malloc();
  11. extern char *optarg;
  12. extern int optind;
  13.  
  14. typedef struct output_char {
  15.   struct output_char *next;
  16.   char c;
  17.   char is_bold;
  18.   int pos;
  19. } output_char;
  20.  
  21. output_char *free_output_char_list = 0;
  22.  
  23. int tab_width = 8;
  24. int lines_per_page = 66;
  25. #ifdef A4
  26. int page_length = 842;        /* in points */
  27. #else
  28. int page_length = 792;        /* in points */
  29. #endif
  30.  
  31. int baseline_offset = 8;    /* distance in points from top of page to */
  32.                 /* first baseline */
  33.  
  34. int line_spacing;        /* in points */
  35.  
  36. int left_margin = 18;        /* in points */
  37. int char_width;
  38.  
  39. int pageno = 0;
  40.  
  41. char *font = "Courier";
  42. char *bold_font = "Courier-Bold";
  43. enum { NONE, ROMAN, BOLD } current_font;
  44.  
  45. void do_file();
  46. void prologue();
  47. void trailer();
  48. char *prog;
  49.  
  50. void usage()
  51. {
  52.   fprintf(stderr, "usage: %s [-l n] [ files ... ]\n", prog);
  53.   exit(1);
  54. }
  55.  
  56. main(argc, argv)
  57. int argc;
  58. char **argv;
  59. {
  60.   int bad_files = 0;
  61.   int cpi = 12;            /* characters per inch */
  62.   int lpi = 6;            /* lines per inch */
  63.   int opt;
  64.  
  65.   prog = argv[0];
  66.  
  67.   while ((opt = getopt(argc, argv, "l:")) != EOF)
  68.     switch (opt) {
  69.     case 'l':
  70.       if (sscanf(optarg, "%d", &lines_per_page) != 1)
  71.     usage();
  72.       break;
  73.     case '?':
  74.       usage();
  75.     default:
  76.       abort();
  77.     }
  78.  
  79.   char_width = 72/cpi;
  80.   line_spacing = 72/lpi;
  81.   prologue();
  82.   if (optind >= argc)
  83.     do_file(stdin);
  84.   else {
  85.     int i;
  86.     for (i = optind; i < argc; i++)
  87.       if (strcmp(argv[i], "-") == 0)
  88.     do_file(stdin);
  89.       else {
  90.     FILE *fp;
  91.     if ((fp = fopen(argv[i], "r")) == NULL) {
  92.       perror(argv[i]);
  93.       bad_files++;
  94.     }
  95.     else {
  96.       do_file(fp);
  97.       fclose(fp);
  98.     }
  99.       }
  100.   }
  101.   trailer();
  102.   exit(bad_files);
  103. }
  104.  
  105.  
  106. output_char *new_output_char()
  107. {
  108.   if (free_output_char_list) {
  109.     output_char *tem = free_output_char_list;
  110.     free_output_char_list = free_output_char_list->next;
  111.     return tem;
  112.   }
  113.   else {
  114.     output_char *tem;
  115.     if ((tem = (output_char *)malloc(sizeof(output_char))) == NULL) {
  116.       fprintf(stderr, "%s: out of memory\n", prog);
  117.       exit(1);
  118.     }
  119.     return tem;
  120.   }
  121. }
  122.  
  123. void delete_output_char(p)
  124. output_char *p;
  125. {
  126.   p->next = free_output_char_list;
  127.   free_output_char_list = p;
  128. }
  129.  
  130.  
  131. void pschar(c)
  132. int c;
  133. {
  134.   if (!isascii(c) || iscntrl(c))
  135.     printf("\\%03o", c &0377);
  136.   else if (c == '(' || c == ')' || c == '\\') {
  137.     putchar('\\');
  138.     putchar(c);
  139.   }
  140.   else
  141.     putchar(c);
  142. }
  143.  
  144. /* output_line is ordered greatest position first */
  145.  
  146. void print_line(output_line, vpos)
  147. output_char *output_line;
  148. int vpos;
  149. {
  150.   output_char *rev = output_line;
  151.   output_line = 0;
  152.   while (rev != 0) {
  153.     output_char *tem = rev;
  154.     rev = rev->next;
  155.     tem->next = output_line;
  156.     output_line = tem;
  157.   }
  158.   while (output_line != NULL) {
  159.     output_char *tem;
  160.     output_char **p = &output_line;
  161.     int start_pos = output_line->pos;
  162.     int is_bold = output_line->is_bold;
  163.     int pos;
  164.     if (is_bold) {
  165.       if (current_font != BOLD) {
  166.     printf("B");
  167.     current_font = BOLD;
  168.       }
  169.     }
  170.     else {
  171.       if (current_font != ROMAN) {
  172.     printf("R");
  173.     current_font = ROMAN;
  174.       }
  175.     }
  176.     putchar('(');
  177.     pschar(output_line->c);
  178.     pos = output_line->pos + 1;
  179.     tem = output_line;
  180.     output_line = output_line->next;
  181.     delete_output_char(tem);
  182.     for (;;) {
  183.       while (*p != NULL
  184.          && ((*p)->pos < pos || (*p)->is_bold != is_bold))
  185.     p = &(*p)->next;
  186.       if (*p == NULL)
  187.     break;
  188.       while (pos < (*p)->pos) {
  189.     pschar(' ');
  190.     pos++;
  191.       }
  192.       pschar((*p)->c);
  193.       pos++;
  194.       tem = *p;
  195.       *p = tem->next;
  196.       delete_output_char(tem);
  197.     }
  198.     putchar(')');
  199.     printf("%d %d L\n",
  200.        left_margin + start_pos*char_width, 
  201.        page_length - baseline_offset - vpos*line_spacing);
  202.   }
  203. }
  204.  
  205. void page_start()
  206. {
  207.   printf("%%%%Page: ? %d\nPS\n", ++pageno);
  208.   current_font = NONE;
  209. }
  210.  
  211. void page_end()
  212. {
  213.   printf("PE\n");
  214. }
  215.  
  216. void prologue()
  217. {
  218.   printf("%%!PS-Adobe-2.0\n");
  219.   printf("%%%%DocumentFonts: %s %s\n", font, bold_font);
  220.   printf("%%%%Pages: (atend)\n");
  221.   printf("%%%%EndComments\n");
  222.   printf("/L { moveto show } bind def\n");
  223.   printf("/R [ /%s findfont %d 6 div scalefont /setfont load ] cvx def\n",
  224.      font, char_width*10);
  225.   printf("/B [ /%s findfont %d 6 div scalefont /setfont load ] cvx def\n", 
  226.      bold_font, char_width*10);
  227.   printf("/PS { /level0 save def } bind def\n");
  228.   printf("/PE { level0 restore showpage } bind def\n");
  229.   printf("%%%%EndProlog\n");
  230. }
  231.  
  232. void trailer()
  233. {
  234.   printf("%%%%Trailer\n%%%%Pages: %d\n", pageno);
  235. }
  236.  
  237. /* p is ordered greatest position first */
  238.  
  239. void add_char(c, pos, p)
  240. int c;
  241. int pos;
  242. output_char **p;
  243. {
  244.   for (;; p = &(*p)->next) {
  245.     if (*p == NULL || (*p)->pos < pos) {
  246.       output_char *tem = new_output_char();
  247.       tem->next = *p;
  248.       *p = tem;
  249.       tem->c = c;
  250.       tem->is_bold = 0;
  251.       tem->pos = pos;
  252.       break;
  253.     }
  254.     else if ((*p)->pos == pos) {
  255.       if (c == (*p)->c) {
  256.     (*p)->is_bold = 1;
  257.     break;
  258.       }
  259.     }
  260.   }
  261. }
  262.  
  263. void do_file(fp)
  264. FILE *fp;
  265. {
  266.   int c;
  267.   int vpos = 0;
  268.   int hpos = 0;
  269.   int page_started = 0;
  270.   int esced = 0;
  271.   output_char *output_line = 0;
  272.   while ((c = getc(fp)) != EOF)
  273.     if (esced)
  274.       switch(c) {
  275.       case '7':
  276.     if (vpos > 0) {
  277.       if (output_line != NULL) {
  278.         if (!page_started) {
  279.           page_started = 1;
  280.           page_start();
  281.         }
  282.         print_line(output_line, vpos);
  283.         output_line = 0;
  284.       }
  285.       vpos -= 1;
  286.     }
  287.     /* hpos = 0; */
  288.     esced = 0;
  289.     break;
  290.       default:
  291.     /* silently ignore */
  292.     esced = 0;
  293.     break;
  294.       }
  295.     else
  296.       switch (c) {
  297.       case '\033':
  298.     esced = 1;
  299.     break;
  300.       case '\b':
  301.     if (hpos > 0)
  302.       hpos--;
  303.     break;
  304.       case '\f':
  305.     if (!page_started)
  306.       page_start();
  307.     print_line(output_line, vpos);
  308.     output_line = 0;
  309.     page_end();
  310.     hpos = 0;        /* ?? */
  311.     vpos = 0;
  312.     page_started = 0;
  313.     break;
  314.       case '\r':
  315.     hpos = 0;
  316.     break;
  317.       case '\n':
  318.     if (output_line != NULL) {
  319.       if (!page_started) {
  320.         page_started = 1;
  321.         page_start();
  322.       }
  323.       print_line(output_line, vpos);
  324.       output_line = 0;
  325.     }
  326.     vpos += 1;
  327.     if (vpos >= lines_per_page) {
  328.       if (!page_started)
  329.         page_start();
  330.       page_end();
  331.       page_started = 0;
  332.       vpos = 0;
  333.     }
  334.     hpos = 0;
  335.     break;
  336.       case ' ':
  337.     hpos++;
  338.     break;
  339.       case '\t':
  340.     hpos = ((hpos + tab_width)/tab_width)*tab_width;
  341.     break;
  342.       default:
  343.     if (!(isascii(c) && iscntrl(c))) {
  344.       add_char(c, hpos, &output_line);
  345.       hpos++;
  346.     }
  347.     break;
  348.       }
  349.   if (output_line != NULL) {
  350.     if (!page_started) {
  351.       page_started = 1;
  352.       page_start();
  353.     }
  354.     print_line(output_line, vpos);
  355.     output_line = 0;
  356.   }
  357.   if (page_started)
  358.     page_end();
  359. }
  360.