/*************************************************************************/
/*                                                                       */
/* PCWTONYW.C - changes a PC-WRITE (TM of Quicksoft) PR.DEF file into a  */
/*              PRT file for the New York Word wp.                       */
/*                                                                       */
/* (C) Copyright 1986  Marc Adler    All Rights Reserved                 */
/*************************************************************************/

#include <stdio.h>
#include <ctype.h>

char *span_blanks(), *span_chars();
char *strchr();

#define ON  1
#define OFF 0


main(argc, argv)
  int  argc;
  char *argv[];
{
  FILE *inf, *outf, *fopen();
  char *fgets();
  char buf[120], outbuf[80], *s, *t;
  int  letter, state, type, spacing;

  /* Open the input file and the output file */
  if (argc < 2)
  {
    printf("Usage input-file [output-file]\n");
    exit(1);
  }

  if ((inf  = fopen(argv[1], "r")) == NULL)
  {
cant:
    printf("Can't open files\n");
    exit(1);
  }

  strcpy(buf, argv[(argc < 3) ? 1 : 2]);
  if ((s = strchr(buf, '.')) != NULL)
    *s = '\0';
  sprintf(outbuf, "%s.PRT", buf);
  if ((outf = fopen(outbuf, "w")) == NULL)
    goto cant;


  while (fgets(buf, 120, inf))
  {
    buf[strlen(buf)-1] = '\0';     /* get rid of the trailing newline */

    switch (buf[0])                /* examine the first character     */
    {
      case '#'  :
      case '$'  :
                 type   = buf[0];
                 letter = buf[1];
                 state  = ON;

                 if (type == '$' &&  (letter == 'S' || letter == 'H'))
                   spacing = atoi(&buf[2]);

                 /* = sign is buf[2], number is buf[3] - ..., then blank */
                 if ((s = strchr(buf+1, '=')) == NULL)
                   continue;
                 *s++ = '\0';

                 /* For a font char, span the screen attribute chars */
                 if (type == '#' && (s = span_chars(s)) == NULL)
                   continue;

                 if ((s = span_blanks(s)) != NULL)
                 {
                   while (*s && *s != ' ')
                   {
                     if (*s == '+')
                     {
                       state = ON;
                       s++;
                     }
                     else if (*s == '-')
                     {
                       state = OFF;
                       s++;
                     }
                     else if (type == '#' || !isdigit(*s))
                       break;

                     for (t = outbuf;  isdigit(*s);  )
                     {
                       *t++ = atoi(s);            /* make into a number */
                       while (isdigit(*s))  s++;  /* span the digits    */
                       if (*s == ',')  s++;       /* go past the comma  */
                     }

                   output(outf,type,letter,state,outbuf,(int)(t-outbuf),spacing);

                   } /* while */
                 }

                 break;

      case '('  :/* comment line - echo it */
                 fprintf(outf, "# %s\n", buf);
                 break;

      default   :
                 break;

    }
  }

  exit(0);
}


typedef struct _prtinfo
{
  int  letter;
  char *onname, *offname;
} PRTINFO;

PRTINFO font_prtinfo[] =
{
  'B', "bs", "be",     /* bold */
  'C', "cC", "ce",     /* compressed */
/*'D', "ds", "de",*/   /* double width */
  'E', "cE", "ee",     /* elite */
/*'F', "fs", "fe",*/   /* fast */
  'H', "Ss", "Se",     /* superscript */
  'I', "ib", "ie",     /* italics */
  'L', "ss", "se",     /* subscript */
/*'O', "os", "oe",*/   /* overstrike */
  'P', "cP", "pe",     /* pica */
  'Q', "qs", "qe",     /* quality */
  'S', "ds", "de",     /* double strike */
  'U', "us", "ue",     /* underline */
  'V', "ps", "pe",     /* variable */
/*'W', "ws", "we",*/   /* double underline */
   0,   NULL, NULL
};

#define FONT_PRTSIZE  (sizeof(font_prtinfo) / sizeof(PRTINFO))

PRTINFO ctrl_prtinfo[] =
{
  'P', "is", NULL,     /* initialization sequence */
  'Z', "es", NULL,     /* ending sequence */
  0,   NULL, NULL
};

#define CTRL_PRTSIZE  (sizeof(ctrl_prtinfo) / sizeof(PRTINFO))


output(outf, type, letter, state, outbuf, len, spacing)
  FILE *outf;             /* output file to print to */
  int  type;              /* '#' for font, '$' for control    */
  int  letter, state;     /* starting letter, ON or OFF state */
  char outbuf[];          /* the PC-WRITE sequence string     */
  int  len;               /* length of the PC-WRITE sequence  */
  int  spacing;           /* if $S, the spacing               */
{
  int i, c;
  PRTINFO *p;

  /* Check for a bad sequence string */
  if (len <= 0)
    return;

  if (type == '$' && letter == 'S')
    fprintf(outf, "L%d=", spacing);
  else if (type == '$' && letter == 'H')
    fprintf(outf, "C%d=", spacing);
  else
  {
    /* Search the Prtinfo table for the matching letter */
    p = (type == '#') ? font_prtinfo : ctrl_prtinfo;
    for (  ;  p->letter && letter != p->letter;  p++) ;

    /* Didn't find a match */
    if (p->letter == 0)  return;

    /* Print the proper NYWord two-letter attribute name, followed by '=' */
    fprintf(outf, "%s=", (state == ON) ? p->onname : p->offname);
  }

  /* Translate the PC-WRITE codes into the NYWord sequence string */
  for (i = 0;  i < len;  i++)
    if ((c = outbuf[i]) == 0)         /* special zero byte is \Z */
      fprintf(outf, "\\Z");
    else if (c == 27)                 /* ESC is \E */
      fprintf(outf, "\\E");
    else if (c < ' ' || c > 126)      /* control char is 3 digit number */
    {
      putc('\\', outf);
      fprintf(outf, "%03d", c);
    }
    else                              /* regular character */
      fprintf(outf, "%c", c);

  putc('\n', outf);
}


char *span_blanks(s)
  char *s;
{
  while (*s && isspace(*s))  s++;
  return (*s == '\0') ? NULL : s;
}

char *span_chars(s)
  char *s;
{
  while (*s && !isspace(*s))  s++;
  return (*s == '\0') ? NULL : s;
}
