(* version 2.15 *)

{---------------------------------------------------------------------------}
{ finds the '.' initiating the postfix of the given file name }

function pos_postfix(xx : string) : integer;
var
  i : integer;
begin
  pos_postfix:=0;
  for i:=1 to length(xx) do
    begin
      if (xx[i]='.') then pos_postfix:=i
      else if (xx[i]=']') then pos_postfix:=0
      else if (xx[i]='/') then pos_postfix:=0
      else if (xx[i]='\') then pos_postfix:=0
      else if (xx[i]=':') then pos_postfix:=0
      ; {END IF}
    end
  ; {END DO} 
end;
    
{---------------------------------------------------------------------------}
{ the signed variant of str(n,stg) }

procedure sign_str(num : integer; var out_sign_str : string24);
var
  sign_work : string255;
begin
  str(num, sign_work);
(*  if (num<0) then out_sign_str:='-'+sign_work *)
  if (num<0) then out_sign_str:=truncate24('-'+sign_work)
  else out_sign_str:=truncate24(sign_work)
  ; {END IF}
end;
    
{---------------------------------------------------------------------------}
{ prints/displays a message }

procedure print_msg (verbose_level : integer; msg : string);
begin
  if (verbose >= verbose_level) then write(msg);
  if write_log then write(logfile, msg);
end;

{---------------------------------------------------------------------------}
{ prints/displays a message with RETURN }

procedure println_msg (verbose_level : integer; msg : string);
begin
  if (verbose >= verbose_level) then writeln(msg);
  if write_log then writeln(logfile, msg);
end;

{ ======================================================================= }
{ used at initialization to store one size name (Latex) and its magnitudes }

procedure sizeone(i : integer; s : string; j,k,l : integer;
mag10, mag11, mag12 : integer);
begin
  sizekey[i]:=truncate24(s);
  sizeval[1,i]:=j; sizemags[1,i]:=mag10;
  sizeval[2,i]:=k; sizemags[2,i]:=mag11;
  sizeval[3,i]:=l; sizemags[3,i]:=mag12;
end;

{ ======================================================================= }
{ initialization of LaTeX font heights <==> size keywords }

procedure sizeinit;
var
  k : integer;
begin
  sizeone(1, 'HUGE',       720, 720, 840, 2986, 2986, 3583);
  sizeone(2, 'Huge',       600, 600, 720, 2488, 2488, 2986);
  sizeone(3, 'huge',       500, 500, 600, 2074, 2074, 2488);
  sizeone(4, 'LARGE',      440, 440, 500, 1728, 1728, 2074);
  sizeone(5, 'Large',      360, 360, 440, 1440, 1440, 1728);
  sizeone(6, 'large',      280, 280, 360, 1200, 1200, 1440);
  sizeone(7, 'normalsize', 240, 272, 290, 1000, 1095, 1200);
  sizeone(8, 'small',      220, 240, 272,  900, 1000, 1095);
  sizeone(9,'footnotesize',190, 220, 240,  800,  900, 1000);
  sizeone(10,'scriptsize', 160, 190, 190,  700,  800,  800);
  sizeone(11,'tiny'      , 120, 140, 140,  500,  600,  600);
  for k:=12 to 16 do sizeone(k,'tiny',0,0,0,500,600,600);
  num_diff_sizes:=11;

  for k:=0 to 10 do environ_type[k]:='\RTFerror';

  environ_type[0]:='document'; environ_type[1]:='center';
  environ_type[2]:='flushright';

end;

{ ======================================================================= }

procedure mac_init;
var
  k : integer;
begin

{ install the conversions of RTF accents (coded \'xx in hexa) }
{ build a list of conversion of accented letters }

  for k:=0 to 255 do acc_transl[k]:='';

  acc_transl[hs_to_i('80')]:='"A';
  acc_transl[hs_to_i('81')]:='\AA{}';
  acc_transl[hs_to_i('82')]:='\c{C}';
  acc_transl[hs_to_i('83')]:='\''E';
  acc_transl[hs_to_i('84')]:='\~N';
  acc_transl[hs_to_i('85')]:='\"O';
  acc_transl[hs_to_i('86')]:='\"U';
  acc_transl[hs_to_i('87')]:='\''a';
  acc_transl[hs_to_i('88')]:='\`a';
  acc_transl[hs_to_i('89')]:='\^a';
  acc_transl[hs_to_i('8a')]:='\"a';
  acc_transl[hs_to_i('8b')]:='\~a';
  acc_transl[hs_to_i('8c')]:='\aa{}';
  acc_transl[hs_to_i('8d')]:='\c{c}';
  acc_transl[hs_to_i('8e')]:='\''e';
  acc_transl[hs_to_i('8f')]:='\`e';
  acc_transl[hs_to_i('90')]:='\^e';
  acc_transl[hs_to_i('91')]:='\"e';
  acc_transl[hs_to_i('93')]:='\''{\i}';
  acc_transl[hs_to_i('93')]:='\`{\i}';
  acc_transl[hs_to_i('94')]:='\^{\i}';
  acc_transl[hs_to_i('95')]:='\"{\i}';
  acc_transl[hs_to_i('96')]:='\~n';
  acc_transl[hs_to_i('97')]:='\''o';
  acc_transl[hs_to_i('98')]:='\`o';
  acc_transl[hs_to_i('99')]:='\^o';
  acc_transl[hs_to_i('9a')]:='\"o';
  acc_transl[hs_to_i('9b')]:='\~o';
  acc_transl[hs_to_i('9c')]:='\''u';
  acc_transl[hs_to_i('9d')]:='\`u';
  acc_transl[hs_to_i('9e')]:='\^u';
  acc_transl[hs_to_i('9f')]:='\"u';
  acc_transl[hs_to_i('a0')]:='\dag{}';
  acc_transl[hs_to_i('a1')]:='\degree{}';
  acc_transl[hs_to_i('a3')]:='\pound{}';
  acc_transl[hs_to_i('a4')]:='\S{}';
  acc_transl[hs_to_i('a7')]:='\ss{}';
  acc_transl[hs_to_i('ae')]:='\AE{}';
  acc_transl[hs_to_i('af')]:='\O{}';
  acc_transl[hs_to_i('b0')]:='$\infty ';
  acc_transl[hs_to_i('b1')]:='$\pm ';
  acc_transl[hs_to_i('b2')]:='$\leq ';
  acc_transl[hs_to_i('b3')]:='$\geq ';
  acc_transl[hs_to_i('b5')]:='$\mu ';
  acc_transl[hs_to_i('b6')]:='$\partial ';
  acc_transl[hs_to_i('b7')]:='$\Sigma ';
  acc_transl[hs_to_i('b8')]:='$\Pi ';
  acc_transl[hs_to_i('b9')]:='$\pi ';
  acc_transl[hs_to_i('bd')]:='${1\over2}';
  acc_transl[hs_to_i('bf')]:='\o{}';
  acc_transl[hs_to_i('c6')]:='$\Delta ';
  acc_transl[hs_to_i('c9')]:='...';
  acc_transl[hs_to_i('cb')]:='\`A';
  acc_transl[hs_to_i('cc')]:='\~A';
  acc_transl[hs_to_i('cd')]:='\~O';
  acc_transl[hs_to_i('ce')]:='\OE{}';
  acc_transl[hs_to_i('cf')]:='\oe{}';
  acc_transl[hs_to_i('d0')]:='--{}';
  acc_transl[hs_to_i('d1')]:='---{}';
  acc_transl[hs_to_i('d2')]:='``';
  acc_transl[hs_to_i('d3')]:='''''';
  acc_transl[hs_to_i('d4')]:='`{}';
  acc_transl[hs_to_i('d5')]:='''{}';
  acc_transl[hs_to_i('d6')]:='$\div ';
  acc_transl[hs_to_i('d8')]:='\"y';
  acc_transl[hs_to_i('e1')]:='$\cdot ';
  acc_transl[hs_to_i('e4')]:='\"a';
  acc_transl[hs_to_i('e5')]:='\^A';
  acc_transl[hs_to_i('e6')]:='\^E';
  acc_transl[hs_to_i('e7')]:='\''A';
  acc_transl[hs_to_i('e8')]:='\"E';
  acc_transl[hs_to_i('e9')]:='\`E';
  acc_transl[hs_to_i('ea')]:='\''I';
  acc_transl[hs_to_i('eb')]:='\^I';
  acc_transl[hs_to_i('ec')]:='\"I';
  acc_transl[hs_to_i('ed')]:='\`I';
  acc_transl[hs_to_i('ee')]:='\''O';
  acc_transl[hs_to_i('ef')]:='\^O';
  acc_transl[hs_to_i('f1')]:='\`O';
  acc_transl[hs_to_i('f2')]:='\''U';
  acc_transl[hs_to_i('f3')]:='\^U';
  acc_transl[hs_to_i('f4')]:='\`U';
  acc_transl[hs_to_i('f6')]:='\"o';
  acc_transl[hs_to_i('fb')]:='\degree{}';
  acc_transl[hs_to_i('fc')]:='\"u';

end;


{ ======================================================================= }

procedure ansi_init;
var
  k : integer;
begin

{ install the conversions of RTF accents (coded \'xx in hexa) }
{ build a list of conversion of accented letters }

  for k:=0 to 255 do acc_transl[k]:='';

  acc_transl[hs_to_i('a1')]:='!`';
  acc_transl[hs_to_i('a3')]:='\pound{}';
  acc_transl[hs_to_i('a7')]:='\S{}';
  acc_transl[hs_to_i('a8')]:='\"{ }';
  acc_transl[hs_to_i('a9')]:='\copyright{}';
  acc_transl[hs_to_i('ab')]:='<<';
  acc_transl[hs_to_i('b0')]:='\degree{}';
  acc_transl[hs_to_i('b1')]:='$\pm ';
  acc_transl[hs_to_i('b4')]:='\''{ }';
  acc_transl[hs_to_i('b5')]:='$\mu ';
  acc_transl[hs_to_i('b7')]:='$\cdot ';
  acc_transl[hs_to_i('b8')]:='\c{ }';
  acc_transl[hs_to_i('bb')]:='>>';
  acc_transl[hs_to_i('bc')]:='${1\over4}';
  acc_transl[hs_to_i('bd')]:='${1\over2}';
  acc_transl[hs_to_i('be')]:='${3\over4}';
  acc_transl[hs_to_i('bf')]:='?`';

  acc_transl[hs_to_i('c0')]:='\`A';
  acc_transl[hs_to_i('c1')]:='\''A';
  acc_transl[hs_to_i('c2')]:='\^A';
  acc_transl[hs_to_i('c3')]:='\~A';
  acc_transl[hs_to_i('c4')]:='\"A';
  acc_transl[hs_to_i('c5')]:='\AA{}';
  acc_transl[hs_to_i('c6')]:='\AE{}';
  acc_transl[hs_to_i('c7')]:='\c{C}';
  acc_transl[hs_to_i('c8')]:='\`E';
  acc_transl[hs_to_i('c9')]:='\''E';
  acc_transl[hs_to_i('ca')]:='\^E';
  acc_transl[hs_to_i('cb')]:='\"E';
  acc_transl[hs_to_i('cc')]:='\`I';
  acc_transl[hs_to_i('cd')]:='\''I';
  acc_transl[hs_to_i('ce')]:='\^I';
  acc_transl[hs_to_i('cf')]:='\"I';

  acc_transl[hs_to_i('d1')]:='\~N';
  acc_transl[hs_to_i('d2')]:='\`O';
  acc_transl[hs_to_i('d3')]:='\''O';
  acc_transl[hs_to_i('d4')]:='\^O';
  acc_transl[hs_to_i('d5')]:='\~O';
  acc_transl[hs_to_i('d6')]:='\"O';
  acc_transl[hs_to_i('d8')]:='\O';
  acc_transl[hs_to_i('d9')]:='\`U';
  acc_transl[hs_to_i('da')]:='\''U';
  acc_transl[hs_to_i('db')]:='\^U';
  acc_transl[hs_to_i('dc')]:='\"U';
  acc_transl[hs_to_i('dd')]:='\''Y';
  acc_transl[hs_to_i('df')]:='\ss{}';


  acc_transl[hs_to_i('e0')]:='\`a';
  acc_transl[hs_to_i('e1')]:='\''a';
  acc_transl[hs_to_i('e2')]:='\^a';
  acc_transl[hs_to_i('e3')]:='\~a';
  acc_transl[hs_to_i('e4')]:='\"a';
  acc_transl[hs_to_i('e5')]:='\aa{}';
  acc_transl[hs_to_i('e6')]:='\ae{}';
  acc_transl[hs_to_i('e7')]:='\c{c}';
  acc_transl[hs_to_i('e8')]:='\`e';
  acc_transl[hs_to_i('e9')]:='\''e';
  acc_transl[hs_to_i('ea')]:='\^e';
  acc_transl[hs_to_i('eb')]:='\"e';
  acc_transl[hs_to_i('ec')]:='\`i';
  acc_transl[hs_to_i('ed')]:='\''i';
  acc_transl[hs_to_i('ee')]:='\^i';
  acc_transl[hs_to_i('ef')]:='\"i';

  acc_transl[hs_to_i('f1')]:='\~n';
  acc_transl[hs_to_i('f2')]:='\`o';
  acc_transl[hs_to_i('f3')]:='\''o';
  acc_transl[hs_to_i('f4')]:='\^o';
  acc_transl[hs_to_i('f5')]:='\~o';
  acc_transl[hs_to_i('f6')]:='\"o';
  acc_transl[hs_to_i('f8')]:='\o';
  acc_transl[hs_to_i('f9')]:='\`u';
  acc_transl[hs_to_i('fa')]:='\''u';
  acc_transl[hs_to_i('fb')]:='\^u';
  acc_transl[hs_to_i('fc')]:='\"u';
  acc_transl[hs_to_i('fd')]:='\''y';
  acc_transl[hs_to_i('ff')]:='\"y';



end;

{ ======================================================================= }

procedure charinit;
var
  K : integer;
begin
  for K:=0 to 255 do catcode[K]:=12;
  for K:=ord('A') to ord('Z') do catcode[K]:=11;
  for K:=ord('a') to ord('z') do catcode[K]:=11;
  for K:=ord('0') to ord('9') do catcode[K]:=16;
  K:=ord(' '); catcode[K]:=10;
  K:=ord('{'); catcode[K]:=1;
  K:=ord('}'); catcode[K]:=2;
  K:=ord('('); catcode[K]:=3;
  K:=ord(')'); catcode[K]:=4;
  K:=ord('\'); catcode[K]:=0;

  icharz:=ord('0');

{ build an empty list of conversion of accented letters }

  for K:=0 to 255 do acc_transl[K]:='';

{ Now install the conversions of "ftech" characters into math codes
... or letters}

  for K:=0 to 255 do ftech_transl[K]:='';
  ftech_transl[ord('a')]:='\alpha ';
  ftech_transl[ord('A')]:='\Alpha ';
  ftech_transl[ord('b')]:='\beta ';
  ftech_transl[ord('B')]:='\Beta ';
  ftech_transl[ord('c')]:='\chi ';
  ftech_transl[ord('C')]:='\Chi ';
  ftech_transl[ord('d')]:='\delta ';
  ftech_transl[ord('D')]:='\Delta ';
  ftech_transl[ord('e')]:='\varepsilon ';
  ftech_transl[ord('E')]:='\Epsilon ';
  ftech_transl[ord('f')]:='\phi ';
  ftech_transl[ord('F')]:='\Phi ';
  ftech_transl[ord('g')]:='\gamma ';
  ftech_transl[ord('G')]:='\Gamma ';
  ftech_transl[ord('h')]:='\eta ';
  ftech_transl[ord('H')]:='\Eta ';
  ftech_transl[ord('i')]:='\iota ';
  ftech_transl[ord('I')]:='\Iota ';
  ftech_transl[ord('j')]:='\varphi ';
  ftech_transl[ord('J')]:='\vartheta ';
  ftech_transl[ord('k')]:='\kappa ';
  ftech_transl[ord('K')]:='\Kappa ';
  ftech_transl[ord('l')]:='\lambda ';
  ftech_transl[ord('L')]:='\Lambda ';
  ftech_transl[ord('m')]:='\mu ';
  ftech_transl[ord('M')]:='\Mu ';
  ftech_transl[ord('n')]:='\nu ';
  ftech_transl[ord('N')]:='\Nu';
  ftech_transl[ord('o')]:='o';
  ftech_transl[ord('O')]:='\Omicron ';
  ftech_transl[ord('p')]:='\pi ';
  ftech_transl[ord('P')]:='\Pi ';
  ftech_transl[ord('q')]:='\theta ';
  ftech_transl[ord('Q')]:='\Theta ';
  ftech_transl[ord('r')]:='\rho ';
  ftech_transl[ord('R')]:='\Rho ';
  ftech_transl[ord('s')]:='\sigma ';
  ftech_transl[ord('S')]:='\Sigma ';
  ftech_transl[ord('t')]:='\tau ';
  ftech_transl[ord('T')]:='\Tau ';
  ftech_transl[ord('u')]:='\upsilon ';
  ftech_transl[ord('U')]:='\varUpsilon ';
  ftech_transl[ord('v')]:='\varpi ';
  ftech_transl[ord('V')]:='\varsigma ';
  ftech_transl[ord('w')]:='\omega ';
  ftech_transl[ord('W')]:='\Omega ';
  ftech_transl[ord('x')]:='\xi ';
  ftech_transl[ord('X')]:='\Xi ';
  ftech_transl[ord('y')]:='\psi ';
  ftech_transl[ord('Y')]:='\Psi ';
  ftech_transl[ord('z')]:='\zeta ';
  ftech_transl[ord('Z')]:='\Zeta ';

  ftech_transl[ord('@')]:='\cong ';
  ftech_transl[ord('~')]:='\sim ';
  ftech_transl[ord('"')]:='\forall ';
  ftech_transl[ord('$')]:='\exists ';

  ftech_transl[hs_to_i('27')]:='\ni ';
  ftech_transl[hs_to_i('5e')]:='\bot ';
  ftech_transl[hs_to_i('a0')]:='\dag ';
  ftech_transl[hs_to_i('a1')]:='\Upsilon ';
  ftech_transl[hs_to_i('a2')]:='''';
  ftech_transl[hs_to_i('a3')]:='\leq ';
  ftech_transl[hs_to_i('a4')]:='/';
  ftech_transl[hs_to_i('a5')]:='\infty ';
  ftech_transl[hs_to_i('a6')]:='\cap ';
  ftech_transl[hs_to_i('a7')]:='\clubsuit ';
  ftech_transl[hs_to_i('a9')]:='\heartsuit ';
  ftech_transl[hs_to_i('aa')]:='\spadesuit ';
  ftech_transl[hs_to_i('ab')]:='\leftrightarrow ';
  ftech_transl[hs_to_i('ac')]:='\leftarrow ';
  ftech_transl[hs_to_i('ad')]:='\uparrow ';
  ftech_transl[hs_to_i('ae')]:='\rightarrow ';
  ftech_transl[hs_to_i('af')]:='\downarrow ';
  ftech_transl[hs_to_i('b0')]:='^{\circ}';
  ftech_transl[hs_to_i('b1')]:='\pm ';
  ftech_transl[hs_to_i('b2')]:='''''';
  ftech_transl[hs_to_i('b3')]:='\geq ';
  ftech_transl[hs_to_i('b4')]:='\times ';
  ftech_transl[hs_to_i('b5')]:='\propto ';
  ftech_transl[hs_to_i('b6')]:='\partial ';
  ftech_transl[hs_to_i('b7')]:='\bullet ';
  ftech_transl[hs_to_i('b8')]:='\div ';
  ftech_transl[hs_to_i('b9')]:='\neq ';
  ftech_transl[hs_to_i('ba')]:='\equiv ';
  ftech_transl[hs_to_i('bb')]:='\approx ';
  ftech_transl[hs_to_i('bc')]:='\ldots ';
  ftech_transl[hs_to_i('bd')]:='\mid ';
  ftech_transl[hs_to_i('c0')]:='\aleph ';
  ftech_transl[hs_to_i('c1')]:='\Im ';
  ftech_transl[hs_to_i('c2')]:='\Re ';
  ftech_transl[hs_to_i('c3')]:='\wp ';
  ftech_transl[hs_to_i('c4')]:='\otimes ';
  ftech_transl[hs_to_i('c5')]:='\oplus ';
  ftech_transl[hs_to_i('c6')]:='\oslash ';
  ftech_transl[hs_to_i('c7')]:='\cap ';
  ftech_transl[hs_to_i('c8')]:='\cup ';
  ftech_transl[hs_to_i('c9')]:='\supset ';
  ftech_transl[hs_to_i('ca')]:='\supseteq ';
  ftech_transl[hs_to_i('cb')]:='\not\subset ';
  ftech_transl[hs_to_i('cc')]:='\subset ';
  ftech_transl[hs_to_i('cd')]:='\subseteq ';
  ftech_transl[hs_to_i('ce')]:='\in ';
  ftech_transl[hs_to_i('cf')]:='\not\in ';
  ftech_transl[hs_to_i('d0')]:='\angle ';
  ftech_transl[hs_to_i('d1')]:='\nabla ';
  ftech_transl[hs_to_i('d2')]:='\registered ';
  ftech_transl[hs_to_i('d3')]:='\copyright ';
  ftech_transl[hs_to_i('d4')]:='\trademark ';
  ftech_transl[hs_to_i('d5')]:='\prod ';
  ftech_transl[hs_to_i('d7')]:='\cdot ';
  ftech_transl[hs_to_i('d8')]:='\neg ';
  ftech_transl[hs_to_i('d9')]:='\wedge ';
  ftech_transl[hs_to_i('da')]:='\vee ';
  ftech_transl[hs_to_i('db')]:='\Leftrightarrow ';
  ftech_transl[hs_to_i('dc')]:='\Leftarrow ';
  ftech_transl[hs_to_i('dd')]:='\Uparrow ';
  ftech_transl[hs_to_i('de')]:='\Rightarrow ';
  ftech_transl[hs_to_i('df')]:='\Downarrow ';
  ftech_transl[hs_to_i('e0')]:='\diamondsuit ';
  ftech_transl[hs_to_i('e1')]:='\langle ';
  ftech_transl[hs_to_i('e2')]:='\registered ';
  ftech_transl[hs_to_i('e3')]:='\copyright ';
  ftech_transl[hs_to_i('e4')]:='\trademark ';
  ftech_transl[hs_to_i('e5')]:='\sum ';
  ftech_transl[hs_to_i('e9')]:='\lceil ';
  ftech_transl[hs_to_i('ea')]:='\mid ';
  ftech_transl[hs_to_i('eb')]:='\lfloor ';
  ftech_transl[hs_to_i('f1')]:='\rangle ';
  ftech_transl[hs_to_i('f2')]:='\int ';

  end_math_code:='$';
end;

{ ======================================================================= }
{ this procedure returns a set of 4 chars, the size preamble of a non std font }
function sizealpha(i : integer) : string5;
var
  h : integer;
begin
  h:=i div 2;
  if h<= 5 then sizealpha:='\fiv'
  else if h<= 6 then sizealpha:='\six'
  else if h<= 7 then sizealpha:='\sev'
  else if h<= 8 then sizealpha:='\egt'
  else if h<= 9 then sizealpha:='\nin'
  else if h<= 10 then sizealpha:='\ten'
  else if h<= 11 then sizealpha:='\elv'
  else if h<= 13 then sizealpha:='\twl'
  else if h<= 15 then sizealpha:='\frt'
  else if h<= 18 then sizealpha:='\svtn'
  else if h<= 23 then sizealpha:='\twty'
  else if h<= 28 then sizealpha:='\twfv'
  else  sizealpha:='\thtw'
  ; {END IF}

end;

{ ======================================================================= }
{ write "help" information }

procedure write_help;
begin
      writeln('Usage: RTFLATEX [options] <input-file> [options] <output-file>');
      writeln('Options:');
      writeln('         -b         : set explicit \baselineskip at par ends');
      writeln('         -d<nnn>    : debug level: 1=default, 0=quiet, >1=verbose');
      writeln('         -f<templ>  : file template to put figures (need a * )');
      writeln('         -l<style>  : latex style (default is "report")');
      writeln('         -m         : put debugging marks in output TeX');
      writeln('         -o<option> : latex style option (cumulative)');
      writeln('         -p<value>  : std font size (10, 11, 12)');
      writeln('         -r<file>   : LOG output file (default is none)');
      writeln('         -s         : use slanted instead of italic');
      writeln('         -t         : omit LaTeX \documentstyle etc.');
      writeln('         -v         : convert text and fonts, not spacings');
      writeln('         -x         : inhibit output simplification');
      writeln('         -z<file>   : file containing list of ignored keywords');
      writeln('         -209       : assume ancient Latex209');
      halt;
end;

{---------------------------------------------------------------------------}
{ this procedure open files and set the -xxxx options }

procedure open_files;
var
  skipname, outputname, inputname, logname, optstr : string128;
  testio, cat, ikar, kparm, L, pospt : integer;
  first_char, kar : char;
  success : boolean;
  inskipk : string24;
  kkk, number_params : integer;

begin
  figure_path:='rtf*.bit'; figure_type:='';
  stdsize:=12; stdkz:=3; { standard LaTeX size : 10, 11, 12 pt }
  inputname:=''; outputname:=''; skipname:=paramstr(0); kparm:=0;
  num_skip_strings:=1;
  for L:=1 to max_skip_strings do skip_strings[L]:='';

  pospt:=pos_postfix(skipname);
  if pospt>0 then
    begin
      if (copy(skipname,pospt,length(skipname))='.EXE') then
         skipname:=copy(skipname,1,pospt)+'SKW'
      else if (copy(skipname,pospt,length(skipname))='.exe') then
         skipname:=copy(skipname,1,pospt)+'skw'
      ;
    end
  else skipname:=skipname+'.skw'
  ; {END IF}
  number_params:=paramcount;

  for kkk:=1 to number_params do
    begin
      kparm:=kkk; optstr:=paramstr(kparm); first_char:=optstr[1];
      if first_char='-' then
        begin
          writeln(first_char,'Option :>',optstr,'<');
          if optstr[2]='p' then
            begin
              stdsize:=0;
              for L:=3 to length(optstr) do
                begin
                  ikar:=ord(optstr[L]); cat:=catcode[ikar];
                  if(cat=16) then
                    stdsize:=10*stdsize+ikar-icharz
                  else
                    begin
                      writeln ('Illegal character in -p option: ',optstr); halt;
                    end
                  ;
                end
              ;
              writeln('Standard size found: ',stdsize,'pt');
              if(stdsize < 11) then stdkz:=1
              else if(stdsize=11) then stdkz:=2
              else stdkz:=3
              ; {END IF}
            end
          else if (optstr[2]='2') then latex209:=TRUE
          else if (optstr[2]='v') then no_space_conv:=TRUE
          else if (optstr[2]='s') then use_sl:=TRUE
          else if (optstr[2]='t') then latex_header:=FALSE
          else if (optstr[2]='x') then simplify_ok:=FALSE
          else if (optstr[2]='b') then base_flag:=TRUE
          else if (optstr[2]='z') then skipname:=copy(optstr,3,999)
          else if (optstr[2]='l') then
            begin latex_style:=truncate24(optstr);
              if latex_style='' then latex_style:='report';
            end
          else if (optstr[2]='o') then
            begin
              if (num_latex_options >= maxstyles) then
                writeln('Too many style options, ',optstr,' ignored !')
              else
                begin
                  num_latex_options:=num_latex_options+1;
                  latex_options[num_latex_options]:=
                    truncate24(copy(optstr,3,bfslen));
                end
              ; {END IF num_latex_options}
            end
          else if (optstr[2]='f') then
            begin figure_path:=copy(optstr,3,999); writeln('-f:',figure_path);
            end
          else if (optstr[2]='r') then
            begin logname:=copy(optstr,3,999); write_log:=TRUE;
            end
          else if (optstr[2]='m') then
            tex_verbose:=1 { insert marks in TeX output }
          else if (optstr[2]='d') then
            begin
              verbose:=0;
              for L:=3 to length(optstr) do
                begin ikar:=ord(optstr[L]); cat:=catcode[ikar];
                  if(cat=16) then
                    verbose:=10*verbose+ikar-icharz
                  else
                    begin
                      writeln ('Illegal character in -d option: ',optstr); halt;
                    end
                  ; {END IF}
                  if verbose>0 then writeln('Verbose=',verbose);
                end
            end
          else writeln('Unsupported option, ignored: ',optstr)
          ; {END IF}
        end
      else if (inputname='') then inputname:=optstr
      else if (outputname='') then outputname:=optstr
      else if (optstr <> '') then
        begin writeln ('Too many non option args : ',optstr);
          writeln ('This one ignored !');
        end
      ; {END IF}
    end
  ; {END WHILE}

  pospt:=pos('*',figure_path);
  if(pospt=0) then
    begin
      writeln('NO * in -f<path> option'); halt;
    end;
  figure_type:=copy(figure_path,pospt+1,999);
  figure_path:=copy(figure_path,1,pospt-1);

  if inputname='' then write_help; (* stops if help written *)

  if (pos_postfix(inputname)=0) then inputname:=inputname+'.rtf';

  {$I-}
  assign(inputfile,inputname); reset(inputfile);
  testio:=ioresult; success:=(testio=0);
  if (not success) then
    begin
      writeln('Unable to open input file ',inputname,' ; code=',testio); halt;
    end;

  if outputname='' then
    begin
      pospt:=pos_postfix(inputname); outputname:=copy(inputname,1,pospt)+'tex';
      writeln('Output name taken from input: ',outputname);
    end;

  if(outputname=inputname) then
    begin
      writeln('Input and output files have same names, abort!');
      writeln('  Input:  ',inputname); writeln('  Output: ',inputname);
      close(inputfile); halt;
    end;

  assign(outputfile,outputname); rewrite(outputfile);
  testio:=ioresult; success:=(testio=0);

  if not success then
    begin
      writeln('ioresult (output)=',testio);
      writeln('Unable to open output file ',outputname,' ; code=',testio);
      close(inputfile); halt;
    end
  ;
 
 (* opening skip file to eliminate useless output \RTFxxx keywords *)
  if skipname='' then
    begin
      pospt:=pos_postfix(inputname); skipname:=copy(inputname,1,pospt)+'skw';
      writeln('keyword skip file name taken from input: ',skipname);
    end;

  if(skipname=inputname) then
    begin
      writeln('Input and skip files have same names, abort!');
      writeln('  Input:  ',inputname); writeln('  skip: ',inputname);
      close(inputfile); halt;
    end;

  assign(skipfile,skipname); reset(skipfile);
  testio:=ioresult; success:=(testio=0);

  if not success then
    begin
      writeln('ioresult (keyword skip file)=',testio);
      writeln('Unable to open keyword skip file ',skipname,' ; code=',testio);
      close(inputfile); halt;
    end
  ;

  {$I-}

  if write_log then
    begin
      if (logname='') then
        begin
          pospt:=pos_postfix(inputname); logname:=copy(inputname,1,pospt)+'log';
          writeln('Log name taken from input   : ',logname);
        end
      ; {END IF logname}

      if(logname=inputname) or (logname=outputname) then
        begin
          writeln('Log and input or output files have same names, abort!');
          writeln('  Log:    ',logname);  close(inputfile); halt;
        end
      ; {END IF logname}

      assign(logfile,logname); rewrite(logfile); testio:=ioresult;
      write_log:=(testio=0);

      if not write_log then
        begin
          writeln('ioresult (Log)=',testio);
          writeln('Unable to open log file ',logname,' ; code=',testio);
          close(inputfile); halt;
        end
      ; {END IF not success}
      {$I-}
      write(logname,', ');
    end
  ; {END IF write_log}
  writeln(inputname,', ',skipname,' and ',outputname,' successfully opened.');

  while (not eof(skipfile)) do
    begin
      readln(skipfile,inskipk); println_msg(2,'Cancelling "'+inskipk+'"');
      if inskipk<> '' then
        begin
          if length(inskipk)+length(skip_strings[num_skip_strings])<255 then
            skip_strings[num_skip_strings]:=
              skip_strings[num_skip_strings]+inskipk+' '
          else if num_skip_strings<max_skip_strings then
            begin num_skip_strings:=num_skip_strings+1;
            skip_strings[num_skip_strings]:=
              skip_strings[num_skip_strings]+inskipk+' '
            end
          else
            println_msg(1,'Too many keywords to ignore, '+inskipk+' not recorded!')
          ; {END IF}
        end
      ; {END IF}
    end
  ; {END DO}
end;

{---------------------------------------------------------------------------}
{ clean the output line }

procedure cleanout;
begin
 for i:=1 to olmx do exline[i]:=' '; kout:=0;
end;


{---------------------------------------------------------------------------}
{ prints/displays the current stored output line }

procedure print_line (verbose_level : integer);
var
  i : integer;
begin
  for i:=1 to kout do print_msg(verbose_level,exline[i]);
  println_msg(verbose_level,'<<<');
end;

{---------------------------------------------------------------------------}
{ makes the pos function in an array of type exline_type }

function array_pos (oldstring : string; testline : exline_type;
  array_long : integer) : integer;
var
  string_found : boolean;
  lth1, jpos, kpos : integer;
begin
  array_pos:=0; lth1:=length(oldstring);
  for kpos:=1 to array_long-lth1+1 do
    begin
      string_found:=TRUE;
      for jpos:=1 to lth1 do
        string_found:=string_found and (oldstring[jpos]=testline[kpos+jpos-1])
      ; {END DO}
      if string_found then
        begin
          array_pos:=kpos; exit;
        end
      ; {END IF}
    end
  ; {END DO}
end;


{---------------------------------------------------------------------------}
{ substitute a string with another in output line }

procedure outsubstitute (oldstring, newstring : string);
var
  string_found : boolean;
  lth1, lth2, jpos, kpos, oldkout : integer;
  oldline : exline_type;
begin
  string_found:=TRUE; lth1:=length(oldstring); lth2:=length(newstring);
  while string_found do
    begin
      kpos:=array_pos(oldstring,exline,kout);
      string_found:=(kpos>0);
      if string_found then
        begin
          oldline:=exline; oldkout:=kout; kout:=kpos-1;
          for jpos:=1 to lth2 do
            begin
              kout:=kout+1; exline[kout]:=newstring[jpos];
            end
          ; {END DO}
          for jpos:=kpos+lth1 to oldkout do
            begin
              kout:=kout+1; exline[kout]:=oldline[jpos];
            end
          ; {END DO}
          for jpos:=kout+1 to olmx do exline[jpos]:=' '
          ; {END DO}
        end
      ; {END IF}
    end
  ; {END DO}
end;

{---------------------------------------------------------------------------}
{ converts an integer number of twips into a decimal string }

procedure  str_twips_pt(numval: integer; var outpts: string24);
var
  k, l: integer;
  wk: string24;
begin
  k:=5*numval; { convert to hundredth of pts }
  sign_str(k,wk); if(length(wk)<2) then wk:=truncate24('00'+wk);
  l:=length(wk); outpts:=truncate24(copy(wk,1,l-2)+'.'+copy(wk,l-1,2));
end;

{---------------------------------------------------------------------------}
{ eliminates end replaces useless sequences in output -- pragmatic feature }

procedure simplify (oldstring, newstring : string);
begin if simplify_ok then outsubstitute(oldstring, newstring);
end;


{---------------------------------------------------------------------------}
{ read the future chars, excluding control chars < ord(' ') }

procedure read_next_char;
var
  next_ikar : integer;
  next_char : char;
begin
  next_ikar:=0; next_char:=chr(next_ikar);
  while ((not eof(inputfile)) and (next_ikar < ord(' ')) and
    (length(next_rtf)<8)) do
    begin
      read(inputfile,next_char); next_ikar:=ord(next_char);
      if next_ikar=13 then
        begin input_line_number:=input_line_number+1;
          prev_line:=inpline; prev_kinp:=kinp; kinp:=0;
        end
      else if (next_ikar >= ord(' ')) then
        next_rtf:=next_rtf+next_char
      ; {END IF}
    end
  ; {END DO}
end;

{---------------------------------------------------------------------------}
{ read one char except nulls }

procedure read_char;
begin
  if (length(next_rtf)>0) then
    begin kar:=next_rtf[1]; delete(next_rtf,1,1); read_next_char;
    end
  else
    kar:=chr(26)
  ; {END IF}
  ikar:=ord(kar); cat:=catcode[ikar];
  if (length(next_rtf)=0) then next_rtf:=next_rtf+chr(26)
  ; {END IF}

  if kinp<lmx then
    begin kinp:=kinp+1; inpline[kinp]:=kar;
    end
  ; {END IF}
end;


{---------------------------------------------------------------------------}
{ outputs the stored output line }

procedure output_line;
var
  i : integer;
  simpl_pattern : string24;
begin
  numl:=numl+1;
  simplify('{{}','{'); simplify('{}}','}'); simplify('{}{}','{}');
  for i:=1 to num_diff_sizes do
    begin simpl_pattern:=truncate24('\'+sizekey[i]);
      simplify(simpl_pattern+'{}\',simpl_pattern+'\');
      simplify(simpl_pattern+'}','}');
    end
  ; {END DO}
  simplify('\root{}\of{','\sqrt{');

  for i:=1 to kout do write(outputfile, exline[i]);
  writeln(outputfile);

  if((NUML mod 100)=0) then
    begin
      if (verbose>0) then
        begin sign_str(NUML,works); print_msg(1,'Output : '+works+' lines ');
          for j:=1 to bracelvl do print_msg(1,'{'); println_msg(1,'');
        end
      else write('.')
      ;
    end
  ; {END IF NUML}
  cleanout;
end;

{---------------------------------------------------------------------------}
{ write a character into output line }

procedure output_real_line;
begin
  if (kout>0) then output_line;
end;

{---------------------------------------------------------------------------}
{ write a character into output line }

procedure outchr (CHARAC : char);
var
  oldchar, newchar : char;
begin
  newchar:=CHARAC;
    if(kout > 0) then
      begin oldchar:=exline[kout];
        if((oldchar=' ') and (newchar=' ')) then exit;
      end
    else if ((kout=0) and last_percent and (CHARAC=' ')) then
      begin kout:=1; EXLINE[kout]:='\';
      end
    ; {END IF}
    last_percent:=FALSE;

    if(kout < olmx-2) then
      begin kout:=kout+1; exline[kout]:=newchar;
        if(newchar='}') and (kout > 80) then
          begin
            if (EXLINE[kout-1]=';') then
              begin EXLINE[kout]:='\';
                kout:=kout+1; EXLINE[KOUT]:='r';
                kout:=kout+1; EXLINE[KOUT]:='e';
                kout:=kout+1; EXLINE[KOUT]:='l';
                kout:=kout+1; EXLINE[KOUT]:='a';
                kout:=kout+1; EXLINE[KOUT]:='x'; output_line;
                kout:=kout+1; EXLINE[KOUT]:=' ';
                kout:=kout+1; EXLINE[KOUT]:=newchar;
              end
            else if (kout > 120) then
              begin
                kout:=kout+1; EXLINE[KOUT]:='%';
                kout:=kout+1; EXLINE[KOUT]:='%';
                output_line; last_percent:=TRUE;
              end
            ; {END IF}
          end
        else if(newchar=' ') and (kout > 64) then  output_line
        ; {END IF}
      end
    else
      begin sign_str(KOUT,works); println_msg(0,'Output overflow, KOUT:='+works);
      end
    ; {END IF}
end;


{ ===================================================================== }
{ change contents of bfslcode[bracelvl] : replace first arg with 2nd }
{ but do not declare font, since output will be standard }

procedure font_subs2e(old, new: string);
var
  workstg : string[48];
  positn : integer;
begin
  positn:=pos(old,bfslcode[bracelvl]); if(positn=0) then exit;
  if lvlcode[bracelvl]= 9 then exit; (* ignore new fonts in header/footer *)
  if (verbose>=2) then
    write('font_subs2e: ',old,'|',bfslcode[bracelvl],'|',new)
  ;
  workstg:=bfslcode[bracelvl]; delete(workstg,positn,length(old));
  if (pos(new,workstg)=0) then insert(new,workstg,positn);
  bfslcode[bracelvl]:=truncate24(workstg);
  if (verbose>=2) then
    writeln('=>',workstg)
  ;
end;

{---------------------------------------------------------------------------}
{ inserts a new font specification like \bf \rm \sc into bfslcode[bracelvl] }

procedure add_to_bfsl(kod : string);
var
  bfsl_try : string[64]; bfsl_old : string[64];
begin (* bfsl_old:=bfslcode[bracelvl]; *)
  bfsl_try:=bfslcode[bracelvl]+'\';
  if (pos(kod+'\',bfsl_try)>0) then exit;
  bfslcode[bracelvl]:=truncate24(bfslcode[bracelvl]+kod);
  (*  writeln('add_to:',bfsl_old,'+',kod,'=',bfslcode[bracelvl]); *)
end;


{---------------------------------------------------------------------------}
{ output one character capitalized if needed }

procedure outchrc (CHARAC : char);
var
  kar : char;
begin
  if(lvlcode[bracelvl]=2) then kar:=upcase(CHARAC)
  else kar:=CHARAC; outchr(kar);
end;

{---------------------------------------------------------------------------}
{ write a string into output line }

procedure outstg (CHARACs : string);
var
  k : integer;
begin for k:=1 to length(CHARACs) do outchr(CHARACs[k]);
end;

{ ===================================================================== }
{ checks the presence of a string at end of current output }

function last_is(CHARACs : string) : boolean;
var
  k, long : integer;
begin
  long:=length(CHARACs); last_is:=FALSE;
  if(kout < long) then exit;
  for k:=1 to long do
    if (exline[kout-long+k] <> CHARACs[k]) then exit;
  last_is:=TRUE;
end;

{ ===================================================================== }
{ remove one string from output }

procedure outrem(CHARACs : string);
var
  k, l, long : integer;
begin
  long:=length(CHARACs); removed_OK:=last_is(CHARACs);
  if(not removed_OK) then exit;
  for k:=kout-long+1 to kout do exline[kout]:=' ';
  kout:=kout-long;
end;

{ ===================================================================== }
{ remove all empty pairs of braces at the end of output }

procedure outrem_empty_braces;
var
  num_removed : integer;
begin
  num_removed:=0; removed_OK:=TRUE;
  while removed_OK do
    begin
      outrem('{}'); if removed_OK then num_removed:=num_removed+1;
    end
  ; {END WHILE}
  removed_OK:=(num_removed>0);
end;


{---------------------------------------------------------------------------}
{ output a TeX keyword ( the \ not in args ) on output line EXLINE }

procedure outkeyw(CHARACs : string);
var
  k : integer;
begin
{ eliminate useless brace pairs terminating a previous keyword}
  outrem_empty_braces;
  outchr('\'); for k:=1 to length(CHARACs) do outchr(CHARACs[k]);
end;


{---------------------------------------------------------------------------}
{ outputs the new \bf \sl code if different from current at that level }

procedure output_bfsl;
begin
  if bfslcode[bracelvl]=currbfsl[bracelvl] then exit
  else if bfslcode[bracelvl]='\relax' then exit
  else if math_mode[bracelvl]>0 then exit
  else
    begin outrem_empty_braces; outrem(currbfsl[bracelvl]);
      font_subs2e('\rm\bf','\bf');
      font_subs2e('\rm\tt','\tt');
      font_subs2e('\rm\it','\it');
      font_subs2e('\rm\sf','\sf');
      font_subs2e('\rm\sl','\sl');

      if(latex209) then
      else (* latex2e *)
        begin
          font_subs2e('\bf\it','\bfit');
          font_subs2e('\it\bf','\bfit');
          font_subs2e('\bf\sl','\bfsl');
          font_subs2e('\sl\bf','\bfsl');
          font_subs2e('\bf\sf','\sfbf');
          font_subs2e('\sf\bf','\sfbf');
          font_subs2e('\sf\it','\sfit');
          font_subs2e('\sf\sl','\sfsl');
          font_subs2e('\tt\bf','\ttbf');
          font_subs2e('\tt\it','\ttit');
          font_subs2e('\tt\sl','\ttsl');
          font_subs2e('\bf\tt','\ttbf');
          font_subs2e('\it\tt','\ttit');
          font_subs2e('\sl\tt','\ttsl');
          font_subs2e('\sfit\bf','\sfbfit');
          font_subs2e('\sfsl\bf','\sfbfsl');
          font_subs2e('\bfit\sf','\sfbfit');
          font_subs2e('\bfsl\sf','\sfbfsl');
        end
      ; {END IF latex209}
      outstg(bfslcode[bracelvl]); outstg('{}');
      currbfsl[bracelvl]:=bfslcode[bracelvl];
    end
end;

{---------------------------------------------------------------------------}
{ outputs the new \large code if different from current at that level }

procedure output_size ( codesize : string24 );
begin
  if codesize=currsize[bracelvl] then exit
  else if codesize='relax' then exit
  else if lvlcode[bracelvl]=8 then exit
  else if lvlcode[bracelvl]=9 then exit
  else if math_mode[bracelvl]>0 then exit
  else
    begin outkeyw(codesize);
      if (not base_flag) then
        begin outstg('{}'); currsize[bracelvl]:=codesize;
        end
      ; {END IF}
      currbfsl[bracelvl]:='\relax';
    end
end;

{ ----------------------------------------------------------------------}
procedure ensure_sizebfsl;
begin
  if(par_to_begin) then exit;
  if last_is('{') then output_size(sizecode[bracelvl]);
  output_bfsl;
end;

{ ----------------------------------------------------------------------}
procedure output_skips;
begin
  if(leftcurskip<>leftskip) then
    begin str_twips_pt(leftskip,worksa);
    outkeyw('global\leftskip '); outstg(worksa); outstg('pt\relax');
    leftcurskip:=leftskip;
  end;

  if(rightcurskip<>rightskip) then
    begin str_twips_pt(rightskip,worksa);
    outkeyw('global\rightskip '); outstg(worksa); outstg('pt\relax');
    rightcurskip:=rightskip;
  end;
end;


{---------------------------------------------------------------------------}
procedure close_files;

begin
 close(outputfile); close(inputfile); if write_log then close(logfile);
end;


{ ===================================================================== }
{ remove one keyword from output }

procedure outkrem(CHARACs : string);
begin
  outrem('\'+CHARACs);
end;


{ --------------------------------------------------------------------------}
{ open brace and increment  bracelvl }

procedure open_brace;
begin
  if(bracelvl < maxlevel) then
    begin bracelvl:=bracelvl+1;
      bfslcode[bracelvl]:=bfslcode[bracelvl-1];
      tab_nb_cellx[bracelvl]:=tab_nb_cellx[bracelvl-1];
      tab_cellx[bracelvl]:=0;
      sizecode[bracelvl]:=sizecode[bracelvl-1];
      currsize[bracelvl]:=currsize[bracelvl-1];
      currbfsl[bracelvl]:=currbfsl[bracelvl-1];
      spacingcode[bracelvl]:=spacingcode[bracelvl-1];
      lvlcode[bracelvl]:=lvlcode[bracelvl-1];
      if(bracelvl<maxlevel) then lvlcode[bracelvl+1]:=0;
      active_RTFf[bracelvl]:=active_RTFf[bracelvl-1];
{ propagate math_mode, but say 2 if previous was 1 to avoid extra closins by $ }
      math_mode[bracelvl]:=math_mode[bracelvl-1];
      if(math_mode[bracelvl]=1) then math_mode[bracelvl]:=2;

      flushright_flag[bracelvl]:=flushright_flag[bracelvl-1];
      if(flushright_flag[bracelvl]=2) then flushright_flag[bracelvl]:=3;

      center_flag[bracelvl]:=center_flag[bracelvl-1];
      if(center_flag[bracelvl]=2) then center_flag[bracelvl]:=3;

      underl_flag[bracelvl]:=FALSE;
      auto_close[bracelvl]:=FALSE; form_code[bracelvl]:=''; close_kar[bracelvl]:=' ';
      if(lvlcode[bracelvl]=3) then lvlcode[bracelvl]:=4
      else if(lvlcode[bracelvl]=10) then {in objects}
        lvlcode[bracelvl]:=-lvlcode[bracelvl]
      else if(lvlcode[bracelvl]=15) then {brace opened after \RTFintbl => set normal}
        lvlcode[bracelvl]:=0
      else if(lvlcode[bracelvl] >= 16) then {in formulas}
        lvlcode[bracelvl]:=-lvlcode[bracelvl]
      ; {END IF}
    end
  else
    begin sign_str(maxlevel,works);
      print_msg(0,'Too many brace levels, max is '+works);
      sign_str(NUML+1,works); println_msg(0,' at line'+works);
      print_line(0); if write_log then close_files; halt;
    end
  ; {END IF bracelvl<maxlevel}
end;


{---------------------------------------------------------------------------}
{ output \begin(<arg>) }

procedure begin_env(environ : integer);
begin
  if (kout>0) then output_line; outkeyw('begin{');
  outstg(environ_type[environ]); outstg('}\strut');
  open_brace; output_line;
end;

{ ----------------------------------------------------------------------}
(* execute \begin{center}/{flushright} is center_flag set to 1 *)
procedure make_center;
begin
  if center_flag[bracelvl]=1 then
    begin begin_env(1); center_flag[bracelvl]:=2;
    end
  ;
  if flushright_flag[bracelvl]=1 then
    begin begin_env(2); flushright_flag[bracelvl]:=2;
    end
  ;
end;

{ ----------------------------------------------------------------------}
procedure begin_par;
var
  k : integer;
begin if (not par_to_begin) then exit;
  if (lvlcode[bracelvl]=6) then exit;
  if (lvlcode[bracelvl]=8) then exit;
  if (lvlcode[bracelvl]=9) then exit;
  if ((center_flag[bracelvl]+flushright_flag[bracelvl])=0) then
    output_skips;
  space_after:=save_skip; save_skip:=0;
  if (num_indent=0) and (lvlcode[bracelvl]<>15) 
    and (center_flag[bracelvl]=0) and (flushright_flag[bracelvl]=0) then
      outkeyw('noindent ');
  for k:=2 to num_indent do outkeyw('indent '); num_indent:=0; make_center;
  output_size(sizecode[bracelvl]); output_bfsl;
  outkeyw('beginparagraph{}');
  par_to_begin:=FALSE;
end;


{---------------------------------------------------------------------------}
{ write a string into math mode onto output line, and leave in math mode }

procedure out_math_leave (CHARACs : string);
begin
  if math_mode[bracelvl]>0 then outchr(' ')
  else
    begin outrem_empty_braces; outrem('$');
      if removed_OK then math_mode[bracelvl]:=1;
    end
  ; {END IF math_mode}
  if math_mode[bracelvl]=0 then
    begin begin_par; outchr('$'); math_mode[bracelvl]:=1;
    end
  ; {END IF math_mode=0}
  outstg(CHARACs);
end;

{---------------------------------------------------------------------------}
{ close math_mode if possible, i.e. =1 }

procedure close_math;
begin
  if math_mode[bracelvl]=1 then
    begin outstg(end_math_code); math_mode[bracelvl]:=0;
    end
  ; {END IF math_mode}
end;

{---------------------------------------------------------------------------}
{ write a string into math mode onto output and close math mode if possible}

procedure out_math (CHARACs : string);
begin
  out_math_leave(CHARACs); close_math;
end;


{ ===================================================================== }
{ output one string and capitalize it if required }

procedure outstgc(CHARACs : string);
var
  k : integer;
begin
  for k:=1 to length(CHARACS) do outchrc(CHARACs[K]);
end;
{ ===================================================================== }
{ output a number }

procedure output_num(numb : integer);
var
  wkk : string24;
begin
  sign_str(numb, wkk);
  outstg(wkk);
end;


{ ===================================================================== }
{ output one keyword and capitalize it }

procedure outkeywc(CHARACs : string);
var
  k : integer;
begin
  outrem_empty_braces; outchr('\');
  for K:=1 to length(CHARACS) do outchrc(CHARACs[K]);
end;


{ ===================================================================== }
{ close brace pair and remove all sub/superscripted empty pairs at end of output }

procedure close_subs;
begin
  if(math_mode[bracelvl]>0) then outrem(' '); outchr('}');
  outrem('^{}'); outrem('_{}'); outrem('^{ }'); outrem('_{ }');
end;

{ ===================================================================== }
{ declares a new font as \global, and record it }

procedure declare_font(font_id, fontname: string; magnification : integer);
var
  i,j : integer;
begin
  for i:=1 to numfonts do
    if (newfonts[i]=font_id) then exit;
  if (numfonts >= maxfonts) then
    begin
      println_msg(0,'Font '+font_id+' cannot be declared... too many fonts !'); exit;
    end
  ; {END IF}

  numfonts:=numfonts+1; newfonts[numfonts]:=truncate24(font_id);

  if(kout > 1) then output_line; { to have font decl at left of a line }
  outstg('\ifx'); outstg(font_id); outstg('\undefined \global\font');
  outstg(font_id); outstg('=\FontHdg\FontHdge '); outstg(fontname);
  sign_str(magnification,works);
  outstg(' scaled '); outstg(works); outstg('\fi'); output_line;

end;

{ ===================================================================== }
{ change contents of bfslcode[bracelvl] : replace first arg with 2nd }

procedure font_subs(old, new, fontname: string; magnification : integer);
var
  workstg : string[48];
  positn : integer;
begin
  positn:=pos(old,bfslcode[bracelvl]); if(positn=0) then exit;
  if lvlcode[bracelvl]= 9 then exit; (* ignore new fonts in header/footer *)
  workstg:=bfslcode[bracelvl]; delete(workstg,positn,length(old));
  if (pos(new,bfslcode[bracelvl])=0) then insert(new,workstg,positn);
  bfslcode[bracelvl]:=truncate24(workstg);
  declare_font(new, fontname, magnification);
end;

{---------------------------------------------------------------------------}
{ builds the correct LaTeX font size according to NUMVAL (unit=1/2 pt) }
{ stores it in sizecode[bracelvl] ; uses the global variable "stdsize" }

procedure outfsize (numval : integer; var magnif : integer);
var
  ll, selectsize, latex_size, best_diff: integer;
begin
{ I select the nearest sizemags }
  latex_size:=numval*50; (* convert from half points to hundredths of points *)
  best_diff:=30000;     (* big integer *)
  sizecode[bracelvl]:='tiny'; selectsize:=0;
  for LL:=1 to numsizes do
    begin
      if(abs(sizemags[stdkz,ll]-latex_size) < best_diff) then
        begin sizecode[bracelvl]:=sizekey[LL]; selectsize:=sizemags[stdkz,ll];
          magnif:=sizemags[stdkz,ll]; best_diff:=abs(selectsize-latex_size);
        end
      ; {END IF}
    end
  ; {END DO}

  sign_str(selectsize,works); println_msg(2,' selectsize='+works+' xkey='+sizecode[bracelvl]);

end;

{---------------------------------------------------------------------------}
procedure font_clean (sizeheader : string; magnification : integer);
begin
  if(latex209) then
    begin
      font_subs('\rm\bf\it',sizeheader+'bfit','bxti10',magnification);
      font_subs('\rm\it\bf',sizeheader+'bfit','bxti10',magnification);
      font_subs('\rm\bf\sl',sizeheader+'bfsl','bxsl10',magnification);
      font_subs('\rm\sl\bf',sizeheader+'bfsl','bxsl10',magnification);
      font_subs('\rm\bf\sf',sizeheader+'sfbf','ssbx10',magnification);
      font_subs('\rm\sf\bf',sizeheader+'sfbf','ssbx10',magnification);
      font_subs('\bf\it',sizeheader+'bfit','bxti10',magnification);
      font_subs('\it\bf',sizeheader+'bfit','bxti10',magnification);
      font_subs('\bf\sl',sizeheader+'bfsl','bxsl10',magnification);
      font_subs('\sl\bf',sizeheader+'bfsl','bxsl10',magnification);
      font_subs('\bf\sf',sizeheader+'sfbf','ssbx10',magnification);
      font_subs('\sf\bf',sizeheader+'sfbf','ssbx10',magnification);
      if magnification>2000 then
        begin {definir explicitement les grosses polices}
          font_subs('\rm\oul',sizeheader+'obf','obx10',magnification);
          font_subs('\rm\sf',sizeheader+'sf','ss10',magnification);
          font_subs('\rm\it',sizeheader+'it','ti10',magnification);
          font_subs('\rm\sl',sizeheader+'sl','sl10',magnification);
          font_subs('\rm\sc',sizeheader+'sc','csc10',magnification);
          font_subs('\rm\tt',sizeheader+'tt','tt10',magnification);
          font_subs('\sf',sizeheader+'sf','ss10',magnification);
          font_subs('\it',sizeheader+'it','ti10',magnification);
          font_subs('\sl',sizeheader+'sl','sl10',magnification);
          font_subs('\sc',sizeheader+'sc','csc10',magnification);
          font_subs('\tt',sizeheader+'tt','tt10',magnification);
        end
      ;
    end
  else (* latex2e *)
    begin
      font_subs2e('\rm\bf\it','\bfit');
      font_subs2e('\rm\it\bf','\bfit');
      font_subs2e('\rm\bf\sl','\bfsl');
      font_subs2e('\rm\sl\bf','\bfsl');
      font_subs2e('\rm\bf\sf','\sfbf');
      font_subs2e('\rm\sf\bf','\sfbf');
      font_subs2e('\rm\sf\it','\sfit');
      font_subs2e('\rm\sf\sl','\sfsl');
      font_subs2e('\bf\it','\bfit');
      font_subs2e('\it\bf','\bfit');
      font_subs2e('\bf\sl','\bfsl');
      font_subs2e('\sl\bf','\bfsl');
      font_subs2e('\bf\sf','\sfbf');
      font_subs2e('\sf\bf','\sfbf');
      font_subs2e('\sf\it','\sfit');
      font_subs2e('\sf\sl','\sfsl');
      if magnification>2000 then
        begin {definir explicitement les grosses polices}
          font_subs('\rm\oul',sizeheader+'obf','obx10',magnification);
          font_subs('\rm\sf',sizeheader+'sf','ss10',magnification);
          font_subs('\rm\it',sizeheader+'it','ti10',magnification);
          font_subs('\rm\sl',sizeheader+'sl','sl10',magnification);
          font_subs('\rm\sc',sizeheader+'sc','csc10',magnification);
          font_subs('\rm\tt',sizeheader+'tt','tt10',magnification);
          font_subs('\sf',sizeheader+'sf','ss10',magnification);
          font_subs('\it',sizeheader+'it','ti10',magnification);
          font_subs('\sl',sizeheader+'sl','sl10',magnification);
          font_subs('\sc',sizeheader+'sc','csc10',magnification);
          font_subs('\tt',sizeheader+'tt','tt10',magnification);
        end
      ;
    end
  ; {END IF latex209}
  font_subs('\rm\oul',sizeheader+'obf','obx10',magnification);

end;

{---------------------------------------------------------------------------}
{ output the correct LaTeX spacing size according to NUMVAL (unit=1/20 pt) }
{ stores it in spacingcode[bracelvl] ; uses the global variable "stdsize" }

procedure outpsize (numval : integer);
var
  ll, selectsize, best_diff: integer;
begin
  if base_flag then
    begin str_twips_pt(numval,worksa);
      spacingcode[bracelvl]:=truncate24('baselineskip'+worksa+'pt');
    end
  else
    begin
    { I select the nearest sizeval -- spacings in twips }
      best_diff:=30000;     (* big integer *)
      spacingcode[bracelvl]:='tiny'; selectsize:=0;
      for LL:=1 to numsizes do
        begin
          if(abs(sizeval[stdkz,ll]-numval) < best_diff) then
            begin
              spacingcode[bracelvl]:=sizekey[ll]; selectsize:=sizeval[stdkz,ll];
              best_diff:=abs(sizeval[stdkz,ll]-numval);
            end
          ; {END IF}
        end
      ; {END DO}

      sign_str(numval,works); sign_str(selectsize,worksa);
      print_msg(2,'--> (\par)numval='+works+' selectsize='+worksa+
       ' pkey='+spacingcode[bracelvl]);
    end
  ; {END IF}
end;

{---------------------------------------------------------------------------}
{ remove $^ before, and remove math_mode if possible }

procedure remove_mathat;
begin
  if(math_mode[bracelvl]>0) then
    begin
      if(auto_close[bracelvl]) then
        begin outrem('{'); if removed_OK then bracelvl:=bracelvl-1;
        end;
      outrem('^'); outrem('\relax');
      if(math_mode[bracelvl]=1) then
        begin outrem('$'); if(removed_ok) then math_mode[bracelvl]:=0;
        end;
    end
  ; {END IF math_mode}
  outrem('{}');
end;


{ --------------------------------------------------------------------------}
{ close brace and decrement  bracelvl }

procedure close_brace;
begin
  if(bracelvl <= 0) then
    begin sign_str(NUML+1,works); println_msg(0,'Too many } at line '+works);
      print_line(0); outstg('}%%%%% *****');
    end
  else
    if lvlcode[bracelvl]<>6 then
      if tex_verbose>1 then
        begin sign_str(bracelvl,worksa); sign_str(lvlcode[bracelvl], works);
          outstg('\closebr{'+worksa+'['+works+']}\relax'); output_line;
        end
    ;
    bracelvl:=bracelvl-1;
{ reset footnote cleaning }
    if(lvlcode[bracelvl]= 3) then lvlcode[bracelvl]:=0;
  ; {END IF bracelvl}
end;

{---------------------------------------------------------------------------}
{ output \end(<arg>) }

procedure end_env(environ : integer);
begin
  output_line; outkeyw('end{'); outstg(environ_type[environ]); outchr('}');
  close_brace; output_line;
end;

{---------------------------------------------------------------------------}
{ stores a new couple of word font chars and number taken in
decl_font_num which is a global variable }

procedure store_word_font(font_type : string);
var
  k : integer;
  new_fnt_name : string[255];
  loc_brace_count : integer;
begin
  sign_str(decl_font_num,works);
  for k:=1 to num_word_fonts do
    if word_font_num[k]=decl_font_num then
      begin println_msg(0,'RTF font No. '+works+'/'+font_type+
          ' already declared; this one ignored.'); exit;
      end
  ; {END/IF + END FOR}
  if num_word_fonts >= maxfonts then
    begin println_msg(0,'Too many RTF fonts: '+works+
        '/'+font_type+'; this one ignored.'); exit;
    end
  ; {END IF}
  new_fnt_name:=''; loc_brace_count :=0;
  while ((kar<>';') and (kar<>'}')) or (loc_brace_count>0) do
(*  while (kar<>';') do *)
    begin
      if kar='{' then loc_brace_count:=loc_brace_count+1;
      if kar='}' then loc_brace_count:=loc_brace_count-1;
      read_char; if kar<>' ' then new_fnt_name:=new_fnt_name+kar;
    end
  ;
  outrem_empty_braces; num_word_fonts:=num_word_fonts+1;
  word_font_num[num_word_fonts]:=decl_font_num;
  word_fonts[num_word_fonts]:=truncate24(font_type);
  sign_str(num_word_fonts,worksa);
  if (pos('Courier',new_fnt_name)>0) then
    equiv_fonts[num_word_fonts]:='\tt'
  else if (pos('TTY',new_fnt_name)>0) then
    equiv_fonts[num_word_fonts]:='\tt'
  else if (pos('Helvetica',new_fnt_name)>0) then
    equiv_fonts[num_word_fonts]:='\sf'
  else if (pos('SansSerif',new_fnt_name)>0) then
    equiv_fonts[num_word_fonts]:='\sf'
  else
    equiv_fonts[num_word_fonts]:=''
  ; {END IF}
  println_msg(2,worksa+' Font '+works+' stored: "'+font_type+'" = '
    +new_fnt_name);
end;