Category : Word Processors
Archive   : MANPREP2.ZIP
Filename : MANPREP.C

 
Output of file : MANPREP.C contained in archive : MANPREP2.ZIP

/*
MANPREP.C

Reformat a "generic printer" doc file for video
output. I call this MANPREP in honor of the wonderful
micro-MAN program by David L. Rick.

manprep does 2 things:
remove adjacent "blank" lines greater than a parameter, and
"back up" over a character followed by a backspace.

Input and output files default to stdin and stdout.
The -l parameter defaults to 2.

Copyright 1987 by Francis X. Guidry
All Rights Reserved

*/


#include
#include

/*--------------------------------------------------------------------
main() does the command line processing "in the raw," then calls
a driver to do the real work. */

main(argc,argv)
int argc;
char *argv[];
{
/* Initialize the variables to the defaults instead of 0 - it's
just as easy to test, and maybe a little clearer to read. */

int i=1, n=2;
FILE *in=stdin, *out=stdout;
int insave;

/* Command line processing is such a drag. I feel silly
linking in a library routine for two filenames and one
option, so I just do the command line here in main().

I would love to be able to omit the file names and use only
i/o redirection, but that is very slow on my old PC.

I prefer to allow numeric options to be contiguous with or
separate from the option letter, so "-l2" and "-l 2" are
both valid. And I prefer to allow options to precede,
follow, or be intermixed with file names. All this flexibility
makes the code a mess, but I think it cuts down on frustration
for the user.
*/
while(i < argc) {
if(argv[i][0] == '-')
if(argv[i][1] == 'l') {
if(argv[i][2] && isdigit(argv[i][2]))
n = atoi(argv[i]+2);
else if(isdigit(argv[i+1][1]))
n = atoi(argv[++i]);
else merror("-l option requires a numeric parameter.");
++i;
continue;
} else merror("invalid option.");

if(in == stdin) {
if(!(in = fopen(argv[i],"r")))
merror("unable to open input file.");
else insave = i;
} else if(out != stdout)
merror("too many parameters.");
else if(!strcmp(argv[i],argv[insave]))
merror("input and output files _must_ be different!");
else if(!(out = fopen(argv[i],"w")))
merror("unable to open output file.");
++i;
}

/* Finally, we can do some work. */

process(in,out,n);
fclose(in);
fclose(out);
exit(0);
}

/*----------------------------------------------------------------------
This function runs the show, reading input, passing out the lines
to be worked on, then writing out the good stuff. */

#define BSIZE 320
char line[BSIZE];
char *strchar();

process(in,out,n)
FILE *in, *out;
int n;
{
int t = 0;
int counter = 0;
char *fold();

while(fgets(line,BSIZE,in)) {
if((t = test(line)) < 1)
counter++;
else counter = 0;
if(counter < n)
if(strchr(line,'\b'))
fputs(fold(line),out);
else fputs(line,out);
}
}


/*----------------------------------------------------------------------
test() returns a failing grade for "blank" lines, those with no
character greater than a space. */

int test(line)
char *line;
{
do {
if(*line > ' ')
return(1);
} while(*(++line));
return(0);
}


/*----------------------------------------------------------------------
fold() gets rid of unsightly backspace clutter, by "backing up"
over the preceding character and throwing away the backspace.
The only tricky part is avoiding backing up past the beginning of
the output buffer. */

char oline[BSIZE];
char *fold(line)
char *line;
{
char *o = oline;

while(*line == '\b')
line++;
while(*o = *line) {
if(*line == '\b')
o = o > oline ? --o : o;
else o++;
line++;
}
return(oline);
}

/*----------------------------------------------------------------------
merror() is a one-way function. After printing the message it
terminates the program with an errorlevel. */

merror(s)
char *s;
{
printf("manprep v1.1 copyright 1987 by Francis X. Guidry\n\n",s);
printf("Sorry, %s\n\n",s);
printf("Usage: manprep [filein] [fileout] [-l | -l ]\n");
printf("Defaults: stdin stdout -l2\n");
printf("-l: is a number which specifies maximum \n");
printf(" adjacent blank lines in the output.\n");
exit(1);
}