这是ps2txt的源代码,翻译成OP可能不难吧!
#include <stdio.h>
#define Putc(x) putchar(x);
/* makes some lines not exceed 80 chars. */
#define TRUE 1
#define FALSE 0
void dviparse();
/* function prototypes */
void psparse();
void main(argc, argv)
int argc;
char *argv[];
{
int i, /* everybody's favorite counter */
known_flag, /* used during command line parsing */
dvi_file = FALSE;
/* true if -dvi option found on command line */
FILE *file, *source;
/* input stream */
source = stdin;
/* default input source */
for(i=1;
i<argc;
i++) /* parse command line args */
{
known_flag = FALSE;
if (strcmp(argv,"-dvi") == 0) /* is it a dvitps PostScript file? */
{
dvi_file = TRUE;
known_flag = TRUE;
}
if (strcmp(argv,"-") == 0) /* weirdo-user explicitly wants stdin */
{
source = stdin;
known_flag = TRUE;
}
if (!known_flag) /* must be the input file name */
{
if ((file=fopen(argv,"r")) != NULL )
source=file;
else
{
fprintf(stderr,"ps2txt: error opening file %s/n",argv);
fprintf(stderr,"usage: ps2txt [-dvi] [-] [input_file.ps]/n");
exit(1);
}
}
}
if (dvi_file)
dviparse(source);
/* use my algorithm */
else
psparse(source);
/* use Iqbal's algorithm */
}
void dviparse(source)
FILE *source;
{
int ch, /* current character */
prev_ch = '/n', /* previously read character */
in_paren = FALSE, /* inside or outside of parentheses? */
b_flag = FALSE, /* true if previous character was ')' */
b_space = TRUE;
/* true if a 'b' should produce a space */
char junk[80];
/* place to throw away comment lines */
while ((ch = fgetc(source)) != EOF)
{
if (ch == '/n') ch = fgetc(source);
/* ignore newlines in input! */
if (in_paren) /* strings to print come inside parentheses */
switch(ch)
{
case ')' : in_paren--;
b_flag=1;
break;
/* not in paren's anymore */
case '/n' : Putc(' ');
break;
/* <cr> = ' ' in parens */
case '//' :
switch(ch=fgetc(source))
{
case '(' :
case ')' : Putc(ch);
break;
/* from /? */
case 't' : Putc('/t');
break;
/* write a tab */
case 'n' : Putc('/n');
break;
/* write a <cr> */
case '//': Putc('"');
break;
/* open quotes */
case '0' : switch(ch=fgetc(source))
{
case '1': switch(ch=fgetc(source))
{
case '3' : fputs("ff",stdout);
break;
/* from /01? */
case '4' : fputs("fi",stdout);
break;
case '5' : fputs("fl",stdout);
break;
case '6' : fputs("ffi",stdout);
break;
case '7' : fputs("ffl",stdout);
break;
default: fputs("//01",stdout);
Putc(ch);
/* unknown code */
} break;
/* from /0? */
default: fputs("//0",stdout);
Putc(ch);
/* unknown code */
} break;
case '1' : case '2' : case '3' : case '4' :
case '5' : case '6' : case '7' : Putc('//');
/* unknown code */
default: Putc(ch);
} break;
/* from original switch */
default: Putc(ch);
}
else
/* not in paren's */
switch(ch)
{
case '%' : fgets(junk, 80, source);
break;
/* toss out comments */
case '/n' : break;
/* skip <cr>'s outside of parens */
case '-' : if (b_flag)
{
b_flag = 0;
/* because now prev. char != ')' */
b_space = 0;
/* but the number after ')' is negative, so no */
/* space in case the letter code is 'b'. */
/* the default is b_space = 1 */
} break;
case '(' : in_paren++;
/* back in parens again */
switch(prev_ch) /* check prev char to see if we need a space */
{
case 'l' : case 'm' : case 'n' : case 'o' : /* not for these 8 */
case 'q' : case 'r' : case 's' : case 't' :
break;
case 'y' : Putc('/n');
break;
/* need a newline */
case 'b' : if (b_space) Putc(' ');
break;
/* 'b' w/ a + number */
case 'a' : case 'c' : case 'd' : case 'e' :
case 'f' : case 'g' : case 'h' : case 'i' :
case 'j' : case 'k' : case 'x' : Putc(' ');
break;
default: break;
}
b_space = 1;
/* reset flag to default for next time */
break;
default: b_flag = 0;
break;
/* junk stuff not in parens */
}
prev_ch=ch;
/* remember this char in case !in_paren and next ch = '(' */
}
}
void psparse(source) /* Iqbal's original uncommented program, unmodified */
FILE *source;
/* except for stripping i/o stuff off the top, etc: */
{
char *str;
char junk[80];
int ch, para=0, last=0;
while ((ch=fgetc(source)) != EOF)
{
switch (ch)
{
case '%' : if (para==0) fgets(junk, 80, source);
else
putchar(ch);
case '/n' : if (last==1) { puts("");
last=0;
} break;
case '(' : if (para++>0) putchar(ch);
break;
case ')' : if (para-->1) putchar(ch);
else
putchar(' ');
last=1;
break;
case '//' : if (para>0)
switch(ch=fgetc(source))
{
case '(' :
case ')' : putchar(ch);
break;
case 't' : putchar('/t');
break;
case 'n' : putchar('/n');
break;
case '//': putchar('//');
break;
case '0' : case '1' : case '2' : case '3' :
case '4' : case '5' : case '6' : case '7' :
putchar('//');
default: putchar(ch);
break;
}
break;
default: if (para>0) putchar(ch);
}
}
}