home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / print / lj2 / lj2.c < prev    next >
C/C++ Source or Header  |  1993-06-04  |  13KB  |  488 lines

  1.  /****************************************************************************
  2.  **
  3.  **   lj -- A printing utility for the HP LaserJet
  4.  **
  5.  **
  6.  **   This program prints a series of files on the LaserJet printer.  The
  7.  **   files are printed in a "landscape" font at 17 characters to the inch.
  8.  **   To take advantage of this density, two "pages" of information from
  9.  **   the file are printed on each piece of paper (left and right halves).
  10.  **
  11.  **   Usage is:       lj  file1 file2 file3 ...
  12.  **
  13.  **   Where file# is a valid MS-DOS filename, included on the command line.
  14.  **
  15.  **   Originally written by Joe Barnhart and subsequently modifed by
  16.  **   Ray Duncan and Chip Rabinowitz.  This program has been placed in
  17.  **   the public domain for use without profit.
  18.  **
  19.  **   See the ChangeLog for update information.
  20.  **
  21.  ****************************************************************************/
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <time.h>
  27. #include <ctype.h>
  28. #include <fcntl.h>
  29.  
  30. #ifdef __STDC__
  31. # define _PROTO(x) x
  32. #else
  33. # define _PROTO(x) ()
  34. #endif
  35.  
  36. int  printfile _PROTO((char  *filename));
  37. int  printpage _PROTO((void));
  38. void header    _PROTO((char  *filename,int  pagenum));
  39. void timestamp _PROTO((char  *timestr));
  40. void datestamp _PROTO((char  *datestr));
  41. void dovert    _PROTO((void));
  42. void usage     _PROTO((void));
  43. void shade     _PROTO((void));
  44.  
  45. int     MAXLINE=66;        /* maximum lines per page on LaserJet */
  46. int     MAXLINE_RESET=66;  /* maximum lines per page on LaserJet */
  47. #define MAXVERT 69         /* maximum lines per page on LaserJet */
  48.  
  49. FILE *fp;               /* FILE pointer for the file to be printed */
  50. FILE *lp = stdout;
  51.  
  52. int line_no = 1;
  53. int pagenum;
  54.  
  55. int  hdrflag;     /* Header print suppress flag */
  56. int  pgflag;      /* Page separator flag */
  57. int  tab = 4;     /* default value of one tab stop */
  58. int  pgside;      /* left/right half of page indicator  */
  59. int  psprint = 0;   /* proportional using Helv 6 pt. */
  60. int  shade_it = 0;  /* shade every other line */
  61. int  book = 0;      /* indent left 6 additional spaces for punching*/
  62. int  maxcol=85;
  63. int  numbers = 0;
  64. int  duplex=0;
  65. int  formfeed=0;
  66.  
  67. int do_print=1;     /*flags for doing duplex printing*/
  68.  
  69. /*************************************************************************
  70.  
  71. main
  72.  
  73. *************************************************************************/
  74.  
  75. main(argc, argv)
  76. int argc;
  77. char *argv[];
  78. {
  79. int filenum;
  80. char *fname;
  81. int first;
  82.  
  83. #ifdef __EMX__
  84.    _wildcard (&argc, &argv);
  85. #endif
  86.  
  87.    if (argc <= 1) usage();
  88.  
  89.    for (first = 1; first < argc; first++)  {
  90.       if (*argv[first] != '-') /* check for flags */
  91.          break;               /* and exit if none */
  92.       argv[first]++;
  93.       switch (tolower(*argv[first])) {
  94.       case 'e':      /* Helv proportional font */
  95.          psprint = 1;
  96.          maxcol=104;
  97.          break;
  98.       case 'h':      /* suppress headers flag */
  99.          hdrflag++;
  100.       MAXLINE=69;
  101.       MAXLINE_RESET=69;
  102.          break;
  103.       case 't':      /* Horizontal tab value */
  104.          tab = atoi(++argv[first]);
  105.          if (tab < 1 || tab > 8) {
  106.              fprintf(stderr, "Invalid tab value specified\n"); /* -- defaulting to 8\n"); */
  107.              /* tab = 8; */
  108.             exit(1);
  109.          }
  110.          break;
  111.       case 'l':
  112.          MAXLINE = atoi(++argv[first]);
  113.          if (MAXLINE < 1 || MAXLINE > MAXLINE_RESET) {
  114.              fprintf(stderr, "Invalid lines/page value specified\n"); /*  -- defaulting to MAX\n"); */
  115.             /* MAXLINE = MAXLINE_RESET; */
  116.             exit(1);
  117.          }
  118.          break;
  119.       case 'p':      /* suppress page eject between files */
  120.          pgflag++;
  121.          break;
  122.       case 's':
  123.          shade_it++;
  124.          break;
  125.       case 'n':
  126.          numbers++;
  127.          break;
  128.       case 'b':
  129.          book++;
  130.          maxcol=79;
  131.          break;
  132.       case 'd':
  133.          duplex=1;
  134.          break;
  135.       case 'i':
  136.          formfeed++;
  137.          break;
  138.       default:
  139.          fprintf(stderr, "Invalid Flag Specified ('%s')\n",  /* -- ignored.....\n", */
  140.                --argv[first]);
  141.          usage();
  142.       }
  143.    }
  144.  
  145.    if(duplex) {
  146.      if((argc - 1) > first) {
  147.         fprintf(stderr, "Only one file at a time may be printed when using DUPLEX mode.\n");
  148.         exit(1);
  149.      }
  150.    }
  151.  
  152.    fprintf(stderr, "Lines per page set to %d\n",MAXLINE);
  153.  
  154.    for(filenum = first; filenum < argc; filenum++ ) {
  155.       fp = fopen(fname = argv[filenum], "r");
  156.       if( fp == NULL ) {
  157.          fprintf(stderr,  "File %s doesn't exist.\n", fname );
  158.       }
  159.       else {
  160.          fprintf(stderr,  "Now printing %s\n", fname );
  161.          if (first) {   /* initialize the LaserJet for landscape, etc. */
  162.             fprintf( lp,"\033E\033&l1O\033(s17H\033&l5.14C\033&l70F\033&l5E" );
  163.             if (psprint)
  164.                fprintf(lp,"\033&l1O\033(0U\033(s1p6vsb4T");
  165.             first = 0;
  166.          }
  167.          printfile( fname );
  168.          fclose( fp );
  169.       }
  170.    }    /* of loop through run-time args */
  171.  
  172.    if (first == 0) {             /* we found a file */
  173.       if (pgflag && pgside)
  174.          fputc('\f', lp);
  175.       fprintf( lp, "\r\033E" );      /* clear LaserJet */
  176.       if (lp != stdout)
  177.          fclose(lp);
  178.         fputc('\n', stderr);
  179.    }
  180.    return(0);
  181. }
  182.  
  183. /*************************************************************************
  184.  
  185. printfile (filename)
  186.  
  187. *************************************************************************/
  188.  
  189. printfile(filename)
  190. char *filename;
  191. {
  192.    int retval = 0;
  193.    int printed = 0;
  194.    int pass=0;
  195.    int c2;
  196.    int f_feed=0;
  197.    int phys_pages=0;
  198.    int plus=1;
  199.  
  200. do_it_again:
  201.    pagenum=1;
  202.    while( (feof(fp)==0) && (retval==0) ) {
  203.       f_feed=0;
  204.       if (pgside == 0) {
  205.          printed = 0;
  206.          c2 = fgetc(fp);
  207.          if(feof(fp)) break;
  208.          switch (c2) {
  209.          case EOF:
  210.          case '\032':
  211.             retval = -1;
  212.             break;
  213.          default:
  214.             printed=1;
  215.             if(do_print) {
  216.                     dovert();
  217.                 if(psprint)
  218.                    fprintf(lp,"\033&a0r0c128m0L\r");
  219.                 else if(book)
  220.                    fprintf(lp, "\033&a0r0c85m7L\r"); /* set LaserJet to left half */
  221.                 else
  222.                    fprintf(lp, "\033&a0r0c85m0L\r"); /* set LaserJet to left half */
  223.                 if(shade_it && do_print)
  224.                         shade();
  225.                 }
  226.             ungetc(c2,fp);
  227.             header(filename, pagenum++);       /* title top of page */
  228.             retval = printpage();                 /* print one page */
  229.             pgside ^= 1;
  230.          }
  231.       }
  232.       if(feof(fp)==0 && retval==0) {      /* if more to print... */
  233.             if (do_print) {
  234.                 if(psprint)
  235.                 fprintf(lp,"\033&a0r0c255m131L\r");
  236.              else if(book)
  237.                 fprintf(lp, "\033&a0r0c175m97L\r");    /* LaserJet to right half */
  238.              else
  239.                 fprintf(lp, "\033&a0r0c175m90L\r");    /* LaserJet to right half */
  240.             }
  241.          c2 = fgetc(fp);
  242.          if(feof(fp)) break;
  243.          switch (c2) {
  244.          case EOF:
  245.          case '\032':
  246.             retval = -1;
  247.             break;
  248.          default:
  249.             ungetc(c2,fp);
  250.             header(filename, pagenum++);          /* title top of page */
  251.             retval = printpage();                 /* print one page */
  252.             pgside ^= 1;
  253.          }
  254.       }
  255.  
  256.       if (printed && do_print && (pgflag == 0 || pgside == 0)) {
  257.          fputc('\f', lp);
  258.          pgside = 0;
  259.          f_feed = 1;
  260.          if(plus)
  261.             ++phys_pages;
  262.          else
  263.             --phys_pages;
  264.       }
  265.       if(duplex) do_print ^= 1;
  266.    }
  267.  
  268.    if(duplex) {
  269.       if(pass) {
  270.          while(phys_pages) {
  271.             fputc('\f',lp);
  272.             --phys_pages;
  273.          }
  274.          return(0);
  275.       }
  276.       plus=0;
  277.       if(!f_feed && retval == 0)
  278.          fputc('\f',lp);
  279.       fflush(lp);
  280.       ++pass;
  281.       rewind(fp);
  282.       retval=0;
  283.       do_print = 0;
  284.       pgside = 0;
  285.       fprintf(stderr, "\nFlip the paper and press any key when ready\n");
  286.       getchar();
  287.       goto do_it_again;
  288.    }
  289.    return(0);
  290. }
  291.  
  292. /*******************************************************************************
  293.  
  294. printpage
  295.    print a logical page
  296.  
  297. *************************************************************************/
  298.  
  299. printpage()
  300. {
  301.    int c;
  302.    int line,col;
  303.    static int cont = 0;
  304.    static char *cont1 = "---->";
  305.  
  306.    line = col = 0;
  307.    if(cont)
  308.       {
  309.       if(do_print) fprintf(lp,cont1);
  310.       col = strlen(cont1);
  311.       cont = 0;
  312.       }
  313.  
  314.    while( line < MAXLINE ) {
  315.       c = fgetc(fp);
  316.       if(feof(fp)) return(-1);
  317.  
  318.       if(col>maxcol) {
  319.          line++;
  320.          switch(c) {
  321.          case '\n':
  322.          case '\r':
  323.          case '\f':
  324.          case EOF:
  325.          case '\032':
  326.             break;
  327.          default:
  328.             if(line >= MAXLINE) {
  329.                cont = 1;
  330.                ungetc(c,fp);
  331.                return(0);
  332.             }
  333.             if(do_print) fprintf(lp,"\n%s",cont1);
  334.             col = strlen(cont1);
  335.             break;
  336.          }
  337.       }
  338.  
  339.       if(col == 0) {
  340.          if(do_print) {
  341.             fprintf(stderr, "Printing page %4.4d line %4.4d\r",pagenum-1,line);
  342.          }
  343.          else {
  344.             fprintf(stderr, "Skipping page %4.4d line %4.4d\r",pagenum-1,line);
  345.          }
  346.          if(numbers) {
  347.             if(do_print) fprintf(lp,"%4.4d:",line_no);
  348.             col=5;
  349.          }
  350.          ++line_no;
  351.       }
  352.  
  353.       switch(c) {
  354.       case '\n':           /* newline found */
  355.          col = 0;          /* zero column and */
  356.          line++;           /* advance line count */
  357.          if( line < MAXLINE )
  358.             if(do_print) fprintf(lp,"\n");
  359.          break;
  360.       case '\r':           /* CR found */
  361.          break;            /* discard it */
  362.       case '\t':           /* TAB found */
  363.          do {
  364.             if(do_print) fputc(' ',lp);
  365.          } while ( (++col % tab) != 0 );
  366.          break;
  367.       case '\f':                      /* Page break or */
  368.          if(formfeed) break;
  369.          if(line != 0)
  370.             line = MAXLINE;      /* force termination of loop */
  371.             break;
  372.       case EOF:            /* EOF mark */
  373.       case '\032':         /* EOF mark */
  374.          return(-1);
  375.       default:              /* no special case */
  376.          if(do_print) fputc(c,lp);       /* print character */
  377.          col++;
  378.          break;
  379.       }
  380.    }
  381.    return(0);
  382. }
  383.  
  384. /*************************************************************************
  385.  
  386. header
  387.    print a page header
  388.  
  389. *************************************************************************/
  390.  
  391. void header( filename, pagenum )
  392. char *filename;
  393. int pagenum;
  394. {
  395.    char datestr[11], timestr[11];
  396.  
  397.    if (hdrflag || !do_print) {
  398.       return;     /* skip if flag set */
  399.       }
  400.    timestamp(timestr);
  401.    datestamp(datestr);
  402.    fprintf(lp,"\033&d0D");
  403.    if(book)
  404.       fprintf(lp, "File: %-40s%s   %s  --  Page: %03d \n\n",
  405.         filename,datestr,timestr,pagenum);
  406.     else
  407.       fprintf(lp, "File: %-40s%s   %s  --  Page: %03d       \n\n",
  408.           filename,datestr,timestr,pagenum);
  409.    fprintf(lp,"\033&d@");
  410. }
  411.  
  412. void timestamp( timestr )
  413. char   *timestr;
  414. {
  415.    struct tm *tod;
  416.    time_t tt;
  417.    tt = time(NULL);
  418.    tod = localtime(&tt);
  419.    sprintf(timestr,"%02d:%02d", tod->tm_hour, tod->tm_min);
  420.    return;
  421. }
  422.  
  423. void datestamp( datestr )
  424. char  *datestr;
  425. {
  426.    struct tm *tod;
  427.    time_t tt;
  428.    tt = time(NULL);
  429.    tod = localtime(&tt);
  430.    sprintf(datestr,"%02d/%02d/%02d", tod->tm_mon + 1, tod->tm_mday,
  431.    tod->tm_year + 1900);
  432.    return;
  433. }
  434.  
  435. /*************************************************************************
  436.  
  437. dovert()
  438.    draw a vertical line down the center of the physical page
  439.  
  440. *************************************************************************/
  441.  
  442. void dovert()
  443. {
  444.    int line = 1;
  445.  
  446.    if(psprint)
  447.       fprintf(lp,"\033&a0r0c131m129L\r|");
  448.    else
  449.       fprintf(lp,"\033&a0r0c90m88L\r|");
  450.  
  451.    while(line++ < MAXVERT) fprintf(lp,"\n|");
  452. }
  453.  
  454.  
  455. /*************************************************************************
  456.  
  457. usage
  458.    print help and exit
  459.  
  460. *************************************************************************/
  461.  
  462. void usage()
  463. {
  464.    fprintf(stderr, "\nUsage: lj2 [flags] file1 [file2 ...]\n\n");
  465.    fprintf(stderr, "\t-e  select Helv proportional 6 PT font\n");
  466.    fprintf(stderr, "\t-h  suppress page headers\n");
  467.    fprintf(stderr, "\t-tx set tab stop value (where x is 1 to 8)\n");
  468.    fprintf(stderr, "\t-p  do not leave blank half pages between files\n");
  469.    fprintf(stderr, "\t-s  shade every other line\n");
  470.    fprintf(stderr, "\t-n  print line numbers\n");
  471.    fprintf(stderr, "\t-b  indent for punching\n");
  472.    fprintf(stderr, "\t-d  for duplex printing\n");
  473.    fprintf(stderr, "\t-lxx set lines/page to x(where x is 1 to 66)\n");
  474.    fprintf(stderr, "\t-i  ignore formfeed characters\n");
  475.    exit(1);
  476. }
  477.  
  478.  
  479. void shade()
  480. {
  481.    int i;
  482.  
  483.    fprintf (lp, "\033&f0S\033*p0x0Y\033*c3300a32b10G");
  484.    for (i=1; i <= 35; i++)
  485.       fprintf (lp, "\033*c2P\033&a+2R");
  486.    fprintf (lp, "\033&f1S");
  487. }
  488.