{$M 64384,0,655360}

{Soutezici cislo 15
Reseno 1..4}

{Program prochazi cely datovy soubor 2x. Prvne se zjistuji maximalni
velikosti jednotlivych sloupcu. Tyto hodnoty se ulozi do pole SIRKA.
(Uvazuji, ze muze byt maximalne 100 sloupcu - const MaxSloupcu.)
Potom se otestuje, zda se takto siroke sloupce vejdou do zadaneho N.
V druhem prubehu se postupne nacitaji a ukladaji hodnoty v polickach.
}

const maxsloupcu=100;
      aleft=1;
      aright=2;
      acenter=3;
      ahcenter=4;

type radka=record {Pouzito pro komunikaci mezi nacitanim a zobrazovanim a
                   kreslenim car}
             sloupcu:byte;
             text:array[1..MaxSloupcu] of string;
             sirka:array[1..MaxSloupcu] of byte;
             sirkap:array[1..maxsloupcu] of byte;
             vyskap:array[1..maxsloupcu] of byte;
             umysteni:array[1..maxsloupcu] of byte;
             typ:array[1..MaxSloupcu] of byte;
           end;

type dradka=record
              {Pouzito pro policka, ktere jsou vysi nez jedna radka. Tyto
              policka se pak ulozi do D:DRADKA a postupne se odecita
              umisteni (zbyvajici pocet radek do radky, ve ktere ma byt
              text napsan) a pokr (jestli policko pokracuje - nesmi byt
              preskrtnuto carou)}
              text:array[1..MAxSloupcu] of string;
              sirka:array[1..maxsloupcu] of byte;
              sirkap:array[1..maxsloupcu] of byte;
              typ:array[1..MaxSloupcu] of byte;
              pokr:array[1..MaxSloupcu] of byte;
              umysteni:array[1..maxsloupcu] of byte;
            end;

var Fvs,Fvy:text;
    delka,param:byte;
    s:string;
    i1,i2:integer;
    sirka:array[1..MaxSloupcu]of byte;
    radek,sloupcu,sloupec:word;
    d:dradka;


function velke(s:string):string;
{Zveci zadany retezec znaku (na velka pismena)}
var i:byte;
begin
  for i:=1 to length(s) do s[i]:=upcase(s[i]);
  velke:=s;
end;

procedure ctiradku(s:String;var r:radka);
{Podprogram, ktery ze zadaneho retezce S vytvori RADKA - informace uz
rozdelene na policka, sirku, stredeni,...}
var s1,s2,s3:string;
    poz,sloupec:byte;
    i,i1:integer;
    byls:boolean;

begin
  poz:=1;
  for sloupec:=1 to maxsloupcu do begin
    {Nulovani radky}
    r.text[sloupec]:='';
    r.sirka[sloupec]:=0;
    r.sirkap[sloupec]:=1;
    r.typ[sloupec]:=0;
    r.umysteni[sloupec]:=0;
    r.vyskap[sloupec]:=0;
  end;
  sloupec:=0;
  byls:=false;
  while poz<=length(s) do begin
    {postupne se prochazi celym S- nactena radka ze souboru}
    if d.pokr[sloupec+1]>0 then begin
      {Pokud na tomto sloupci je nejake pokracujici policko}
      inc(sloupec);
      if d.umysteni[sloupec]=0 then begin
        {Pokud uz je ted spravna pozice na umisteni textu pokrac. policka}
        r.text[sloupec]:=d.text[sloupec];
        r.sirka[sloupec]:=d.sirka[sloupec];
      end;
      r.typ[sloupec]:=d.typ[sloupec];
      r.vyskap[sloupec]:=d.pokr[sloupec]-1;
      r.sirkap[sloupec]:=d.sirkap[sloupec];
      d.pokr[sloupec]:=d.pokr[sloupec]-1;
      {Odecet promennych - zbyvajici delka policka,...}
      if d.umysteni[sloupec]=0 then d.umysteni[sloupec]:=255;
      if (d.umysteni[sloupec]>0) and (d.umysteni[sloupec]<255) then dec(d.umysteni[sloupec]);
    end;
    if s[poz]='<' then begin
      {Instrukce <..>}
      inc(poz);
      s1:='';
      while (length(s)>=poz) and (s[poz]<>'>') do begin
        s1:=s1+s[poz];
        inc(poz);
      end;
      inc(poz);
      s1:=velke(s1);
      if s1='TR' then;
      if (length(s1)>1) and (s1[1]='T') and ((s1[2]='H') or (s1[2]='D')) then begin
        byls:=true;
        inc(sloupec);
        if s1[2]='H' then r.typ[sloupec]:=ahcenter+acenter;
        {Pokud je TH, pak nastavi stredeni vertikalni i horizontalni}
        delete(s1,1,2);
        {Instrukce muze pokracovat stredenim,...  nacte zbytek instrukce
        do s2 a s3}
        while length(s1)>0 do begin
          while s1[1]=' ' do delete(s1,1,1);
          s2:='';
          while (length(s1)>0) and (s1[1]<>'=') do begin
            s2:=s2+s1[1];
            delete(s1,1,1);
          end;
          delete(s1,1,1);
          s3:='';
          while (length(s1)>0) and (s1[1]<>' ') do begin
            s3:=s3+s1[1];
            delete(s1,1,1);
          end;
          if s2='ALIGN' then begin
            if s3='LEFT' then r.typ[sloupec]:=r.typ[sloupec] and 252 +1;
            if s3='RIGHT' then r.typ[sloupec]:=r.typ[sloupec] and 252 +2;
            if s3='CENTER' then r.typ[sloupec]:=r.typ[sloupec]and 252 +3;
            {stredeni vodorovne}
          end;
          if s2='COLSPAN' then begin
            val(s3,i,i1);
            if i1=0 then begin
              r.sirkap[sloupec]:=i;
            end;
          end;
          if s2='ROWSPAN' then begin
            {Propojeni policek na vysku - nastavi se tady vyska
            policka v RADCE a potom dale v programu se "pretahnou" vlastnosti
            a text do promene D:DRADKA - urcena pro prubezna policka}
            val(s3,i,i1);
            if i1=0 then begin
              r.vyskap[sloupec]:=i;
              if (r.typ[sloupec]) and 4 =4 then r.umysteni[sloupec]:=i-1
              else r.umysteni[sloupec]:=0;
            end;
          end;
        end;
      end;
    end
    else if (s[poz]<>'<') and (s[poz]<>'>') then begin
      {Text a hodnoty do policka}
      s1:='';
      while (poz<=length(s)) and (s[poz]<>'<') do begin
        {Znaky <,>,&}
        if s[poz]='&' then begin
          if velke(s[poz+1]+s[poz+2]+s[poz+3])='LT;' then begin
            inc(poz,3);
            s1:=s1+'<';
          end;
          if velke(s[poz+1]+s[poz+2]+s[poz+3])='GT;' then begin
            inc(poz,3);
            s1:=s1+'>';
          end;
          if velke(s[poz+1]+s[poz+2]+s[poz+3]+s[poz+4])='AMP;' then begin
            inc(poz,4);
            s1:=s1+'&';
          end;
        end
        else begin
          {Muze byt jenom jedna mezera, pokud je jich vice, neukladaji se}
          if s[poz]=chr(9) then s[poz]:=' ';
          if (s[poz]=' ') and (s1[length(s1)]=' ') then
          else s1:=s1+s[poz];
        end;
        inc(poz);
      end;
      if byls then begin
        while (s1[1]=' ') and (length(s1)>0) do delete(s1,1,1);
        while (length(s1)>0) and (s1[length(s1)]=' ') do delete(s1,length(s1),1);
        r.text[sloupec]:=s1;
        r.sirka[sloupec]:=length(s1);
      end;
      if (r.vyskap[sloupec]>1) and (d.pokr[sloupec]=0) then begin
        {Ulozeni prubeznych policek}
        d.text[sloupec]:=r.text[sloupec];
        d.sirka[sloupec]:=r.sirka[sloupec];
        r.text[sloupec]:='';
        r.sirka[sloupec]:=0;
        d.typ[sloupec]:=r.typ[sloupec];
        d.pokr[sloupec]:=r.vyskap[sloupec]-1;
        d.sirkap[sloupec]:=r.sirkap[sloupec];
        d.umysteni[sloupec]:=r.umysteni[sloupec]-1;
      end;
    end
    else inc(poz);
  end;
  r.sloupcu:=sloupec;
end;

function csirka:word;
{Vypocet celkove sirky}
var b:byte;
    delka:word;

begin
  delka:=1;
  for b:=1 to sloupcu do delka:=delka+sirka[b]+3;
  csirka:=delka;
end;

procedure maxsirka;
{Maximalni sirky jednotlivych policek -> SIRKY}
var i,i1:integer;
    s:string;
    r:radka;
    psloupec:word;

begin
  radek:=0;
  sloupcu:=0;
  for i:=1 to MaxSloupcu do sirka[i]:=0;
  while not eof(fvs) do begin
    inc(radek);
    readln(fvs,s);
    ctiradku(s,r);

    psloupec:=1;
    for i1:=1 to r.sloupcu do begin
      if r.sirkap[i1]=1 then
      if r.sirka[i1]>sirka[psloupec] then sirka[psloupec]:=r.sirka[i1];
      psloupec:=psloupec+r.sirkap[i1];
    end;
    if r.sloupcu>sloupcu then sloupcu:=r.sloupcu;
  end;
end;


procedure zapis;
{Provede zapsani tabulky do souboru.}
var r:radka;
    pozr,sirkap,psloupec:word;
    b,b1,b2:byte;
    s,s2,s3,s4,s5:string;

procedure cara1;
{Spodni a horni cara tabuky}
var s:string;
    b:byte;
    delka:word;

begin
  delka:=1;
  for b:=1 to sloupcu do delka:=delka+sirka[b]+3;
  s:='+';
  for b:=1 to delka-2 do s:=s+'-';
  s:=s+'+';
  writeln(fvy,s);
end;

procedure cara2;
{vodorovne cary uvnitr tabulky - testuje se jestli neni prubezne policko}
var s,s2,s3,s4,s5:string;
    b,b1,b2:byte;
    delka,sirkap:word;

begin
  s:='|';
  psloupec:=1;
  for b:=1 to r.sloupcu do begin
    sirkap:=0;
    for b1:=psloupec to psloupec+r.sirkap[b]-1 do sirkap:=sirkap+sirka[b1];
    psloupec:=psloupec+r.sirkap[b];
    sirkap:=sirkap+3*(r.sirkap[b]-1);

    s2:='';
    {Rozhodovani, zda cara, mezery nebo text}
    if r.vyskap[b]=0 then for b2:=1 to sirkap+2 do s2:=s2+'-'
    else if d.umysteni[b]<>0 then for b2:=1 to sirkap+2 do s2:=s2+' '
    else begin
      {Do prubezneho policka patri stredeny text}
      s3:=''; s4:=''; s5:='';
      for b2:=d.sirka[b] to sirkap do s3:=s3+' ';
      for b2:=d.sirka[b] div 2 to sirkap div 2 do s4:=s4+' ';
      for b2:=d.sirka[b]+length(s4) to sirkap do s5:=s5+' ';
      if (d.typ[b] and 3)<=1 then s2:=s2+' '+d.text[b]+s3;
      if (d.typ[b] and 3)=2 then s2:=s2+s3+d.text[b]+' ';
      if (d.typ[b] and 3)=3 then s2:=s2+s4+d.text[b]+s5+' ';
    end;
    if d.umysteni[b]=0 then d.umysteni[b]:=255;
    if d.umysteni[b]>0 then dec(d.umysteni[b]);

    s:=s+s2+'+';
  end;
  delete(s,length(s),1);
  s:=s+'|';
  writeln(fvy,s);
end;

begin
  {Psani radek, ktere jsou mezi carami - vlastni policka}
  cara1;
  for pozr:=1 to radek do begin
    readln(fvs,s);
    ctiradku(s,r);
    s2:='|';
    psloupec:=1;
    for b:=1 to r.sloupcu do begin
      sirkap:=0;
      for b1:=psloupec to psloupec+r.sirkap[b]-1 do sirkap:=sirkap+sirka[b1];
      psloupec:=psloupec+r.sirkap[b];
      sirkap:=sirkap+3*(r.sirkap[b]-1);

      {Podle stredeni se pripravuji mezery vlevo, vpravo a na obe strany}
      s3:=''; s4:=''; s5:='';
      for b2:=r.sirka[b] to sirkap do s3:=s3+' ';
      for b2:=r.sirka[b] div 2 to sirkap div 2 do s4:=s4+' ';
      for b2:=r.sirka[b]+length(s4) to sirkap do s5:=s5+' ';
      if (r.typ[b] and 3)<=1 then s2:=s2+' '+r.text[b]+s3;
      if (r.typ[b] and 3)=2 then s2:=s2+s3+r.text[b]+' ';
      if (r.typ[b] and 3)=3 then s2:=s2+s4+r.text[b]+s5+' ';

      s2:=s2+'|';
    end;
    writeln(fvy,s2);
    if (pozr<>radek) then cara2;
  end;
  cara1;
end;



begin
  i1:=0;
  param:=1;
  s:=paramstr(1);
  delka:=80; {Standardni delka radky, neni-li uvedeno jinak}
  if s[1]='-' then begin
    delete(s,1,1);
    val(s,delka,i1);
    inc(param); {Param - pozice v Paramstr s jeste nevyuzitym parametrem}
  end;
  if (paramcount<2) or (i1<>0) then writeln('Spoustet 15tab -n table_description formatted_table')
  else begin
    {Jmena vstupu a vystupu}
    assign(fvs,paramstr(param));
    reset(fvs);
    assign(fvy,paramstr(param+1));
    rewrite(fvy);
    for sloupec:=1 to maxsloupcu do begin
      d.text[sloupec]:='';
      d.sirka[sloupec]:=0;
      d.sirkap[sloupec]:=1;
      d.typ[sloupec]:=0;
      d.umysteni[sloupec]:=0;
      d.pokr[sloupec]:=0;
    end;


    maxsirka;  {Zjisteni sirky jednotlivych policek}

    for sloupec:=1 to maxsloupcu do begin
      d.text[sloupec]:='';
      d.sirka[sloupec]:=0;
      d.sirkap[sloupec]:=1;
      d.typ[sloupec]:=0;
      d.umysteni[sloupec]:=0;
      d.pokr[sloupec]:=0;
    end;
    close(fvs);
    reset(fvs);

    if csirka>delka then writeln('Error: Table is too long to fit line')
      {Nevejde se do zadane sirky}
    else zapis;  {Vejde se a provede se ulozeni tabulky}
    close(fvs);
    close(fvy);
  end;
end.