/*  tw2html.c
    (C)1997 Adrian O' Neill
    Converts Transwrite files to HTML format
    See readme.txt for more information
*/

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

#define def_lineclip 70
#define out_lineclip 70
#define BUFSIZE 5120
#define MaxFilename 250

enum align_type {
    left,
    right,
    center
};

int lineclip=def_lineclip;
enum align_type alignment = left;
int al_change = 0;

void OutputLine(char *str, FILE *fptr)
{
    char *end, *space;
    static char buffer[out_lineclip+2];

    while (strlen(str) > out_lineclip)  {
        strncpy(buffer, str, out_lineclip);
        buffer[out_lineclip] = 0;
        if (space = strrchr(buffer, ' '))  {
            *space=0;
            fprintf(fptr, "%s\15\12",buffer);
            str = str + (space - buffer + 1);
        } else {
            fprintf(fptr, "%s", buffer);
            str = str + def_lineclip;
        }
    }
    fprintf(fptr, "%s\15\12", str);
}


void PrintLine(char *line, int line_len, FILE *fptr)
{
    if ((line_len < lineclip) && (!al_change))  {
        OutputLine(line, fptr);
        fprintf(fptr, "<br>\15\12");
    } else {
        al_change = 0;
        OutputLine(line, fptr);
        fprintf(fptr, "\15\12<p");
        if (alignment != left)  {
            fprintf(fptr, " align=");
            switch (alignment)  {
                case right: fprintf(fptr, "right"); break;
                case center:  fprintf(fptr, "center"); break;
            }
        }
        fprintf(fptr, ">\15\12");
    }
}

void ConvertLine(char *inline, char *outline)
{
    unsigned char i;
    unsigned char ch[8], num[8];
    int bold = 0, italic = 0, under = 0;
    int j, count = 1;

    i = *inline;
    *outline = 0;

    while (*inline++)  {
        if ((i < 32) && (i >= 0))  {
            ch[0]=0;
            switch (i)  {
                case 2:
                    if (!italic)  {
                        italic = (count++);
                        strcpy(ch,"<i>");
                    }
                    break;
                case 3:
                    if (!bold)  {
                        bold = (count++);
                        strcpy(ch,"<b>");
                    }
                    break;
                case 4:
                    if (!under)  {
                        under = (count++);
                        strcpy(ch,"<u>");
                    }
                    break;
                case 5:
                    italic = 0;
                    strcpy(ch,"</i>");
                    break;
                case 6:
                    bold = 0;
                    strcpy(ch,"</b>");
                    break;
                case 7:
                    under = 0;
                    strcpy(ch,"</u>");
                    break;
                default : ch[0] = 0;
            }
        } else {
            if ((i >= 32) && (i < 160))  {
                switch (i)  {
                    case '<' : strcpy(ch,"&lt;"); break;
                    case '>' : strcpy(ch,"&gt;"); break;
                    case '&' : strcpy(ch,"&amp;"); break;
                    default:
                        ch[0] = i;
                        ch[1] = 0;
                        if (i >= 128)
                            ch[0] = 0;
                }
            } else {
                strcpy(ch, "&#");
                sprintf(num, "%i", i);
                strcat(ch, num);
                strcat(ch, ";");
            }
        }
        strcat(outline, ch);
        i = *inline;
    }
    for (j=count; j>=1; j--)  {
        if (bold == j)
            strcat(outline, "</b>");
        if (italic == j)
            strcat(outline, "</i>");
        if (under == j)
            strcat(outline, "</u>");
    }
}


void ChangeAlignment(*str)
{
    if ((strncmp(str, "jl", 2) == 0) || (strncmp(str, "jf", 2) == 0))
        alignment = left;
    if (strncmp(str, "jr", 2) == 0)
        alignment = right;
    if (strncmp(str, "jc", 2) == 0)
        alignment = center;
}


void ProcessAlign(char *str)
{
    do {
        str++;
        ChangeAlignment(str);
    } while ((*str) && (str = strchr(str, ':')));
}


void ReadData(unsigned char *in, FILE *fin)
{
    int emptyline = 1;

    while ( (emptyline) && (fgets(in, BUFSIZE, fin)) )  {
        emptyline = 0;
        if ( (*in==0) || (*in==10) || (strspn(in," ")==strlen(in)) )  {
            emptyline=1;
        } else {
            while ( (*in==167) || ((*in > 0) && (*in < 32)) )  {
                if (*in == 167)  {
                    ProcessAlign(in);
                    emptyline = 1;
                    break;
                }
                in++;
            }
        }
    }
}


int main(int argc, char *argv[])
{
    unsigned char *in1, *in2, *out;
    FILE *fin, *fout;
    char outfilename[MaxFilename + 5];
    enum align_type first, second;

    if ((argc<2) || (argc>3))  {
        printf("Usage: %s TWFile [OutputFile]\n", argv[0]);
        exit(1);
    }

    if ( !(in1 = (unsigned char *) malloc (BUFSIZE)) ||
            !(in2 = (unsigned char *) malloc (BUFSIZE)) ||
            !(out = (unsigned char *) malloc (6*BUFSIZE)) )  {
        printf("Error: Not enough memory available.\n");
        exit(1);
    }

    if (!(fin=fopen(argv[1], "r")))  {
        printf("Error: Can't open %s for reading.\n",argv[1]);
        exit(1);
    }

    if (strlen(argv[1]) > MaxFilename) {
        printf("Error: Filename too big!\n");
        exit(1);
    }

    if (argc==2)  {
        strcpy(outfilename, argv[1]);
        strcat(outfilename, ".html");
    } else {
        strcpy(outfilename, argv[2]);
    }

    if (!(fout=fopen(outfilename, "w")))  {
        printf("Error: Can't open %s for writing.\n",outfilename);
        exit(1);
    }

    fprintf(fout, "<html>\15\12<head>\15\12<title>%s</title>\15\12",argv[1]);
    fprintf(fout, "<meta name=\"Generator\" content=\"tw2html\">\15\12");
    fprintf(fout, "</head>\15\12<body>\15\12");

    ReadData(in1, fin);

    if (alignment != left)  {
        al_change = 1;
        PrintLine("", 0, fout);
    }

    while (!feof(fin))  {
        first = alignment;
        ReadData(in2, fin);
        second = alignment;
        if (first != second)
            al_change = 1;
        ConvertLine(in1, out);
        PrintLine(out, strlen(in2), fout);
        strcpy(in1, in2);
    }

    fprintf(fout, "</body>\15\12</html>\15\12");
    fclose(fin);
    fclose(fout);
    free(in1);
    free(in2);
    free(out);
    return(0);
}



