#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// Strop MTS Algol-W keywords...

char *Algol[] = {
  // OK to include some extra keywords from specific compilers
  "algol",  "and",  "array",  "begin",  "boolean",  "code", "codeoff",
  "codeon",  "comment",  "do",  "else",  "end",  "eop", "eq",
  "equiv",  "eqv",  "external", "for",  "fortran",
  "ge",  "go", "goto",  "gt",  "if",  "impl",  "integer",
  "kdf9", "label",  "le",  "library", "lt",  "ne",  "not",  "notequal",
  "notgreater",  "notless",  "or",  "own",  "power",  "procedure",
  "program",  "real",  "step",  "string",  "switch",  "then", "to",
  "until",  "value",  "while",
  "dummy", "base", "global", "logical", "byte", "short", "long",
  "of", "abs", "shll", "shrl", "shra", "shla", "case", "record", "reference",
  "close", "syn", "segment", "result", "null",
  "abs", "equate", "character",
  NULL
};

void html(int c) {
  /*if (c == '&') fprintf(stdout, "&amp;");
  else if (c == '<') fprintf(stdout, "&lt;");
  else if (c == '>') fprintf(stdout, "&gt;");
  else if (c == '{') fprintf(stdout, "<u>[</u>");
  else if (c == '}') fprintf(stdout, "<u>]</u>");
  else*/ fputc(c, stdout);
}

int keyword(char *lowers) {
  int key = 0;
  for (;;) {
    if (Algol[key] == NULL) return 0;
    if (strcmp(lowers, Algol[key++]) == 0) {
      return 1;
    }
  }
}

int strop(char *s, int allalpha) {
  char lowers[128];
  char *from = s, *to = lowers;
  int c;
  if (allalpha) {
    for (;;) {
      *to++ = tolower(c = *from++);
      if (c == '\0') break;
    }
    if (keyword(lowers)) {
      fprintf(stdout, "'%s'", lowers);
      return strcmp(lowers, "comment") == 0;
    }
  }
  fprintf(stdout, "%s", s);
  return 0;
}

int main(int argc, char **argv)
{
  int c, lastc, p, allalpha, commenting, openquote, pendingspace, nocloser;
  static char atom[128];
  // fix up fake algol files to use proper stropping.
  // (for now skip the special case of IBM360 JCL at the head of the file...)
  commenting = 0; openquote=0; pendingspace = 0; nocloser = 1;
  //fprintf(stdout, "<html><body><pre>");
  for (;;) {
    c = fgetc(stdin);
    pendingspace = 0;
    if (commenting) commenting = (c != ';'); // commenting &&= (c != ';') ???
    else switch (c) {

    case '{': {
      int balance = 0;
      if (commenting) break;
      for (;;) {
	if (c == '{') balance += 1;
	html(c);
	c = fgetc(stdin); if (c == EOF) break;
	if (c == '}') {
	  balance -= 1;
	  if (balance == 0) break;
	}
      }
      break;
    }

    // Just in case we later support LOWER CASE STROPPING I'll separate out upper and lower letters:
    case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':case 'G':case 'H':case 'I':case 'J':case 'K':case 'L':case 'M':
    case 'N':case 'O':case 'P':case 'Q':case 'R':case 'S':case 'T':case 'U':case 'V':case 'W':case 'X':case 'Y':case 'Z':

    case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':
    case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':
      allalpha = 1;
      p = 0;
      for (;;) {
	atom[p++] = c;
	c = fgetc(stdin);
        if (isdigit(c)) allalpha = 0;
        if ((c == EOF) || (p == 127) || !isalnum(c)) break;
      }
      ungetc(c, stdin);
      atom[p] = '\0';
      commenting = strop(atom, allalpha);
      openquote = 0; nocloser = 0;
      continue;
    case '"':
      for (;;) {
        html(c);
        c = fgetc(stdin);
        if ((c == EOF) || (c == '"')) break;
      }
    default:
      break;
    }
    if (c == EOF) break;
    html(c);
  }
  //fprintf(stdout, "</pre></body></html>\n");
  exit(0);
  return 1;
}
