/*  jason black, feb 18 1992

ps2txt.c extracts strings from a PostScript file.  This version has been 
modified to correctly deal with the oddities of PostScript files generated by 
dvi-to-PostScript converters, so if you keep this and the original program 
around, you might want to rename one of them.

Input can come from stdin, from '-' or from a file named on the command line:
		    	ps2txt file.ps
		 	cat file.ps | ps2txt 
			ps2txt - < file.ps
			etc.

VERSION:  1.1	Fixed bug dealing with comments.
	  1.2	By popular demand:  put spaces between strings.
	  2.0   fixed most problems of extraneous spaces and newlines
		between strings.
		added support for the ligatures ff, fi, fl, ffi, & ffl.
		re-designed the control structures, and otherwise cleaned
		up the code.

Originally by Iqbal Qazi.  This version has been about 98% re-written, so I'm
going to claim it as mine.

Comments/suggestions to cloister@u.washington.edu
*/

#include <stdio.h>
#define Putc(x) putchar(x);

void main(argc, argv)
int argc; 
char **argv;
{
  int ch,             /* current character */
      prev_ch = '\n', /* previously read character */
      in_paren = 0,   /* inside or outside of parentheses? */
      b_flag = 0,     /* true if previous character was ')' */
      b_space = 1;    /* true if a 'b' should produce a space */
  char junk[80];
  FILE *file, *source;

  if ((argc == 1) || ((argv[1][0] == '-') && (argv[1][1] == 0)))
    source = stdin;
  else
    if ((file=fopen(argv[1],"r"))!=NULL)
      source=file;
    else 
      {
	fprintf(stderr,"ps2txt: error opening file %s\n",argv[1]);
	exit(1);
      }
    
  while ((ch = fgetc(source)) != EOF)
    {
      if (ch == '\n') ch = fgetc(source);
      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 = '(' */
    }
}


