{Number: 19}
{Tasks: 1,2}

Program Table_formater;

Uses Dos,Crt;

const
     max=80;                    { Default length of the line.}

type
    rec=record
              f,sf:byte;        {function: 0 - TD,1 - TH,2 - Align_r
                                           3 - Align_l,4 - Align_c
                                 spec_fun: 1 - Rowspan,2-Colspan}
              t:string[80];     { Text}
        end;
    wiersz=array[1..10] of rec; {Data of rows}


var
   g,m,s2,ss:word;
   f_in,f_out:text;
   s,s1:string;
   len,x,c,tc,n,li:byte;
   w:word;
   spec_r,spec_c:boolean;
   poz:array[1..80] of byte;
   tab:array[1..50] of wiersz;
   tcell:array[1..50] of byte;

Procedure Open_files(n:byte);
Begin
     assign(f_in,paramstr(n));
     reset(f_in);
     assign(f_out,paramstr(n+1));
     rewrite(f_out)
End;

Procedure Func;
var
   f:string;
   e:byte;
Begin
     inc(x);
     repeat
           f:='';
           repeat
                 if (s[x]<>#32) then f:=f+s[x];
                 inc(x)
           until (s[x]=#32)or(s[x]='>');
           if f='TD' then tab[tc][n].f:=0
           else
           if f='TH' then tab[tc][n].f:=1
           else
           if f='ALIGN=RIGHT' then tab[tc][n].f:=2
           else
           if f='ALIGN=LEFT' then tab[tc][n].f:=3
           else
           if f='ALIGN=CENTER' then tab[tc][n].f:=4
           else
           if (f[1]='R')and(f[8]='=') then
           Begin
           End
           else
           if (f[1]='C')and(f[8]='=') then
           Begin
           End
     until s[x]='>'
End;

{ '<' - &lt, '>' - &gt, '&' -&amp }
Procedure s_char;
Begin
     if s[x+1]='l' then
     Begin
          tab[tc][n].t:=tab[tc][n].t+'<';
          x:=x+2
     End
     else
     if s[x+1]='g' then
     Begin
          tab[tc][n].t:=tab[tc][n].t+'>';
          x:=x+2
     End
     else
     Begin
          tab[tc][n].t:=tab[tc][n].t+'&';
          x:=x+3
     End
End;

{ Read text. }
Procedure R_txt;
Begin
     if tab[tc][n].t<>'' then
     repeat
           inc(n)
     until tab[tc][n].t='';
     tab[tc][n].t:=' ';
     repeat
           if s[x]='&' then s_char
           else

           { spaces reducing}

           if (s[x]=#10)or(s[x]=#13)or(s[x]=#9)or(s[x]=#32) then
           Begin
                repeat
                      inc(x)
                until (s[x]<>#10)and(s[x]<>#13)and(s[x]<>#9)and(s[x]<>#32)
                      or(s[x]='&');
                if s[x]='&' then
                Begin
                     tab[tc][n].t:=tab[tc][n].t+' ';
                     s_char
                End
                else
                if s[x]<>'<' then tab[tc][n].t:=tab[tc][n].t+' '+s[x]
           End
           else tab[tc][n].t:=tab[tc][n].t+s[x];
           inc(x)
     until (x=length(s)+1)or(s[x]='<');
     tab[tc][n].t:=tab[tc][n].t+' ';
     dec(x);
     inc(n)
End;

{Drawing a horiz. line}
Procedure Line(p:char;d:byte;k:char;b:boolean);
Begin
     if p<>'@' then write(f_out,p);
     for d:=d downto 1 do write(f_out,'-');
     write(f_out,k);
     if b=true then writeln(f_out)
End;

Procedure Center(s:string;le:byte);
var
   a,b:byte;
Begin
     a:=le div 2;
     a:=a-length(s) div 2;
     if a>0 then
        for b:=1 to a do write(f_out,' ');
     write(f_out,s);
     for b:=le-(a+length(s)) downto 1 do write(f_out,' ')
End;

Procedure A_right(s:string;le:byte);
var
   a:byte;
Begin
     for a:=1 to le-length(s)do write(f_out,' ');
     write(f_out,s)
End;

Procedure A_left(s:string;le:Byte);
var
   a:byte;
Begin
     write(f_out,s);
     for a:=1 to le-length(s) do write(f_out,' ')
End;

{ Write a row of table }
Procedure Wier(l:byte);
var
   r,r_cnt:byte;
Begin
     r:=1;
     repeat
           write(f_out,'|');
           if tab[l][r].f=0 then
           Begin
                write(f_out,tab[l][r].t);
                for li:=1 to poz[r]-length(tab[l][r].t) do write(f_out,' ')
           End
           else
           if tab[l][r].f=1 then center(tab[l][r].t,poz[r])
           else
           if tab[l][r].f=2 then a_right(tab[l][r].t,poz[r])
           else
           if tab[l][r].f=3 then a_left(tab[l][r].t,poz[r])
           else
           if tab[l][r].f=4 then center(tab[l][r].t,poz[r]);
           inc(r)
     until tab[l][r].t='';
     writeln(f_out,'|')
End;

Procedure Build_table;
var
   y,z,m,dl,k:byte;
Begin
     m:=0;
     for y:=1 to tc do
     Begin
          k:=1;
          repeat
                if poz[k]<length(tab[y][k].t) then poz[k]:=length(tab[y][k].t);
                inc(k)
          until tab[y][k].t='';
     End;
     dec(k);
     m:=k-1;
     for k:=k downto 1 do m:=m+poz[k];

     {m - max. line length}

     if m>len then
     Begin
          writeln;
          writeln('Error: Table is too long to fit line.');
          Close(f_out);
          Close(f_in);
          Halt
     End;

     line('+',m,'+',true);
     for y:=1 to tc do
     Begin
          wier(y);
          li:=1;
          if y<tc then
          Begin
               write(f_out,'|');
               repeat
                     if (poz[li]>0)and(poz[li+1]>0) then
                        line('@',poz[li],'+',false)
                     else
                     if poz[li+1]=0 then line('@',poz[li],'|',true);
                     inc(li)
               until poz[li]=0
          End
     End;
     line('+',m,'+',true);
End;

Procedure Read_tbl;
var
   zn:char;
Begin
     repeat
           c:=5;
           readln(f_in,s);
           x:=5;
           n:=1;
           repeat
                 if s[x]='<' then func
                 else r_txt;
                 inc(x)
           until x>length(s);
           inc(tc)
     until eof(f_in);
     dec(tc);
     build_table
End;

{****************************** START ***************************************}
Begin
     len:=max;
     tc:=1;
     s:=paramstr(1);
     if s[1]='-' then
     Begin
          s1:='';
          for x:=2 to length(s) do s1:=s1+s[x];
          val(s1,len,w);
          Open_files(2)
     End
     else Open_files(1);
     Read_tbl;
     Close(f_out);
     Close(f_in)
End.
{*************************** END OF PROGRAM *********************************}