#!/usr/bin/perl -w
##
# (K.B): modified Sun Dec  5 16:41:03 MET 2004
##
#
# $Id: gphtml,v 1.7 2002/12/25 16:12:02 fenrir Exp $
#
# This script generates html documentation of the gp/pari functions
# on using the tex documentation as given in chapter 3 of the users manual.
# Currently this is a workaround since there seems to exist no reasonable
# plain TeX to html converter. Here we just take the outputs of
# gphelp -raw (or alternatively -detex) and translate them into html form.
# It will be easy to replace, in the following code, the use of this
# function by a more powerful tex2html translator
# (if there were one in sight).
#
# Usage: gphtml [--dist|--4gui|--subsections|--no_entries|--check|--use_detex]
#
# Without any option this will create, in the directory where you
# called, a subdirectory named html, and therein the html documentation.
# With --dist this will add this file and a tar archive of html to html.
# With --4gui this creates a directory called ref containing the reference
# docs for pariguide.
# The other options are for debugging purposes or consistency checks only.
#
# Adjust the three pathes below (look for AdJuSt).
#########################################################################


#use strict 'vars';

my (
    $USERSCH3_TEX, $INIT_C, $HTML, $REF, $REF_HEADER,
#    $DATE,
    $distFlag, $guiFlag, $subsectionsFlag, $no_entriesFlag, $checkFlag, $option,
    %pics, %basicFrames,
#    $version,
    @shortcuts, %subsections, %sections, %fill,
    @ou, %tr, %trans0, %trans1, %trans, %html,
    $gl_key, $gl_item, $gl_letter, $gl_contents,
    );

$DATE = localtime();


##############
# AdJuSt these
##############
$HTML         = './html/';   # or where ever you like the html pages
$REF          = './ref/';    # or wherever you like the pariguide ref pages
$base = "/usr/local/src/pari"; # the toplevel PARI/GP sources 

#########################
# Parse the argument line
#########################
$option = '-raw';
$distFlag = $guiFlag = $subsectionsFlag = $no_entriesFlag = $checkFlag = 0;
for (@ARGV) {
    /--dist/            and do { $distFlag = 1; next;};
    /--4gui/            and do { $guiFlag = 1; $HTML = $REF; next;};
    /--subsections/     and do { $subsectionsFlag = 1; next;};
    /--no_entries/      and do { $no_entriesFlag = 1; next;};
    /--check/           and do { $checkFlag = 1; next;};
    /--use_detex/       and do { $option = '-detex'; next;};
    /--base=(.*)/       and do { $base = $1; next;};
    /--HTML=(.*)/       and do { $HTML = $1; next;};
    &usage;
}
$USERSCH3_TEX = "$base/doc/usersch3.tex";
$INIT_C       = "$base/src/language/init.c";
$gp           = "$base/gp";
$gphelp       = "$base/doc/gphelp";

sub usage {
    print STDERR "Usage: $0 [--dist|--4gui|--subsections|--no_entries|--check|--use_detex]\n";
    exit( 0);
}


############################################################
# We see first what information the system has about pari/gp
# and collect it
############################################################
initVersionAndShortcuts();
initSubsections();
cleanSubsections();


#########################################
# If we only want to list the subsections
# of usersch3.tex, then this
#########################################
1 == $subsectionsFlag and do {
    foreach $gl_key ( sort keys %sections) {
	print "$gl_key $sections{$gl_key}\n";
    }
    foreach $gl_key ( sort keys %subsections) {
	print "\n\n $gl_key \n\n";
	foreach $gl_item ( @{ $subsections{ $gl_key}}) {
	    print "\t$gl_item\n";
	}
    }
    exit( 0);
};


##########################################
# If we only want to compare the functions
# found in init.c to the subsections
# in usersch3.tex,then this
##########################################
1 == $checkFlag and do {
    &checkFunctions();
    exit( 0);
};


######################################################################
# Here we start writing all *.html files of the pariguide doc 
# to a directory named ref.
######################################################################
1 == $guiFlag and do {
    system( "mkdir -p $REF");

    $REF_HEADER = "<table cellpadding=2 cellspacing=0 bgcolor=\"#83a2ef\" width=\"100%\" border=0>\n<tr>\n"
	."<td><b>Pari/GP Reference Documentation</b></td>\n"
	    ."<td align=right><a href=\"index.html\"><img src=\"./home.gif\" border=0 />&nbsp;Contents</a>\n"
		." - <a href=\"function_index.html\">Index</a>\n"
		    ." - <a href=\"meta_commands.html\">Meta commands</a></td>\n"
			."</tr>\n</table><br/>\n\n";

# Write the icons ...
writeData4Ref( *DATA);

#toc
    writeToC4Ref();

# Write function index using 6 columns,
    writeIndex( 6);

# subsection pages,
    foreach $gl_key ( sort keys %subsections) {
	1 == $no_entriesFlag or &writeEntries4Ref( $gl_key);
    }

# and meta commands.
    $gl_contents = $REF_HEADER;
    $gl_contents = $gl_contents."<h3 align=left>Meta commands</h3>\n";
    foreach $gl_item (@shortcuts) {
	$gl_contents = $gl_contents.$gl_item.'<br/>';
    }
    printHTML( 'meta_commands.html', 'Meta Commands',
	       'bgcolor="#FFFFFF"', $gl_contents);
    exit(0);
};


######################################################################
# Here we start writing all *.html files to a directory named html
# and according to the frame layout sketched in the data section below
# (all after __DATA__ ).
# The look and feel can be changed on the fly by altering the
# descriptions in the data section.
######################################################################
system( "mkdir -p $HTML");

# Write basic frames ...
writeData( *DATA);
writeToC();
# ... and the pages for the frame "item"
foreach $gl_key ( sort keys %subsections) {
    writeFunctionsByCategorie( $gl_key);
}
foreach $gl_letter ( (A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)) {
    writeFunctionsByAlphabet( $gl_letter);
}
# ... and the pages for the frame "entry"
foreach $gl_key ( sort keys %subsections) {
    1 == $no_entriesFlag or &writeEntries( $gl_key);
}
$gl_contents = "\n<H3>Keyboard Shortcuts</H3>\n";
foreach $gl_item (@shortcuts) {
    $gl_contents = $gl_contents.$gl_item.'<br>';
}
printHTML( 'keyboard_shortcuts.html', 'GP Keyboard Shortcuts',
	   'bgcolor="#FFFFFF"', $gl_contents);
if( 1 == $distFlag) {
  system("cp gphtml $HTML; tar cfz `basename $HTML`.tgz $HTML");
}
##############
# ... Done !!!
##############


########### The subroutines ##################

sub warning {
    print STDERR "\t\e[0;31m\e[1mWarning:\e[m ".$_[0]."\n";
}

sub fatal {
    die "\t\e[0;31m\e[1mError:\e[m ".$_[0]."\n";
}

sub happy {
    print STDERR "\t".$_[0]." ...... \e[0;32m\e[1m OK\e[m\n";
}

sub unhappy {
    print STDERR "\t".$_[0]." ...... \e[0;31m\e[1m FAILED\e[m\n";
}


sub initVersionAndShortcuts {
##############################################
# Sets ups $version and the list @shortcuts
# of GP keyboard shortcuts. Calls gp!
# Checks if gphelp is available and for init.c
##############################################
    my( $entry);

    $version = `echo quit | $gp | grep Version`;
    $version =~ s/^\s*(.*)\s*$/$1/;
    @shortcuts = split "\n", `echo '?\\' | $gp -q -test`;
    if( $version eq "") {
	warning( "gp not found: no version, no keyboard shortcut information");
    }
    else {
	happy( "gp found");
    }
    #
    $entry = `$gphelp -detex addprimes`;
    if( $entry eq "") {
	fatal( "gphelp not found");
    }
    else {
	happy( "gphelp found");
    }
    if( -e $INIT_C) {
	happy( "$INIT_C found");
    }
    else {
	warning( "$INIT_C not found: option --check is not available");
    }
}


sub initSubsections {
####################################################
# Sets up hash of lists %subsections.
# Keys are the sections of usersch3.tex.
# Values are the list of corresponding subsections.
# Non-consistent use of sec/subsec layout in sec. 12
# yields havock!
####################################################
    my( $j, $key, $tmp);

    open IN, "<$USERSCH3_TEX"
	or fatal( "Cannot open $USERSCH3_TEX: Adjust the path in the script or make a link");

    $j=1; $key = "Dummy";
    while (<IN>) {
	if (s/\\section\{(.*?)\}//) {
	    $key = $1;
	    $subsections{$key} = []; #["\[loeffel\]\_\_\(\)\_\_"];
	    $sections{$j} = $key;
	    $tmp = $key; $tmp =~ s/\ /\_/g;
#KB print "$key ==> $tmp\n";
	    $fill{$key} = $tmp;
	    $j++;
	}
	if( s/\\subseckbd\{(.*?)\}//) {
	    push @{ $subsections{ $key}}, "\[$1\]\_\_\(kbd\)\_\_";
	}
	if( s/\\subsecidx\{(.*?)\}//) {
	    push @{ $subsections{ $key}}, "\[$1\]\_\_\(idx\)\_\_";
	}
	if( s/\\subsec\{(.*?)\}//) {
	    push @{ $subsections{ $key}}, "\[$1\]\_\_\(nix\)\_\_";
	}
	if( s/\\subsubsecidx\{(.*?)\}//) {
	    push @{ $subsections{ $key}}, "\[$1\]\_\_\(sidx\)\_\_";
	}
	if( s/\\subsubsecidxunix\{(.*?)\}//) {
	    push @{ $subsections{ $key}}, "\[$1\]\_\_\(sidxu\)\_\_";
	}
    }

    close IN;
}


sub cleanSubsections {
##########################
# Some subsection titles
# are not found by gphelp.
# Here we help "by hand".
##########################

    my( $key, $pair, $item, $a, $j, %table);

    %table = (
	     "Conversions and similar elementary functions or commands"
	      => [["components of a PARI object", "component"]],

	      "Programming under GP" # up to pari-2-2-6
	      => [['Control statements', '?'],
		  ['Specific functions used in GP programming', '?']],

	      "Programming in GP" # pari-2-2-7 and onward
	      => [['Control statements', '?'],
		  ['Specific functions used in GP programming', '?']],

	      "Standard monadic or dyadic operators"
	      => [['\%', '?'],
		  ['+$/$-', '+/-'],
		  ['\bs','\\'], # :-)
		  ['\bs/','\/'],
		  ['\pow','^'],
		  ['Comparison and boolean operators','<,<,>=,>,==,!=,||,&&,!,|,&,<>']],

	      "Transcendental functions"
	      => [['\pow','^']]
	      );

    foreach $key ( keys %table) {
        next if (!defined($subsections{$key}));
	foreach $pair ( @{ $table{ $key}}) {
	    $j=0;
	    foreach $item ( @{ $subsections{ $key}}) {
		$a = quotemeta(@{ $pair}[0]);
#		$item =~ s/^\[$a\]/\[@{ $pair}[1]\]/
		if( $item =~ /^\[$a\]/) {
		    if( @{ $pair}[1] eq '?') {
			splice @{ $subsections{ $key}}, $j, 1;
		    }
		    else {
			splice @{ $subsections{ $key}}, $j, 1, "[@{ $pair}[1]]__()__";
		    }
		}
		$j++;
	    }
	}
    }
}


sub checkFunctions {
    my( %functions, $key, $n, $nn, $cqm, $qm);

    open IN, "<$INIT_C"
	or fatal( "Cannot open $INIT_C: Adjust the path or make a link");
    print STDERR "\tcomparing $INIT_C: entree functions_basic[] to $USERSCH3_TEX   ...\n";
    $cqm ='{"'; $qm = '"'; #cause of emacs bug !
    while ($_ = <IN>) {
	/$cqm/ and do {
	    /^$cqm(.*?)$qm\,(.*?)\,(.*?)\,(.*?)\,/;
	    $functions{$1} = $4;
	};
    }
    $n = $nn = 0;
    foreach $key ( keys %functions) {
	$n = grep /\[$key\]/, @{$subsections{ $sections{$functions{ $key}}}};
	if( 1 != $n) {
	    unhappy( "search for $key in $USERSCH3_TEX section $functions{ $key}");
	    $nn++;
	}
    }
    if( 0 == $nn) {
	print STDERR "\t   ... \e[0;32m\e[1m DONE\e[m\n";
    }
    else {
	unhappy( "\t$nn functions");
    }
   close IN;
}


sub writeToC4Ref {
###################################
# Writes index.html, the entry page
# for the reference documentation.
# Relies on the hash %subsection.
###################################

    my( $key, $contents, $toc1, $toc2, $letter);

    $toc1 = $toc2 ='';
    $z = 0;
    foreach $key ( sort keys %subsections) {
	0 == $z and $toc1 = $toc1."<tr>\n";
	$toc1 = $toc1
	    .'<td><a href="./'."$fill{$key}".'.html">'
		.$key
		    .'</a></td>'."\n";
	1 == $z and $toc1 = $toc1."</tr>\n";
	$z++; 2 == $z and $z = 0; 
    }
    1 == $z and $toc1 = $toc1."<td>&nbsp;</td>\n</tr>";

    foreach $letter ( (A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)) {
	$toc2 = $toc2
	    .'<a href = "./function_index.html#'.$letter.'">'
		.$letter.'</a>'."\n";
    }

    $contents = <<"__UP_TO_HERE__";
<DIV align=left>

<h4 align=left>Functions by Category</h4>

<table cellpadding=0 cellspacing=0 border=0 width="100%">
$toc1
</table>

<h4 align=left><a href="./meta_commands.html">Meta Commands</a></h4><br/>

<h4>Functions in Alphabetical Order</h4><br/>
$toc2
<br>
<hr>
<br>
<small>
Catalogue of Functions for the $version.
<br>
(generated by gphtml on $DATE.)</small>
</DIV>
__UP_TO_HERE__

    $contents = $REF_HEADER.$contents;

    printHTML( "index.html", "Table of Contents",
	       'bgcolor="#FFFFFF"', $contents);
}


sub writeToC {
#################################
# Writes toc.html.
# Relies on the hash %subsection.
#################################

    my( $key, $contents, $toc1, $toc2, $letter);

    $toc1 = $toc2 ='';
    foreach $key ( sort keys %subsections) {
        die "Unknown subsection: $key" if ( !defined($fill{$key}) );
	$toc1 = $toc1
	    .'<A href="./'."cont_$fill{$key}".'.html" target="itemFrame">'
		.$key
		    .'</A>'."\n".'<HR>'."\n";
    }
    foreach $letter ( (A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)) {
	$toc2 = $toc2
	    .'&nbsp;<A href = "./cont_'.$letter.'.html" target="itemFrame">'
		.$letter.'</A>'."\n";
    }

    $contents = <<"__UP_TO_HERE__";
<DIV align=center>
  <A href="http://pari.math.u-bordeaux.fr/" target="_top">
  <IMG border=0 alt="Pari/GP Home Page" src="./logo.jpg"></A>
</DIV>

<DIV align=left>

<H4>Functions by Category</H4>
$toc1
<H4><A href="./keyboard_shortcuts.html" target="entryFrame">Keyboard Shortcuts</A></H4>

<H4>Functions in Alphabetical Order</H4>
$toc2
</DIV>
__UP_TO_HERE__

    printHTML( "toc.html", "Table of Contents",
	       'background="./toc.jpg"', $contents);
}


sub writeFunctionsByCategorie {
############################################
# Writes, for each list of subsection titles
# pointed to by $key, an html file called
# cont_$key.html. This a a collection of
# links to the respective entries in
# $key.html.
# Uses the hash %subsection.
# Call in the form
# writeFunctionsByCategorie( $key)
############################################

    my( $key, $item, $contents);

    $key = $_[0];

    $contents ="\n<h3 align=center>Index: $key</h3>\n";
    foreach $item (sort @{ $subsections{$key}}) {
	$item =~ /^\[(.*?)\]\_\_\((.*?)\)\_\_$/;
	$contents = $contents
	    .'&nbsp;&nbsp;<A href="./'.$fill{$key}.'.html#'.$1.'" target="entryFrame">'.$1.'</A>'."\n";
    }
    printHTML( "cont_$fill{$key}.html", "$key", 'bgcolor = "#FFFFFF"', $contents);
}


sub writeIndex {
############################################
# Writes an html file called
# function_index.html. This a a collection of
# links to the respective entries in
# the entry pages.
# Uses the hash %subsection.
# Call in the form
# writeIndex( number_of_columns)
############################################
    my( $numOfCols, $letter, @tmp, $key, $item, $contents, $z, %subsectionsByAl);

    $numOfCols = $_[0];

    $contents = $REF_HEADER;
    $contents = $contents
	."<h3 align=left>Index of Functions</h3>\n";
    $contents = $contents
	.'<table cellpadding=0 cellspacing=0 width="100%" border=0>'."\n"; 

    foreach $letter ( (A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)) {

	$subsectionsByAl{ $letter} = []; @tmp = ();
	foreach $key ( keys %subsections) {
	    foreach $item ( @{ $subsections{ $key}}) {
		if( $item =~ /^\[$letter/ || $item =~ /^\[\l$letter/) {
		    $item =~ /^\[(.*?)\]\_\_\((.*?)\)\_\_$/;
		    push @{ $subsectionsByAl{ $letter}}, "\[$1\]\_\_\($key\)\_\_\n";
		    push @tmp, "\[$1\]\_\_\($key\)\_\_\n";
		}
	    }
	}

	$contents = $contents."<tr>\n<td><a name=\"$letter\" /><b>$letter</b></td>\n";
	$z = 1;
	foreach $item (sort @tmp) {
	    $item =~ /^\[(.*?)\]\_\_\((.*?)\)\_\_$/;
	    if( $z == $numOfCols) {
		$contents = $contents."</tr>\n<tr>\n<td>&nbsp;</td>\n";
		$z = 1;
	    }
	    $contents = $contents
		.'<td><A href="./'.$fill{$2}.'.html#'.$1.'">'.$1.'</A>'."</td>\n";
	    $z++;
	}
	for(; $z < $numOfCols; $z++) {
	    $contents = $contents."<td>&nbsp;</td>\n";
	} 
	$contents = $contents.'</tr>'."\n";
	
    }
    $contents = $contents."</table>";
    printHTML("function_index.html", "Index of Functions", 'bgcolor = "#FFFFFF"', $contents);
}


sub writeFunctionsByAlphabet {
############################################
# Writes, for each letter $letter
# an html file called
# cont_$letter.html. This a a collection of
# links to the respective entries in
# the entry pages.
# Uses the hash %subsection.
# Call in the form
# writeFunctionsByAlphabet( $letter)
############################################


    my( $letter, @tmp, $key, $item, $contents, %subsectionsByAl);

    $letter = $_[0];

    $subsectionsByAl{ $letter} = []; @tmp = ();
    foreach $key ( keys %subsections) {
	foreach $item ( @{ $subsections{ $key}}) {
	    if( $item =~ /^\[$letter/ || $item =~ /^\[\l$letter/) {
		$item =~ /^\[(.*?)\]\_\_\((.*?)\)\_\_$/;
		push @{ $subsectionsByAl{ $letter}}, "\[$1\]\_\_\($key\)\_\_\n";
		push @tmp, "\[$1\]\_\_\($key\)\_\_\n";
	    }
	}
    }
    $contents = "\n<h3 align=center>Index: $letter</h3>\n";;
    foreach $item (sort @tmp) {
	$item =~ /^\[(.*?)\]\_\_\((.*?)\)\_\_$/;
	$contents = $contents
	    .'&nbsp;&nbsp;<A href="./'.$fill{$2}.'.html#'.$1.'" target="entryFrame">'
		.$1.'</A>'."\n";
    }
    printHTML( "cont_$letter.html", "$letter", 'bgcolor = "#FFFFFF"', $contents);
    
}



sub writeEntries4Ref() {
###############################################
# Writes, for each list pointed to by $key,
# a file $key.html which will contain the
# subsections of the corresponding section
# in usersch3.tex.
# Needs correcly initializes hash %subsectiones
# and uses for the moment "gphelp -detex" or
# "gphelp -detex" (accordingly to what option
# is set)
# to convert subsections of usersch3.tex
# into html.
# Use in the form writeEntries( $key)
###############################################

    my( $contents, $item, $entry, $l, $r, $d, $key, @text, $link, $function);

    $key = $_[0];
    print STDERR "\twriting: $key   ...\n";

    initFixedData();

    $contents = "<A NAME=\"top\" />\n".$REF_HEADER;
    $contents = $contents."<h3 align=left>$key</h3><br/>\n\n";
    $contents = $contents
	."<table cellpadding=4 cellspacing=0 bgcolor=\"\#FFFFEE\" width=\"100%\" border=0>\n"
	    ."<tr><td colspan=2>\n";

    foreach $item (sort @{ $subsections{$key}}) {
	$item =~ /^\[(.*?)\]\_\_\((.*?)\)\_\_$/;
	$contents = $contents
	    .'<a href="./'.$fill{$key}.'.html#'.$1.'">'.$1.'</a>&nbsp;&nbsp;'."\n";
    }

    $contents = $contents
	."</td></tr>\n<tr><td colspan=2>&nbsp;</td></tr>\n";

    foreach $item (@{ $subsections{$key}}) {
	$item =~ s/^\[(.*?)\]\_\_\((.*?)\)\_\_$/$1/;
	$entry = `$gphelp '$option' '$item'`;
	$entry =~ /not\ found/ and unhappy("\t$item");
	if( $option eq '-raw') {
            # first kill TeX leftovers
	    for $key ( keys %trans0) {
		$l = quotemeta( $key); $r = $trans0{$key};
		$entry =~ s/$l/$r/gs;
	    }
	    for $key ( keys %trans1) {
		$l = quotemeta( $key); $r = $trans1{$key};
		$entry =~ s/$l/$r/gs;
	    }
# TO_DO: Fix the dirty hack from here
	    $l = '\@1\@\[startcode\]'; $r = '<pre><font color=#a3682a><tt>';  
	    $entry =~ s/$l(.*?)/$r$1/gs;
	    $l = '\@2\@\[endcode\]'; $r = '</tt></font></pre>';
	    $entry =~ s/$l(.*?)/$r$1/gs;
# to here.
	    for $key ( keys %trans) {
		$l = quotemeta( $key); $r = $trans{$key};
		$entry =~ s/$l/$r/gs;
	    }
            # then make a nice header
	    $entry =~ s/^(.*?)\:/\<h4\>$1\<\/h4\>\n\<p\>/gs;
            # now care for the @[] markers
	    for $key ( @ou) {
		$l = quotemeta( $tr{$key}); $r = $html{$key};
		$entry =~ s/$l(.*?)/$r$1/gs;
	    }
            # where @[dollar] is more difficult (or should we just throw it ?)
	    $d = '\@\[dollar\]';
#	    while( $entry =~ s/$d(.*?)$d/\<math\>$1\<\/math\>/gs) {;}
	    $entry =~ s/$d//gs;
            # finally break into paragraphs
	    $entry =~ s/\n\n/\<\/p\>\n<p\>/gs;
	    $entry =~ s/\<p\>(\n*?)\e\[0m//gs;
	}
	else {
	    # heading
	    $entry =~ s/\e\[1m(.*?)\e\[m(.*?):\n\n/\<h4\>$1$2\<\/h4\>\n\<p\>/g;
	    # bold
	    while( $entry =~ s/\e\[1m(.*?)\e\[m/\<b\>$1\<\/b\>/gs) {;}
	    # underline
	    while( $entry =~ s/\e\[4m(.*?)\e\[m/\<var\>$1\<\/var\>/gs) {;}
	    # break into paragraphs
	    $entry =~ s/\n\n/<\/p>\n\n\<p\>/gs;
	    # throw the rest
	    $entry =~ s/\e\[m//gs;
	    $entry =~ s/\<p\>\e\[0m//gs;
	    # treat special symbols
	    $entry =~ s/\&/\&amp;/gs;
	}


#	$entry =~ /\e\[/ and print STDERR $item,"\n";
	$entry =~ s/\<h4\>(.*?)\<\/h4\>//;
	$function = $1;

	$link = "</td><td align=right><a href=\"./index.html\">"
	    ."<img src=\"./home.gif\" border=0 /></a>&nbsp;&nbsp;<a href=\"#top\">"
		."<img src=\"./top.gif\" border=0 /></a></td></tr>";

	$contents = $contents
	    ."<tr bgcolor=\"#EEEEAA\">\n"
		."<td><a name=\"$item\"></a> $function$link\n"
		    ."<tr><td colspan=2>$entry\</td></tr>\n";
	$contents = $contents
	    ."<tr bgcolor=\"#FFFFFF\"><td colspan=2 height=6></td></tr>\n";
    }
    $contents = $contents
	.'</table>';

    printHTML( "$fill{$key}.html", "$key", 'bgcolor=\"#FFFFFF\"', $contents); 

    print STDERR "\t   ... \e[0;32m\e[1m DONE\e[m\n";
}


sub writeEntries() {
###############################################
# Writes, for each list pointed to by $key,
# a file $key.html which will contain the
# subsections of the corresponding section
# in usersch3.tex.
# Needs correcly initializes hash %subsectiones
# and uses for the moment "gphelp -detex" or
# "gphelp -detex" (accordingly to what option
# is set)
# to convert subsections of usersch3.tex
# into html.
# Use in the form writeEntries( $key)
###############################################

    my( $contents, $item, $entry, $l, $r, $d, $key);

    $key = $_[0];
    print STDERR "\twriting: $key   ...\n";

    initFixedData();

    $contents = "\n<h3 align=center>$key</h3>\n\n";
    foreach $item (@{ $subsections{$key}}) {
	$item =~ s/^\[(.*?)\]\_\_\((.*?)\)\_\_$/$1/;
	$entry = `$gphelp '$option' '$item'`;
	$entry =~ /not\ found/ and unhappy("\t$item");
	if( $option eq '-raw') {
            # first kill TeX leftovers
	    for $key ( keys %trans0) {
		$l = quotemeta( $key); $r = $trans0{$key};
		$entry =~ s/$l/$r/gs;
	    }
	    for $key ( keys %trans1) {
		$l = quotemeta( $key); $r = $trans1{$key};
		$entry =~ s/$l/$r/gs;
	    }
# TO_DO: Fix the dirty hack from here
	    $l = '\@1\@\[startcode\]'; $r = '<pre><font color=#a3682a><tt>';  
	    $entry =~ s/$l(.*?)/$r$1/gs;
	    $l = '\@2\@\[endcode\]'; $r = '</tt></font></pre>';
	    $entry =~ s/$l(.*?)/$r$1/gs;
# to here.
	    for $key ( keys %trans) {
		$l = quotemeta( $key); $r = $trans{$key};
		$entry =~ s/$l/$r/gs;
	    }
            # then make a nice header
	    $entry =~ s/^(.*?)\:/\<h4\>$1\<\/h4\>\n\<p\>/gs;
            # now care for the @[] markers
	    for $key ( @ou) {
		$l = quotemeta( $tr{$key}); $r = $html{$key};
		$entry =~ s/$l(.*?)/$r$1/gs;
	    }
            # where @[dollar] is more difficult (or should we just throw it ?)
	    $d = '\@\[dollar\]';
#	    while( $entry =~ s/$d(.*?)$d/\<math\>$1\<\/math\>/gs) {;}
	    $entry =~ s/$d//gs;
            # finally break into paragraphs
	    $entry =~ s/\n\n/\<\/p\>\n<p\>/gs;
	    $entry =~ s/\<p\>(\n*?)\e\[0m//gs;
	}
	else {
	    # heading
	    $entry =~ s/\e\[1m(.*?)\e\[m(.*?):\n\n/\<h4\>$1$2\<\/h4\>\n\<p\>/g;
	    # bold
	    while( $entry =~ s/\e\[1m(.*?)\e\[m/\<b\>$1\<\/b\>/gs) {;}
	    # underline
	    while( $entry =~ s/\e\[4m(.*?)\e\[m/\<var\>$1\<\/var\>/gs) {;}
	    # break into paragraphs
	    $entry =~ s/\n\n/<\/p>\n\n\<p\>/gs;
	    # throw the rest
	    $entry =~ s/\e\[m//gs;
	    $entry =~ s/\<p\>\e\[0m//gs;
	    # treat special symbols
	    $entry =~ s/\&/\&amp;/gs;
	}

#	$entry =~ /\e\[/ and print STDERR $item,"\n";

	$contents = $contents
	    ."<a name=\"$item\"></a>\n$entry\n\<br\>\n<hr></hr><br>\n\n";
    }
    printHTML( "$fill{$key}.html", "$key", 'bgcolor="#FFFFFF"', $contents); 

    print STDERR "\t   ... \e[0;32m\e[1m DONE\e[m\n";
}


sub writeData4Ref {
##########################################
# Writes the images home.gif and top.gif
# described in file FILE. (Use hexdump for
# byte to hex conversion.) For the the
# syntax of such a description
# see below __DATA__
# Call in the form
# writeData ( *FILEHANDLE)
##########################################
    my( $IN, $Mode, $currLine, @parm, $data);
    
    $IN = $_[0];
    $Mode = '';
    while ( <$IN>) {
	$currLine = $_;
	if( $currLine =~ /^\s*\@PIC\{\s*(.*?)\s*\}/) {
	    @parm = ($1);
	    if( "home.gif" eq $parm[0] or "top.gif" eq $parm[0]) {
		$Mode = 'PIC';
		$data = '';
	    }
	    next;
	}
	if( $currLine =~ /^\s*\@HTML\{\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\}/) {
	    $Mode = 'HTML';
	    next;
	}
	if( $currLine =~ /\@DONE/) {
	    if( $Mode eq 'PIC') {
		$data =~ s/\s//g;
		printPIC( @parm, $data);
	    }
	    $Mode = '';
	    next;
	}
	if( $Mode eq 'PIC') {
	    $data = $data . $currLine;
	    next;
	}
    }
}


sub writeData {
########################################
# Writes html pages and images described
# in file FILE. For the the syntax of
# such a description
# see below __DATA__
# Call in the form
# writeData ( *FILEHANDLE)
########################################
    my( $IN, $Mode, $currLine, @parm, $data);
    
    $IN = $_[0];
    $Mode = '';
    while ( <$IN>) {
	$currLine = $_;
	if( $currLine =~ /^\s*\@PIC\{\s*(.*?)\s*\}/) {
	    $Mode = 'PIC';
	    @parm = ($1);
	    $data = '';
	    next;
	}
	if( $currLine =~ /^\s*\@HTML\{\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\}/) {
	    $Mode = 'HTML';
	    $parm[0] = $1;
	    @parm = ($1, $2, $3);
	    $data = '';
	    next;
	}
	if( $currLine =~ /\@DONE/) {
	    if( $Mode eq 'PIC') {
		$data =~ s/\s//g;
		printPIC( @parm, $data);
	    }
	    if( $Mode eq 'HTML') {
		printHTML( @parm, $data);
	    }
	    $Mode = '';
	    next;
	}
	if( $Mode eq 'PIC' or $Mode eq 'HTML') {
	    'HTML' eq $Mode and do { # eval. variables in DATA section
		$currLine =~ s/\$(\w+)/${$1}/g;
	    };
	    $data = $data . $currLine;
	    next;
	}
    }
}


sub printHTML {
###################################################################
# Writes a html page.
# Call in the form
# printHTML( $name_of_file, $title_of_page, $background, $contents)
# with properly initialized scalar arguments.
# If $background eq "NO_BODY_TAGS",
# then no <BODY> tags will be printed.
###################################################################
    my( $standardHead);

    $standardHead = <<"__UP_TO_HERE__";
<HTML>
<HEAD>
  <TITLE>
    Catalogue of GP/PARI Functions: __TITLE__
  </TITLE>

  <META NAME="author"       CONTENT="Nils-Peter Skoruppa">
  <META NAME="created"      CONTENT="$DATE">
  <META NAME="author-email" CONTENT="skoruppa\@math.uni-siegen.de">
  <META NAME="keywords"     CONTENT="PARI, GP, DOC">
</HEAD>
__UP_TO_HERE__

    open OUT, ">$HTML/$_[0]"
	or fatal("Cannot create the file $HTML/$_[0]\n");
    $standardHead =~ s/__(TITLE)__/$_[1]/;
    print OUT $standardHead;
    if( $_[2] eq "NO_BODY_TAGS") {
	print OUT "\n\n$_[3]\n\n";
    }
    else {
	print OUT "<BODY $_[2]>\n\n\n$_[3]\n\n</BODY>\n";
    }
    print OUT "</HTML>";
    close OUT;
}


sub printPIC {
#######################################
# Writes a stream of 2 digit hex values
# as chars to file.
# Call in the form
# printPIC( $file, $stream)
#######################################
    open OUT, ">${HTML}/$_[0]"
	or fatal( "Cannot create the file ${HTML}/$_[0]\n");	
	$_[1] =~ s/(..)/chr(hex($1))/ge;
	print OUT $_[1];
    close OUT;
}



##########################DO NOT ALTER BELOW THIS LINE #############################
sub initFixedData
{

@ou = qw( 
	  nbrk
	  startbold endbold
	  startcode endcode
          startpodcode endpodcode
	  startbi endbi
	  startit endit
	  startword endword
	  startlword endlword
	  pm
	  obr cbr
	  lt gt
	  agrave eacute uuml ouml
	  );

#         dollar                              => <math> ... </math>
#         nbrk                                               => ignore
#         startbold endbold        -gp/pari functions        => boldface
#         startcode endcode        -???                      => color
#         startpodcode endpodcode  -???                      => go
#startlink endlink                 -nix da in raw
#startbcode endbcode               -nix da in raw
#         startbi endbi            -blackboard boldface      => boldface
#         startit endit            -optional argments        => underline
#         startword endword        -greek letters            => color
#         startlword endlword      -math.abbrev. like $\log$ => ignore
#         pm                       -+-                       =>
#empty gt lt podleader             -nix da in raw            => ignore
#
# Neu in parigp.2.1.1:
#         obr cbr                                            => { }
#         lt gt                                              => < >
#	  agrave eacute uuml ouml                            => &agrave; ...

@tr{@ou} = map "\@[$_]", @ou;

%html = (
	 nbrk         => '',
	 startbold    => '<b>',
	 endbold      => '</b>',
#NILS	 startcode    => "<font color=#a3682a>",
	 startcode    => "<font color=#a3682a><tt>\n",
#NILS	 endcode      => '</tt></font></pre>',
	 endcode      => '</tt></font>',
	 startpodcode => '',
	 endpodcode   => '',
	 startbi      => '<b>',
	 endbi        => '</b>',
	 startit      => '<u>',
	 endit        => '</u>',
	 startword    => '<font color=#FF0000>',
	 endword      => '</font>',
	 startlword   => '',
	 endlword     => '',
	 pm           => '&#177;',
	 obr          => '{',
	 cbr          => '}',
	 lt           => '&#60;',
	 gt           => '&#62;',
	 agrave       => '&agrave;',
	 eacute       => '&eacute;',
	 uuml         => '&uuml;',
	 ouml         => '&uml;',
	 );

%trans0 = (
	  '&'          => '&amp;',
	   );
%trans1 = (
	  '<'          => '&#60;',
	  '>'          => '&#62;'
	  );
%trans = (
	  '\{'         => '{',
	  '\}'         => '}',
	  '\langle'    => '&#60;',
	  '\rangle'    => '&#62;',
	  '@1'         => '',
	  '@2'         => '',
	  '@0'         => '&nbsp;',
	  );

}



__DATA__


Layout of frames:
=================

         / empty empty empty empty
        /              item
 index <   empty toc   ----- empty
        \              entry
         \ empty empty title empty



@HTML{index.html, Main Page, NO_BODY_TAGS}
<FRAMESET COLS="1%,280,*,1%" ROWS="1%,91%,8%" BORDER=0 FRAMEBORDER="no" FRAMESPACING=0>
<FRAME src="empty.html" scrolling="no"></FRAME>
<FRAME src="empty.html" scrolling="no"></FRAME>
<FRAME src="empty.html" scrolling="no"></FRAME>
<FRAME src="empty.html" scrolling="no"></FRAME>

<FRAME src="empty.html" scrolling="no"></FRAME>
<FRAME src="toc.html"></FRAME>
<FRAMESET rows="140,*" border=0 frameborder="yes" framespacing=0>
<FRAME name="itemFrame"   src="item.html"></FRAME>
<FRAME name="entryFrame"  src="entry.html"></FRAME>
</FRAMESET>
<FRAME src="empty.html" scrolling="no"></FRAME>

<FRAME src="empty.html" scrolling="no"></FRAME>
<FRAME src="empty.html" scrolling="no"></FRAME>
<FRAME src="title.html" scrolling="no"></FRAME>
<FRAME src="empty.html" scrolling="no"></FRAME>
</FRAMESET>
@DONE


@HTML{ empty.html, Empty Page :-), BACKGROUND="./empty.jpg"}
@DONE


@HTML{ title.html, Title Page, BACKGROUND = "./empty.jpg"}
Catalogue of Functions for $version.
<br>
<small>(generated by gphtml on $DATE.)</small>
@DONE


@HTML{ item.html, Items Page, BGCOLOR=#FFFFFF}
@DONE


@HTML{ entry.html, Welcome Page, BGCOLOR=#FFFFFF}
<br><br>
<center>
<h2>This is a html documentation of<br>
functions available under the $version.<br>
Comments and proposals for improvement
<a href="mailto:countnumber@math.uni-siegen.de">
are welcome.</a></h2>
</center>
<br><br>
You can <a href="../html.tgz">download these html files</a> (as
gzipped tar file) or generate them by yourself using
the perl script
<a href="../gphtml">gphtml</a> (provided perl, gp, gphelp
and the gp/pari
tex documentation file usersch3.tex is installed on your system).
@DONE


@PIC{empty.jpg}
ffd8ffe000104a46494600010101004800480000fffe0017437265617465642077697468205468652047494d50ffdb004300080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432ffdb0043010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc0001108000a000a03012200021101031101ffc4001500010100000000000000000000000000000006ffc40014100100000000000000000000000000000000ffc4001501010100000000000000000000000000000506ffc40014110100000000000000000000000000000000ffda000c03010002110311003f00b800c261ffd9
@DONE

@PIC{toc.jpg}
ffd8ffe000104a46494600010101004800480000fffe0017437265617465642077697468205468652047494d50ffdb004300080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432ffdb0043010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc00011080014011803012200021101031101ffc40017000101010100000000000000000000000002000106ffc4001510010100000000000000000000000000000001ffc40017010101010100000000000000000000000002010506ffc4001511010100000000000000000000000000000001ffda000c03010002110311003f00ee0a0946c399850861094694128850a10c242850a0c28250a3632362142282510a142830a2146c3810e2146c2184250a1418510a146c646c42850a0c282508a09442850a0c28851b0a0c28850a10c24285128909c01449aae76142484a34a24850a124850a14484a146c490a114490a142892146c3892146c2484a1428921428d8921428512128451242850a24851b0a24850a124850a24909ffd9
@DONE

@PIC{logo.jpg}
ffd8ffe000104a46494600010101000100010000ffdb004300080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432ffdb0043010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc0001108002c006003012200021101031101ffc4001c0000020203010100000000000000000000060704050001030802ffc400371000010303020502040306070000000000010203040005110621071213314122511461718115379132427482b1b3085375a1c1c2f0ffc400190100030101010000000000000000000000000203040501ffc4002a11000202010302040603000000000000000102000311042131127113415181226191b1c1d114e1f1ffda000c03010002110311003f006d6a1d79a7b4abc1bbd4a9110288097150de536a246701612524e3c035093c53d24bb67e2699d28dbf9f90cbfc3a47482bd8af9302a878f9f962f7f16cff005351b8290a2dcb840a8535a43b15f7e436ea17d8a4900d108c9b3df6d5a8217c65a67c798c67056cac2b07d88ee0fc8d41bacd7d3a8a04361f525223bcfbc9491b805084e7eea27ed485e03392a2f126e50a038b76d85873acaee9504ab0da89f7df6fa9a6b4cba3ea91ab6fb1c248865bb7c65a939196815b871e473b98fe5abd2000d61e147df6fce7da2952e422f24e2145a26bce5dae30df714b280d3cdf3784293ca40fe642bf5a9d74ba47b44232e52641692707a11dc7943e7ca804e36ef8c50659ee4e99fa6eef24a79ae2c390df50181cf9e746df5c8fbd1f1ed5834cd94c1f2ff62540a96adb952440bb7715f47dddf5316db8499af25056a6e3dbe438a091dc9011db71fad59d8b5de99d4b25516d57765e949ce63ac29b776efe858076fa524b821f9c1a83f8693fdf4556719dd6d8e31c776c4ae5b925b8e5c2c9c2be2398f2fdf97a75a2567a46f37b876184664ff880c273ccb66338f728009254109240c0ee76a1983c5cd17739688902e8fcb92bc94b4c4090b59c0c9c008cf6a34567a473df1bd7993fc3b7e625c3fd35cfeeb74427a752a0a4850ce08cee315bacaca2115fc7cfcb17bf8b67fa9aa0e11e997b5070afe1d7a82ed0a2bd21e42d886594023233ea2d958cf9f551671434bea6d6968364b622d4cc32ea1d5489321cea2b97c04041037f39391e056f85fa5f5368bb40b25cd16a7a18756ea644690e7513cde0a14800efe7231ec68849b1ac5a77855a42e736d713a61a64b8e38e28a9c7d636424a8fb920003037ed42970d16fdbf49fe2336e5244c531f112232701beaab0543f53447a8df1a9f5c5b34ab395c382a4dc2e853dbd3bb4d9faab0a23d80a2c9b118b8483164b49758536438dabb281ffc2b4dda7514aab0f88e4fb797efb623e9f54f4d9d4a76c8cfd778ad8ba45e7f478bcc6b84954961b125b8c774020e76f9e01a69d96e6d5e6cb12e0d11cafb61440fdd3e47d8e457cc1871e0b8b871d94371c2004b691b01edfee681ed0fdd34bdfae5a620b119e53cb326de253ca69be539c8ca52a3b7b63f74ee2b8f59f0986783b1efe521aad6d965e19cfc2491db7dbf513dc3fb3aaf7af356456ae726d8f887296d4b61f5345b5079382a292329f707c7cf06ad386ef234fde22dbdc6ac8e5fa7bca5b32e7214b5a0e3f642f3b648d8e0649c6f5d8f0ef53688913ef173976d5b5730a8eea622d64e56b0e11ea48f4e51ef53ee3c2bb96b1b2586eb627214494d21deb3ef3eb429443a79301283db1df3e7b6d5a598b59d0274eba96bd37f218649381e9de32aedab2f7a760bdf8c5ad9538b4911e4c451532578d92b07053ff3487e09ca990b52dea641e87c4316a75ec3e9252a4a5682a1b1073db07e5f3d9f2e42d5f3f45b96abac4b1cbb8adbe929e131c436bd8e1c23a4485021270363b9c8ed4b4d31c2ad5ba11dba5d16fd964c676dcf479084bee05841009527d18e6052363b1edb77a6c119de4c3d6e530b839dfd0f1fdc63694d517ed5289a50ab74754608c05475a828ab3dfd631daa7587599977a76c5768e88b726945014dab2db846f819dc1c6f8a14e185d205b1bbb2e74b663a4868a7a8b00ab1cd9c0f3f6addba13dab388cbbd4565c45b5890973aea04057200001f324038f00ef505b1ba548392674aed355e25aacb850363f3c0fae6362b473838ef5bacad738506b46e941a5e049ebcb54db94e78c8992d4305c59f61e00f1f5357cd30a44871d52b3cdd87b0aef5955b2e7b18bb1dcc50a062705b0a54943c950181823dea15cb4fc0bacf83364a17d784be769685149fa123c677ab4acace6b52082399e1ad5810441bd756676f5a5df663a4a9f6541f6d2064a8a7b81f3209aace18dc51274caa0923ab0dd524a7cf2a8f303fa923ed46f54d334b59674b329e8412fabf69c656a694afa94119fbd2b21ebeb137d7a85341a2ce33904797da2bb8890e143d52db16f65b682984171b676016491d876246299b74b7c4b6e8eb9c7871db61a10ddf4a138c9e42327dceddcd6e1e90b0c09625316e6cc8079838ea94e281f70544ef536e767857867a3352eb8d6305b4bcb4255f509233dbcd2ad44751f596bb58960ad01385e7e7ed9fcc5ff08c03f8be47f93ff7a6780076aa281a3ac96c9024418cec7776ca9b90e0c8ce707d5b8f91abda7a94a2f4990d75c97dc6c4cefebda7ffd9
@DONE

@PIC{home.gif}
47494638396110000d00b30000000000664433995522444444bb6644bb8866aa8888ccbb88bbccddddddddddbb99ffddbbffffddddeeffc0c0c0ffffff21f9040100000c002c0000000010000d0040042c90c949ab7429eb9d9cbf5cd84d5e699614b6391673bedee88a2b4b9a2d18be3a9db12a5acc1614a17a464604003b
@DONE

@PIC{top.gif}
4749463839610f000b00f10300000000c0c0c0ddddddffffff21f90401000003002c000000000f000b0000025edcb871e3c28d1b376edcb871a1c28d1b376edcb850a2c28d1b376e5c2851a2c28d1b372e942851a2c28d1b17268c283161c28d1b372e94a870e3c68d1b3746949871e3c68d1b174a54b871e3c68d1b234accb871e3c68d0b1326dcb87105003b
@DONE







