#include <stdio.h>
#ifdef __STDC__
# include <stdlib.h>
#endif
#include <ctype.h>
#include <string.h>

#define ML 512
#define streq(A,B) (strcmp((A),(B))==0)
#ifndef TRUE
# define TRUE 1
# define FALSE 0
#endif

int indent;
int wrap_index = 78;

#ifdef __STDC__
void kilspaces(char *t)
#else
kilspaces(t)
char *t;
#endif
{
    int i=0, j=0;

    strcat(t,"   ");

    while(t[i]!='\0')
    {
         while( t[i]!='\0' && strchr("\t\r\n ",t[i]) )
              i++;
         while( t[i]!='\0' && !strchr("\t\r\n ",t[i]) )
         {
              t[j]=t[i];
              j++;
              i++;
         }
         t[j++]=' ';
    }
    t[j]='\0';

    return;
}

#ifdef __STDC__
void force_out(char *t)
#else
force_out(t)
char *t;
#endif
{
    int i, j;

    kilspaces(t);

    if(t[0]=='\0')
    {
         putchar('\n');
         return;
    }

    if(strlen(t)>wrap_index)
    {
         for(i=wrap_index-5*indent;t[i]!=' ';i--)
              ;
         t[i++]='\0';   /* i indexes the beginning of the next string */
    }
    else
         i=0;

    if(indent)
         fputs("     ",stdout);

    for(j=0;t[j]!='\0';j++)
    {
         if(t[j]=='~')
              putchar(' ');
         else if(t[j]=='.' && t[j+1]==' ')
              fputs(". ",stdout);
         else
              putchar(t[j]);
    }
    putchar('\n');

    if(i)
         strcpy(t,t+i);
    else
         t[0]='\0';

    indent=FALSE;

    return;
}

#ifdef __STDC__
void usage(void)
#else
usage()
#endif
{
    puts("usage: tex2asc [-w wrap_limit]");
    return;
}

#ifdef __STDC__
int main(int argc, char **argv)
#else
main(argc, argv)
int argc;
char **argv;
#endif
{
    char c, cc, s[ML], t[ML];
    int i, cr=0, t_index=0, chapter=1;
    int control=FALSE, print_line=FALSE, center=FALSE;

    while(*++argv!=NULL)
    {
         if((*argv)[0]!='-')
         {
              usage();
              return 1;
         }
         else
              while(*(++*argv)!='\0')
                   switch(**argv)
                   {
                        case 'w':
                             if(*++argv!=NULL)
                             {
                                  wrap_index = atoi(*argv);
                                  *argv+=(strlen(*argv)-1);
                                  break;
                             }
                        default:
                             usage();
                             return 1;
                   }
    }

    indent=TRUE;
    memset(t,'\0',ML-1);
    while((c=getchar())!=EOF)
    {
         if(c=='%')             /* TeX comments */
              while((c=getchar())!=EOF && c!='\n')
                   ;
         if(cr && c=='\n')
         {
              if(t_index)
              {
                   t[t_index]='\0';
                   while(t[0]!='\0')
                        force_out(t);
              }
              t_index=0;
              indent=TRUE;   /* paragraph beginning */
         }
         if(control && isspace(c))
              continue;
         else
              control=FALSE;
         if(strchr("${}",c))      /* ignore these characters: ${} */
              continue;
         if(c=='\n')
         {
              cr++;
              if(print_line)
              {
                   cr=0;
                   t[t_index]='\0';
                   kilspaces(t);
                   if(center && wrap_index > strlen(t))
                        for(i=0;i<(wrap_index-strlen(t))/2;i++)
                             putchar(' ');

                   for(i=0;t[i]!='\0';i++)
                        if(t[i]=='~')
                             putchar(' ');
                        else
                             putchar(t[i]);
                   putchar('\n');

                   t_index = 0;
                   indent=FALSE;
                   print_line = FALSE;
                   center = FALSE;
                   memset(t,'\0',ML);

                   continue;
              }
              else
                   c=' ';
         }
         else
              cr=0;

         if(c!='\\')
              t[t_index++]=c;
         else
         {
           control_code:
              control=TRUE;
              i=0;
              while((c=getchar())!=EOF
                   && !strchr("{}\\",c)
                   && !isspace(c))
              {
                   s[i++]=c;
                   if(!isalnum(c))
                        break;
              }
              s[i]='\0';
              cc=c;
              if(streq(s,"-") || streq(s,"\""))
                   ;         /* ignore */
              else if(streq(s,"%"))
                   t[t_index++]='%';
              else if(streq(s,"bf"))
                   ;
              else if(streq(s,"bigskip"))
              {
                   t[t_index]='\0';
                   while(t[0]!='\0')
                        force_out(t);
                   putchar('\n');
                   t_index = 0;
              }
              else if(streq(s,"centerline"))
              {
                   center++;
                   print_line++;
              }
              else if(streq(s,"chap"))
              {
                   sprintf(t+t_index," [%d] ",chapter++);
                   if(chapter >= 100)
                        t_index+= 2;
                   else if(chapter >= 10)
                        t_index += 1;
                   t_index += strlen(" [1] ");
              }
              else if(streq(s,"dag"))
                   t[t_index++]='%';
              else if(streq(s,"end"))
                   ;
              else if(streq(s,"hbox"))
                   ;
              else if(streq(s,"input"))
                   while((c=getchar())!='\n')
                        ;
              else if(streq(s,"langle"))
                   t[t_index++]='<';
              else if(streq(s,"line"))
                   print_line++;
              else if(streq(s,"linline"))
              {
                   print_line++;
                   indent++;
              }
              else if(streq(s,"lline"))
                   print_line++;
              else if(streq(s,"narrower"))
                   ;
              else if(streq(s,"noindent"))
                   indent=FALSE;
              else if(streq(s,"poetrysize"))
                   wrap_index=50;
              else if(streq(s,"raggedbottom"))
                   ;
              else if(streq(s,"rangle"))
                   t[t_index++]='>';
              else if(streq(s,"sc"))
                   ;
              else if(streq(s,"sec"))
                   ;
              else if(streq(s,"vbox"))
                   ;
              else if(streq(s,"vfill"))
                   ;
              if((c=cc)=='\\')
                   goto control_code;
         }
         if( !print_line && isspace(t[t_index-1]) && t_index >
                                                 wrap_index+20 )
         {
              t[t_index]='\0';
              force_out(t);
              t_index = strlen(t);
         }
    }
    return 0;
}