home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 170_01 / textform.c < prev    next >
Text File  |  1979-12-31  |  9KB  |  361 lines

  1. /********************************************************
  2. *                            *
  3. *           T E X T  F O R M             *
  4. *           Text file formatter for MSDOS        *
  5. *                            *
  6. *          T. Jennings 23 Dec. 82        *
  7. *            created 14 Nov. 82        *
  8. *                            *
  9. *********************************************************
  10.  
  11.     TEXTFORM prints and/or formats edited text, using WordStar
  12. compatible dot commands, for use on non-WordStar systems. See 
  13. TEXTFORM.DOC for details. */
  14.  
  15. #include <stdio.h>
  16. #include <ctype.h>
  17.  
  18. #define FALSE 0
  19. #define TRUE 1
  20. #define ERROR -1
  21. #define CONTROLZ 0x1a
  22. #define CR 0x0d                /* useful ASCII characters */
  23. #define LF 0x0a
  24. #define FF 0x0c
  25. #define TAB 9
  26. #define BS 8
  27. #define PAGE_LEN 66            /* default lines per page */
  28. #define DEF_LMARGIN 8            /* default left margin, */
  29. #define DEF_TMARGIN 1            /* default top of page margin */
  30. #define DEF_BMARGIN 8            /* bottom of page margin */
  31.  
  32. char c;                    /* a useful variable for everyone */
  33. int line_count;                /* total lines, */
  34. int this_line;                /* current line #/page */
  35. int this_page;                /* current page */
  36. int page_size;                /* current max page length */
  37. int lmargin,rmargin;            /* current left and right margins */
  38. int top_margin;                /* lines from top of page */
  39. int bot_margin;                /* lines at bottom of page */
  40. int line_num;                /* true if line numbers in index */
  41.  
  42. int inbuf;                /* text file */
  43. int outbuf;
  44. char inname[80];            /* where we save ASCII filenames */
  45. char outname[80];
  46. char header[134];            /* top of page header */
  47. char subheader[134];            /* sub title, */
  48.  
  49. int flag;                /* user variable */
  50. int cond_flag;                /* conditional print flag */
  51.  
  52. change_page()                /* dummy function to start a new page */
  53. {}
  54. /* Process the input file. If no output is specified, write it it 
  55. the standard output. */
  56.  
  57. main(argc,argv)
  58. int argc;
  59. char *argv[];
  60. {
  61. char *p,*pp;
  62. int i;
  63. int have_file;
  64. int arg_error;
  65.  
  66.     fprintf (stderr,"TEXTFORM -- Text file Formatter (c) T. Jennings 23 Dec. 1982\n");
  67.     page_size =PAGE_LEN;
  68.     lmargin =DEF_LMARGIN;
  69.     top_margin= DEF_TMARGIN;
  70.     bot_margin= DEF_BMARGIN;
  71.     line_num= FALSE;
  72.     strcpy(header,"");            /* no header */
  73.     strcpy(subheader,"");
  74.     flag= 0;                /* flags off */
  75.     cond_flag= 1;                /* allow printing */
  76.     have_file= 0;                /* no output file yet */
  77.     arg_error= 0;                /* no error yet, */
  78.  
  79. /* Process the command line. We must have a filename, and optionally one
  80. of two options: list amount of memory, of add line numbers to the index. */
  81.  
  82.     --argc;
  83.     strcpy (inname,argv[1]);        /* get input file, */
  84.     inbuf= open(inname,0x8000);        /* try to open, */
  85.     if (inbuf == ERROR) {
  86.         fprintf(stderr,"Can't seem to find %s.\n",inname);
  87.         fprintf(stderr,"Try: TEXTFORM <file> <outfile>\n");
  88.         fprintf(stderr,"If <outfile> is omitted, output goes\n");
  89.         fprintf(stderr,"to the PRN device.\n");
  90.         exit();
  91.     }
  92.     strcpy(outname,"PRN");            /* default output file */
  93.     --argc; i= 2;
  94.     while (argc-- > 0) {
  95.         p= argv[i++];
  96.         if (*p == '-') {        /* check for options, */
  97.             ++p;            /* skip the dash, */
  98.             fprintf(stderr,"'%c' is not an option.\n",*p);
  99.             ++arg_error;
  100.         } else {
  101.             if (! have_file) {
  102.                 strcpy(outname,p);
  103.                 have_file= 1;
  104.             } else {
  105.                 fprintf(stderr,"Already have an output file!\n");
  106.                 ++arg_error;
  107.             }
  108.         }
  109.     }
  110.     if (arg_error) {
  111.         fprintf(stderr,"Too many mistakes.\n");
  112.         exit();
  113.     }
  114.     outbuf= creat(outname,0x8001);        /* open output file */
  115.     if (outbuf == ERROR) {
  116.         fprintf(stderr,"Can't make new file '%s'.\n",outname);
  117.         exit();
  118.     }
  119.     fprintf(stderr,"Printing to %s.\n",outname);
  120.     print();
  121.     wrtc(FF,outbuf);    /* final formfeed, */
  122.     close(inbuf); close(outbuf);
  123.     exit();            /* exit. */
  124. }
  125. /* Print each line to the printer, processing dot commands as we go. */
  126.  
  127. print()
  128. {
  129. char linebuf[132];        /* character line buffer */
  130. int i;
  131.  
  132.     line_count =0;
  133.     this_page =1;
  134.     this_line =0;
  135.  
  136.     while ( fill_line(linebuf) !=CONTROLZ)        /* until EOF, */
  137.     {    if (scan_line(linebuf) ==TRUE)        /* look for dot cmds */
  138.             continue;            /* get next line */
  139.         if (cond_flag == 0)
  140.             continue;            /* print if enabled */
  141.  
  142.         ++line_count;                /* count total lines,*/
  143.         if (this_line == 0) {
  144.             do_header();            /* do headers, */
  145.             i= top_margin;
  146.             wrtc(CR,outbuf); 
  147.             while (i--) {            /* do top margin, */
  148.                 wrtc(LF,outbuf);
  149.             }
  150.         }
  151.         i= lmargin;                /* do left margin, */
  152.         while (i--) {
  153.             wrtc(' ',outbuf);
  154.         }
  155.         sendstr(linebuf,outbuf);        /* print line, */
  156.  
  157.         if (this_line > (page_size- bot_margin))
  158.         {    wrtc(CR,outbuf);
  159.             while (this_line < page_size)
  160.                 wrtc(LF,outbuf);
  161.             ++this_page;
  162.             this_line= 0;
  163.         }
  164.     }
  165.     return;
  166. }
  167. /* Compare two strings, of a given length. Check only for equality. Return
  168. 0 if equal, else 1. */
  169.  
  170. compl(length,first,last)
  171. int length;
  172. char *first,*last;
  173. {
  174.  
  175.     for (; length >0; length--)
  176.     {    if (  (toupper(*first)) != (toupper(*last))  )
  177.             return (1)
  178.         ;
  179.         ++first; ++last;
  180.     }
  181.     return (0);
  182. }
  183. /* Fill a line buffer with characters. Return CONTROLZ if end of file. */
  184.  
  185. fill_line(buffer)
  186. char buffer[];
  187. {
  188. int i;
  189. char d;
  190.  
  191.     i=0;
  192.     do {    if (read(inbuf,&d,1) != 1)
  193.             return (CONTROLZ);    /* check physical end */
  194.         if (d ==CONTROLZ) {
  195.             return (d);
  196.         }
  197.         buffer[i++]= d& 0x7f;
  198.     }
  199.     while ((d !=LF) && (i <132));
  200.     buffer[i]= 0x00;            /* terminate */
  201.     return(d);
  202. }
  203. /* Scan for dot commands. When and if we find a dot command, fool the 
  204. caller into thinking that the line we were passed is now empty. (Return TRUE)
  205. If we find a formfeed, treat it the same as a .pa. */
  206.  
  207. scan_line(buffer)
  208. char *buffer;
  209. {
  210. int i;
  211. char c;
  212.     if (*buffer =='.')        /* as per WS specs, must be first atom */
  213.     {    if (compl (3,buffer,".pa") ==0)
  214.         {    wrtc(CR,outbuf);
  215.             while (this_line < page_size) {
  216.                 wrtc(LF,outbuf);
  217.             }
  218.             ++this_page;
  219.             this_line =0;
  220.  
  221.         } else if (compl (3,buffer,".pn") == 0) {
  222.             i= get_next_num(buffer);    /* get new page num, */
  223.             if (i)                /* if not zero, */
  224.                 this_page= i;        /* set it, */
  225.  
  226.         } else if (compl (3,buffer,".pl") == 0) {
  227.             i= get_next_num(buffer);    /* get new paper */
  228.             if (i > 5)            /* length, */
  229.                 page_size= i;
  230.  
  231.         } else if (compl (3,buffer,".mt") == 0) {
  232.             i= get_next_num(buffer);
  233.             if (i == 0)
  234.                 i= 1;
  235.             if (i < 40)            /* get top margin, */
  236.                 top_margin= i;        /* set if reasonable */
  237.         } else if (compl (3,buffer,".mb") == 0) {
  238.             i= get_next_num(buffer);
  239.             if (i < page_size)        /* set bottom margin */
  240.                 bot_margin= i;
  241.  
  242.         } else if (compl (3,buffer,".he") == 0) {
  243.             while (isgraph(*buffer))    /* skip the .he, */
  244.                 ++buffer;
  245.             if (*buffer == ' ')        /* and any space, */
  246.                 ++buffer;
  247.             strcpy(header,buffer);        /* copy the header, */
  248.  
  249.         } else if (compl (3,buffer,".sh") == 0) {
  250.             while (isgraph(*buffer))
  251.                 ++buffer;        /* skip the .sh, */
  252.             if (*buffer == ' ')
  253.                 ++buffer;
  254.             strcpy(subheader,buffer);
  255.  
  256.         } else if (compl (5,buffer,".flag") == 0) {
  257.                 flag= get_next_num(buffer); /* set variable */
  258.  
  259.         } else if (compl (7,buffer,".ifflag") == 0) {
  260.                 cond_flag= flag;
  261.  
  262.         } else if (compl (6,buffer,".endif") == 0) {
  263.                 cond_flag= 1;        /* allow printing */
  264.  
  265.         } else if (compl (3,buffer,".lm") == 0) {
  266.                 i= get_next_num(buffer);
  267.                 if (i <80)
  268.                     lmargin= i;
  269.         }
  270.         return (TRUE);
  271.     }
  272.  
  273.     if (*buffer == FF) {
  274.         wrtc(FF,outbuf);
  275.         ++this_page;
  276.         this_line= 0;
  277.         return(TRUE);
  278.     }
  279.     return (FALSE);
  280. }
  281. /* Print the top of page header. If we find a #, replace it with 
  282. the current page number, and replace % with the user flag. */
  283.  
  284. do_header() {
  285.  
  286. char c;
  287. char *p;
  288. char pnum[8];
  289.  
  290.     p= header;
  291.     while (*p) {            /* look at current char, */
  292.         if (*p == '#') {
  293.             sprintf(pnum,"%d",this_page);
  294.             sendstr(pnum,outbuf);
  295.         } else if (*p == '%') {
  296.             sprintf(pnum,"%d",flag);
  297.             sendstr(pnum,outbuf);
  298.         } else
  299.             wrtc(*p,outbuf);
  300.         ++p;
  301.     }
  302.     p= subheader;
  303.     while (*p) {
  304.         if (*p == '#') {
  305.             sendstr(pnum,outbuf);
  306.             sprintf(pnum,"%d",this_page);
  307.         } else if (*p == '%') {
  308.             sprintf(pnum,"%d",flag);
  309.             sendstr(pnum,outbuf);
  310.         } else 
  311.             wrtc(*p,outbuf);
  312.         ++p;
  313.     }
  314.     return;
  315. }
  316. /* Send an ascii string to the output file */
  317.  
  318. sendstr(string)
  319. char *string;
  320. {
  321.     while (*string)
  322.     {    wrtc (*string++,outbuf);
  323.     }
  324. }
  325. /* Write a character to the file. Count LF's as lines as they go by. */
  326.  
  327. wrtc(c,file)
  328. char c;
  329. int file;
  330. {
  331.     if (iscntrl(c)) { 
  332.         switch(c) {
  333.             case LF:
  334.                 ++this_line;
  335.             case CR:
  336.             case FF:
  337.             case TAB:
  338.             case BS:
  339.                 write(file,&c,1);
  340.                 break;
  341.             default:
  342.                 break;
  343.         }
  344.     } else write(file,&c,1);
  345.  
  346.     return;
  347. }
  348. /* Find the next number in the string, return it's value, or 0 
  349. if none found. */
  350.  
  351. get_next_num(string)
  352. char *string;
  353. {
  354. int i;
  355.     while (! isdigit(*string))
  356.         ++string;        /* skip leading text, */
  357.     if (sscanf(string,"%d",&i) == 0)/* if cant convert, */
  358.         return(0);        /* return 0000 */
  359.     return(i);
  360. }
  361.