%{
#include <stdio.h>

FILE *out;
char outname[32]="anon";
int use_stdout= 1;
int part=0;

void init_html (void)
{char name [32];

  if (use_stdout && part==0)
    out= stdout;
  else
  {
    if (part)
      sprintf(name, "%s_%d.html", outname, part);
    else
      sprintf(name, "%s.html", outname);
    out=fopen(name,"w");
  }
  fprintf(out,"<!DOCTYPE HTML SYSTEM \"html.dtd\">\n");
  fprintf(out,"%cHTML><HEAD>%cTITLE>WARNING: AUTOMATICALLY CONVERTED FROM ROFF</TITLE></HEAD><BODY>\n",'<','<');
}

void end_html (void)
{
  fprintf(out,"</BODY></HTML>\n");
  fclose(out);
}

void do_break (char yytext[])	/* yytext = [ UPN|-]+\n */
{int done= 0;

  while (!done)
  {
    switch (yytext[0])
    {
    case 'U':
	fprintf(out,"<A HREF=%s.html>UP</A>\n", outname);
	break;
    case 'P':
	if (part-1)
	  fprintf(out,"<A HREF=%s_%d.html>PREVIOUS</A>\n", outname, part-1);
	else
	  fprintf(out,"<A HREF=%s.html>PREVIOUS</A>\n", outname);
	break;
    case 'N':
	fprintf(out,"<A HREF=%s_%d.html>NEXT</A>\n", outname, part+1);
	break;
    case '-':
	fprintf(out,"<HR>\n");
	break;
    case '|':
	end_html();
	part++;
	init_html();
	break;
    case ' ':
	break;
    case '\n':
    default:
	done= 1;
    }
    yytext++;
  }
}

enum font {R, I, B};
int font= R;

char *at_eoln= NULL;

void eoln (char *s)
{
  if (at_eoln)
  {
    fprintf(out,"%s", at_eoln);
    at_eoln= NULL;
  }
  else if (s)
    fprintf(out,"%s", s);
}

%}

%s PRE TAB EQ SKIP SKIPTOEOLN

%%

<SKIPTOEOLN>.*\n		{BEGIN (INITIAL);}

<INITIAL>^\.de.*\n		{BEGIN (SKIP);}
<SKIP>^\.\.\n			{BEGIN (INITIAL);}
<SKIP>.*\n			;

<INITIAL>^\.nf			{fprintf(out,"<PRE>"); BEGIN (PRE);}
<INITIAL>^\.DS.*$		{fprintf(out,"<PRE>"); BEGIN (PRE);}
<PRE>^\.fi			{fprintf(out,"</PRE>"); BEGIN (INITIAL);}
<PRE>^\.DE			{fprintf(out,"</PRE>"); BEGIN (INITIAL);}

<INITIAL>^\.TS\n		{fprintf(out,"<PRE>"); BEGIN (TAB);}
<TAB>^.*\.\n			{BEGIN (PRE);}
<TAB>^.*\n			;
<PRE>^\.T&\n			{BEGIN (TAB);}
<PRE>^\.TE\n			{fprintf(out,"</PRE>"); BEGIN (INITIAL);}

\\\(ua				{fprintf(out,"^");}
\\\(bu				{fprintf(out,"*");}
\\\(dg				{fprintf(out,"+");}
\\\(sc				{fprintf(out,"$");}
\\\(bv				{fprintf(out,"|");}
\\\(mi				{fprintf(out,"-");}
\\\(em				{fprintf(out,"-");}
\\\(da				{fprintf(out,"v");}
\\\(\*\*			{fprintf(out,"*");}
\\\(fm				{fprintf(out,"'");}
\\e				{fprintf(out,"\\");}
\\0				{fprintf(out," ");}
\\&				;
\\f[0-9]+			;
\\f\(..				;
\\s[-+]?[0-9]+			;
\\\|				;
\\\*\(\[\.			{fprintf(out,"[");}
\\\*\(\.\]			{fprintf(out,"]");}

\\fB$				{fprintf(out,"<P><STRONG>"); font= B;}
\\fB				{fprintf(out,"<STRONG>"); font= B;}
^\.B\n				{fprintf(out,"<STRONG>\n"); font= B;}
^\.ft\ B			{fprintf(out,"<STRONG>\n"); font= B;}
\\fI$				{fprintf(out,"<P><EM>"); font= I;}
\\fI				{fprintf(out,"<EM>"); font= I;}
^\.I\n				{fprintf(out,"<EM>"); font= I;}
^\.ft\ I			{fprintf(out,"<EM>"); font= I;}

^".I "				{char *s="</EM>\n"; at_eoln= s; fprintf(out,"<EM>");}
^".B "				{char *s="</STRONG>\n"; at_eoln= s;
				fprintf(out,"<STRONG>");}
^".ul"\n			{char *s="</STRONG>\n"; at_eoln= s;
				fprintf(out,"<STRONG>");}

\\fP$|\\fR$			{if (font==B) fprintf(out,"</STRONG><P>");
				else if (font==I) fprintf(out,"</EM><P>");
				font= R;}
\\fP|\\fR			{if (font==B) fprintf(out,"</STRONG>");
				else if (font==I) fprintf(out,"</EM>");
				font= R;}
^\.R\n|^\.P\n			{if (font==B) fprintf(out,"</STRONG>");
				else if (font==I) fprintf(out,"</EM>");
				font= R;}
^\.ft\ R|^\.ft\ P		{if (font==B) fprintf(out,"</STRONG>");
				else if (font==I) fprintf(out,"</EM>");
				font= R;}

\\.				{fprintf(out,"%s", yytext+1);}
\\\(..				{fprintf(out,"%s", yytext+2);}
\\\*\.				;
\\\*\(..			;

\<				{fprintf(out,"&lt;");}
\>				{fprintf(out,"&gt;");}
\&				{fprintf(out,"&amp;");}
\"				{fprintf(out,"&quot;");}

<PRE>.				{/* ^.*\n */ fprintf(out,"%s", yytext);}

<INITIAL>^\.\\\"HTML-BREAK[ UPN|-]+\n	{do_break(yytext+13);}

<INITIAL>^\.\\\"HTML-OFF\n	{BEGIN (EQ);}
<INITIAL>^\.\\\"HTML.*\n	{fprintf(out,"%s", yytext+7);}
<INITIAL>^\.EQ\n		{BEGIN (EQ);}
<EQ>^\.EN\n			{BEGIN (INITIAL);}
<EQ>^\.\\\"HTML-ON\n		{BEGIN (INITIAL);}
<EQ>^.*\n			;
^\.\\\".*\n			;

<INITIAL>^".ds CH \\fB\\s+2"	{char *s="</H1>\n"; at_eoln= s; fprintf(out,"<H1>");
				/*redundant & silly!*/}
<INITIAL>\\s0\\fP\n		{eoln(NULL);/*redundant & silly!*/}

<INITIAL>^".ds [F "		{char *s=".\n"; at_eoln= s; fprintf(out,"<P>");}
<INITIAL>^".ds [V "		{char *s=",\n"; at_eoln= s; fprintf(out,"vol. ");}
<INITIAL>^".ds [N "		{char *s=",\n"; at_eoln= s; fprintf(out,"no. ");}
<INITIAL>^".ds [P "		{char *s=",\n"; at_eoln= s; fprintf(out,"no. ");}
<INITIAL>^".ds [D "		{char *s=".\n"; at_eoln= s;}
<INITIAL>^".ds [".		{char *s=",\n"; at_eoln= s;}
<INITIAL>^".as [".\ \"		{char *s=",\n"; at_eoln= s;}
<INITIAL>^".]".*\n		;
<INITIAL>^".ds"			{BEGIN (SKIPTOEOLN);}

<INITIAL>^".nr".*\n		;
^".ta".*\n			;
<INITIAL>^\.TA			;
<INITIAL>^".2C".*\n		;

<INITIAL>^".bp"\n		{fprintf(out,"<BR>\n");}
<INITIAL>^".br"\n		{fprintf(out,"<BR>\n");}
<INITIAL>^" "			{fprintf(out,"<BR>\n ");}

<INITIAL>^(\.LP\n)+		{fprintf(out,"<P>\n");}

<INITIAL>^(\.PP\n)+		{fprintf(out,"<P>\n");}

<INITIAL>^\.IP.*\n		{int i= yyleng-2;
				while(isdigit(yytext[i])) {yytext[i]= 0; i--;}
	/* BUT WHAT IF THERE IS ONLY A NUMBER? */
				if (yytext[4]=='"')
				{ while(yytext[i]!='"') {yytext[i]= 0; i--;}
				  yytext[i]=0;
				  fprintf(out,"<P><STRONG>%s</STRONG>\n", yytext+5);
				}else
				  fprintf(out,"<P><STRONG>%s</STRONG>\n", yytext+4);
				}

<INITIAL>^\.TL\n		{char *s="</H1>\n"; at_eoln=s; fprintf(out,"<H1>");}
<INITIAL>^\.AU.*\n		{fprintf(out,"Authors:\n");}
<INITIAL>^\.SH\n\.nf\n		{fprintf(out,"<PRE>"); BEGIN (PRE);}
<INITIAL>^\.SH\n\.ce.*\n	{char *s="</H2>\n"; at_eoln=s; fprintf(out,"<H2>");}
<INITIAL>^\.SH\n		{char *s="</H2>\n"; at_eoln=s; fprintf(out,"<H2>");}
<INITIAL>^\.NH\ [1]\n		{char *s="</H2>\n"; at_eoln=s; fprintf(out,"<H2>");}
<INITIAL>^\.NH\ [2]\n		{char *s="</H3>\n"; at_eoln=s; fprintf(out,"<H3>");}
<INITIAL>^\.NH\ [3456]\n	{char *s="</H4>\n"; at_eoln=s; fprintf(out,"<H4>");}
<INITIAL>^\.NH\n		{char *s="</H2>\n"; at_eoln=s; fprintf(out,"<H2>");}
<INITIAL>^\.LG\n		;
<INITIAL>^\.SM\n		;

<INITIAL>^\n+			{eoln(NULL); fprintf(out,"<P>\n");}
\n				{eoln("\n");}
^\.sp.*\n			{fprintf(out,"<P>\n");}
<INITIAL>^\.SP.*\n		{fprintf(out,"<P>\n");}

<INITIAL>^\.RS			;
<INITIAL>^\.RE			;
<INITIAL>^\.KS			;
<INITIAL>^\.KE			;

<INITIAL>^\.ce.*\n		;

<INITIAL>^\.c\n			;
<INITIAL>^\.ns\n		;
<INITIAL>^\.ND			;
<INITIAL>^\.MH\n		;
<INITIAL>^\.RP\n		;
<INITIAL>^\.AI\n		;
<INITIAL>^\.AB\n		{fprintf(out,"<H2>Abstract</H2>\n");}
<INITIAL>^\.hc.*\n		;
<INITIAL>^\.bd.*\n		;
<INITIAL>^\.if.*\n		;
<INITIAL>^\.in.*\n		;
<INITIAL>^\.tr.*\n		;
<INITIAL>^\.SG.*\n		;
<INITIAL>^\.CS.*\n		;
<INITIAL>^\.OK\n		{fprintf(out,"<P>Keywords:\n");}

<INITIAL>^\.[A-Z]S.*		{fprintf(out,"<P><EM>\n");}
<INITIAL>^\.[A-Z]E.*		{fprintf(out,"</EM><P>\n");}

<INITIAL>^".BX "\".*\"$		{yytext[yyleng-1]=0; fprintf(out,"[%s]",yytext+5);}
<INITIAL>^\.BX.*$		{fprintf(out,"[%s]", yytext+3);}

.				{fprintf(out,"%s", yytext);}

%%

int yywrap() {return 1;}

int main (int argc, char *argv[])
{int ok= 1;

  if (argc>2)
    ok= 0;
  else if (argc==2)
  {
    if (argv[1][0]=='-' || strchr(argv[1],'.'))
      ok= 0;
    else
    {
      use_stdout= 0;
      strcpy(outname, argv[1]);
    }
  }
  if (!ok)
  {
    printf ("ms2html expects at most one parameter, a name.\n");
    printf ("This name should not start with a '-', or contain a '.'\n");
    return 0;
  }
  init_html();
  yy_flex_debug= 0;
  yylex();
  end_html();
  return 0;
}
