program rtflatex (input, output);  (* version 2.15 *)

uses dos;

{$I rtflatex.h}
{$I rtflatex.cmn}


{---------------------------------------------------------------------------}
{ sets active_RTFf of current bracelvl at the alpha value recorded with kkk
as \F<number> in \fonttbl declaration }

procedure set_active_RTFf(kkk : integer);
var
  k : integer;
begin
  for k:=1 to num_word_fonts do
    if word_font_num[k]=kkk then
      begin sign_str(kkk,works);
        println_msg(2,'RTF font No. '+works+' of type '+word_fonts[k]+
          ' "'+equiv_fonts[k]+'"');
        add_to_bfsl(equiv_fonts[k]); ensure_sizebfsl;
        active_RTFf[bracelvl]:=word_fonts[k]; exit;
      end
  ; {END/IF + END FOR}
  if (lvlcode[bracelvl] <> 6) then
    begin print_line(2); sign_str(num_word_fonts,works);
      println_msg(2,'num_word_fonts='+works);
      for k:=1 to num_word_fonts do
        begin sign_str(word_font_num[k],works);
          println_msg(2,'     '+works+' --> "'+word_fonts[k]+'"');
        end;
      sign_str(kkk,works); print_msg(2,'RTF font No. '+works);
      sign_str(lvlcode[bracelvl],works);
      sign_str(bracelvl,worksa);
      println_msg(2,' font of type unknown, lvlcode['+worksa+']='+works);
      sign_str(lvlcode[bracelvl-1],works);
      sign_str(bracelvl-1,worksa);
      println_msg(2,' font of type unknown, lvlcode['+worksa+']='+works);
    end
  ; {END IF lvlcode}
  active_RTFf[bracelvl]:='';
end;

{ ------------------------------------------------------------------------- }
{ closing a \sum(...) ... possibly at a ) found !!!!!}

procedure close_sum;
begin
  close_brace; close_math;
end;

{ ------------------------------------------------------------------------- }
{ closing a \sum(...) ... possibly at a closing brace if no ) found !!!!!}

procedure close_sum_emergency(kode : string);
var
  k : integer;
begin
  sign_str(input_line_number,works);
  println_msg(1,'Emergency close of \|su or \|i due to }'+kode+' at inp.line '
    +works);
  sign_str(ord(next_rtf[1]),works);
  print_msg(1,'pattern : "'+kar+next_rtf[1]+'" '+works);
  print_line(1); writeln('kinp=',kinp, ' prev_kinp=',prev_kinp);
  for k:=1 to prev_kinp do print_msg(1,prev_line[k]);  println_msg(1,' ');
  for k:=1 to kinp do print_msg(1,inpline[k]);  println_msg(1,' ');
  outstg('\emergcA '); close_sum;
end;


{ --------------------------------------------------------------------------}
procedure perform_RTFcell;

begin
      if (verbose>0) then
        writeln('(found)',inkeyw,'[',lvlcode[bracelvl],',',
        tab_nb_ands[bracelvl],',',bracelvl,']');
      if (lvlcode[bracelvl]=15) then
        begin
          output_real_line;
          (* count the number of ampersands in the tabular line *)
          tab_nb_ands[bracelvl]:=tab_nb_ands[bracelvl]+1;
          if (tab_nb_ands[bracelvl] < tab_nb_cellx[bracelvl]) then
            begin
              outstg(' & ');
              if (verbose>1) then
                writeln('(after &)',inkeyw,'[',lvlcode[bracelvl],',',
                bracelvl,']');
            end
          else
            begin outstg('\\'); if clbrdrb then outkeyw('hline ');
              if (verbose>1) then
                writeln('(after &->\\)',inkeyw,'[',lvlcode[bracelvl],',',
                bracelvl,']');
            end
          ;
        end
      else
        begin
          if (verbose>2) then
            writeln(inkeyw,'[',lvlcode[bracelvl],',',bracelvl,']');
          outkeyw('relax'); output_line; (* next line to ensure possible removal *)
          outkeyw('RTFcell ');
        end
      ; {END IF lvlcode}

end;

{ --------------------------------------------------------------------------}
{ procedure to close center and flushright environments }

procedure close_envir;
var
  RTF_cell_removed : boolean;
begin
  envir_closed_ok:=FALSE;
  if center_flag[bracelvl]=2 then
    begin
      if no_space_conv then
      else output_size(spacingcode[bracelvl])
      ;
      outkrem('RTFcell '); RTF_cell_removed:=removed_OK;
      center_flag[bracelvl]:=0; end_env(1);
      if RTF_cell_removed then perform_RTFcell;
      output_line; envir_closed_ok:=TRUE; (* output_line; *)
    end
  else if flushright_flag[bracelvl]=2 then
    begin
      if no_space_conv then
      else output_size(spacingcode[bracelvl])
      ;
      outkrem('RTFcell '); RTF_cell_removed:=removed_OK;
      flushright_flag[bracelvl]:=0; end_env(2);
      if RTF_cell_removed then perform_RTFcell;
      output_line; envir_closed_ok:=TRUE; (* output_line; *)
    end
  ; {END IF center_flag}
end;

{ --------------------------------------------------------------------------}
(* procedure to perform RTFsb/RTFsa *)

procedure make_RTFsab (numval : integer);
begin
  if(numval > 300) then outkeyw('bigskip{}')
  else if(numval > 200) then outkeyw('medskip{}')
  else if(numval > 100) then outkeyw('smallskip{}')
  else if(numval > 0) then outkeyw('vspace 0.5\smallskipamount{}')
  else if(numval < 0) then
    begin sign_str(numval,works); println_msg(1,'neg. spacing, NUMVAL:='+works);
    end
  ; {END IF}
end;

{ --------------------------------------------------------------------------}
(* procedure to perform RTFpar (separate since it may be delayed after a } *)

procedure make_RTFpar (texcode : string);
var
  k, num_forced : integer;
  was_underl : boolean;
begin
  num_forced:=0;
  while math_mode[bracelvl]>1 do
    begin
      if lvlcode[bracelvl]=16 then outstg('\relax %%% ???')
      else outstg('}\relax %%% !!!')
      ; output_line;
      close_brace; num_forced:=num_forced+1;
    end
    ; close_math;
    if num_forced>0 then
      begin close_envir; output_size(spacingcode[bracelvl]);
        output_line; output_line; par_to_begin:=TRUE;
        num_indent:=0;
        if space_after<>0 then make_RTFsab(space_after); space_after:=0;
        sign_str(input_line_number,worksa); sign_str(bracelvl,works);
        println_msg(0,'input line '+worksa+', bracelvl='+works);
        sign_str(num_forced,works); println_msg(0,'num_forced='+works);
      end
    ; {END IF}

    was_underl:=underl_flag[bracelvl];
    outkrem(bfslcode[bracelvl]); if was_underl then outchr('}'); output_line;
    if no_space_conv then
    else output_size(spacingcode[bracelvl])
    ;
    close_envir;
    if(not (envir_closed_ok or no_space_conv)) then outkeyw('null ');
    outstg(texcode);
    if space_after<>0 then make_RTFsab(space_after); space_after:=0;
    par_to_begin:=TRUE; num_indent:=0;

    if was_underl then outkeyw('underbar{');

    for k:=1 to num_forced do
      begin outchr('{'); bracelvl:=bracelvl+1;
        math_mode[bracelvl]:=0; {do not open ??? }
      end
    ; {END DO}

    sign_str(bracelvl,works);
    if num_forced>0 then println_msg(0,'restored bracelvl='+works);
end;

{ --------------------------------------------------------------------------}
{ replace recent space with a ~ (before : ; ? ! in general }
procedure insert_tilde ( CHARAC : char );
begin
  if math_mode[bracelvl]=0 then
    begin outrem(' '); if removed_OK then outchr('~');
    end
  ; {END IF}
  begin_par; outchr(CHARAC); keyw:=0;
end;

{ --------------------------------------------------------------------------}
{ initiates "tabular" but does not reset parms to zero }
procedure perform_RTFtrow;

begin
  if (verbose>0) then
    writeln('(init row)',inkeyw,'[',lvlcode[bracelvl],',',
      bracelvl,']');
  open_brace; lvlcode[bracelvl]:=13;
  if (verbose>1) then
    writeln(inkeyw,'(after)[',lvlcode[bracelvl],',',bracelvl,']');
  tab_nb_ands[bracelvl]:=0;
end;


{ --------------------------------------------------------------------------}
procedure perform_RTFrow;

begin
  if (lvlcode[bracelvl]=15) then
    begin
      if (verbose>0) then
        writeln('\RTFrow[',lvlcode[bracelvl],',',tab_nb_cellx[bracelvl],
        ',',bracelvl,']');
      close_brace; outkeyw('end{tabular}\par ');
      tab_nb_cellx[bracelvl]:=tab_nb_cellx[bracelvl+1];
    end
  else 
    begin
      if (verbose>1) then
        writeln('\RTFrow[',lvlcode[bracelvl],',',bracelvl,']');
      output_real_line; outkeyw('RTFrow ');
    end
  ; {END IF lvlcode}      

end;


{ --------------------------------------------------------------------------}
procedure make_closing_brace;
var
  pict_byte : char;
  already_closed : boolean;
begin
  already_closed:=FALSE;
  while auto_close[bracelvl] do
    begin
      if (math_mode[bracelvl]=1) then outchr('$'); outchr('}'); close_brace;
    end
  ; {END WHILE auto_close}
 { check "}{" within \|I(...) and similar : then ignore pair }
  if (lvlcode[bracelvl]>=16) and (next_rtf[1]='{') then next_rtf[1]:=chr(0)
  else if (form_code[bracelvl]<>'') and (next_rtf[1]='{') then next_rtf[1]:=chr(0)
  else
    begin
{ special case of \|su(...) closing }
      if (lvlcode[bracelvl]=25) then close_sum
      else if (lvlcode[bracelvl]>=16) then close_sum_emergency('lvlc')
      ; {END IF}
      close_math;

      if(lvlcode[bracelvl]=4) then
{ this is footnote first and dummy RTF argument closing brace }

      else if(lvlcode[bracelvl]=5) then
{ this is \RTFpict closing brace }
        begin
          if (pict_left_hexa) then
{ look whether there is already one hexa digit stored}
            begin pict_last_hexa:=16*pict_last_hexa;
              pict_byte:=chr(pict_last_hexa); write(figurefile,pict_byte);
              pict_byte_number:=pict_byte_number+1;
              pict_last_hexa:=0; pict_left_hexa:=FALSE;
            end
          ; {END IF pict_left_hexa}

          close(figurefile);
          print_msg(1,'closed file '+figure_name); sign_str(pict_byte_number,works);
          println_msg(1,'('+works+' bytes)'); outchr(kar)
        end
      else if(lvlcode[bracelvl]=10) then
{ this is \RTFobject closing brace }
        begin
          println_msg(1,'closed dummy file '+figure_name);
          outchr(kar)
        end
{ if there was a \cell just before, put it outside the closing brace }
      else if last_is('\RTFcell ') then
        begin
          if (verbose>1) then
            writeln('closing}[',lvlcode[bracelvl],',',bracelvl,']');
          outkrem('RTFcell ');
          if (not removed_OK) then writeln('*** \RTFcell not removed before } ***');
          outchr(kar); close_brace; already_closed:=TRUE;
          if (verbose>0) then
            writeln('moved \RTFcell [',lvlcode[bracelvl],',',bracelvl,']');
          perform_RTFcell;
        end
{ if there was a \row just before, put it outside the closing brace }
      else if last_is('\RTFrow ') then
        begin
          if (verbose>1) then
            writeln('closing}[',lvlcode[bracelvl],',',bracelvl,']');
          outkrem('RTFrow ');
          outchr(kar); close_brace; already_closed:=TRUE;
          if (verbose>0) then
            writeln('moved \RTFrow [',lvlcode[bracelvl],',',bracelvl,']');
          perform_RTFrow;
        end
      else   { this is an ordinary closing brace }
        begin
{ if there was a \par just before, put it outside the closing brace }
          if last_is('\null \par ') then
            begin
              outkrem('null \par '); outchr(kar);
              if no_space_conv then
                outkeyw('par ')
              else
                outkeyw('null \par ')
              ;
            end
          else if last_is('\par ') then
            begin
              outkrem('par '); outchr(kar);
              outkeyw('par ');
            end
          else outchr(kar)
          ; {ENF IF}

          if (form_code[bracelvl]<>'') then
            if (form_code[bracelvl-1]='') then
              form_code[bracelvl-1]:=form_code[bracelvl]
            else
              close_sum_emergency('form')
            ; {END IF}
          ; {END IF}
        end
      ; {END IF}
      if (not already_closed) then close_brace;
    end;
  ; {END IF}
end;
{ --------------------------------------------------------------------------}
{ special output of single characters due to \TeX special codings }

procedure special_TeX_chars;
begin begin_par;
  if (kar='$') then outstg('\$')
  else if (kar='_') then outstg('\_')
  else if (kar='#') then outstg('\#')
  else if ((kar='>') or (kar='<')) and (math_mode[bracelvl]=0) then
    out_math(kar)
  else if (kar='&') then outstg('\&')
  else if (kar='%') then outstg('\%')
  else if (kar='^') then outstg('\^{ }')
  else if (kar='~') then out_math('\sim{}')
  else outchr(kar)
  ; {END IF}
end;

{ --------------------------------------------------------------------------}
{ **************** Beginning of RTF decoding procedures ******************* }
{---------------------------------------------------------------------------}
{ treats a character when KEYW is 0 }
{ no keyword decoding presently active }

procedure keyw_is_0;
var
  i,j,k,hexa_digit : integer;
  pict_byte: char;
  open_kar, RTFform, acc_converted : string24;
begin
  if(CAT=0) then { this is a backslash }
    begin
      if(lvlcode[bracelvl]=3) then
{ ignore after \footnote until opening brace }
      else if(lvlcode[bracelvl]=4) then
{ ignore after \footnote { (first brace pair after) }
      else if(lvlcode[bracelvl]=9) then

      else
        begin keyw:=1; numval:=0; numsign:=1; inkeyw:='\RTF';
        end
      ; {END IF}
    end
  else if(CAT=1) then   { this is an opening brace }
    begin
      if no_RTFrtf then { ignore first opening brace before \rtf1 }
      else if(lvlcode[bracelvl]=3) then open_brace
      else if(lvlcode[bracelvl]=4) then open_brace
      else if(lvlcode[bracelvl]=6) then
        begin outchr(kar); open_brace;
        end
      else
        begin if(par_to_begin) then output_size(sizecode[bracelvl]);
          make_center; outchr(kar); open_brace;
        end
      ; {END IF}
    end
  else if(CAT=2) then  { this is a closing brace }
    begin close_envir;
      if bracelvl>0 then make_closing_brace;
    end
  else if(CAT=3) then  { this is an opening parenthesis '(' }
    begin
      if (form_code[bracelvl] <> '') then
        begin
          if form_code[bracelvl]='\RTFformulaB' then
            form_code[bracelvl]:=truncate24(form_code[bracelvl]+'BC(');
          if form_code[bracelvl]='\RTFformulaBLC' then
            form_code[bracelvl]:=truncate24(form_code[bracelvl]+'(');
          if form_code[bracelvl]='\RTFformulaBRC' then
            form_code[bracelvl]:=truncate24(form_code[bracelvl]+'(');
          if form_code[bracelvl]='\RTFformulaBBC' then
            form_code[bracelvl]:=truncate24(form_code[bracelvl]+'(');
          if pos('\RTFformulaBBC',form_code[bracelvl])>0 then
            begin
              RTFform:=form_code[bracelvl]; open_kar:=RTFform[length(RTFform)];
              if(open_kar='{') then open_kar:='\{';
              out_math_leave('\left'); outstg(open_kar); outchr(' ');
              form_code[bracelvl]:=''; open_brace;
              lvlcode[bracelvl]:=16; { special code to close with ) }
              if(open_kar='(') then close_kar[bracelvl]:=')'
              else if(open_kar='[') then close_kar[bracelvl]:=']'
              else if(open_kar='\{') then close_kar[bracelvl]:='\}'
              else close_kar[bracelvl]:=open_kar
              ; {END IF open_kar}
              kar:=' ';  { to prevent do_it_again }
            end
          else if pos('\RTFformulaBLC',form_code[bracelvl])>0 then
            begin
              RTFform:=form_code[bracelvl]; open_kar:=RTFform[length(RTFform)];
              if(open_kar='{') then open_kar:='\{';
              out_math_leave('\left'); outstg(open_kar); outchr(' ');
              form_code[bracelvl]:=''; open_brace;
              lvlcode[bracelvl]:=16; { special code to close with ) }
              close_kar[bracelvl]:='.';
              kar:=' ';  { to prevent do_it_again }
            end
          else if pos('\RTFformulaBRC',form_code[bracelvl])>0 then
            begin
              RTFform:=form_code[bracelvl]; open_kar:=RTFform[length(RTFform)];
              if(open_kar='{') then open_kar:='\{';
              out_math_leave('\left. ');
              form_code[bracelvl]:=''; open_brace;
              lvlcode[bracelvl]:=16; { special code to close with ) }
              if(open_kar='(') then close_kar[bracelvl]:=')'
              else if(open_kar='[') then close_kar[bracelvl]:=']'
              else if(open_kar='\{') then close_kar[bracelvl]:='\}'
              else close_kar[bracelvl]:=open_kar
              ; {END IF open_kar}
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|F( ... ; ... ) }
          else if ('\RTFformulaF'=form_code[bracelvl]) then
            begin
              form_code[bracelvl]:=''; out_math_leave('{\displaystyle ');
              open_brace; lvlcode[bracelvl]:=17;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|D\|BA() or \|D\|FO() }
          else if ('\RTFformulaDFO'=form_code[bracelvl]) then
            begin sign_str(displ_skip,worksa);
              form_code[bracelvl]:=''; outkeyw('kern '+worksa+'pt');
              open_brace; lvlcode[bracelvl]:=28;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|D\|LI() }
          else if ('\RTFformulaDLI'=form_code[bracelvl]) then
            begin sign_str(displ_skip,worksa); form_code[bracelvl]:='';
              outkeyw('RTFhrule '+worksa+'pt');
              open_brace; lvlcode[bracelvl]:=28;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|O( ... ; ... ) }
          else if ('\RTFformulaO'=form_code[bracelvl]) then
            begin form_code[bracelvl]:=''; begin_par;
              outkeyw('hbox{\ooalign{\hfil{}'); open_brace;
              lvlcode[bracelvl]:=26; math_mode[bracelvl]:=0;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|L( ... ; ... ) }
          else if ('\RTFformulaL'=form_code[bracelvl]) then
            begin form_code[bracelvl]:=''; begin_par;
              outchr('{'); open_brace;
              lvlcode[bracelvl]:=27;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|R( ... ; ... ) }
          else if ('\RTFformulaR'=form_code[bracelvl]) then
            begin form_code[bracelvl]:='';
              out_math_leave('\sqrt{'); open_brace;
              lvlcode[bracelvl]:=23;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|X( ... ; ... ) }
          else if pos('\RTFformulaX',form_code[bracelvl])>0 then
            begin form_code[bracelvl]:=''; begin_par;
              outstg('\boxed'+copy(form_code[bracelvl],11,3)+'{'); open_brace;
              lvlcode[bracelvl]:=7;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|S( ... ; ... ) }
          else if ('\RTFformulaS'=form_code[bracelvl]) or
            ('\RTFformulaSUP'=form_code[bracelvl]) then
            begin form_code[bracelvl]:='';
              out_math_leave('^{'); open_brace; lvlcode[bracelvl]:=18;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|SDO( ... ; ... ) }
          else if ('\RTFformulaSDO'=form_code[bracelvl]) then
            begin form_code[bracelvl]:='';
              out_math_leave('_{'); open_brace; lvlcode[bracelvl]:=19;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|I( ... ; ... ) }
          else if ('\RTFformulaI'=form_code[bracelvl]) then
            begin form_code[bracelvl]:='';
              out_math_leave('\int_{'); open_brace; lvlcode[bracelvl]:=20;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|ISU( ... ; ... ) }
          else if ('\RTFformulaISU'=form_code[bracelvl]) then
            begin form_code[bracelvl]:='';
              out_math_leave('\displaystyle\sum_{'); open_brace; lvlcode[bracelvl]:=20;
              kar:=' ';  { to prevent do_it_again }
            end
    { case of \|IPR( ... ; ... ) }
          else if ('\RTFformulaIPR'=form_code[bracelvl]) then
            begin form_code[bracelvl]:='';
              out_math_leave('\displaystyle\prod_{'); open_brace; lvlcode[bracelvl]:=20;
              kar:=' ';  { to prevent do_it_again }
           end
          ; {END IF}
        end
  { if an opening parenthese is found inside a deep formula, set lvlcode at 25 }
      else if (abs(lvlcode[bracelvl]) >=17) then
        begin outchr(kar); open_brace; lvlcode[bracelvl]:=25;
        end
      else
        begin begin_par; outchr(kar);
        end
      ; {END IF form_code }
    end
  else if(CAT=4) then  { this is a closing parenthesis ')' }
    begin
    (* test 23 sept *)
      while (lvlcode[bracelvl]<0) and (auto_close[bracelvl]) do
        begin
          if (math_mode[bracelvl]=1) then outchr('$'); outchr('}'); close_brace;
        end
      ; {END WHILE auto_close}
    (* fin test 23 sept *)
    { special case of \|B..(...) closing }
      if (lvlcode[bracelvl]=16) then
        begin outstg('\right'); outstg(close_kar[bracelvl]); close_sum;
        end
    { special case of \|X..(...) closing }
      else if (lvlcode[bracelvl]=7) then
        begin outchr('}'); close_sum;
        end
    { closing parenthese found inside a formula, was opened with another ( 25 }
      else if (lvlcode[bracelvl]=25) then
        begin outchr(kar); close_brace;
        end
    { closing parenthese found inside a formula \|O }
      else if (lvlcode[bracelvl]=26) then
        begin close_math; outstg('\hfil}}'); close_brace;
        end
    { closing parenthese found inside a formula \|L }
      else if (lvlcode[bracelvl]=27) then
        begin outchr('}'); close_brace;
        end
    { closing parenthese found inside a formula \|D }
      else if (lvlcode[bracelvl]=28) then
        begin outstg('{}'); close_brace;
        end
    { special case of \|F(...) closing }
    { special case of \|S(...) closing }
    { special case of \|SDO(...) closing }
    { special case of \|I(...) closing }
    { special case of \|I(..;..) closing }
    { special case of \|I(..;..;..) closing }
    { special case of \|R(...) closing }
      else if (lvlcode[bracelvl]>=17) then
        begin close_subs; close_sum;
        end
    { closing parenthese found inside a deep formula, make it 1 level lower }
      else if (-lvlcode[bracelvl]>=17) then
        begin next_rtf:='}){'+next_rtf;
        end
      else
        begin begin_par; outchr(kar);
        end
      ; {END IF lvlcode}
    end
{ Ignore chars to be ignored }
  else if(lvlcode[bracelvl]=1) then

  else if(lvlcode[bracelvl]=3) then

  else if(lvlcode[bracelvl]=4) then

  else if(lvlcode[bracelvl]=5) then { we are in the hexa part of a \RTFpict }
    begin
      { ignore possible blanks and control characters within hexadecimal field }
      if ord(kar)>32 then
        begin hexa_digit:=hx_to_i(kar);
          pict_char_number:=pict_char_number+1;
          if (pict_left_hexa) then
{ there is already one hexa digit stored}
            begin pict_last_hexa:=16*pict_last_hexa+hexa_digit;
              pict_byte:=chr(pict_last_hexa); write(figurefile,pict_byte);
              pict_byte_number:=pict_byte_number+1;
              pict_last_hexa:=0; pict_left_hexa:=FALSE;
            end
          else
{ there is no hexa digit stored}
            begin pict_last_hexa:=hexa_digit; last_kar:=kar; pict_left_hexa:=TRUE;
            end
          ; {END IF pict-left_hexa}
        end
      ; {END IF}
    end
  else if(abs (lvlcode[bracelvl])=10) then { we are in \RTFobject }

  else if(abs (lvlcode[bracelvl])=9) then { ignore other than braces }

  else if(cat=11) then  { this is a letter }
    begin begin_par;
      if (lvlcode[bracelvl]=2) then { letters to be capitalized ? }
        begin kar:=upcase(kar); ikar:=ord(kar);
        end
      ; {END IF lvlcode=2}
      if (active_RTFf[bracelvl]='ftech') then
        begin acc_converted:=ftech_transl[ikar];
          if acc_converted <> '' then out_math(acc_converted)
          else outchr(kar)
          ; {END IF acc_converted}
        end
      else
        begin
          outrem('\beginparagraph{}');
          if(removed_OK and (kout>0)) then outstg('{}');
          outchr(kar);
        end
      ; {END IF active_RTF}
    end
  else if (active_RTFf[bracelvl]='ftech') then
    begin begin_par; acc_converted:=ftech_transl[ikar];
      if acc_converted <> '' then out_math(acc_converted)
      else special_TeX_chars
      ; {END IF acc_converted}
    end
  else if (kar='-') then
    begin
      if (last_is('\beginparagraph{}')) then
        begin
          outrem('\beginparagraph{}');
          outkeyw('plainitem{--}');
        end
      else
        outchr(kar)
      ; {END IF}
    end
  else if(kar='"') then
    begin begin_par;  (*  test march 94 *)
      if (math_mode[bracelvl]=0) and ((kout=0) or last_is(' ')) then
        outstg('``')
      else outstg('''''')
      ; {END IF}
    end
  else if(kar=';') then
    begin
{ ignore ; in colortbl section }
      if (lvlcode[bracelvl]=9) then
{ special case of \|F(. ; .) intermediate semi-colon }
      else if (lvlcode[bracelvl]=17) then
        outstg(' \over\displaystyle ')
{ special case of \|S(. ; .) intermediate semi-colon }
      else if (lvlcode[bracelvl]=18) then
        begin close_subs; out_math_leave(' _{');
        end
{ special case of \|SDO(. ; .) intermediate semi-colon }
      else if (lvlcode[bracelvl]=19) then
        begin close_subs; out_math_leave(' ^{');
        end
{ special case of \|I(. ; .) intermediate semi-colon }
      else if (lvlcode[bracelvl]=20) then
        begin close_subs; outstg(' ^{'); lvlcode[bracelvl]:=21;
        end
{ special case of \|su(. ; .) second intermediate semi-colon }
      else if (lvlcode[bracelvl]=21) then
        begin close_subs; outchr('{'); lvlcode[bracelvl]:=22;
        end
{ special case of \|R(. ; .) intermediate semi-colon }
      else if (lvlcode[bracelvl]=23) then
        begin outsubstitute('\sqrt{','\root{');
        outstg('}\of{'); lvlcode[bracelvl]:=24; output_line; (* safety *)
      end
{ special case of \|O(. ; .) intermediate semi-colon }
      else if (lvlcode[bracelvl]=26) then outstg('\hfil\crcr\hfil{}')
{ special case of \|L(. ; .) intermediate semi-colon }
      else if (lvlcode[bracelvl]=27) then outchr(',')
      else outchr(kar)
      ; {END IF}
    end
  else
    special_TeX_chars
  ; {END IF active_RTF}
end;

{---------------------------------------------------------------------------}
{ treats a character when KEYW is 1 }
{ Keyword being decoded, we are just after the BACKSLASH }

procedure keyw_is_1;
begin
  if(cat=11) then
    begin { letter : store and say KEYW:=2 }
      inkeyw:=inkeyw+kar; keyw:=2 ;
    end
  else if(cat=16) then
    begin { case of a digit : store \RTF }
      outrem_empty_braces; outstg(inkeyw); outchr(KAR); keyw:=0;
    end
(* turn \{ into \RTFaccol and... try to continue ! *)
  else if(kar='{') then
    begin out_math('\{'); keyw:=0;
    (*  inkeyw:=inkeyw+'accol '; keyw:=2 ; *)
    end
(* turn \} into \RTFlocca and... try to continue ! *)
  else if(kar='}') then
    begin out_math('\}'); keyw:=0;
    (* inkeyw:=inkeyw+'locca '; keyw:=2 ; *)
    end
  else if(kar='(') then
    begin begin_par; outkeyw('RTFparen '); keyw:=0;
    end
  else if(kar='-') then
    begin
{ case of a word cutting hyphen \- }
      begin_par; outkeyw(KAR); keyw:=0;
    end
  else if(kar='*') then
    begin
      if (abs(lvlcode[bracelvl])<10) or (abs(lvlcode[bracelvl])>12) then
         begin begin_par; outchr(KAR);
         end
      ;  keyw:=0; {END IF}
    end
  else if(kar='_') then
    begin
{ case of a word non cutting hyphen \_ }
      begin_par; outchr('-'); keyw:=0;
    end
  else if(kar='~') then
    begin
{ case of a non breaking space }
      begin_par; outchr(KAR); keyw:=0;
    end
  else if(kar='''') then
    begin keyw:=4; num_hexa:=0;
    end
  else if(kar=':') then insert_tilde(kar)
  else if(kar=';') then insert_tilde(kar)
  else if(kar=')') then
    begin begin_par; outchr(kar);
    end
  else if(kar='(') then
    begin begin_par; outchr(kar);
    end
  else if(kar='\') then
    begin
      if (next_rtf[1]='f') and (lvlcode[bracelvl]=12) then
        lvlcode[bracelvl]:=9
      else
        begin
          begin_par; outstg('{\char92}'); keyw:=0;
        end
      ;
    end
  else if(kar='|') then
    if next_rtf[1]='}' then
      (* if \|} cancel \| and post it for later *)
      begin inkeyw:=''; keyw:=0;
        delete(next_rtf,1,1); next_rtf:='}\|'+next_rtf;
      end
    else
      begin
{ case of \| (in formulae) store as "formula" and expect letters }
        inkeyw:=inkeyw+'formula'; keyw:=2;
      end
  else
    begin
{ store \RTF and try again }
      outkeyw('RTF{}'); keyw:=0; do_it_again:=TRUE;
    end
  ; {END IF}
end;


{---------------------------------------------------------------------------}
{ treats a character when KEYW is 2 }
{ We are in a letter keyword }

procedure keyw_is_2;
var
  poskeyw, k, num_forced, posbsl, font_equiv_spacing, testio : integer;
  inkeywb : string24;
begin
  if(cat=11) then
    begin
{ letter : store and capitalize for formulas }
      if (pos('\RTFformula',inkeyw)>0 ) then
        inkeyw:=inkeyw+upcase(kar)
      else inkeyw:=inkeyw+kar
      ; {END IF}
    end
  else if(cat=16) then
    begin
{ case of a digit : store with opening brace and say KEYW:=3 }
      inkeyw:=inkeyw+'{'+kar;
      numval:=ord(kar)-icharz; numsign:=1; keyw:=3;
    end
  else if(kar='-') then
    begin
{ case of a - introduction : store opening brace and say KEYW:=3 }
      inkeyw:=inkeyw+'{-'; numval:=0; numsign:=-1; keyw:=3;
    end
  else
    begin
{ delay \begin(center) to further opening \par }
      if(inkeyw='\RTFqc') then
        begin if (lvlcode[bracelvl]<>9) then
          begin center_flag[bracelvl]:=1;
          end
        end
{ delay \begin(flushright) to further opening \par }
      else if(inkeyw='\RTFqr') then
        begin if (lvlcode[bracelvl]<>9) then flushright_flag[bracelvl]:=1;
        end
{ interpret some other keywords }
      else if(inkeyw='\RTFtab') then
        begin
          if par_to_begin then num_indent:=num_indent+1
          else outkeyw('indent ')
          ;
        end
      else if(inkeyw='\RTFchpgn') then
        begin begin_par; outkeyw('the\count0{}')
        end
      else if(inkeyw='\RTFb') then
        begin add_to_bfsl('\bf'); ensure_sizebfsl;
        end
      else if(inkeyw='\RTFscaps') then
        begin add_to_bfsl('\sc'); ensure_sizebfsl;
        end
      else if(inkeyw='\RTFoutl') then
        begin add_to_bfsl('\oul'); ensure_sizebfsl;
        end
      else if(inkeyw='\RTFul') then
        begin outrem('{');
          if removed_OK then
            if math_mode[bracelvl]=0 then
              begin begin_par; outkeyw('underbar{');
              end
            else
              begin begin_par; outkeyw('underline{');
              end
          else
            outkeyw('RTFul{}')
          ; {END IF removed_OK}
          ; underl_flag[bracelvl]:=TRUE
        end
      else if(inkeyw='\RTFuldb') then
        begin outrem('{');
          if removed_OK then
            if math_mode[bracelvl]=0 then
              begin begin_par; outkeyw('underbar{\bf{}');
              end
            else
              begin begin_par; outkeyw('underline{');
              end
          else
            outkeyw('RTFuldb{}')
          ; {END IF removed_OK}
          ; underl_flag[bracelvl]:=TRUE
        end
      else if(inkeyw='\RTFv') then
        begin outrem('{');
          if removed_OK then
            begin begin_par; outkeyw('index{');
            end
          else
            outkeyw('RTFul{}')
          ; {END IF removed_OK}
          ; underl_flag[bracelvl]:=TRUE
        end
      else if(pos('\RTFheader',inkeyw)+pos('\RTFfooter',inkeyw)>0) then
        begin outrem('{');
          if removed_OK then outkeyw(copy(inkeyw,2,999)+'{')
          else outkeyw(copy(inkeyw,2,999)+'{\relax}')
          ; {END IF removed_OK}
          lvlcode[bracelvl]:=9;
        end
      else if(inkeyw='\RTFi') then
        begin
          if use_sl then add_to_bfsl('\sl')
          else add_to_bfsl('\it')
          ; {END IF}
          ensure_sizebfsl;
        end
      else if(inkeyw='\RTFpard') then
        begin (* old center_flag[bracelvl]:=0; flushright_flag[bracelvl]:=0; *)
          close_math; close_envir;
          center_flag[bracelvl]:=0; flushright_flag[bracelvl]:=0;
          bfslcode[bracelvl]:='\rm';
          
          if (abs(lvlcode[bracelvl])<>8) and (abs(lvlcode[bracelvl])<>9)
            and (lvlcode[bracelvl]<>13) and (lvlcode[bracelvl]<>15) then
            begin
              leftskip:=0; rightskip:=0;
              num_indent:=0; par_to_begin:=TRUE;
              if last_is('\end{tabular}\par ') then
              else (* never cut line+\check after \end{tabular} *)
                begin
                  if (KOUT>0) then output_line;
                  outstg(' %\check '); output_line; (* for testing *)
                end
              ;
            end
          ; {END IF}
          if lvlcode[bracelvl]=2 then lvlcode[bracelvl]:=0;
        end
      else if(inkeyw='\RTFpar') then
        begin
          if next_rtf[1]='}' then
            begin inkeyw:='';
              delete(next_rtf,1,1); next_rtf:='}\par '+next_rtf;
            end
          else make_RTFpar('\par ')
        ; {END IF next_rtf[1]}
        end
      else if(inkeyw='\RTFpagebb') then
        begin
          if next_rtf[1]='}' then
            begin inkeyw:='';
              delete(next_rtf,1,1); next_rtf:='}\pagebb '+next_rtf;
            end
          else make_RTFpar('\clearpage ')
        ; {END IF next_rtf[1]}
        end
      else if(inkeyw='\RTFpage') then
        begin
          if next_rtf[1]='}' then
            begin inkeyw:='';
              delete(next_rtf,1,1); next_rtf:='}\page '+next_rtf;
            end
          else
            begin output_size(spacingcode[bracelvl]);
             outkeyw('break\eject\noindent '); output_size(sizecode[bracelvl]);
             output_bfsl;
            end
        ; {END IF next_rtf[1]}
        end
      else if(inkeyw='\RTFsect') then
        begin
          if next_rtf[1]='}' then
            begin inkeyw:='';
              delete(next_rtf,1,1); next_rtf:='}\par '+next_rtf;
            end
          else make_RTFpar('\par  \relax ')
        ; {END IF next_rtf[1]}
        end
      else if(inkeyw='\RTFrquote') then outchr('''')
      else if(inkeyw='\RTFlquote') then outchr('`')
      else if(inkeyw='\RTFmac') then mac_init
      else if(inkeyw='\RTFansi') then ansi_init
      else if(inkeyw='\RTFline') then outkeyw('break ')
{ flag to say future capitalized }
      else if(inkeyw='\RTFcaps') then lvlcode[bracelvl]:=2
{ flag to say we are in \fonttbl block }
      else if(inkeyw='\RTFfonttbl') then
        begin lvlcode[bracelvl]:=6; outrem_empty_braces;
          outkrem(sizecode[bracelvl]); outrem('{');
          if removed_OK then outkeyw('RTFfonttbl{')
          else outkeyw('RTFfonttbl{}{}{}\relax ')
          ; {END IF}
        end
      else if(inkeyw='\RTFcolortbl') then
        begin outrem_empty_braces; lvlcode[bracelvl]:=9;
          outkrem(sizecode[bracelvl]); outrem('{');
          if removed_OK then outkeyw('RTFcolortbl{')
          else outkeyw('RTFcolortbl{}{}{}\relax ')
          ; {END IF}
        end
      else if(inkeyw='\RTFinfo') then
        begin outrem_empty_braces;
          outkrem(sizecode[bracelvl]); outrem('{');
          if removed_OK then outkeyw('RTFinfo{')
          else outkeyw('RTFinfo{}{}{}\relax ')
          ; {END IF}
        end
      else if(inkeyw='\RTFstylesheet') then
        begin outrem_empty_braces;
          outkrem(sizecode[bracelvl]); outrem('{');
          if removed_OK then
            begin outkrem('RTFcolortbl{}'); outkeyw('RTFstylesheet{');
            end
          else outkeyw('RTFstylesheet{}{}{}\relax ')
          ; {END IF}
          lvlcode[bracelvl]:=8;
        end
      else if(inkeyw='\RTFfield') then
        lvlcode[bracelvl]:=11
      else if(inkeyw='\RTFflddirty') then

      else if(pos('\RTFfldinst',inkeyw)>0) and (lvlcode[bracelvl-1]=11) then
        begin lvlcode[bracelvl]:=12; exit; (* to avoid resetting keyw:=0 *)
        end
      else if(inkeyw='\RTFtrowd') then
        begin
          perform_RTFtrow;
          outkeyw('begin{tabular}{');
          clbrdrr:=FALSE;  clbrdrl:=FALSE;  clbrdrt:=FALSE;  clbrdrb:=FALSE;
          tab_nb_cellx[bracelvl]:=0;
          tab_cellx[bracelvl]:=0;
        end
      else if(inkeyw='\RTFbrdrs') and (lvlcode[bracelvl]=13) then
        (* ignore *)
      else if(inkeyw='\RTFclbrdrl') and (lvlcode[bracelvl]=13) then
        begin outchr('|');
          if (verbose>1) then
            writeln(inkeyw,'[',lvlcode[bracelvl],',',bracelvl,']');
          clbrdrl:=FALSE;
        end
      else if(inkeyw='\RTFclbrdrr') and (lvlcode[bracelvl]=13) then
        begin
          if (verbose>1) then
            writeln(inkeyw,'[',lvlcode[bracelvl],',',bracelvl,']');
          clbrdrr:=TRUE;
        end
      else if(inkeyw='\RTFclbrdrt') and (lvlcode[bracelvl]=13) then
        begin
          if (verbose>1) then
            writeln(inkeyw,'[',lvlcode[bracelvl],',',bracelvl,']');
          clbrdrt:=TRUE;
        end
      else if(inkeyw='\RTFclbrdrb') and (lvlcode[bracelvl]=13) then
        begin
          if (verbose>1) then
            writeln(inkeyw,'[',lvlcode[bracelvl],',',bracelvl,']');
          clbrdrb:=TRUE;
        end
      else if(inkeyw='\RTFintbl') then
        begin
          if (verbose>0) then
            writeln('(found)',inkeyw,'[',lvlcode[bracelvl],',',bracelvl,']');
          if (lvlcode[bracelvl]=13) then
            begin if clbrdrr then outchr('|'); clbrdrr:=FALSE; outchr('}');
              lvlcode[bracelvl]:=15; (* second part of \RTFtrowd *)
              if clbrdrt then
                begin outkeyw('hline'); output_line;
                end
              ;
              tab_nb_ands[bracelvl]:=0;
              if (verbose>1) then
                writeln('(after)',inkeyw,'[',lvlcode[bracelvl],',',
                bracelvl,']');
            end
          else if (lvlcode[bracelvl]=15) then
            begin
              if (verbose>1) then
                writeln('(ignored)',inkeyw,'[',lvlcode[bracelvl],',',bracelvl,']');
            end
          else (* force \RTFtrowd if missing *)
            begin
              if (verbose>0) then
                writeln('forcing\RTFtrowd',inkeyw,'[',
                lvlcode[bracelvl],',',bracelvl,']');
              if last_is('\\\end{tabular}\par ') then
                outkrem('end{tabular}\par ')
              else if last_is('\\\hline \end{tabular}\par ') then
                outkrem('end{tabular}\par ')
              else if last_is('\end{tabular}\par ') then
                begin
                  outkrem('end{tabular}\par '); outstg('\\');
                  if clbrdrb then outkeyw('hline ');
                end
              else
                outkeyw('begin{tabular}{ppppppppppppppp}')
              ;  {END IF last_is(...)}
              perform_RTFtrow;
              lvlcode[bracelvl]:=15; (* second part of \RTFtrowd *)
              if (verbose>1) then
                writeln('(<after)',inkeyw,'[',lvlcode[bracelvl],',',
                tab_nb_cellx[bracelvl],',',bracelvl,']')
               {END IF verbose};
            end
          ;
        end
      else if(inkeyw='\RTFrow') then
        begin
          perform_RTFrow;
        end
      else if(inkeyw='\RTFcell') then
        begin
          perform_RTFcell;
        end
      else if(inkeyw='\RTFobject') then
        begin
          rtfpicw:=0; rtfpich:=0;   { reset picture width and height to 0 }
          pict_char_number:=0; pict_byte_number:=0;
          pict_last_hexa:=0;        { reset last hexa byte of the picture }
          pict_left_hexa:=FALSE; pict_number:=pict_number+1; { count picture number }
          sign_str(pict_number,pict_name);
          figure_name:=figure_path+pict_name+figure_type;
          while (pos('\',figure_name)>0) do
            begin
              posbsl:=pos('\',figure_name); figure_name[posbsl]:='/';
            end
          ; {END DO}
          begin_par; outkeyw(copy(inkeyw,2,99)+'{'+figure_name+'}');
          figure_name:=figure_path+pict_name+figure_type;
          output_line;
          println_msg(1,'Skipped object file '+figure_name);
          lvlcode[bracelvl]:=10;
        end
      else if(inkeyw='\RTFpict') then
        begin
          rtfpicw:=0; rtfpich:=0;   { reset picture width and height to 0 }
          pict_char_number:=0; pict_byte_number:=0;
          pict_last_hexa:=0;        { reset last hexa byte of the picture }
          pict_left_hexa:=FALSE; pict_number:=pict_number+1; { count picture number }
          sign_str(pict_number,pict_name);
          figure_name:=figure_path+pict_name+figure_type;
          while (pos('\',figure_name)>0) do
            begin
              posbsl:=pos('\',figure_name); figure_name[posbsl]:='/';
            end
          ; {END DO}
          begin_par; outkeyw(copy(inkeyw,2,99)+'{'+figure_name+'}');
          figure_name:=figure_path+pict_name+figure_type;
          output_line;
          {$I-}
          assign(figurefile,figure_name); rewrite(figurefile); testio:=ioresult;
          if (testio <> 0) then
            begin sign_str(testio,works);
              println_msg(0,'Unable to open figure file '+figure_name
                +' ; code='+works);
              close_files; halt;
            end
          ; {ENF IF testio}
          {$I+}
          println_msg(1,'Opened picture file '+figure_name);
          lvlcode[bracelvl]:=5;
        end
      else if(inkeyw='\RTFfootnote') then
        begin
          if math_mode[bracelvl]=0 then
            begin lvlcode[bracelvl]:=3; outrem('{');
              if removed_OK then outkeyw('footnote{')
              else outkeyw('footnote ')
              ; {END IF removed}
            end
          else if math_mode[bracelvl]=1 then
            begin close_math;
              next_rtf:='\footnote '+next_rtf
            end
          else if math_mode[bracelvl-1]=1 then
            next_rtf:='}{\footnote '+next_rtf
          else if (bracelvl>=2) and (math_mode[bracelvl-2]=1) then
            next_rtf:='}}{{\footnote '+next_rtf
          else if (bracelvl>=3) and (math_mode[bracelvl-3]=1) then
            next_rtf:='}}}{{{\footnote '+next_rtf
          else outkeyw('footnote ')
          ; {END IF math_mode}
        end
      else if(inkeyw='\RTFplain') then
        begin outpsize(20*stdsize);
          bfslcode[bracelvl]:='\rm';
          sizecode[bracelvl]:='normalsize';
        end
      else if(inkeyw='\RTFchftn') then
        begin remove_mathat;
        end
      else if(inkeyw='\RTFendash') then
        if(math_mode[bracelvl]>0) then outchr('-')
        else outstg('--')
      else if(inkeyw='\RTFemdash') then
        if(math_mode[bracelvl]>0) then outchr('-')
        else outstg('---')
      else if(inkeyw='\RTFfnil') then
        store_word_font('fnil') { decl_font_num is a global variable }
      else if(inkeyw='\RTFfroman') then
        store_word_font('froman')
      else if(inkeyw='\RTFfmodern') then
        store_word_font('fmodern')
      else if(inkeyw='\RTFfdecor') then
        store_word_font('fdecor')
      else if(inkeyw='\RTFfswiss') then
        store_word_font('fswiss')
      else if(inkeyw='\RTFfscript') then
        store_word_font('fscript')
      else if(inkeyw='\RTFftech') then
        store_word_font('ftech')
      else if(inkeyw='\RTFformulaB') then
        form_code[bracelvl]:=truncate24(inkeyw)
      else if(inkeyw='\RTFformulaO') then
        form_code[bracelvl]:=truncate24(inkeyw)
      else if(inkeyw='\RTFformulaLC') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'LC')
      else if(inkeyw='\RTFformulaRC') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'RC')
      else if(inkeyw='\RTFformulaBC') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'BC')
      else if(inkeyw='\RTFformulaF') then
        form_code[bracelvl]:=truncate24(inkeyw)
      else if(inkeyw='\RTFformulaR') then
        form_code[bracelvl]:=truncate24(inkeyw)
      else if(inkeyw='\RTFformulaS') then
        form_code[bracelvl]:=truncate24(inkeyw)
      else if(inkeyw='\RTFformulaD') then
        form_code[bracelvl]:=truncate24(inkeyw)
      else if(inkeyw='\RTFformulaX') then
        form_code[bracelvl]:=truncate24(inkeyw)
      else if(inkeyw='\RTFformulaI') then
        form_code[bracelvl]:=truncate24(inkeyw)
      else if(inkeyw='\RTFformulaSU') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'SU')
      else if(inkeyw='\RTFformulaPR') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'PR')
      else if(inkeyw='\RTFformulaIN') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'IN')
      else if(inkeyw='\RTFformulaRI') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'RI')
      else if(inkeyw='\RTFformulaBO') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'BO')
      else if(inkeyw='\RTFformulaLE') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'LE')
      else if(inkeyw='\RTFformulaTO') then
        form_code[bracelvl]:=truncate24(form_code[bracelvl]+'TO')
{ case of \|<non-alpha> }
      else if(inkeyw='\RTFformula') then
        begin
          if (CAT=0) and (next_rtf[1]='{') then
            begin form_code[bracelvl]:=truncate24(form_code[bracelvl]+'{');
              kar:=' '; next_rtf[1]:=chr(0); { to prevent do_it_again }
            end
          else if (CAT=0) and (next_rtf[1]='}') then
            begin form_code[bracelvl]:=truncate24(form_code[bracelvl]+'}');
              kar:=' '; next_rtf[1]:=chr(0); { to prevent do_it_again }
            end
          else
            begin form_code[bracelvl]:=truncate24(form_code[bracelvl]+kar);
              kar:=' ';  { to prevent do_it_again }
            end
          ; {END IF}
        end
(* case of \{ *)
      else if(inkeyw='\RTFaccol ') then out_math('\{')
(* case of \} *)
      else if(inkeyw='\RTFlocca ') then out_math('\}')
      else
        begin poskeyw:=0; inkeywb:=truncate24(inkeyw+' ');
(* check whether this keyword should be skipped in output *)
          for k:=1 to num_skip_strings do
            poskeyw:=poskeyw+pos(inkeyw,skip_strings[k])
          ; {END DO}
{ output other keywords with an additional space }
          if poskeyw=0 then
            begin outrem_empty_braces; outstg(inkeyw);
{ do not put a space if following is a (, for TeX macros syntax }
              if kar <> '(' then outchr(' ');
            end
          ; {END IF poskeyw}
        end
      ; {END IF}
{ reset KEYW and try again }
      keyw:=0; if(kar <> ' ') then do_it_again:=TRUE;
    end
  ; {END IF cat=11}
end;

{---------------------------------------------------------------------------}
{ treats a character when KEYW is 3 }
{ Numeric arg of Keyword being decoded }

procedure keyw_is_3;
var
  sizeheader : string24;  { will be 'large', 'Large', 'footnotesize'... }
  magnification : integer;  { will be 1000, 1095, 900... }
  diff_cellx, style_ref, poskeyw, k, posmod : integer;
  acc_converted, inkeywb, newfont : string24;
  test_RTFstyle : string_RTFstyle;
begin
  if(cat=16) then
{ case of a digit }
    begin inkeyw:=inkeyw+kar; numval:=10*numval+numsign*(ord(kar)-icharz);
    end
  else
    begin
{ case of a non digit: terminate but ignore some keywords with brace pairs }
      if(pos('RTFsl{',inkeyw) > 0) then
        begin outpsize(numval); sign_str(numval,works);
          println_msg(2,'\RTFsl{'+works+'} -->  \'+spacingcode[bracelvl]);
        end
      else if(pos('RTFli{',inkeyw) > 0) and (center_flag[bracelvl]<2) then
        begin
          if lvlcode[bracelvl]<>8 then leftskip:=numval
          ; {END IF}
        end
      else if(pos('RTFri{',inkeyw) > 0) and (center_flag[bracelvl]<2) then
        begin
          if lvlcode[bracelvl]<>8 then rightskip:=numval
          ; {END IF}
        end
      else if(pos('RTFf{',inkeyw) > 0) then
        begin decl_font_num:=numval; { store numval for further use }
          set_active_RTFf(numval); outstg('{}');
        end
{ use _ and ^ for sub/superscripts and put in math mode if needed }
      else if(pos('RTFup{',inkeyw) > 0) then
        begin
          out_math_leave('\relax^{'); open_brace; auto_close[bracelvl]:=TRUE;
        end
      else if(pos('RTFdn{',inkeyw) > 0) then
        begin
          out_math_leave('\relax_{'); open_brace; auto_close[bracelvl]:=TRUE;
        end
{ ignore \RTFfi if option '-v' }        
      else if (pos('RTFfi{',inkeyw) > 0) then
        begin
          num_indent:=1;
          if (no_space_conv) and(numval>0) then
          else
            begin outkeyw('parindent='); output_num(numval);
              outkeyw('RTFtwips'); output_line;
            end
          ;  
        end
{ style description }
      else if(pos('RTFs{',inkeyw) > 0) then
        begin  sign_str(numval,works);
          if (abs(lvlcode[bracelvl])=8) then
            begin
              if num_styles>=maxRTFstyles then
                println_msg(0,'Too many styles, style '+works+' ignored.')
              else if numval>255 then
                println_msg(0,'Illegal style number, style '+works+' ignored.')
              else
                begin num_styles:=num_styles+1; ref_styles[numval]:=num_styles;
                  test_RTFstyle:=kar;
                  while (kar<>';') and (kar<>'}') do
                    begin read_char; test_RTFstyle:=test_RTFstyle+kar;
                    end
                  ; {END while}
(* clean style to the first blank after \snext *)
                  if kar=';' then kar:=' ';
                  k:=pos('\snext',test_RTFstyle);
                  m:=length(test_RTFstyle);
                  for l:=k to length(test_RTFstyle) do
                    begin if (test_RTFstyle[l]=' ') and (l<m) then m:=l;
                    end
                  ;  sign_str(num_styles,worksa);
(* start at the first space in style text *)
                  n:=pos(' ',test_RTFstyle)+1;
                  RTFstyles[num_styles]:=copy(test_RTFstyle,n,m-n+1);
                  println_msg(2,works+' --> '+worksa+' "'+
                     RTFstyles[num_styles]+'"');
                end
              ; {END IF}
            end
          else
            begin style_ref:=ref_styles[numval];
              if (style_ref<=0) or (style_ref>255) then
                println_msg(0,'Illegal style number, style '+works+' ignored.')
              else
                begin if kar<>' ' then next_rtf:=kar+next_rtf;
                  kar:=' '; next_rtf:=RTFstyles[style_ref]+next_rtf;
                end
              ; {END IF}
            end
          ; {END IF}
        end
{ font size description }
      else if(pos('RTFfs{',inkeyw) + pos('RTFfldinstfs{',inkeyw) > 0)
        and (lvlcode[bracelvl]<>8) then
        begin
{ before putting \LARGE, \Huge etc., remove previous \bf, \rm, etc. }
          outrem_empty_braces; outrem(bfslcode[bracelvl]);

{ output \large, \normalsize, \footnotesize according to NUMVAL }
          outfsize(numval, magnification);

          sizeheader:=truncate24('\'+sizecode[bracelvl]);
          if(sizeheader='\footnotesize') then sizeheader:='\footnsize';

(* correct font names in bfslcode[bracelvl] according to latex209  or latex2e *)
          font_clean(sizeheader,magnification);
          
          if (not par_to_begin) then
            begin output_size(sizecode[bracelvl]);
              output_bfsl;
              if last_is('}') then
              else if last_is('{') then
              else outstg('{}')
              ; {END IF}
            end
          ; {END IF}
        end
      else if(pos('RTFsb{',inkeyw) > 0) then
        begin outkrem('par'); outkrem('par ');
          if(lvlcode[bracelvl]<>8) and (lvlcode[bracelvl]<>9) then outkeyw('par ');
             make_RTFsab(numval);
        end
      else if(pos('RTFsa{',inkeyw) > 0) then save_skip:=numval
      else if(pos('RTFtrleft{',inkeyw) > 0) then (* en attente *)
      else if(pos('\RTFcellx{',inkeyw)>0) and (lvlcode[bracelvl]=13) then
        begin
          (* \RTCcellx gives absolutes abscissae, but tabular's p{} needs differences *)
          diff_cellx:=numval-tab_cellx[bracelvl];
          outstg('p{'); output_num(diff_cellx); outstg('\RTFtwips}');
          if clbrdrl then outchr('|'); clbrdrl:=FALSE;
          tab_nb_cellx[bracelvl]:=tab_nb_cellx[bracelvl]+1;
          tab_cellx[bracelvl]:=numval;
        end
      else if(pos('RTFpicw{',inkeyw) > 0) then
        begin inkeyw:=inkeyw+'}'; outrem_empty_braces; outstg(inkeyw);
          rtfpicw:=NUMVAL;
        end
      else if(pos('RTFpich{',inkeyw) > 0) then
        begin inkeyw:=inkeyw+'}'; outrem_empty_braces; outstg(inkeyw);
          rtfpich:=NUMVAL;
        end
      else if(pos('RTFobjw{',inkeyw) > 0) then
        begin inkeyw:=inkeyw+'}'; outrem_empty_braces; outstg(inkeyw);
          rtfpicw:=NUMVAL;
        end
      else if(pos('RTFobjh{',inkeyw) > 0) then
        begin inkeyw:=inkeyw+'}'; outrem_empty_braces; outstg(inkeyw);
          rtfpich:=NUMVAL;
        end
{ case of \|DO( ... ) }
      else if(pos('\RTFformulaDO{',inkeyw) > 0) then
        if form_code[bracelvl]='' then form_code[bracelvl]:='\RTFformulaSDO'
        else form_code[bracelvl]:=truncate24(form_code[bracelvl]+'DO')
{ case of \|UP( ... ) }
      else if(pos('\RTFformulaUP{',inkeyw) > 0) then
        if form_code[bracelvl]='' then form_code[bracelvl]:='\RTFformulaSUP'
        else form_code[bracelvl]:=truncate24(form_code[bracelvl]+'UP')
{ case of \|FO( ... ) }
      else if(pos('\RTFformulaFO{',inkeyw) > 0) then
        begin
          if form_code[bracelvl]='' then form_code[bracelvl]:='\RTFformulaDFO'
          else form_code[bracelvl]:=truncate24(form_code[bracelvl]+'FO')
          ; displ_skip:=numval;
        end
{ case of \|UP( ... ) }
      else if(pos('\RTFformulaBA{',inkeyw) > 0) then
        begin
          if form_code[bracelvl]='' then form_code[bracelvl]:='\RTFformulaDFO'
          else form_code[bracelvl]:=truncate24(form_code[bracelvl]+'FO')
          ; displ_skip:=-numval;
        end
{ case of \|UP( ... ) }
      else if(pos('\RTFformulaLI{',inkeyw) > 0) then
        begin
          if form_code[bracelvl]='' then form_code[bracelvl]:='\RTFformulaDLI'
          else form_code[bracelvl]:=truncate24(form_code[bracelvl]+'LI')
          ; displ_skip:=numval;
        end
{ case of \|AI( ... ) }
      else if(pos('\RTFformulaAI{',inkeyw) > 0) then
{ case of \|DI( ... ) }
      else if(pos('\RTFformulaDI{',inkeyw) > 0) then
{ this test is eliminate first brace opened }
      else if(pos('RTFrtf{',inkeyw) > 0) then
        begin no_RTFrtf:=FALSE;
          inkeyw:=inkeyw+'}'; outrem_empty_braces; outstg(inkeyw);
        end
{ explicit references to symbol characters }
      else if((pos('RTFfldinstsymbol',inkeyw) +
               pos('RTFfldinstbsymbol',inkeyw) +
               pos('RTFfldinstbisymbol',inkeyw)) > 0) then
        begin if numval>255 then numval:=0;
          acc_converted:=ftech_transl[numval];
          if acc_converted <> '' then out_math(acc_converted)
          else outchr('?')
          ; {END IF acc_converted}
        end
      else
        begin poskeyw:=0; k:=pos('{',inkeyw);
          if k>0 then inkeywb:=copy(inkeyw,1,k)
          else inkeywb:=truncate24(inkeyw+'}');
(* check whether this keyword should be skipped in output *)
          for k:=1 to num_skip_strings do
            poskeyw:=poskeyw+pos(inkeywb,skip_strings[k])
          ; {END DO}
          if poskeyw=0 then
            begin inkeyw:=inkeyw+'}'; outrem_empty_braces; outstg(inkeyw);
            end
          ; {END IF poskeyw}
        end
      ; {END IF}
      keyw:=0;
      if(kar <> ' ') then do_it_again:=TRUE;
    end
  ; {END IF}
end;

{---------------------------------------------------------------------------}
{ treats a character when KEYW is 4 }
{ Hexadecimal arg of RTFac }

procedure keyw_is_4;
var
  acchexa : string2;
  acc_converted : string24;
  posbrace : integer;
begin
  if(cat=10) then

  else if(num_hexa=0) then
    begin num_hexa:=1; hexaone:=kar;
    end
  else if(num_hexa=1) then
    begin hexatwo:=kar; acchexa:=hexaone+hexatwo; begin_par;
      if (active_RTFf[bracelvl]='ftech') then
        begin acc_converted:=ftech_transl[hs_to_i(acchexa)];
          if (acc_converted <> '') then out_math(acc_converted)
          else outkeyw('RTFac{'+acchexa+'}')
          ; {END IF acc_converted}
        end
      else
        begin acc_converted:=acc_transl[hs_to_i(acchexa)];
          if (acc_converted <> '') then
            begin if (acc_converted[1]='\') then outrem_empty_braces;
              posbrace:= pos('{',acc_converted);
              if (acc_converted[1]='$') then
                begin outrem_empty_braces;
                  out_math(copy(acc_converted,2,999));
                end
              else if posbrace<=1 then
                outstgc(acc_converted)
              else if (pos('\c{',acc_converted)
                      +pos('\dag{',acc_converted)
                      +pos('\pound{',acc_converted)
                      +pos('\copyright{',acc_converted)
                      +pos('\degree{',acc_converted))>0 then
                begin
                  outstg(copy(acc_converted,1,posbrace-1));
                  outstgc(copy(acc_converted,posbrace,999));
                end
              else outstgc(acc_converted)
              ; {END IF}
            end
          else
            begin outkeyw('RTFac{'); outstg(acchexa); outchr('}');
            end
          ; {END IF acc_converted}
        end
      ; {END IF active_RTF}
      num_hexa:=0; keyw:=0;
    end
  else
    begin sign_str(num_hexa,works); println_msg(0,'Wrong num_hexa:'+works);
    end
  ; {END IF}

end;

{---------------------------------------------------------------------------}
procedure make_latex_header;
var
  i : integer;
  strpts : string24;
begin
  if latex209 then
    outkeyw('documentstyle[')
  else
    outkeyw('documentclass[')
  ; {END IF}
  if(stdsize <> 10) then
    begin sign_str(stdsize, strpts); outstg(strpts+'pt,')
    end
  ; {END IF}
  outstg('twoside');  

  if latex209 then
    begin
      for i:=0 to num_latex_options do
      outstg(','+latex_options[i]);
      outstg(']{'+latex_style+'}'); output_line;
    end
  else
    begin
      outstg(']{'+latex_style+'}'); output_line;
      outkeyw('usepackage{');
      outstg(latex_options[0]);
      for i:=1 to num_latex_options do
      outstg(','+latex_options[i]);
      outstg('}'); output_line;
    end    
  ;    



  outkeyw('begin{document}\RTFsetfontheading'); output_line;
end;

{---------------------------------------------------------------------------}
{                               MAIN                                        }
{---------------------------------------------------------------------------}
begin
  clean_all;   (* for safety... *)

 latex209:=FALSE; write_log:=FALSE; use_sl:=FALSE; latex_header:=TRUE;
 simplify_ok:=TRUE; no_RTFrtf:=TRUE; base_flag:=FALSE;
 no_space_conv:=FALSE;
 last_percent:=FALSE; num_latex_options:=0; latex_style:='report';
 latex_options[0]:='rtflatex'; kar:=chr(0); save_skip:=0; space_after:=0;
 math_mode[0]:=0; auto_close[0]:=FALSE; bracelvl:=0; input_line_number:=1;
 (* envir_closed_ok:=FALSE; (test) *)
 envir_closed_ok:=TRUE;
 num_styles:=0; displ_skip:=0;
 for k:=0 to 255 do ref_styles[k]:=0;

 verbose:=1; { default moderate verbosity }
 tex_verbose:=0; { no insertion of flags within TeX output }

 title; charinit; sizeinit; open_files;

{ "lvlcode" : say what to do of the contents of that block. 1=ignore
until end of  current block, 2=caps, 3=ignore footnote headings, 4=
ignore contents of first arg of \footnote, 5= \RTFpict text, 6= \fonttbl
declaration, 7= \RTFformulaX[xx], 8= within \stylesheet, 9= within
\header/\footer, 9= within \RTFcolortbl, 10= \RTFobject text, 11=
\RTFfield text, 12= inside \RTFfldinst, 13= inside \RTFtrowd/\RTFrow,
15= inside \RTFtrowd/RTFrow after \RTFintbl, 16=
within \RTFformulaB(...), 17= within \RTFformulaF(...), 18=
\RTFformulaSUP(...), 19= \RTFformulaSDO(...), 20= \RTFformulaI, 21= idem
after ";", 22= idem after second ";", 23= \RTFformulaR, 24= \RTFformulaR
after ";", 25= ordinary brace within a formula, 26=\RTFformulaO,
27=\RTFformulaL, 28=\RTFformulaD }
 lvlcode[0]:=0;

{ bfslcode stores the recorded \bf, \sl, \it, \sf commands
 to repeat them AFTER \large, \Large }
 bfslcode[0]:=''; sizecode[0]:='normalsize'; active_RTFf[0]:='';
close_kar[0]:=' '; form_code[0]:=''; spacingcode[0]:='relax';
currsize[0]:=''; currbfsl[0]:=''; leftskip:=0; rightskip:=0;
leftcurskip:=0; rightcurskip:=0;
tab_nb_cellx[0]:=0; (* the number of cells in a tabular line = #\RTFcellx *)
tab_nb_ands[0]:=0; (* the number of &, must be < #\RTFcellx *)
tab_cellx[0]:=0; (* current \RTFcellx value *)
clbrdrr:=FALSE;  clbrdrl:=FALSE;  clbrdrt:=FALSE;  clbrdrb:=FALSE;

 inkeyw:=''; numl:=0; numval:=0; numsign:=1; num_hexa:=0; ikar:=0; kinp:=0;
 prev_kinp:=0; next_rtf:=''; num_indent:=0;
 num_word_fonts:=0; { number of RTF/Word defined fonts }
 numfonts:=0; { number of specially defined fonts }
 KEYW:=0; { a flag to say whether we are decoding a keyword }
 pict_number:=0; { counts the pictures }

 center_flag[0]:=0; flushright_flag[0]:=0; do_it_again:=FALSE;
 underl_flag[0]:=FALSE; par_to_begin:=TRUE;

 cleanout;  { clean EXFILE for safety }

 if(latex_header) then make_latex_header;

{ main loop to read input RTF file }

 read_next_char;
 while (ikar <> 26) do
  begin
  { read one character unless said to be retried }
    if(do_it_again) then do_it_again:=FALSE
    else read_char
    ; {END IF}
    if(ikar>=ord(' ')) then
      case KEYW of
        0: keyw_is_0;
        1: keyw_is_1;
        2: keyw_is_2;
        3: keyw_is_3;
        4: keyw_is_4;
      end; { case KEYW }
    ; {END IF ikar}

  end;
  if center_flag[bracelvl] > 0 then outkeyw('end{center}');
  if latex_header then outkeyw('end{document}')
  else outkeyw('bye')
  ; {END IF latex_header}
  output_line;

  println_msg(0,'RTFLaTeX terminated');
  sign_str(bracelvl,works); println_msg(0,'brace level finally is:'+works);
  sign_str(numl,works);
  if(numl>0) then println_msg(0,works+' lines of code were generated.');
  sign_str(numfonts,works);
  if(numfonts>0) then println_msg(0,works+' new fonts were declared:');
  for k:=1 to numfonts do println_msg(0,'    '+newfonts[k]);
  sign_str(pict_number,works);
  if(pict_number>0) then println_msg(0,works+' pictures were stored in binary files.');
  close_files;
end.


