
/*

	BAKPRINT.C	Vers 1.0	By Craig Derouen  May 12,1985


 Bakprint is a little printer utility that is most useful from printing
 documents and other text files that have 'backspaces' inserted in the
 text. These backspaces are inserted in the text to implement text 
 formatting such as undserscore or bold print. There are many printers out
 there such as my OKI 92A that do not accept a backspace character. This
 program is designed to filter out the backspaces and convert the format
 to a readable one accepted by most any printer. This program was done out
 of necessity because of all the un-forgiving PD author's who put out text
 files with backspaces in them! Do they think we all have Epson FX-80's!!

 The program works by reading a line of text into a buffer. When it encounters
 a backspace, it will set a flag and save the next character and its position
 for later manipulation. The line buffer is scanned up to a cr-lf set. Then
 the line is printed out to the printer WITHOUT a linefeed. A cr is also
 sent to the printer which will return the printer head back to the start of
 the line, then the backspace/chars are output at their respective positions.
 Spaces are inserted to produce a full line. The printer is advanced to the
 next line and the process starts over. BAKPRINT will read in a file
 specified. To read in a file from backprint type the following:

	BAKPRINT (pathname) [(output pathname)]

 Wild cards are not accepted at this time. Pathname is any legal DOS path
 name. If no output pathname is specified, the output goes to the standard
 printer output. If the input pathname can not be opened, the filter mode
 will be set. If the output file already exists it will be re-written. If
 the output name is illegal or can not be opened, output goes to printer.

 As an additional feature this program will convert XENIX text files 
 (terminated with cr only) to a cr-lf terminator accepted by MS-DOS. Also 
 tabs are expanded, again because most printers can not accept tabs!

*/

#define vers 1.00

#include "stdio.h"
#include "ctype.h"

#define maxlen  132     /* Maximum length of line from input file */
#define true 1
#define false 0

#define lf	0x0a
#define cr  0x0d
#define bsp 0x08
#define tab 0x07
#define blank 0x20

#define tabpos 8		/* Spaces between tabs */

FILE *infile,*outfile;
int _fmode = 0x8000;	/* Raw mode */
int testchar,outcount,backcount,line;
char outline[maxlen+1];
char bkspline[maxlen*2];
char testline[maxlen];
int linecount=0,charpos=0,backflag,notcon=false;

main (argc,argv)
int argc;
char *argv[];

{
	if (argc < 2) {		/* No files were specified so make us a filter */
	   infile = fopen(stdin,"r");
	   outfile = fopen(stdout,"w");
	}
 	else if ((infile = fopen(argv[1],"r")) == NULL ) {
	   printf ("\007Sorry,bad filename\n");
	   exit (1);
	}
	if (argc > 2) {
	   if ((outfile = fopen(argv[2],"w")) == NULL ) { 
		  outfile = fopen(stdout,"w");	/* to the console instead */
		  printf("\007Bad output file, output will goto console\n");
	   }
	   else notcon=true;
	}
 	else outfile = fopen(stdout,"w");
	if (notcon) printf("BAKPRINT Ver: %04f By Craig Derouen\n\n",vers);
	while (!(feof(infile))) {
	   getline();
	   if (notcon) printf("\tNow printing line %d\r",linecount);
	   fputs(outline,outfile); /* print out the line minus backspaces */
	   backline();	/* Print any chars that were paired with backspaces */
	   putc (lf,outfile);
	}
 	fclose(infile);
	fclose(outfile);
	if (notcon) printf("\n");
	exit (0);
}

getline () {

int tabcount=0;   

/* Read in a line of text and put it into the buffer. Strip
	all the backspaces and their respective characters */

	charpos=0;	/* Starting fresh */
	outcount=0; /* Number of chars in the line */
	backcount=0;
 	backflag=false;
 	line=false;
   	while (((testchar=getc(infile)) != EOF ) && (!line)) {
		switch(testchar) {
			case cr : { 	/* We must be at the end of the line */
			   ++linecount;
			   outline[outcount++]=testchar;
			   line=true;
			   break;
			 }

		 	case lf : {
			   line=true;
			   break;		/* Just swallow the linefeeds */
			}

			case bsp : {	/* This is the one we are looking for */
			   backflag=true;
			   testchar=getc(infile); /* Get the next character */
			   if (testchar !=cr) {
			   		bkspline[backcount++] = charpos; /* Get the current position */
			   		bkspline[backcount++] = testchar; /* Put in the character */
			   }
			   else ungetc(testchar,infile); /* Put it back */
			   break;
			}
		 	
		 	case tab : {	/* Expand any tabs */
			   tabcount=tabpos-(charpos & tabpos);
			   while (tabcount) {
				  outline[outcount++]=blank; /* Put in a blank */
				  charpos++;
			      tabcount--;
			    }
			}

			default : {  /* the rest of the story */
			   outline[outcount++]=testchar; /* save it */
			   charpos++;
			   break;
			}
		}
	}
 	outline[outcount++]=NULL;
}

backline() {	

/* This function will print any characters that were paired with the 
backspace key in the original line. They will be placed in their proper
position in the line */

	int count=0,skip;
	if (backflag) { 

	   /* Create a string of blanks */
	   while (count < maxlen)
		  testline[count++]=blank;
	   count=0;
	   while (backcount) {
		  skip=bkspline[count++];	/* Get the char position */
		  testline[skip-1]=bkspline[count++];
	      backcount --;
	      backcount --;
	   }
 	   testline[outcount++]=cr;
	   testline[outcount]=NULL;
	   fputs(testline,outfile); 
	}
}
      b