#!/usr/bin/perl
###############################
#### Mif2Lyx ##################
##(c) Pablo Funes, 2000 #######
#### pablo@cs.brandeis.edu ####
# www.cs.brandeis.edu/~pablo ##
###############################
# public license - you can use#
# this code but not patent it #
###############################
$version="0.1";
require "mif.pl";  
use File::Basename;
#print "started----------------------------\n";
$debuglevel=0;
@greek=(
       "alpha","beta","xi","delta","epsilon",
       "phi","gamma","eta","iota","varphi",
       "kappa","lambda","mu","nu","omicron",
       "pi","theta","ro","sigma","tau",
       "upsilon","varpi","omega","xi","psi",
       "zeta");
$mif::MIFToken{'String'} = 'main::Token';
$mif::MIFToken{'Char'} = 'main::Token';
$mif::MIFToken{'Font'} = 'main::Font';
$mif::MIFToken{'FAngle'}  = 'main::Font';
$mif::MIFToken{'FWeight'}  = 'main::Font';
$mif::MIFToken{'FPosition'}  = 'main::Font';
$mif::MIFToken{'FTag'} = 'main::Font';
$mif::MIFToken{'FFamily'} = 'main::Font';
$mif::MIFToken{'ParaLine'} = 'main::Token';
$mif::MIFToken{'Para'} = 'main::Token';
$mif::MIFToken{'PgfTag'} = 'main::Token';
$mif::MIFToken{'TextFlow'} = 'main::Token';
$mif::MIFToken{'FNote'} = 'main::Token';
$mif::MIFToken{'Notes'} = 'main::Noop';
$mif::MIFToken{'TFTag'} = 'main::Token';
$mif::MIFToken{'MIFFile'} = 'main::Init';
$mif::MIFToken{'Variable'} = 'main::Var';
$mif::MIFToken{'VariableName'} = 'main::Var';
$mif::MIFToken{'VariableFormat'} ='main::Var';
$mif::MIFToken{'VariableDef'} ='main::Var';
$mif::MIFToken{'ID'} = 'main::Token';
$mif::MIFToken{'AFrames'} = 'main::Token';
$mif::MIFToken{'AFrame'} = 'main::Token';
$mif::MIFToken{'Frame'} = 'main::Token';
$mif::MIFToken{'FrameType'} = 'main::Token';
$mif::MIFToken{'Math'} = 'main::Token';
$mif::MIFToken{'ImportObject'} = 'main::Token';
$mif::MIFToken{'ImportObFile'} = 'main::Token';
$mif::MIFToken{'TextRect'} = 'main::Token';
$mif::MIFToken{'TextRectID'} = 'main::Token';
$mif::MIFToken{'Marker'} = 'main::Token';
$mif::MIFToken{'MText'} = 'main::Token';
$mif::MIFToken{'XRef'} = 'main::Token';
$mif::MIFToken{'XRefEnd'} =  'main::Token';
$mif::MIFToken{'XRefSrcText'} = 'main::Token';
# tables
$mif::MIFToken{'ATbl'} = 'main::Token';
foreach $t ('Tbls','Tbl','TblID','TblNumColumns',
	'TblTitle', 'TblTitleContent', 'TblH',
	'Row','Cell','CellContent','TblBody') {
    $mif::MIFToken{$t} = 'main::tables';
    }

@lyx_list=(
	     # list of known lyx styles
	     # standard styles, ie style{text} as in section for example
	     "section","subsection","subsubsection",
	     "section*","subsection*","subsubsection*",
	     "caption",
	     "tt:\\family typewriter:\\family default:",
	     "author",
	     "title",
	     # begin-end styles (end with a dot)
	     "abstract", 
	     #special styles name:begin:end:
	     "standard","quote",
	     "comment",
	     "date",
	     "bibliography",
	     "invisible:::",
	     "none:::",
	     "noprint:noprint::",
	     "bulleted:\\layout Itemize::",
	     "itemize:\\layout Itemize::",
	     "lyx-code:\\layout Lyx-Code::",
	     "enumerate:\\layout Enumerate::",
	     'centering:\\align center::',
	     "bibtex:bibtex::",
	    );
$lyx_fonts{bold}[0]="\\series bold";
$lyx_fonts{bold}[1]="\\series default";
$lyx_fonts{it}[0]="\\emph on";
$lyx_fonts{it}[1]="\\emph default";
$lyx_fonts{sup}[0]="\\begin_inset Formula \\( ^{";
$lyx_fonts{sup}[1]="} \\)\n\\end_inset";
$lyx_fonts{sub}[0]="\\begin_inset Formula \\( _{";
$lyx_fonts{sub}[1]="} \\)\n\\end_inset";

%lyx={};
foreach (@lyx_list) {
  if (/^(.+)\:(.*)\:(.*)\:$/) {
    $name=$1;
    $in="$2";
    $out="$3";
  }
  else {
    $name=$_;
    $in="\\layout \u$name";
    $out="";
  }
  debugmsg(1, "lyx STYLE <$name> IN <$in> OUT <$out>\n");
  $lyx{$name}[0]=$in;
  $lyx{$name}[1]=$out;
}
			 
if ($#ARGV < 0) { usage("no filename given"); }  
foreach $file  (@ARGV) {
  if ($file eq "-d") {
      $debuglevel=1;
  }
  elsif ($file eq "-2") {
    $twopass=1;
  }
  else {
      ($name,$path,$suffix)=fileparse($file,'\..*');
      if ($suffix eq "") {
	$suffix=".mif";
	$file=$file.$suffix;
	}
      if ($twopass) {
	$mifpass=1;
	print STDERR "PASS 1\n";
      }
      else {
	$mifpass=0;
      }
      open MIF, "<$file" or die "mif file <$file> not open";
      not eof(MIF) or die "empty mif file";
      #print "opened\n";	     
      
      open (TEX,">$path$name.lyx");
      
      #print "defined\n";
      
      MIFread_mif('main::MIF');
      #print "called.\n";
      if ($twopass) {
	$mifpass=2;
	print STDERR "PASS 2\n";
	seek(MIF,0,0);
	MIFread_mif('main::MIF');
      }
      print TEX "\\the_end\n" ;
      close MIF;
      close TEX;
      }
}

sub Noop {
}

sub Init  {  
  $noprint=0;
  if ($mifpass == 2) {
    return; 
  }
  debugmsg(1, "INIT CALLED\n");
  local($prev)=$/;
  local($style,$open,$close,$prefix);
  local($stylefile)=$path.$name.".m2l";
  @parastack=();
  %font_attr=();
  @font_stack=();
  %doc_style=();
  %doc_font_style=();
  %the_footnotes=();
  
  if (! -f $stylefile) {
    # create default stylefile
    print STDERR "Warning: No Stylefile $stylefile, creating default...\n";
    open X,">$stylefile" or die "Can't Write $stylefile.";
    print X "Body=standard
Bulleted=itemize
CellBody=invisible
CellHeading=invisible
Footnote=standard
Heading1=section
Heading2=subsection
HeadingRunIn=subsubsection
Indented=quote
Numbered=enumerate
Numbered1=enumerate
TableFootnote=invisible
TableTitle=invisible
Title=title
f.emphasis=FAngle.Italic";
    close X;
    print STDERR "You'll probably need to edit $stylefile to suit your document\n";
    
  } 
    open IN,"<$stylefile" or die "Can't open $stylefile";
    $/ = "\n";
    while (<IN>) {
      # debugmsg(1,  "IN line <$_>\n");
      chomp;
      if (/^f\.(.+)=(.+)$/) {
	# font style
	$doc_font_style{$1}=$2;
      }
      if (/^(.+)=(.*)$/) {
	$doc_style{$1}=$2;
      }
      else {
	print STDERR "error in classfile line<$_>\n";
	exit(1);
      }
    }
    close IN;
    

  foreach $k (keys %doc_style) {
    debugmsg(1, "STYLE $k lyx $doc_style{$k} IN $lyx{$doc_style{$k}}[0] OUT $lyx{$doc_style{$k}}[1]\n");
  }
  print TEX '

#created by mif2lyx $version
\lyxformat 2.16
\textclass article
\language default
\inputencoding latin1
\fontscheme default
\graphics default
\paperfontsize default
\spacing single 
\papersize Default
\paperpackage a4
\use_geometry 0
\use_amsmath 0
\paperorientation portrait
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\defskip medskip
\quotes_language english
\quotes_times 2
\papercolumns 1
\papersides 1
\paperpagestyle default

';
  $/=$prev;
} 

sub Var {
  local($token)=$_[0];
  local($mode)=$_[1];
  local(*data)=$_[2];
  $data=unquote($data);
  if ($token eq "VariableFormat") {
    $var__defining=1;
  }
  elsif ($token eq "Variable") {
    $var__defining=0;
  }
  elsif ($token eq "VariableDef") {
    $var__values{$var__name}=$data;
  }
  elsif ($token eq "VariableName") {
    if ($var__defining==1) {
      $var__name=$data;
    }
    else {
      if ($data =~ /^cite-(.+)$/) {
	tex_out("\\begin_inset LatexCommand \\cite{$1}\n\\end_inset\n\n" );
      }
      else {
	tex_out( mifch("$var__values{$data}"));
      }
    }
  }
}

sub Font {
  local($token)=$_[0];
  local($mode)=$_[1];
  local(*data)=$_[2];
  if ($token eq "Font") {
    if ($mode==1) {
      # begin font 
      %font=();
    }
    else {
      # we have a new font
      new_font();
      $parastack[$#parastack]{Font}=%font;
    }
  }
  else {
    $font{$token}=unquote($data);  
    debugmsg(1, "FONT $token $data");
  }
}

sub tables {
    local($token)=$_[0];
    local($mode)=$_[1];
    local(*data)=$_[2];
    if ($token eq "Tbl") {
      $tableid=undef if $mode==-1; 
      }
    elsif ($token eq "TblID") {
        $tableid=$data;
	$tableid="IGNORE" if $mifpass == 2;
	$table_rownow=0;
	$table_colnow=0;
	$table_rows{$tableid}=-1;
	$table_cols{$tableid}=-1;
	$table_data{$tableid}=();
	$table_incol=-1;
	}
    elsif ($token eq 'TblTitle') {
        # I'll put the title in row 0 col 0
	$table_rownow=0;
	$table_colnow=0;
	}
    elsif ($token eq 'Row' ) {
        if ($mode == 1) {
	    $table_rows{$tableid}=1+$table_rows{$tableid};
	    $table_rownow=1+$table_rows{$tableid};
	    $table_colnow=-1;
	    }
	}
    elsif ($token eq 'Cell') {
        if ($mode == 1) {
	    $table_colnow=$table_colnow+1;
	    $table_cols{$tableid}=$table_colnow+1 if
		    ($table_colnow+1)>$table_cols{$tableid};
	    }
	}
    }
        



       

sub tex_out {
  local($string)=$_[0];
  if ($symbolfont == 1) {
    $string=symbol_font($string);
  }
  $string =~ s/\$\$//g;
  $string =~ s/\$(.+)\$/ \\begin_inset Formula \\\( $1 \\\) \\end_inset /g;
  $string =~ s/\\%/%/g;
  debugmsg(1, "TEX_OUT ($noprint) $string.");
  if (defined($footnoteid)) {
    $the_footnotes{$footnoteid} .= $string unless $mifpass == 2;
    debugmsg(1, "(FNOTE $footnoteid)");
  }
  elsif (defined($frameid)) {
    $the_aframes{$frameid} .= $string unless $mifpass == 2 ;
    debugmsg(1, "(FRAME $frameid)");
  }
  elsif (defined($tableid)) {
    $table_data{$tableid}[$table_rownow][$table_colnow] .= $string unless $mifpass == 2;
    debugmsg(1,"(TABLE $tableid ($table_rownow,$table_colnow))");
    }
  else {
    if ($noprint == 1 or $mifpass == 1) {
      debugmsg(1,"(noprint $noprint mifpass $mifpass)");
    }
    else {
      print TEX $string;
    }
  }
  debugmsg(1, "\n");
}

sub font_pop {
  # you can't choose which attribute to turn off
  # you just turn off the last one pushed
  if ($#font_stack < 0) {
    print STDERR "ERROR: POP ON EMPTY FONT STACK\n";
    exit(1);
  }
  local($top)=pop(@font_stack);
  $font_attr{$top}=0;
  tex_out("\n$lyx_fonts{$top}[1]\n");
  debugmsg(1, "font $top was popped\n");
  return $top;
}

sub font_push {
  local($par)=$_[0];
  if (!defined($lyx_fonts{$par})) {
    print STDERR "ERROR: UNKNOWN FONT ATTR <$par>\n";
    exit(1);
  }
  if ($font_attr{'sub'}==1 || $font_attr{'sup'}==1) {
      return ;
      }
  if ($font_attr{$par} != 1) {
    debugmsg(1, "Pushing font $par\n");
    tex_out("\n$lyx_fonts{$par}[0]\n");
    push(@font_stack,$par);
    $font_attr{$par}=1;
  }
}

sub font_off {
  local($par)=$_[0];
  local (@stack)=();
  local($i);
  while ($font_attr{$par} ==1)  {
    push(@stack,font_pop());
  }
  for ($i=0;$i<$#stack;$i++) {
    font_push($stack[$i]);
  }
}

sub font_state {
  if ($_[1] == 1) { font_push($_[0]); }
  else { font_off($_[0]); }
}

sub new_font {
  local($k,$doc);
  foreach $k (keys %doc_font_style) {
    if ($font{FTag} eq $k) {
      $doc=$doc_font_style{$k};
      if ($doc =~ /^(.+)\.(.+)$/) {
	$font{$1}=$2;
      }
      else {
	print STDERR "INCORRECT FONT ATTRIBUTE <$doc>\n";
	exit (1);
      }
    }
  }
  $symbolfont=0; # turn symbol off to avoid interpreting commands
  debugmsg(1, "enter new_font\n"); 
  font_state('sup',($font{FPosition} eq 'FSuperscript'));
  font_state('sub',($font{FPosition} eq 'FSubscript'));
  font_state('bold',($font{FWeight} eq 'Bold'));
  font_state('it', ($font{FAngle} eq 'Italic'));
  $symbolfont=($font{FFamily} eq 'Symbol');
  debugmsg(1, "exit new_font\n");  
}   
  
sub Token { 
  local($token)=$_[0];
  local($mode)=$_[1];
  local(*data) = $_[2];

  $data=unquote($data);

  debugmsg( 1, "<$token>");
  debugmsg( 1, "<$mode>");
  debugmsg( 1, "<$data>\n");

  if ($token eq "Char") {
    # translate Char to String
    $token="String";
    if ($data eq "EnDash") { $data = "--"; }
    elsif ($data eq "EmDash") { $data = "---"; }
    elsif ($data eq "Yen") { $data = "\\Yen "; }
    elsif ($data eq "Pound") {$data = "\\Pound "; }
    elsif ( $data eq "SoftHyphen"
	    or $data eq "Tab" 
	  ) { $token="IGNORE"; }
    else { $data = "($data)" };
  }
  
  if ($token eq "FNote") {
    if (defined($data) && $data ne "0")  {
      # insert footnote
      if (defined($the_footnotes{$data})) {
	tex_out("\n\\begin_float footnote\n".
	"$the_footnotes{$data}\n".
	"\\end_float\n\n");
      }
      else {
	printf STDERR "UNDEFINED FOOTNOTE ID=$data\n";
      }
    }
    else {
      #define footnote
      $footnoteid=undef;
      $footnote=($mode == 1);
    }
  }
  elsif ($token eq "ID") {
    $lastid=$data;
    if ($footnote==1) {$footnoteid=$data;}
    elsif ($in_textrect && defined($frameid)) {
	$par_dest{$data}=$frameid;
	debugmsg (1, "PARDEST $data = $frameid\n");
	}
    elsif ($aframes && $frame) {
	debugmsg (1, "FRAMEID=$data\n");
        $frameid = $data;
	}
  }

  elsif ($token eq "Para") {
    if ($mode == 1) {
      push @parastack, {};
      $parastack[$#parastack]{Font}=();
    }
    else {   
      if ($newpar != 1) {
	style(-1);
      }
      pop @parastack;   
      tex_out( "\n\n") ;
    }
  }
  
  elsif ($token eq "ParaLine") {
    if ($mode==-1) {
      # close fonts
      if (defined($dangling)) {
	tex_out($dangling);
	$dangling=undef;
      }
      %font=();
      new_font();      
      #tex_out( "\n");
      # debugmsg 1, "--------newline-------\n";
    }
  }
  
  elsif ($token eq "PgfTag") {
    $parastack[$#parastack]{PgfTag}=$data;
    $newpar=1;
    debugmsg( 1, "thistag $data\n");
  }
  
  elsif ($token eq "String") {
    if($newpar == 1) {
        style(1);
	if (defined($dangling)) {
	  tex_out($dangling);
	  $dangling=undef;
	}
	$newpar = 0;
	}
    debugmsg( 1, "TEXT $data mode $parastack[$#parastack]{PgfTag}\n");
    tex_out( mifch("$data")) unless $in_xref;
  }

      
  elsif ($token eq "AFrames") { $aframes=($mode==1); 
      debugmsg (1, "AFRAMES=$aframes\n");
      }
  elsif ($token eq "Frame") {
      $frame=($mode == 1);
      $frameid=undef;
      $frametype=undef;
      debugmsg( 1, "FRAME=$frame\n");

      }
  elsif ($token eq "FrameType") {
    if (defined($frameid)) { $framefloat{$frameid}=($data eq "Below") ; }
    }
  elsif ($token eq "ImportObFile") {
    $data=convert_graph($data);
    tex_out("\\layout standard\n\n".
	"\\align center\n\n".
                "\\begin_inset Figure size 100 100\n".
	"file $data\n".
	"width 4 90.00\n".
	"flags 11\n\n".
	"\\end_inset\n\n".
	"\\layout Caption\n\n");
  }
  elsif ($token eq "TextRect") {
      $in_textrect=($mode == 1);
      }
  elsif ($token eq "AFrame") {
      if ($framefloat{$data}) {
	  tex_out("\n\\begin_float fig\n\\layout Standard\n\n"); 
	  }
      else {
	  tex_out("\n");
	}
      tex_out($the_aframes{$data});
      if ($framefloat{$data}) {
          tex_out("\n\\end_float\n\n");
	  }
	else {
	  tex_out("\n");
	  }
  }
  elsif ($token eq "ATbl") {
      if ($table_data{$data}) {
	tex_out("\n\n\\begin_float tab \n".
		"\\layout Standard\n".
		"\\added_space_top 0.3cm \\added_space_bottom 0.3cm ".
		"\\align center \\LyXTable\n".
		"multicol5\n");
	tex_out($table_rows{$data}." ".$table_cols{$data}." ".
		"0 0 -1 -1 -1 -1\n");
	for ($i=0;$i<($table_rows{$data}-1);$i++) {
	    tex_out("1 0 0 0\n");
	    }
	if ($table_rows{$data} > 0) {
	  tex_out("1 1 0 0\n");
	}
	for ($i=0;$i<$table_cols{$data}-1;$i++) {
	    tex_out("8 1 0 \"\" \"\"\n");
	    }
	if ($table_cols{$data} > 0) {
	  tex_out("8 1 1 \"\" \"\"\n");
	}
	for ($i=0;$i<($table_cols{$data}*$table_rows{$data});$i++) {
	    tex_out("0 8 1 0 0 0 0 \"\" \"\"\n");
	    }
	tex_out("\n");
	for ($i=1;$i <= $table_rows{$data}; $i++) {
	    for ($j=0; $j < $table_cols{$data}; $j++) {
	        tex_out($table_data{$data}[$i][$j]);
		tex_out("\n\\newline\n");
	    }
	  }
	tex_out("\n\\layout Caption\n\n");
	tex_out("$table_data{$data}[0][0]");
	tex_out("\n\n\\end_float\n\n");
	}
      else {
          debugmsg(0,"Undefined Table $data");
	  }
      }
  elsif ($token eq "TextRectID") {
      # if this textrectangle was called from an aframe
      # then capture this line to such an aframe
      if ($frame != 1) { $frameid = $par_dest{$data} };
  }
  elsif ($token eq "Math") {
    if ($mode == 1) {
      #tex_out("\nMATH\n");
      tex_out("\\begin_inset Formula \\[\n".
      "a = a\\]\n\n".
      "\\end_inset\n");
    }
  }
  elsif ($token eq "MText") {
    $data =~ s/:.*$// ;
    $dangling .= "\\begin_inset LatexCommand \\label{$data}\n\n".
      "\\end_inset\n";
  }
 
  elsif ($token eq "XRef") {
    $in_xref=1;
  }
  elsif ($token eq "XRefSrcText") {
    $data =~ s/:.*$// ;
    tex_out("\\begin_inset LatexCommand \\ref{$data}\n\n".
    "\\end_inset\n");
  }
  elsif ($token eq "XRefEnd") {
    $in_xref=undef;
  }
  elsif ($token eq "TextFlow") {
    if ($mode == 1) {
      # push noprint
      push @textflow, ($noprint);
    }
    else {
      # pop noprint
      $noprint=pop(@textflow);
    }
  }
  elsif ($token eq "TFTag") {
    if ( $data eq "HTML" ||
	 $data eq "Headings"
       ) {
      # ignore the rest of this textflow, is crap
      $noprint=1;
    }
  }
  else {
    debugmsg (1, "NOP token $token $mode\n");
  }
  
}

sub unquote {
  #debugmsg 1, "UNQUOTE $_[0]\n";
  if ($_[0] =~ /^\`(.*)\'$/ ) {
    #debugmsg 1, "UNQUOTE RETURNS $1\n";
    return $1;
  }
  else { return $_[0]; }
}

  
sub style {
  local($mode)=$_[0];
  local($par_style) = $parastack[$#parastack]{PgfTag};
  if (! defined($par_style)) { return; }
  local($style)=$doc_style{$par_style};
  if (!defined($style)) {
    print STDERR "WARNING: Undefined Sytle <$par_style>\n";
    return ;
  }
  local($texin)=$lyx{$style}[0];
  local($texout)=$lyx{$style}[1];
  if (!defined ($texin)) {
    print STDERR "WARNING: Undefined lyx Style <$style>\n";
    return;
  }
  if ($mode == 1) { debugmsg("BEGIN"); }
  else { debugmsg( 1,"END"); }
  debugmsg(1,"STYLE <$doc_style.$style.$texin.$texout>\n");
  if (defined($texin)) {
    if ($texin eq "bibtex" && $mode == 1) {
      # this is bibtex
      if ($bibtex != 1) {
	# insert bibtex command
        tex_out("\n\\begin_inset LatexCommand \\BibTeX[apalike]{pablo}\n\n".
	"\\end_inset\n\n");
	$noprint=1;
	$bibtex=1;
      }
    }
    elsif ($texin eq "noprint")  {
      $noprint=($mode == 1);
    }
    else {
      if ($mode == 1)  {
	tex_out( "$texin\n");
      }
      else  {
	tex_out( "$texout\n");
      }
    }
  }
  else {
    print STDERR "WARNING: Undefined style $style\n";
  }
  $currentstyle=$style;
}
  

sub mifch {
  $_=$_[0];
  if ($symbolfont) { 
    s/\\x/\\X/g; 
    s/\\Yen /\$\\times\$/g;
    s/\\Pound /\$\\leq\$/g;
  }
  s/\\\*/\$\\backslash\$/g;
  s/\\>/>/g;
  s/#/\\#/g;			
  s/~/\\~/g;
  s/%/\\%/g;
  s/\\%\\%/%/g;
  s/&/\\&/g;
  s/_/\\_\\,/g;
  s/\\_\\,\\_\\,/_/g;
  s/\^/\\^{}/g;
  s/\\And /\& /g;
  s/\\Yen /\$\\sout{Y}\$/g;
  s/\\Bullet /\$\\bullet\$/g;
  s/\\Cent /\$\\not c\$/g;
  s/\\Dagger /\$\\dagger\$/g;
  s/\\DiscHyphen /\\-/g;
  s/\\DoubleDagger /\$\\ddagger\$/g;
  s/\\EmDash /---/g;
  s/\\EnDash /--/g;
  s/\\EnSpace /\;/g;
  s/\\HardReturn /\\\\\\n/g;
  s/\\HardSpace /~/g;
  s/\\NoHyphen //g;
  s/\\NumberSpace /\:/g;
  s/\\Pound /\$\\pounds\$/g;
  s/\\SoftHyphen //g;
  s/\\Tab /\\>/g;
  s/\\ThinSpace /\,/g;
  s/\\Yen /Yen/g;
  s/\{\\([a-zA-Z][a-zA-Z]*)   */ \{\\$1 /g;
  s/\\X41 /A/g;
  s/\\X42 /B/g;
  s/\\X43 /X/g;
  s/\\X44 /\$\\Delta\$/g;
  s/\\X45 /E/g;
  s/\\X46 /\$\\Phi\$/g;
  s/\\X47 /\$\\Gamma\$/g;
  s/\\X48 /H/g;
  s/\\X49 /I/g;
  s/\\X4a /\$\\vartheta\$/g;
  s/\\X4b /K/g;
  s/\\X4c /\$\\Lambda\$/g;
  s/\\X4d /M/g;
  s/\\X4e /N/g;
  s/\\X4f /O/g;
  s/\\X50 /\$\\Pi\$/g;
  s/\\X51 /\$\\Theta\$/g;
  s/\\X52 /P/g;
  s/\\X53 /\$\\Sigma\$/g;
  s/\\X54 /T/g;
  s/\\X55 /\$\\Upsilon\$/g;
  s/\\X56 /\$\\varsigma\$/g;
  s/\\X57 /\$\\Omega\$/g;
  s/\\X58 /\$\\Xi\$/g;
  s/\\X59 /\$\\Psi\$/g;
  s/\\X5a /Z/g;
  s/\\X5b /\$\[\$/g;
  s/\\X5c /therefore/g;
  s/\\X5d /\$\]\$/g;
  s/\\X5e /\$\\perp\$/g;
  s/\\X61 /\$\\alpha\$/g;
  s/\\X62 /\$\\beta\$/g;
  s/\\X63 /\$\\chi\$/g;
  s/\\X64 /\$\\delta\$/g;
  s/\\X65 /\$\\epsilon\$/g;
  s/\\X66 /\$\\phi\$/g;
  s/\\X67 /\$\\gamma\$/g;
  s/\\X68 /\$\\eta\$/g;
  s/\\X69 /\$\\iota\$/g;
  s/\\X6a /\$\\varphi\$/g;
  s/\\X6b /\$\\kappa\$/g;
  s/\\X6c /\$\\lambda\$/g;
  s/\\X6d /\$\\mu\$/g;
  s/\\X6e /\$\\nu\$/g;
  s/\\X6f /\$\\omicron\$/g;
  s/\\X70 /\$\\pi\$/g;
  s/\\X71 /\$\\theta\$/g;
  s/\\X72 /\$\\rho\$/g;
  s/\\X73 /\$\\sigma\$/g;
  s/\\X74 /\$\\tau\$/g;
  s/\\X75 /Y/g;
  s/\\X76 /\$\\varpi\$/g;
  s/\\X77 /\$\\omega\$/g;
  s/\\X78 /\$\\xi\$/g;
  s/\\X79 /\$\\psi\$/g;
  s/\\X7a /\$\\zeta\$/g;
  s/\\X7b /\$\{\$/g;
  s/\\X7c /\$|\$/g;
  s/\\X7d /\$\}\$/g;
  s/\\X7e /\$\\sim\$/g;
  s/\\Xa1 /\$\\upsilon\$/g;
  s/\\Xa2 /\$\'\$/g;
  s/\\Xa3 /\$\\leq\$/g;
  s/\\Xa4 /\$\/\$/g;
  s/\\Xa5 /\$\\infty\$/g;
  s/\\Xa6 /f/g;
  s/\\Xa7 /\$\\clubsuit\$/g;
  s/\\Xa8 /\$\\diamondsuit\$/g;
  s/\\Xa9 /\$\\heartsuit\$/g;
  s/\\Xaa /\$\\spadesuit\$/g;
  s/\\Xab /\$\\leftrightarrow\$/g;
  s/\\Xac /\$\\leftarrow\$/g;
  s/\\Xad /\$\\uparrow\$/g;
  s/\\Xae /\$\\rightarrow\$/g;
  s/\\Xaf /\$\\downarrow\$/g;
  s/\\Xb0 /\$\\deg\$/g;
  s/\\Xb1 /\$\\pm\$/g;
  s/\\Xb2 /\$'"''"'\$/g;
  s/\\Xb3 /\$\\geq\$/g;
  s/\\Xb4 /\$\\times\$/g;
  s/\\Xb5 /\$\\propto\$/g;
  s/\\Xb6 /\$\\partial\$/g;
  s/\\Xb7 /\$\\bullet\$/g;
  s/\\Xb8 /\$\\div\$/g;
  s/\\Xb9 /\$\\neq\$/g;
  s/\\Xba /\$\\equiv\$/g;
  s/\\Xbb /\$\\approx\$/g;
  s/\\Xbc /\\ldots/g;
  s/\\Xbd /\$|\$/g;
  s/\\Xbe /---/g;
  s/\\Xbf /return/g;
  s/\\Xc0 /\$\\aleph\$/g;
  s/\\Xc1 /\$\\Im\$/g;
  s/\\Xc2 /\$\\Re\$/g;
  s/\\Xc3 /\$\\wp\$/g;
  s/\\Xc4 /\$\\otimes\$/g;
  s/\\Xc5 /\$\\oplus\$/g;
  s/\\Xc6 /\$\\emptyset\$/g;
  s/\\Xc7 /\$\\cap\$/g;
  s/\\Xc8 /\$\\cup\$/g;
  s/\\Xc9 /\$\\supset\$/g;
  s/\\Xca /\$\\supseteq\$/g;
  s/\\Xcb /\$\\not\\subset\$/g;
  s/\\Xcc /\$\\subset\$/g;
  s/\\Xcd /\$\\subseteq\$/g;
  s/\\Xce /\$\\in\$/g;
  s/\\Xcf /\$\\not\\in\$/g;
  s/\\Xd0 /\$\\angle\$/g;
  s/\\Xd1 /\$\\nabla\$/g;
  s/\\Xd2 /registered/g;
  s/\\Xd3 /\\copyright/g;
  s/\\Xd4 /\$^{TM}\$/g;
  s/\\Xd5 /\$\\prod\$/g;
  s/\\Xd6 /\$\\surd\$/g;
  s/\\Xd7 /\$\\cdot\$/g;
  s/\\Xd8 /\$\\neg\$/g;
  s/\\Xd9 /\$\\wedge\$/g;
  s/\\Xda /\$\\vee\$/g;
  s/\\Xdb /\$\\Leftrightarrow\$/g;
  s/\\Xdc /\$\\Leftarrow\$/g;
  s/\\Xdd /\$\\Uparrow\$/g;
  s/\\Xde /\$\\Rightarrow\$/g;
  s/\\Xdf /\$\\Downarrow\$/g;
  s/\\Xe0 /\$\\Diamond\$/g;
  s/\\Xe1 /\$\\langle\$/g;
  s/\\Xe2 /registered/g;
  s/\\Xe3 /\\copyright/g;
  s/\\Xe4 /\$^{TM}\$/g;
  s/\\Xe5 /\$\\sum\$/g;
  s/\\Xe6 /paren_left_top/g;
  s/\\Xe7 /\$|\$/g;
  s/\\Xe8 /paren_left_bot/g;
  s/\\Xe9 /\$\\lceil\$/g;
  s/\\Xea /\$|\$/g;
  s/\\Xeb /\$\\lfloor\$/g;
  s/\\Xec /brace_left_top/g;
  s/\\Xed /brace_left_mid/g;
  s/\\Xee /brace_left_bot/g;
  s/\\Xef /\$|\$/g;
  s/\\Xf1 /\$\\rangle\$/g;
  s/\\Xf2 /\$\\int\$/g;
  s/\\Xf3 /integ_top/g;
  s/\\Xf4 /\$|\$/g;
  s/\\Xf5 /integ_bot/g;
  s/\\Xf6 /paren_right_top/g;
  s/\\Xf7 /\$|\$/g;
  s/\\Xf8 /paren_right_bot/g;
  s/\\Xf9 /\$\\rceil\$/g;
  s/\\Xfa /\$|\$/g;
  s/\\Xfb /\$\\rfloor\$/g;
  s/\\Xfc /brace_right_top/g;
  s/\\Xfd /brace_right_mid/g;
  s/\\Xfe /brace_right_bot/g;
  s/\\x80 /\\\"\{A\}/g;
  s/\\x81 /\\AA /g;
  s/\\x82 /\\c{C}/g;
  s/\\x83 /\\\'\{E\}/g;
  s/\\x84 /\\~{N}/g;
  s/\\x85 /\\\"\{O\}/g;
  s/\\x86 /\\\"\{U\}/g;
  s/\\x87 /\\\'\{a\}/g;
  s/\\x88 /\\\`{a}/g;
  s/\\x89 /\\^{a}/g;
  s/\\x8a /\\\"{a}/g;
  s/\\x8b /\\~{a}/g;
  s/\\x8c /\\aa /g;
  s/\\x8d /\\c{c}/g;
  s/\\x8e /\\\'{e}/g;
  s/\\x8f /\\\`{e}/g;
  s/\\x90 /\\^{e}/g;
  s/\\x91 /\\\"{e}/g;
  s/\\x92 /\\\'{i}/g;
  s/\\x93 /\\\`{i}/g;
  s/\\x94 /\\\^{i}/g;
  s/\\x95 /\\\"{i}/g;
  s/\\x96 /\\\~{n}/g;
  s/\\x97 /\\\'{o}/g;
  s/\\x98 /\\\`{o}/g;
  s/\\x99 /\\^{o}/g;
  s/\\x9a /\\\"{o}/g;
  s/\\x9b /\\\~{o}/g;
  s/\\x9c /\\\'{u}/g;
  s/\\x9d /\\\`{u}/g;
  s/\\x9e /\\\^{u}/g;
  s/\\x9f /\\\"{u}/g;
  s/\\xa4 /\\S/g;
  s/\\xa6 /\\P/g;
  s/\\xa7 /\\ss/g;
  s/\\xa9 /\\copyright/g;
  s/\\xaa /\$^{TM}\$/g;
  s/\\xab /\'/g;
  s/\\xac /\\\"{}/g;
  s/\\xae /\\AE/g;
  s/\\xaf /{\\O}/g;
  s/\\xbb /\\b{a}/g;
  s/\\xbc /\\b{o}/g;
  s/\\xbe /{\\ae}/g;
  s/\\xbf /{\\o}/g;
  s/\\xc0 /?\`/g;
  s/\\xc1 /!\`/g;
  s/\\xc2 /\$\\neg\$/g;
  s/\\xc4 /\$f\$/g;
  s/\\xc7 /\$\\ll\$/g;
  s/\\xc8 /\$\\gg\$/g;
  s/\\xc9 /\$\\ldots\$/g;
  s/\\xcb /\\\`{A}/g;
  s/\\xcc /\\~{A}/g;
  s/\\xcd /\\~{O}/g;
  s/\\xce /\\0E/g;
  s/\\xcf /\\oe/g;
  s/\\xd0 /--/g;
  s/\\xd1 /---/g;
  s/\\xd2 /``/g;
  s/\\xd3 /''/g;
  s/\\xd4 /\`/g;
  s/\\xd5 /\'/g;
  s/\\xd8 /\\\"{y}/g;
  s/\\xd9 /\\\"{Y}/g;
  s/\\xda /\//g;
  s/\\xdc /\$<\$/g;
  s/\\xdd /\$>\$/g;
  s/\\xde /fi/g;
  s/\\xdf /fl/g;
  s/\\xe1 /\$\\cdot\$/g;
  s/\\xe2 /,/g;
  s/\\xe3 /\$_{\"}\$/g;
  s/\\xe4 /\$_{o}\$/g;
  s/\\xe5 /\\^{A}/g;
  s/\\xe6 /\\^{E}/g;
  s/\\xe7 /\\\'{A}/g;
  s/\\xe8 /\\\"{E}/g;
  s/\\xe9 /\\\`{E}/g;
  s/\\xea /\\\'{I}/g;
  s/\\xeb /\\^{I}/g;
  s/\\xec /\\\"{I}/g;
  s/\\xed /\\\`{I}/g;
  s/\\xee /\\\'{O}/g;
  s/\\xef /\\^{O}/g;
  s/\\xf1 /\\\`{O}/g;
  s/\\xf2 /\\\'{U}/g;
  s/\\xf3 /\\\^{U}/g;
  s/\\xf4 /\\\`{U}/g;
  s/\\xf5 /\\i/g;
  s/\\xf6 /\\^{}/g;
  s/\\xf7 /\$^{~}\$/g;
  s/\\xf8 /\$^{-}\$/g;
  s/\\xfa /\$^{.}\$/g;
  s/\\xfb /\$^{o}\$/g;
  s/\\xfc /\\c{}/g;
  s/\\xfd /\$'"'"''"'"'\$/g;
  s/  *}/} /g;
# for lyx replace \'{e} with \n\i \'{e}\n etc. 
  s/(\\.\{.\})/\n\\i $1\n/g;
# and \& with &
  s/\\&/&/g;
return $_;
}

sub symbol_font {
  local($string)=$_[0];
  local($c,$r);
  local($dollar)=0;
  debugmsg(1,"Symbol_Font <$_[0]>\n");
  while ($string ne "") {
    if ($string =~ /^\\([^ ]*)  (.*)$/) {
      $c=$1; $string=$2;
    }
    else {
      $string =~ /^(.)(.*)$/;
      $c=$1; $string=$2;
    }
    if ($c eq "\$") { $dollar=(!  $dollar); }
    if ($dollar) {$r .= $c; }
    else {$r .= symbol_char($c) unless $dollar;}
  }
  #$r =~ s/\$\$//g;
  return $r;
}

sub symbol_char {
  local($c)=$_[0];
  local($upper);
  local($ord)=ord($c);
  if ($c ge "A" && $c le "Z") {
    $upper=1;
    $ord += ord("a") - ord("A");
  }
  if ($c ge "a" && $c le "z") {
    $c=$greek[$ord - ord("a")];
    if ($upper) { $c="\u$c";}
    return "\$\\$c\$";
  }
  else { return $c; }
}
  
  

sub convert_graph {
  $file=$_[0];
  local($name,$path,$suffix,$newfile,$cmd);
  local($graphdir)="graph";
  if (! -f $file) {
    print STDERR "Error: No file $file\n";
    return $file;
  } 
  $graphdir .= "/";
  ($name,$path,$suffix)=fileparse($file,'\..*');
  if (! -d $graphdir) { mkdir($graphdir,0777) or die "Can't create directory $graphdir\n"; }
  if ( $suffix =~ /\.(ps|eps|epsi|PS|EPS|EPSI)$/) {
    # already in ps format - make symlink
    $newfile=$graphdir.$name.$suffix;
    if (-f $newfile || -l $newfile) {
      print STDERR "Warning: $newfile is already there\n" unless $mifpass == 2;
    }
    else {
      # correcting stupid behavior by symlink
      if (!($path =~ /^\//)) {
	$file="../".$file;
      }
      # should've worked with this line alone
      symlink $file,$newfile or print STDERR  "Warning: Can't symlink <$file> to <$newfile>";
    }
  }
  else {
    # do conversion
    $newfile=$graphdir.$name.".eps";
  if (-f $newfile) {
      print STDERR "Warning: $newfile is already there\n" unless $mifpass == 2;
    }
    else {
      $cmd="convert $file $newfile";
      print STDERR "Running <$cmd>...\n";
      system($cmd)==0 or print STDERR "Warning: <$cmd> failed!\n";
    }
  }
  return $newfile;
}

sub usage {
  print STDERR "ERROR: $_[0]\n";
  print STDERR "usage: $0 [-d] [-2] file (file...)\n";
  exit (1);
}

sub debugmsg {
  if ($_[0] <= $debuglevel) { print STDERR $_[1]; }
}
