#!/usr/bin/perl

#    Convert latex to html
#    Usage: l2h [options] bla.tex > bla.html
#           see 'l2h -h' for description of options.
#
# Author: Andreas Flick (pvr)
# Changed: DR, GZ (zach@igd.fhg.de)
# Version: 1.2
#
# Requires perl 5.005!
# You need to modify the path of 'fig2dev' in the var. $fig2dev below.
#
# \begin{code} .. \end{code} will be transcribed into
# <PRE CLASS="code"> .. </PRE> 
#


require 5.004;
require "getopts.pl";

$fig2dev = "fig2dev";



#  process options
&Getopts('hni:');

if ( $opt_h )
{
	print " usage: l2h [options..] foo.tex > foo.html\n";
	print " options:\n";
	print " -i <dir>  - directory where images for html file will be put\n";
	print " -n        - don't generate section numbers\n";
	print " -h        - this help message\n";
	exit 0;
}

if ( $opt_i )	{ $imgdir = $opt_i; }
else			{ $imgdir = "."; }

$fn=shift;
$basefn=$fn;
$basefn =~ s/\.tex//og;

# 
# some global variables
#

$s = $ss = 0;
$sec = $cont = $toc="";


#
$addons=shift;

$today=`date +%x`;

#
# abbreviations for often used regexp
#

# contents of next bracket pair
# (mapped to $1, $2, ... without deletion of brackets)

$brck  = "\\s*({.*?})";

# same as above but brackets are NOT referenced (e.g.: ARE deleted)

$brckn = "\\s*{(.*?)}";

# contents of 1./2./3./4. numbered bracket pair
# referenced as $2, $4, $6, $8
# (brackets are deleted)

$brck2 = "\\s*{<(\\d+)>(.*?)<\\1>}";
$brck4 = "\\s*{<(\\d+)>(.*?)<\\3>}";
$brck6 = "\\s*{<(\\d+)>(.*?)<\\5>}";
$brck8 = "\\s*{<(\\d+)>(.*?)<\\7>}";

# some tex tags that are replaced in the brnum function

%TTAGS=(
	'\\\\small'	=>	'SMALL',
	'\\\\tt'	=>	'TT',
	'\\\\ttfamily'	=>	'TT',
	'\\\\rm'	=>	'TT',
	'\\\\em'	=>	'EM',
	'\\\\sl'	=>	'I',
	'\\\\bf'	=>	'B',
	'\\\\tiny'	=>	'SMALL',
	'\\\\center'	=>	'DIV ALIGN=CENTER',
);
$ttags=join ("|",keys(%TTAGS));



$_=&input_tex($fn);

if ( "$_" eq "" )
{
	$fn=$0;
	$fn =~ s#.*/##og;
	die "\nusage: $fn infile.tex \"addons\" > outfile.html\n";
}

$_="$_\n$addons\n";

	# load all tex files

	while ( s#\\input(?:$brckn|\s*(\S*))#&input_tex("$1$2");#oge ) {};
	while ( s#\\include{([^}]*)}#&input_tex("$1.tex");#oge ) {};

	# include .bbl-files (if any)
	s#\\bibliography$brck#&load_bbl#ogse;
	# handle in-source bibliography
	if ( /\\begin{thebibliography}/o )
	{
		s#\\begin{thebibliography}{.*?}#<H3>References</H3>#ogs;
		s#\\end{thebibliography}.*##ogs;
		$bbl=1;
	}

	s#\n\n+#\n<P>\n\n#ogs;

	# delete some tex tags
	s#\\(noindent|pagebreak(\[\d*\])?|vfill|tablefrontskip)##og;
	s#\\(itemsep|hyphenation|bibliographystyle)$brck##og;
	s#\\itemsep\s.*?\s##og;
	s#\\(begin|end){(Bflushleft|samepage)}(\[[^\]]*\])?##og;

	s#\\cleardoublepage\b#<BR><BR><BR><BR><BR><BR>#ogs;
	s#\\ldots(\b|\d)#...$1#og;
	s#\\vdots(\b|\d)#...$1#og;
	s#\\newpage\b#<HR>#og;
	s#\\par\b#<P>\n\n#og;

	s#\\begin{figure}\[[^\]*]\]#{<DIV ALIGN=CENTER>#og;
	s#\\end{figure}#</DIV>}#og;

	s#\\begin{center}#{<P ALIGN=CENTER>#og;
	s#\\end{center}#</P>}#og;

	s#\\begin{quote}#{<BLOCKQUOTE>#og;
	s#\\end{quote}#</BLOCKQUOTE>}#og;

	s#\\begin{description}#{<UL PLAIN>#og;
	s#\\end{description}#</UL>}#og;

	s#\\begin{algorithm}#{<LISTING>#og;
	s#\\end{algorithm}#</LISTING>}#og;

	s#\\begin{itemize}#{<UL>#og;
	s#\\end{itemize}#</UL>}#og;

	s#\\begin{enumerate}#{<OL>#og;
	s#\\end{enumerate}#</OL>}#og;

	s#\\begin{code}#{<PRE CLASS="code">#og;
	s#\\end{code}#</PRE>}#og;

	s#\\begin$brckn#<$1>{#ogs;
	s#\\end$brckn#}</$1>#ogs;

	s#\\item\b#<LI> #og;

	#
	# number bracket pairs
	s#({|}|(?:$ttags)\b\s*)#&brnum($1)#ogse;

	# first check booleans and evaluate ifthenelse
	s|\\setboolean$brck2$brck4|
	{
		if ( $4 eq "false" )
		{
			$var{$2}=6;
		} else {
			$var{$2}=4;
		}
#		print STDERR "boolean: $2=$4 ($var{$2})\n";
		"";
	}|ogse;
	s#\\boolean$brck2#$var{$2}#ogs;
	s#\\ifthenelse$brck2$brck4$brck6#${$2}#ogs;

	s#\\setlength$brck2$brck4##ogs;

	# process title, author & date tags
	s+(\\)(title|author|date)$brck4+
	{
		$var=$2;
		$$var=$4;
		"";
	}+ogse;

	s#\\maketitle#
<H1 ALIGN=CENTER>$title</H1>
<BR>
<H4 ALIGN=CENTER>
$author
<BR><BR>
$date
</H4>\n
postscriptlink\n#o;

	if ( -r "$basefn.ps" )
	{
		s#postscriptlink#
<A HREF="$basefn.ps">Printable postscript version of this document</A>\n#os;
	}
	else
	{
		s#postscriptlink##o;
	}

	while ( s#\\emph$brck2#<EM>$2</EM>#ogs ) {};
	while ( s#\\texttt$brck2#<TT>$2</TT>#ogs ) {};
	#while ( s#\\url$brck2#<TT>$2</TT>#ogs ) {};
	while ( s#\\url$brck2#&convurl($2)#oge ) {};
	while ( s#\\textsl$brck2#<I>$2</I>#ogs ) {};
	while ( s#\\textbf$brck2#<B>$2</B>#ogs ) {};

	# delete tex headers and create HTML env

	# pictures
	s#\\epsfpictxb?$brck2$brck4#&include_picture($2,$4)#ogse;
	s#\\includegraphics\[.*?\]$brck2#&include_picture($2,"")#ogse;
	s#\\epsfpicture$brck2$brck4$brck6#&include_picture($2,$4)#ogse;
	s#\\epsfpictz$brck2$brck4$brck6$brck8#&include_picture($6,$8)#ogse;
	s#\\twopictx$brck2$brck4$brck6$brck8#&two_pics($2,$4,$6,$8)#ogse;

	# clean <TITLE>

	# process title for <TITLE> tag
	$title =~ s#\\thanks$brck##ogs;				# remove \thanks{}
	$title =~ s#<[^>]*>##ogs;
	s#.*<document>#<HTML>
<HEAD>
<TITLE>$title</TITLE>
<!--
<STYLE TYPE="text/css">
PRE.code { font-family: Courier; margin-left: 30px; }
</STYLE>
-->
</HEAD>

<BODY>#os;

	s#</document>.*#</BODY></HTML>#os;

	s#\\frac$brck2$brck4#<SUP>$2</SUP>/<SUB>$4</SUB>#ogs;
	s#\\frac(.)(.)#<SUP>$1</SUP>/<SUB>$2</SUB>#ogs;

	s#\\typeout$brck2##ogs;

	s#\\funcheading$brck2#<P>\n\n<TT><FONT SIZE=+1>$2</FONT></TT><BR>#ogs;
	s#\\funcproto$brck2#<BR><TT>$2</TT><BR>#ogs;
	s#\\funcdescr\b#<BR><B>Description: </B>#og;
	s#\\funcparms\b#<BR><B>Parameters: </B>#og;
	s#\\funcret\b#<BR><B>Returns: </B>#og;
	s#\\funccaution\b#<BR><B><TT>CAUTION: </TT></B>#og;

	s#\\sloppy\b##ogs;
	s#\\fussy\b##ogs;

	s#\\subsectionmark$brck2##ogs;
	s#\\(section|subsection|label)\s*{<(\d+)>(.*?)<\2>}#
		&do_secs($1,$3)#ogse;

	s#\\section\*$brck2#<H2>$2</H2>#og;
	s#\\subsubsection\*$brck2#<H4>$2</H4>#og;

	s#\\paragraph\*?$brck2#<B>$2</B>#og;
	s#\\subparagraph\*?$brck2#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>$2</B>#og;

	# Do the un-*-ed too
	s#\\section$brck2#<H2>$2</H2>#og;
	s#\\subsubsection$brck2#<H4>$2</H4>#og;

	s#\\paragraph?$brck2#<B>$2</B>#og;
	s#\\subparagraph?$brck2#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>$2</B>#og;


	s#\\tableofcontents\b#<H2>Contents</H2>\n\n<UL>\n$toc\n</UL>\n</UL>\n#og;
	s#\\ref$brck2#<A HREF="\#$2">$sec{$2}</A>#og;

	#   tables and arrays
	s#\\linebreak\[.*\]##ogs;
	s#\\renewcommand(\[.*\])?\{.*\}\{.*\}##ogs;
	s#\\phantom\{[^}]*\}# #ogs;
	s#\\baselineskip##ogs;
	s#\\newlength[^\n]*\n##ogs;
	s#\\hline##ogs;
	s#\\coltxthgt{[^}]*}[^\n]*\n##ogs;
	s#\\coltxtwid{[^}]*}[^\n]*\n##ogs;

	# $tables matches the interior of one NON-nested table (at least it should)
	#$tables="<(tabularx?|array)>\\s*{<(\\d+)>(.*?<\\2>}</\\1>)";
	$tables="\\s*{<(\\d+)>((.(?!<(?:<(tabularx?|array)>)>))*?)<\\2>}</\\1>";
	do
	{
		s#<(tabularx?|array)>$tables#&tables("$1",$3)#ogse;
	}
	while ( m#<(tabularx?|array)>#o );

	s#\\caption$brck2#<SMALL>$2</SMALL>#ogs;
	s#\\multicolumn{[^}]*}{[^}]*}$brckn#$1#ogs;
	s#\\(left|right)<HEX:.*?>#\\$1\.#ogs;

	s#\\left\b.(.*?)\\right\b.(.*?)(<HEX:5c>|\\\]|\$)#
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=0><TR><TD>
$1
</TD><TD>
$2
</TD></TR></TABLE>
<BR CLEAR=ALL>
$3
#ogs;

	#   bibliography
	$i=0;
#	s#\\bibitem\[.*?\]#\\bibitem#ogs;
	s#\\bibitem(.*?)()$brck4#$i++;if ( $1 ) { $j=$1; } else { $j="[$i]"; }
"<P>\n\n<A NAME=\"$4\">$j&nbsp;&nbsp;</A>"#ogse;
	s#\\cite$brck2#&cite($2)#ogse;
	s#\\newblock\b#&nbsp;&nbsp;#ogs;

	s#\\bigskip\b#<BR><BR><BR><BR><BR>#og;

	s#\\parbox$brck2$brck4#$4#ogs;
	s#\\fbox$brck2#<TABLE BORDER=3><TR><TD>$2</TD></TR></TABLE>#ogs;

	s#\\mbox\b##og;
	s#\\tablewidth\b#100%#og;

	#  replace special characters "entities"
	#s#---#&mdash;#og;							# some netscape's can't 
	#s#--#&ndash;#og;							# display these
	s#\\\`(\w)#&${1}grave;#og;
	s#\\\'(\w)#&${1}acute;#og;
	s#\\\^(\w)#&${1}circ;#og;
	s@\\\^@&#094;@og;
	s#\\&#&amp;#og;

	#s#\\into\b#INTO#og;

	s#<HEX:5c>#<BR>#og;

	#   footnotes
	# insert footnote numbers
	$i=0;
while (	s#\\(?:footnote|thanks)$brck2(.*?)(<OL>|<UL>|<P>|</TD>)#$i++;
"<SUP>$i)</SUP>$3
<!--begin footnote $i-->
$2
<!--end footnote $i-->
$4"#ose ) {};

	# move footnotes within tables out of tables (?)
while ( s#(<TABLE(?:.(?!</TABLE))*?)(<!--begin footnote (.*)-->.*?<!--end footnote \3-->)(.*?</TABLE.*?>)#$1$4$2#ogs ) {};

	# put footnote text inside rulers and table
while (	s#<!--begin footnote (.*?)-->(.*?)<!--end footnote \1-->#
<!--bgn footnote $1-->
<TABLE ALIGN=RIGHT WIDTH=75% BORDER=0>
<TR>
<TD COLSPAN=2>
<HR>
</TD></TR>
<TR VALIGN=TOP>
<TD>
<SMALL>
$1)
</SMALL>
</TD>
<TD WIDTH=100%><SMALL>
$2
</SMALL>
<HR>
</TD></TR>
</TABLE>
<BR CLEAR=ALL>
<!--e footnote $1-->#os ) {};

	# throw away one of the rules of two consecutive footnotes
	# must be done last thing, because IDs are thrown away!!
	s#(<!--e footnote \d+-->\s*?<!--bgn footnote \d+-->\s*?<TABLE [^>]*?>).*?<HR>\s*?</TD></TR>#$1#ogs;

	# preserve space within table cells
	s#<TD>\s*</TD>#<TD>&nbsp;</TD>#og;

	s#(<P>(?:.(?!<P>))*?)<LABEL:(.*?)>#<A NAME="$2"></A>$1#ogs;

	# special latex commands from my documentation.sty
	s#\\bigcommand$brck2#<P>\n\n$2<BR>#ogs;
	s#\\alcomment$brck2#{$2}#ogs;
	s#\\alname$brck2#<U>$2</U>#ogs;

	# misc latex stuff
	s#~#&nbsp;#og;
	s#\\sim#\~#og;
	s#\\today#$today#og;
	s@\\backslash@&#92;@og;

	# Umlaute
	s#\\\"(\w)#&${1}uml;#og;
	s#ä#&auml;#og;
	s#ö#&ouml;#og;
	s#ü#&uuml;#og;
	s#Ä#&Auml;#og;
	s#Ö#&Ouml;#og;
	s#Ü#&Uuml;#og;
	s#ß#&szlig;#og;
	s#\\ss\b#&szlig;#og;

	s#\\quad\b#&nbsp;&nbsp;#og;

	s#\\and\b#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#og;
	s#\\abstract\b#<H2>Abstract</H2>#og;

	# math

	s#([^\\])_\s*{<(\d+)>(.*?)<\2>}#$1<SUB>$3</SUB>#ogs; # don't substitute \_
	s#([^\\])_(.)#$1<SUB>$2</SUB>#ogs;
	s#\^$brck2#<SUP>$2</SUP>#ogs;
	s#\^(\\\w+)\b#<SUP>$1</SUP>#ogs;
	s#\^(.)#<SUP>$1</SUP>#ogs;

	s#\\approx\b#ca. #og;
	s#\\in\b# is#og;
	s#\\log\b# log#og;
#	s#\\subseteq\b# is#og;
	s#\\althen\b#-&gt;#og;
	s#\\rightarrow\b#-&gt;#og;
	s#\\Rightarrow\b#=&gt;#og;
	s#\\leftarrow\b#&lt;-#og;
	s#\\downarrow\b# down #og;
	s#\\uparrow\b# up #og;
	s#\\times#&times;#og;
	s#\\pm\b#&plusmn;#og;
	s#\\leq\b#&lt;=#og;
	s#\\geq#&gt;=#og;
	s#\\le\b#&lt;#og;
	s#\\ge\b#&gt;#og;
	s#\\wedge\b# AND #og;
	#   folgende Zeichen gehen nur mit utf-8 encoding
	#   man muss also das im browser einstellen (View->Encoding)
	#   oder
	#     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	#   ins HTML document schreiben.
	s#\\circ\b#&deg;#og;
	s:\\alpha\b:&#945;:og;
	s:\\beta\b:&#946;:og;
	s:\\gamma\b:&#947;:og;
	s:\\delta\b:&#948;:og;
	s:\\Delta\b:&#916;:og;
	s:\\Omega\b:&#937;:og;
	s:\\sum\b:&#931;:og;
	s:\\infty\b:infinity:og;
	s:\\pi\b:&#960;:og;

	s#\\cdot\b#<SUP>.</SUP>#og;
	s#\\vc(\b|\s)##og;
	s#\\R(\b|\s)#R#og;

	# non-math

	s#\\;#&nbsp;#og;
	s#''#&quot;#og;
	s#``#&quot;#og;

	s#\\_#_#ogs;								# replace left-over "\_"

	s#\\-##og;
	s#\\\+##og;

	s#\\hspace\*?$brck2#&hspacing($2)#ogse;
	s#\\vspace\*?$brck2#&vspacing($2)#ogse;

	s#\$##og;	#eliminate math-tags ($)
	s#\\\[#<CENTER>#og;
	s#\\\]#</CENTER>#og;

	s#\\verbtabinput$brck2$brck4#<VTI:$4>#ogs;

	s#({<\d+>|<\d+>})##ogs;

	s#(\\\w*)#<FONT COLOR=RED SIZE=+3><BLINK>$1</BLINK></FONT>#ogs
	&&
	print STDERR "\n\nerror: still unresolved symbols: look for red, blinking text\n";


	s|<VTI:(.*?)>|
		$in="";
		open(FH,$1);
		print STDERR "getting $1\n";
		while (<FH>)
		{
			$in="$in$_";
		}
		close FH;
#		expand tabs to space
#		$in =~ s#\t#    #og;
		"<LISTING>
$in
</LISTING>
";
	|ogse;

	# reconvert special characters
	s#<VERB:([^>]*)>#&reconv($1)#ogse;	#reconvert \verb-context
	s#<HEX:3c>#&lt;#og;					# convert <,>
	s#<HEX:3e>#&gt;#og;
	s#<HEX:26>#&amp;#og;
	s#<HEX:([^>]*)>#&reconv($1)#oge;	#reconvert special symbols

	# tidy up
	s#<P>[\s\n]*</P>#<P>#og;
	s#<P>([\s\n]*<P>)+#<P>#og;
	s#<P>[\s\n]*<LI>#<LI>#og;
	s#<P>[\s\n]*((<A\sNAME[^>]*>([\s\n]*</A>)?[\s\n]*)?<H\d>)#$1#og;
	s#(</H\d>)[\s\n]*<P>#$1#og;
	s#<TD>[\s\n]*<P>#<TD>#og;
	s#(<TD[^>]*>)[\s\n]*<P>#$1#og;
	s#<P>[\s\n]*</TD>#</TD>#og;
	s#<TR [^>]*>[\s\n]*<TD>(&nbsp;|[\s\n]+)?</TD>[\s\n]*</TR>[\s\n]*</TABLE>#</TABLE>#og;

	# tidy between <PRE> tags, which were \begin{code}..\end{code} in tex file
	while ( s#(<PRE CLASS="code">)((.(?!</PRE>))*?)<P>(.*?)(</PRE>)#$1$2$4$5#ogs ) {};
	while ( s#(<PRE CLASS="code">)((.(?!</PRE>))*?)\t(.*?)(</PRE>)#$1$2    $4$5#ogs ) {};
	while ( s#(<PRE CLASS="code">)((.(?!</PRE>))*?)<SUB>(.)</SUB>(.*?)(</PRE>)#$1$2_$4$5$6#ogs ) {};


#### END HERE

print;
exit;


#
# Functions
# function call: &fct_name ...



sub brnum
{
	#give corresponding curly bracket pairs a non-ambiguous number
	#e.g. \section{<1>Foo{<2>\tt bar<2>}<1>}

	local ($_)="@_";

	if ( "@_" eq "{" )
	{
		push @M,++$m;
		push @N,"";
		return sprintf "@_<%d>",$m;
	}
	elsif ( "@_" eq "}" )
	{
		return sprintf "%s<%d>}",pop @N,pop @M;
	}
	else
	{
		s#\s*$##og;
		$N[$#N]="</$TTAGS{\"\\$_\"}>$N[$#N]";
		return "<$TTAGS{\"\\$_\"}>";
	}

}


sub do_secs
{
	# replace [sub]sections and build table of contents
	# cmd=[subsection|section]
	# con: context
	# sec=s.ss: section/subsection-number

	my($cmd,$cont)=@_;
	my $head;

	if ( $cmd eq "section" )
	{
		$s++;
		if ( $ss > 0 )
		{
			$toc="$toc\n</UL>";
		}
		$ss=0;
		$sec="$s.$ss";
		if ( $opt_n )
		{
			$head = "$cont";
		}
		else
		{
			$head = "$sec $cont";
		}
		$toc="$toc\n<A HREF=\"#$sec\"><B>$head</B></A><BR>";
		return "\n\n\n<H2><A NAME=$sec>$head</A></H2>\n";
	}
	elsif ( $cmd eq "subsection" )
	{
		if ( $ss==0 )
		{
			$toc="$toc\n<UL>";
		}
		$ss++;
		$sec="$s.$ss";
		if ( $opt_n )
		{
			$head = "$cont";
		}
		else
		{
			$head = "$sec $cont";
		}
		$toc="$toc\n<A HREF=\"#$sec\">$head</A><BR>";
		return "\n\n\n<H3><A NAME=$sec>$head</A></H3>\n";
	}
	elsif ( $cmd eq "label" )
	{
		$sec{$cont}=$sec;
		return "<LABEL:$cont>";
	}

}




sub tables
{
	# call: &tables("type",content);
	
	local ($type,$_)=@_;
	my $width="WIDTH=100%";
	my $border="1";
	my $spec="",$pad="";

	s#$brck2#{$spec=$2;"";}#ose;
	s#$brck2#{$width="WIDTH=$spec";$spec=$2;"";}#ose if ($type eq "tabularx");
	$width =~ s#([\d\.]*)\s*\\(hsize|linewidth)#($1?$1:1)*100 . "%"#oe;

	# spec(ifications) are NOT yet evaluated

	if ($type eq "array")
	{
		$width="";
		$border="0";
		$pad="CELLSPACING=0 CELLPADDING=0";
	}

	# "\\" <=> <HEX:5c>
	# replace "\\" followed by \end{tabular}
	s#<HEX:5c>(?=[^&]*</$type>)##osg;
	# replace "\\" *not* followed by \end{tabular}
	s#<HEX:5c>(?![^&]*</$type>)#</TD>\n</TR\>\n<TR VALIGN=TOP>\n<TD>#osg;
	s#^[ \t]*$##og;

	s#\&#</TD>\n<TD>#og;
	return "<TABLE $width $pad BORDER=$border>
<TR VALIGN=TOP>
<TD NOWRAP>
$_
</TD></TR>
</TABLE>
<P></P>
"

}



sub hspacing
{
	# do horizontal spacing (no proper implementation)

	local($_)=@_;

	/^\-/o && return "";
	return "&nbsp;&nbsp;&nbsp;";
}


sub vspacing
{
	# do vertical spacing (no proper implementation)

	local($_)=@_;

	/^\-/o && return "";
	return "<BR><BR><BR><BR>";
}



sub cite
{
	# make link to bibliography

	my $refs;

	if ( ! $bbl ) { return "<FONT COLOR=RED SIZE=+3><BLINK>[?]</BLINK></FONT>"; }

	foreach my $c (split(/\,/,"@_"))
	{
		$refs="$refs<A HREF=\"#$c\">";
		$c =~ s#[\-\:].*##og;
		$refs="$refs$c</A>\n";
	}
	return "[$refs]";
}




sub convert_picture
{
	my($fn)=@_;

	if ( -f "$imgdir/$fn.gif" )	{ return; }

	if ( -f "$fn.fig" )
	{
		print STDERR "$fn.fig -> $imgdir/$fn.gif\n";
		`$fig2dev -L gif -t #ffffff $fn.fig $imgdir/$fn.gif`;
	}
	elsif ( -f "$fn.eps" || -f "$fn.eps.gz" )
	{
		if ( ! -f "$fn.eps" )
		{ gzcat $fn.eps.gz > $fn.eps; }
		print STDERR "$fn.eps -> $imgdir/$fn.gif\n";
		`convert $fn.eps $fn.ppm && \
		ppmquant 256 $fn.ppm 2>/dev/null | \
		ppmtogif -i -t 1,1,1 >$imgdir/$fn.gif 2>/dev/null && \
		rm $fn.ppm`;
	}
	else
	{
		printf STDERR "ERROR: $fn.{eps[.gz],gif} not found!\n";
	}
}




sub include_picture
{
	my($fn,$txt)=@_;

	$fn =~ s#\.eps$##o;

	#-geom 550 bringt auch nix
	$fig++;
	$sec{"fg:$fn"}=$fig;

	&convert_picture($fn);

	return "<A NAME=fg:$fn></A>
<P ALIGN=CENTER>
<IMG WIDTH=100% SRC=$imgdir/$fn.gif ALT=$fn>
<BR>
Figure $fig: $txt
<\P>";

}




sub two_pics
{
	my($fn1,$txt1,$fn2,$txt2)=@_;

	$sec{"fg:$fn1"}=$fig0=++$fig;
	$sec{"fg:$fn2"}=++$fig;

	&convert_picture($fn1);
	&convert_picture($fn2);

	return "<A NAME=fg:$fn1></A><A NAME=fg:$fn2></A>
<IMG WIDTH=45% ALIGN=LEFT SRC=$imgdir/$fn1.gif ALT=$fn>
<IMG WIDTH=45% ALIGN=RIGHT SRC=$imgdir/$fn2.gif ALT=$fn>
<BR CLEAR=ALL>
<TABLE WIDTH=100% BORDER=0>
<TR VALIGN=TOP>
<TD WIDTH=45%>
Figure $fig0: $txt1
</TD><TD>
&nbsp;
</TD><TD WIDTH=45%>
Figure $fig: $txt2
</TD></TR>
</TABLE>
"
}



sub conv
{
	# convert special chars

	my($what,$chars)=@_;
	my $str;

	$str="";
	foreach my $c (split(//,"$chars"))
	{
		$str=sprintf("$str%.2x",ord($c));
	}
	return "<$what:$str>";
}





sub reconv
{
	# reconvert special chars

	local ($_)=@_;
	my $str="";

	while ( m#..#go )
	{
		$str=sprintf("$str%s",chr(hex($&)));
	}
	return "$str";
}




sub load_bbl
{
	open(FH,"$basefn.bbl")
	|| do {
		warn "Warning: no .bbl-file available: $!\n";
		return;
	};

	print STDERR "loading $basefn.bbl\n";

	while (<FH>)
	{
		$in="$in$_";
	}
	close FH;

	$in =~ s#.*\\begin{thebibliography}{.*?}##ogs;
	$in =~ s#\\end{thebibliography}.*##ogs;
	if ( $in ne "" )
	{
		$bbl=1;
		return "<H3>References</H3>
$in
";
	}
	return "";
}

sub input_tex
{
	my @text;
	local $_;

	open (FH,"@_")
		|| open (FH,"@_.tex")
		|| do {
			warn "Error opening @_: $!\n";
			return "";
		   };

	print STDERR "reading file: @_";
	@text=<FH>;
	close FH;
	$_="@text";

	s#\n #\n#og;		# remove one trailing blank (why is it there?)

	# replace <,> chars by html entities, so netscape doesn't think it's a tag
	s#([<>])#&conv(HEX,$1)#oge;

	# convert \verb-context to <VERB:hex-code>
	s#\\verb\*#\\verb#og;
	s#\\verb(\b.)(.*?)\1#&conv(VERB,$2)#ogse;

	#convert escaped latex symbols
	s#\\([\ \$\.\#\{\}\%\*\/\@\,\_\\\<\>\n&])#&conv(HEX,$1)#oge;
	
	s#%.*\n##og;	# delete comments

	print STDERR "\n";
	return "$_";
}


#  replace / by /&shy;
#  replace _ by \_

sub convurl
{
	my $txt = "@_";

	$txt =~ s|/|/ |ogs;
	$txt =~ s|_|\\_|ogs;
	return "<TT>$txt</TT>";
}


