#! /usr/bin/env perl
#
# makedoc
#
$prog       = "CDO";
$longname   = "Climate Data Operators";
$moddir     = "mod";
$modules    = "Modules";
$help       = "../../src/operator_help.h";
$catalog    = "catalog.tex";
$abclist    = "alphabetic_list.tex";
@oplist     = ();
$refover    = "cdo_ref_over.tex";
#$reference  = "xxx.tex";
$refcard    = "cdo_refcard.tex";
$class      = "cdo_class";
#
open(README,   ">../../OPERATORS");
open(CDOHTML,  ">cdo_oper.html");
open(HELPFILE, ">$help");
open(TCFILE,   ">$catalog");
open(ABCLIST,  ">$abclist");
open(TROVER,   ">$refover");
#open(TRFILE,   ">$reference");
open(TRCARD,   ">$refcard");
open(CLASS,    ">$class");
#
################################################################################
# Preprocess EcaIndices file for grabbing the variable names, which are creates
# by theses operators
my $ecaIndicesFile = "../../src/EcaIndices.c";
my $search_pattern = '(\w*)_NAME\d*\[\] .* = "(\w+)"';
my %ecaVars;

open(ECANAMES,$ecaIndicesFile);
while (<ECANAMES>) {
  if (my ($found) = m/($search_pattern)/o) {
    my $eca        = "eca_".lc($2);
    my $var        = $3;
    $ecaVars{$eca} = [] unless exists $ecaVars{$eca};
    push @{$ecaVars{$eca}}, $var;
  }
}
#foreach $eca (sort keys %ecaVars) {
#  print "$eca: ";
#  my @vars = @{$ecaVars{$eca}};
#  print join ', ', @vars;
#  print ".\n";
#}
################################################################################
#
$threecols = 0;
#
if ( $threecols == 1 ) {
  $len1 = "3.65in";
  $len2 = "0.75in";
  $len3 = "2.56in";
} else {
  $len1 = "3.95in";
  $len2 = "0.85in";
  $len3 = "2.76in";
}
#
$noper = 0;
#
#
open(MOFILE, $modules) || die "Open failed on module file $modules: $!\n";
#
#
print README "===========================\n";
print README "$prog  $longname\n";
print README "===========================\n";
print README "\n";
print README "Operator catalog:\n\n";
print CDOHTML "<H2 align=\"center\">CDO  -  Climate Data Operators</H2>\n";
print TCFILE "\\chapter*{\\label{opercat}Operator catalog}\n";
print TCFILE "\\addcontentsline{toc}{chapter}{Operator catalog}\n";
print TCFILE "\n";
print ABCLIST "\\chapter*{\\label{operlist}Alphabetic List of Operators}\n";
print ABCLIST "\\addcontentsline{toc}{chapter}{Operator list}\n";
print ABCLIST "\n";
print ABCLIST "\\noindent\n";
print ABCLIST "\\begin{longtable}{ll}\n";
#
if ( $threecols == 1 ) {
  print TRCARD "\\documentclass[landscape,a4paper]{article}\n";
  print TRCARD "\\usepackage{threecolumn}\n";
} else {
  print TRCARD "\\documentclass[a4paper,twocolumn,11pt]{article}\n";
}
print TRCARD "\n";
print TRCARD "\\usepackage{graphics}\n";
print TRCARD "\\usepackage{array,colortbl}\n";
print TRCARD "\\usepackage{color}\n";
print TRCARD "\n";
print TRCARD "% A4 29.7x21.0cm  11.7x8.26\n";
print TRCARD "\\setlength{\\hoffset}{-0.8in}\n";
print TRCARD "\\setlength{\\voffset}{-0.7in}\n";
print TRCARD "\n";
print TRCARD "\\setlength{\\headheight}{0in}\n";
print TRCARD "\\setlength{\\headsep}{0in}\n";
print TRCARD "\\setlength{\\topmargin}{0in}\n";
print TRCARD "\n";
if ( $threecols == 1 ) {
  print TRCARD "\\setlength{\\textwidth}{11.3in}\n";
  print TRCARD "\\setlength{\\textheight}{7.8in}\n";
} else {
  print TRCARD "\\setlength{\\textwidth}{7.85in}\n";
  print TRCARD "\\setlength{\\textheight}{11.2in}\n";
}
print TRCARD "\\setlength{\\oddsidemargin}{0in}     % default=0in\n";
print TRCARD "\\setlength{\\evensidemargin}{0in}    % default=0in\n";
print TRCARD "\n";
print TRCARD "\\setlength{\\columnsep}{0.2in}       % default=10pt\n";
print TRCARD "%\\setlength{\\columnseprule}{1pt}     % default=0pt (no line)\n";
print TRCARD "\n";
print TRCARD "%\\setlength{\\topmargin}{-0.15in}    % default=0.20in\n";
print TRCARD "%\\setlength{\\headsep}{0.15in}       % default=0.35in\n";
print TRCARD "\n";
print TRCARD "\\setlength{\\parskip}{-0.02in}\n";
print TRCARD "\\setlength{\\parindent}{0in}\n";
print TRCARD "\n";
print TRCARD "\\newenvironment{defalist}[1]\n";
print TRCARD "{\\begin{list}{}\n";
print TRCARD "{\\settowidth{\\labelwidth}{\\bf #1\\ \\ }\n";
print TRCARD "\\setlength{\\topsep}{-0.5mm}\n";
print TRCARD "\\setlength{\\parsep}{0mm}\n";
print TRCARD "\\setlength{\\itemsep}{0mm}\n";
print TRCARD "\\setlength{\\itemindent}{0mm}\n";
print TRCARD "\\setlength{\\leftmargin}{\\labelwidth}\n";
print TRCARD "\\setlength{\\labelsep}{0mm}\n";
print TRCARD "\\addtolength{\\leftmargin}{\\labelsep}\n";
print TRCARD "}}\n";
print TRCARD "{\\end{list}}\n";
print TRCARD "\n";
print TRCARD "\\begin{document}\n";
print TRCARD "\\footnotesize\n";
if ( $threecols == 1 ) {
  print TRCARD "\\threecolumn\n";
  print TRCARD "\n";
  print TRCARD "\\input{cdoprog}\n";
} else {
  print TRCARD "\\twocolumn\n";
  print TRCARD "\n";
  print TRCARD "\\input{cdoprog}\n";
}
print TRCARD "\n";
print TRCARD "\\vspace*{2mm}\n";
print TRCARD "\\subsection*{Operators}\n";
print TRCARD "\n";
#
print HELPFILE "/* Automatically created with makedoc, don't edit! */\n";
#
$help_print = 1;
$oldchap = "oldchap";
$nline = 0;
while (<MOFILE>) {
    chomp;
    ($modulefile) = split(" ");
    print "process module: $modulefile\n";
    $modulefilename = "${moddir}/${modulefile}";
    open(MODFILE, "$modulefilename") || die "Open failed on module file $modulefilename: $!\n";
    $module    = "";
    $margs     = "";
    $operators = "";
    $trskip = 0;
    $statpos = index($modulefile, "stat", 3);
    if ( $statpos != -1 ) { $statpos += 4; }
    if ( length($modulefile) == $statpos ) { $trskip = 1; }
    undef @doclines;
    $lblock = 0;
    while (<MODFILE>) {
      chomp;
      if ( index($_ , "\@C ") != 0 ) {
	push(@doclines, $_);
      }
    }
    close(MODFILE);

    undef @modlines;
    $lblock = 0;
    foreach $tag (@doclines) {
      ($kword) = split(" ", $tag);
      $kword = uc($kword);
      if ( $lblock == 0 ) {
	if ( "$kword" eq "\@BEGINMODULE" ) {
	  $lblock = 1;
	  next;
	}
      }
      if ( $lblock == 1 ) {
	if ( "$kword" eq "\@ENDMODULE" ) { last; }
	push(@modlines, $tag);
      }
    }

    if ( $lblock == 0 ) {
      print "$modulefile: Module description not found!\n";
      next;
    }

    $mname      = "";
    $mtitle     = "";
    $msection   = "";
    $marguments = "";
    $moperators = "";
    $newpage = 0;
    $oclass     = "Other";
    foreach $tag (@modlines) {
      $line = $tag;
      $line =~ s/^\s+|\s+$//og;
      ($kword, $value) = split(/\s*=\s*/, $line, 2);
      $kword = uc($kword);
      if ( "$kword" eq "\@NAME" ) {
	$mname = $value;
      }
      elsif ( "$kword" eq "\@TITLE" ) {
	$mtitle = $value;
      }
      elsif ( "$kword" eq "\@SECTION" ) {
	$msection = $value;
      }
      elsif ( "$kword" eq "\@ARGUMENTS" ) {
	$marguments = $value;
      }
      elsif ( "$kword" eq "\@OPERATORS" ) {
	$moperators = $value;
      }
      elsif ( "$kword" eq "\@CLASS" ) {
	$oclass = $value;
      }
      elsif ( "$kword" eq "\@NEWPAGE" ) {
	$newpage = 1;
      }
    }

    $chap = $msection;

    $nline = $nline + 1;
    if ( "$chap" ne "$oldchap" ) {
      $oldchap = $chap;
      if ( $nline > 1 ) {
# 	print TCFILE "\\end{tabular*}\n";
# 	print TCFILE "\n";
      }

      print README "-------------------------------------------------------------\n";
      print README "   $chap\n";
      print README "-------------------------------------------------------------\n";
      print TCFILE "\\subsection*{$chap}\n";

      $shortname = lc(substr($chap, 0, 6));
      $shortname =~ s/ /_/og;
      $reference  = "ref_man_${shortname}.tex";
      open(TRFILE, ">$reference");

      $reflist   = "ref_list_${shortname}.tex";
      open(TRLIST, ">$reflist");

      print CDOHTML "<A NAME=\"${shortname}\"></A><H3>$chap</H3>\n";

      print TRLIST "\n";
      print TRLIST "Here is a short overview of all operators in this section:\\\\\n";
      print TRLIST "\n";

      print TROVER "\\newpage\n";
      print TROVER "\\section{$chap}\n";
      print TROVER "\\input{ref_intro_${shortname}}\n";
      print TROVER "\\input{ref_list_${shortname}}\n";
      print TROVER "\\input{ref_man_${shortname}}\n\n";
#      if ( $chap eq "ECA indices" ) {
#	print "find eca!";
#	$refskip = 1;
#      }
#      else {
	print TRCARD "\\subsubsection*{$chap}\n";
	$refskip = 0;
      if ( $chap eq "Statistical values" ) {
	print TRCARD "\\noindent\n";
	print TRCARD "\\hspace*{0.5in}\n";
	print TRCARD "\\begin{tabular*}{2.8in}{|>{\\columncolor{pcolor1}}l>{\\columncolor{pcolor2}}l|} \\hline\n";
	print TRCARD "\\rowcolor{pcolor3}\n";
	print TRCARD "\\makebox[1.8in][c]{Available statistical functions} &\n";
	print TRCARD "\\makebox[0.65in][c]{\$<\\!stat\\!>\$} \\\\ \n";
#	print TRCARD "\\makebox[0.65in][c]{\$<\\!stat\\!>\$} \\\\ \\hline\n";
	print TRCARD "minimum  & {\\bf min}   \\\\ \n";
	print TRCARD "maximum  & {\\bf max}   \\\\ \n";
	print TRCARD "sum      & {\\bf sum}  \\\\ \n";
	print TRCARD "mean     & {\\bf mean}  \\\\ \n";
	print TRCARD "average            & {\\bf avg}  \\\\ \n";
	print TRCARD "variance           & {\\bf var, var1}  \\\\ \n";
	print TRCARD "standard deviation & {\\bf std, std1}  \\\\ \n";
	print TRCARD "\\hline\n";
	print TRCARD "\\end{tabular*}\n";
	print TRCARD "\\vspace{2mm}\n\n";
      }
#      }
#      print TCFILE "\\begin{tabular*}{13cm}{ll}\n";
#      print TCFILE "\\hspace*{30mm} &  \\\\ \n";

#      print TRFILE "\n\n\\section{$chap}\n";
    }

    print HELPFILE "\n";
    print HELPFILE "static char *${mname}Help[] = {\n";

    @hkeys = split(" ", $moperators);
#    print "$#hkeys @hkeys \n";

    print TRFILE "\n";
    if ( $newpage == 1 ) {
       print TRFILE "\n\\newpage\n";
    }
    $modname = uc($mname);
    $mtitlem = $mtitle;
    $mtitlem =~ s/</\$<\$/og;
    $mtitlem =~ s/>/\$>\$/og;
    $mtitlem =~ s/ wrt / w.r.t. /og;
    print TRFILE "\\subsection{$modname - $mtitlem}\n";
#    print TRFILE "\\index{$modname}\n";
    foreach $tag (@hkeys) {
      $ntag = $tag;
      $ntag =~ s/^-//;
      $ntag =~ s/_/\\_/g;
      print TRFILE "\\index{$ntag}\n";
    }
    print TRFILE "\\label{$modname}\n";
    foreach $tag (@hkeys) {
      $ntag = $tag;
      $ntag =~ s/^-//;
      print TRFILE "\\label{$ntag}\n";
    }

#   Decription (module)

    undef @moddeslines;
    $lblock = 0;
    foreach $tag (@modlines) {
      ($kword) = split(" ", $tag);
      $kword = uc($kword);
      if ( $lblock == 0 ) {
	if ( "$kword" eq "\@BEGINDESCRIPTION" ) {
	  $lblock = 1;
	  next;
	}
      }
      if ( $lblock == 1 ) {
	if ( "$kword" eq "\@ENDDESCRIPTION" ) { last; }
	push(@moddeslines, $tag);
      }
    }


#  Operators

    print TCFILE "\\noindent\n";
    print TCFILE "\\begin{tabular*}{13cm}{ll}\n";

    print TRLIST "\\noindent\n";
    print TRLIST "\\begin{tabular*}{13cm}{ll}\n";

    print CDOHTML "<table WIDTH=\"60%\" border=\"0\">\n";

    if ( $refskip == 0 ) {
      print TRCARD "\\noindent\n";
      print TRCARD "\\begin{tabular*}{$len1}{|>{\\columncolor{pcolor2}}l>{\\columncolor{pcolor1}}l|} \\hline\n";
    }

    print HELPFILE "    \"NAME\",\n";
    print HELPFILE "    \"    ";
    $maxlen = 0;
    $maxitem = "";
    foreach $operator (@hkeys) {
      $len = length($operator);
      if ( index("$operator", "-") == 0 ) { $len -= 1; }
      if ( $len > $maxlen ) {
	$maxlen = $len;
        $maxitem = $operator;
	$maxitem =~ s/_/\\_/g;
      }
    }
    $maxlen += 2;

    $icount = 0;
    $slen = 0;
    foreach $operator (@hkeys) {
      if ( $icount > 0 ) {
	print HELPFILE ", ";
        $slen += 2;
      }
      $norefoper = 0;
#      $operator =~ s/^-//;
      if ( index("$operator", "-") == 0 ) {
	$operator =~ s/^-//;
        $norefoper = 1;
      }
      $len = length($operator);
      if ( $len + $slen > 76 ) {
	$slen = 0;
	print HELPFILE "\",\n";
	print HELPFILE "    \"    ";
      }
      $slen += $len;
      print HELPFILE "${operator}";
      if ( $norefoper == 1 ) {
	$operator =~ s/^/-/;
      }
      $icount++;
    }
    print HELPFILE " - ";
    $len = length(${mtitle});
    if ( $len + $slen > 76 ) {
      $slen = 0;
      print HELPFILE "\",\n";
      print HELPFILE "    \"    ";
    }
    print HELPFILE "${mtitle}\",\n";

    undef @oper_title;
    undef @oper_parameter;
    $opercnt = 0;
    foreach $operator (@hkeys) {
      $opercnt += 1;
      $norefoper = 0;
      if ( index("$operator", "-") == 0 ) {
	$operator =~ s/^-//;
        $norefoper = 1;
      }

      undef @oplines;
      $lblock = 0;
      $opname = "";
      foreach $tag (@doclines) {
	($kword, $value) = split("_", $tag,2);
	$kword = uc($kword);
	if ( $lblock == 0 ) {
	  if ( "$kword" eq "\@BEGINOPERATOR" ) {
	    $lblock = 1;
	    $opname = $value;
	    next;
	  }
	}
	if ( $lblock == 1 ) {
	  if ( "$kword" eq "\@ENDOPERATOR" ) {
	    $lblock = 0;
	    if ( "$operator" eq "$opname" ) { last; }
	    else                            { next; }
	  }
	  if ( "$operator" eq "$opname" ) {
	    push(@oplines, $tag);
	  }
	}
      }

      $otitle     = "";
      $oparameter = "";
      foreach $tag (@oplines) {
	$line = $tag;
	$line =~ s/^\s+|\s+$//og;
	($kword, $value) = split(/\s*=\s*/, $line, 2);
	$kword = uc($kword);
	if ( "$kword" eq "\@TITLE" ) {
	  $otitle = $value;
	}
	elsif ( "$kword" eq "\@PARAMETER" ) {
	  (@param) = split(/\s+/, $value);
	  $nopt = 0;
	  for ( $i = 0; $i <= $#param; $i++ ) {
	    $tag = @param[$i];
	    $len = length($tag);
	    $x1 = 0;
	    if ( index($tag, "[") == 0 ) {
	      $nopt++;
	      $x1 = 1;
              $len = $len - 2;
	      $oparameter = "$oparameter\[";
	    }
	    $otag = substr $tag, $x1, $len;
	    $oparameter = "$oparameter,$otag";
	  }
	  for ( $i = 0; $i < $nopt; $i++ ) {
	    $oparameter = "$oparameter\]";
	  }
	}
      }
      @oper_title[$opercnt-1] = $otitle;
      @oper_parameter[$opercnt-1] = $oparameter;

      if ( $norefoper == 1 ) {
	$operator =~ s/^/-/;
      }
    }
#    print "@hkeys\n";
#    print "@oper_title\n";

    $istart = 0;
    if ( $#hkeys > 0 ) {
      $istart = $#hkeys + 1;
      for ( $i = 1; $i <= $#hkeys; $i++ ) {
#	printf ("%d: %s\n",$i, @hkeys[$i]);
	if ( "@oper_parameter[$i]" ne "@oper_parameter[0]" )
	  {
	    $istart = $i;
	    last;
	  }
      }

      if ( $istart == 1 ) { $istart = 0; }
    }

    print HELPFILE "    \"\",\n";
    print HELPFILE "    \"SYNOPSIS\",\n";
    print TRFILE "\n\\subsection*{Synopsis}\n\n";

    if ( $istart > 0 )  {
      $parameter = @oper_parameter[0];
      print HELPFILE "    \"    <operator>${parameter}  ${marguments}\",\n";
      print TRFILE "\\hspace*{8mm}{\$<\\!operator\\!>\$}{\\sl $parameter} \\ {\\tt $marguments}\n\n";
    }

   for ( $i = $istart; $i <= $#hkeys; $i++ ) {
      $operator = @hkeys[$i];
      $parameter = @oper_parameter[$i];
      printf HELPFILE ("    \"    %s%s  %s\",\n", $operator, $parameter, $marguments);
      $operatorx = $operator;
      $operatorx =~ s/_/\\_/g;
      print TRFILE "\\hspace*{8mm}{\\bf $operatorx}{\\sl $parameter} \\ {\\tt $marguments}\n\n";
    }

    print HELPFILE "    \"\",\n";
    print HELPFILE "    \"DESCRIPTION\",\n";

    print TRFILE "\n\\subsection*{Description}\n\n";
    if ( $#moddeslines >= 0 ) {
      print TRFILE "\\setlength{\\miniwidth}{\\textwidth}\n";
      print TRFILE "\\addtolength{\\miniwidth}{-8mm}\n";
      print TRFILE "\\hspace*{8mm}\\begin{minipage}{\\miniwidth}\n";
    }

    # Add list of variables created by this operator. This can only be done for eca_* operators
    if (exists $ecaVars{$hkeys[0]}) {
      push(@moddeslines, "The following variables are created: ");
      push(@moddeslines, '@BEGINITEMIZE');
      foreach $var (@{$ecaVars{$hkeys[0]}}) {
        push(@moddeslines, '@ITEM = '.$var);
      }
      push(@moddeslines, '@ENDITEMIZE');
    }

    $help_spaces = 0;
    print_description(@moddeslines);

    if ( $#moddeslines >= 0 ) {
      print TRFILE "\\end{minipage}\n";
      print TRFILE "\\addtolength{\\miniwidth}{8mm}\n";
    }

    if ( $#hkeys > 0 ) {
      print HELPFILE "    \"\",\n";
      print HELPFILE "    \"OPERATORS\",\n";
      print TRFILE "\n\\subsection*{Operators}\n\n";
    }
    else {
      print TRFILE "\\setlength{\\miniwidth}{\\textwidth}\n";
      print TRFILE "\\addtolength{\\miniwidth}{-8mm}\n";
      print TRFILE "\\hspace*{8mm}\\begin{minipage}{\\miniwidth}\n";
    }

    $opercnt = 0;
    $xopercnt = 0;
    $operpara = "";
    foreach $operator (@hkeys) {
      $norefoper = 0;
      if ( index("$operator", "-") == 0 ) {
	$operator =~ s/^-//;
        $norefoper = 1;
      }
      $opercnt += 1;
      $xopercnt += 1;
      print "      operator: $operator\n";
      $noper += 1;

      print CLASS "$operator\t$oclass\n";

      undef @oplines;
      $lblock = 0;
      $opname = "";
      foreach $tag (@doclines) {
	($kword, $value) = split("_", $tag, 2);
	$kword = uc($kword);
	if ( $lblock == 0 ) {
	  if ( "$kword" eq "\@BEGINOPERATOR" ) {
	    $lblock = 1;
	    $opname = $value;
	    next;
	  }
	}
	if ( $lblock == 1 ) {
	  if ( "$kword" eq "\@ENDOPERATOR" ) {
	    $lblock = 0;
	    if ( "$operator" eq "$opname" ) { last; }
	    else                            { next; }
	  }
	  if ( "$operator" eq "$opname" ) {
	    push(@oplines, $tag);
	  }
	}
      }

      if ( "$operator" ne "$opname" ) {
	print "$modulefile($operator): Operator description not found!\n";
	next;
      }

      $otitle = @oper_title[$opercnt-1];
      $oparameter = @oper_parameter[$opercnt-1];

      $opernamex = $opername;
      $opernamex =~ s/_/\\_/g;
      $operatorx = $operator;
      $operatorx =~ s/_/\\_/g;
      if ( $#hkeys > 0 ) {
	printf HELPFILE ("    \"    %-*s%s\",\n", $maxlen, $operator, $otitle);
	if ( $xopercnt == 1 ) {
	  print TRFILE "\\begin{defalist2}{\\bf $maxitem \\ }\n";
	}
	print TRFILE "\\item[{\\bf $operatorx}\\ \\ \\hfill]\n";
	print TRFILE "$otitle \\\\\n";
      }

      if ( "$otitle" ne "" ) {
	if ( $refskip == 0 && $xopercnt > 1 && "$oparameter" ne "$operpara" ) {
#	  print TRCARD "\\rowcolor[gray]{.9}\n";
	  print TRCARD "\\multicolumn{2}{|>{\\columncolor{pcolor3}}l|}";
	  if ( $xopercnt == 2 ) {
	    print TRCARD "{{\\bf $opernamex}{\\sl $operpara} \ {\\tt $marguments}} ";
	  } else {
	    print TRCARD "{{\$<\\!operator\\!>\$}{\\sl $operpara} \ {\\tt $marguments}} ";
	  }
	  print TRCARD "\\\\ \\hline \n";
	  $xopercnt = 1;
	}
	$opername = $operator;
	$operpara = $oparameter;

	if ( $norefoper == 0 ) {
	  printf README ("   %-13s %-15s %s\n", $modulefile, $operator, $otitle);
	  print CDOHTML "<tr>\n";
	  print CDOHTML "<td WIDTH=\"30%\" BGCOLOR=\"#FFF1B3\"> $operator </A> </td>\n";
	  print CDOHTML "<td WIDTH=\"70%\" BGCOLOR=\"#FFFFCC\"> $otitle </td>\n";
	  print CDOHTML "</tr>\n";
	}

	$operatorx = $operator;
	$operatorx =~ s/_/\\_/g;
 	print TCFILE "\\hspace*{5mm}\\makebox[3cm][l]{\\bf \\htmlref{$operatorx}{$operator}} ";
 	print TCFILE "& $otitle ";
 	print TCFILE "\\\\ \n";
        push @oplist, "\\hspace*{5mm}\\makebox[3cm][l]{\\bf \\htmlref{$operatorx}{$operator}} & $otitle \\\\ \n";

	$otitlem = $otitle;
	$otitlem =~ s/</\$<\$/og;
	$otitlem =~ s/>/\$>\$/og;
	$otitlem =~ s/ wrt / w.r.t. /og;
 	print TRLIST "\\hspace*{5mm}\\makebox[3cm][l]{\\bf \\htmlref{$operatorx}{$operator}} ";
 	print TRLIST "& $otitlem ";
 	print TRLIST "\\\\ \n";

	$modulname = lc($modulefile);
	$modulname =~ s/stat//;
	$operfunc = $operatorx;
	$operfunc =~ s/$modulname//;
	$statfunc = 0;
	if ( $trskip == 1 ) {
	  if ( $operfunc eq "min" || $operfunc eq "max" || $operfunc eq "sum" || $operfunc eq "mean" || $operfunc eq "avg" || $operfunc eq "var" || $operfunc eq "var1" || $operfunc eq "std" || $operfunc eq "std1" ) { $statfunc = 1; }
	}
	if ( $refskip == 0 && $norefoper == 0 ) {
	  if ( $statfunc == 0 ) {
	    print TRCARD "\\makebox[$len2][l]{\\bf {$operatorx}} ";
	    print TRCARD "& \\makebox[$len3][l]{$otitle} ";
	    print TRCARD "\\\\ \n";
	  }
	  elsif ( $statfunc == 1 && $operfunc eq "min" ) {
	    print TRCARD "\\makebox[$len2][l]{\\bf {$modulname\$<\\!stat\\!>\$}} ";
	    print TRCARD "& \\makebox[$len3][l]{$mtitle} ";
	    print TRCARD "\\\\ \n";
	  }
	}
      } else {
 	print "$operator: TITLE not found!\n";
      }


#   Decription (operator)

      undef @deslines;
      $lblock = 0;
      foreach $tag (@oplines) {
	($kword) = split(" ", $tag);
	$kword = uc($kword);
	if ( $lblock == 0 ) {
	  if ( "$kword" eq "\@BEGINDESCRIPTION" ) {
	    $lblock = 1;
	    next;
	  }
	}
	if ( $lblock == 1 ) {
	  if ( "$kword" eq "\@ENDDESCRIPTION" ) { last; }
	  push(@deslines, $tag);
	}
      }

      if ( $#hkeys > 0 ) {
	$help_spaces = $maxlen;
      } else {
	$help_spaces = 0;
      }
      print_description(@deslines);
    }

    if ( $#hkeys > 0 ) {
      print TRFILE "\\end{defalist2}\n";
    }
    else {
      print TRFILE "\\end{minipage}\n";
      print TRFILE "\\addtolength{\\miniwidth}{8mm}\n";
    }

#   Parameter

    undef @parlines;
    $lblock = 0;
    foreach $tag (@doclines) {
      ($kword,$kopt) = split(" ", $tag);
      $kword = uc($kword);
      if ( $lblock == 0 ) {
	if ( "$kword" eq "\@BEGINPARAMETER" ) {
	  $lblock = 1;
	  next;
	}
      }
      if ( $lblock == 1 ) {
	if ( "$kword" eq "\@ENDPARAMETER" ) { last; }
	push(@parlines, $tag);
      }
    }

    if ( $lblock == 1 ) {
      $maxlen = 0;
      $maxitem = "";
      foreach $tag (@parlines) {
	$line = $tag;
	($kword,$kopt) = split(" ", $line);
	$kword = uc($kword);
#	if ( index("$kword", "\@ITEM") != -1 ) {
	if ( "$kword" eq "\@ITEM" ) {
	  ($kopt, $value) = split(/\s*=\s*/, $line, 2);
	  $len = length($value);
	  if ( $len > $maxlen ) {
	    $maxlen = $len;
	    $maxitem = $value;
	    $maxitem =~ s/_/\\_/g;
	  }
	}
      }

      print HELPFILE "    \"\",\n";
      print HELPFILE "    \"PARAMETER\",\n";

      print TRFILE "\n\\subsection*{Parameter}\n\n";
      print TRFILE "\\setlength{\\miniwidth}{\\textwidth}\n";
      print TRFILE "\\addtolength{\\miniwidth}{-8mm}\n";
      print TRFILE "\\hspace*{8mm}\\begin{minipage}{\\miniwidth}\n";
      print TRFILE "\\begin{defalist}{\\sl $maxitem \\ }\n";

      foreach $tag (@parlines) {
	$line = $tag;
	($kword,$kopt) = split(" ", $line);
	$kword = uc($kword);
#	if ( index("$kword", "\@ITEM") != -1 ) {
	if ( "$kword" eq "\@ITEM" ) {
	  ($kopt, $value) = split(/\s*=\s*/, $line, 2);
	  printf HELPFILE ("    \"    %-*s  ", $maxlen, $value);
	  $value =~ s/_/\\_/g;
	  print TRFILE "\\item[{\\sl $value}\\ \\ \\hfill]\n";
	} else {
	  $line =~ s/^DOUBLE/FLOAT/g;
	  $hline = $line;
	  $hline =~ s/\\%/%/g;
	  $hline =~ s/\@celsius/°C/og;
	  print HELPFILE "$hline\",\n";
	  $line =~ s/^FLOAT/\\makebox[20mm][l]{\\sf \\small FLOAT}/;
	  $line =~ s/^INTEGER/\\makebox[20mm][l]{\\sf \\small INTEGER}/;
	  $line =~ s/^STRING/\\makebox[20mm][l]{\\sf \\small STRING}/;
	  $line =~ s/_/\\_/g;
	  $line =~ s/\@celsius/{\\textcelsius}/og;
	  print TRFILE "$line\n";
	}
      }
      print TRFILE "\\end{defalist}\n";
      print TRFILE "\\end{minipage}\n";
      print TRFILE "\\addtolength{\\miniwidth}{8mm}\n";
    }

#   Environment

    undef @parlines;
    $lblock = 0;
    foreach $tag (@doclines) {
      ($kword,$kopt) = split(" ", $tag);
      $kword = uc($kword);
      if ( $lblock == 0 ) {
	if ( "$kword" eq "\@BEGINENVIRONMENT" ) {
	  $lblock = 1;
	  next;
	}
      }
      if ( $lblock == 1 ) {
	if ( "$kword" eq "\@ENDENVIRONMENT" ) { last; }
	push(@parlines, $tag);
      }
    }

    if ( $lblock == 1 ) {
      $maxlen = 0;
      $maxitem = "";
      foreach $tag (@parlines) {
	$line = $tag;
	($kword,$kopt) = split(" ", $line);
	$kword = uc($kword);
#	if ( index("$kword", "\@ITEM") != -1 ) {
	if ( "$kword" eq "\@ITEM" ) {
	  ($kopt, $value) = split(/\s*=\s*/, $line, 2);
	  $len = length($value);
	  if ( $len > $maxlen ) {
	    $maxlen = $len;
	    $maxitem = $value;
	    $maxitem =~ s/_/\\_/g;
	  }
	}
      }

      print HELPFILE "    \"\",\n";
      print HELPFILE "    \"ENVIRONMENT\",\n";

      print TRFILE "\n\\subsection*{Environment}\n\n";
      print TRFILE "\\setlength{\\miniwidth}{\\textwidth}\n";
      print TRFILE "\\addtolength{\\miniwidth}{-8mm}\n";
      print TRFILE "\\hspace*{8mm}\\begin{minipage}{\\miniwidth}\n";
      print TRFILE "\\begin{defalist}{\\tt $maxitem \\ }\n";

      foreach $tag (@parlines) {
	$line = $tag;
	($kword,$kopt) = split(" ", $line);
	$kword = uc($kword);
#	if ( index("$kword", "\@ITEM") != -1 ) {
	if ( "$kword" eq "\@ITEM" ) {
	  ($kopt, $value) = split(/\s*=\s*/, $line, 2);
	  printf HELPFILE ("    \"    %-*s\",\n", $maxlen, $value);
	  $value =~ s/_/\\_/g;
	  print TRFILE "\\item[{\\tt $value}\\ \\ \\hfill]\n";
	} else {
	  $hline = $line;
	  $hline =~ s/\"/\\\"/g;
	  $hline =~ s/\\cite//og;
#	  if ( $lines == 0 ) {
#	    print HELPFILE "$hline\",\n";
#	  }
#	  else {
	    print HELPFILE "    \"        $hline\",\n";
#	  }
#	    $line = /\sFLOAT/XXX
	  $line =~ s/^FLOAT/\\makebox[20mm][l]{\\sf \\small FLOAT}/;
	  $line =~ s/^DOUBLE/\\makebox[20mm][l]{\\sf \\small FLOAT}/;
	  $line =~ s/^INTEGER/\\makebox[20mm][l]{\\sf \\small INTEGER}/;
	  $line =~ s/^STRING/\\makebox[20mm][l]{\\sf \\small STRING}/;
	  $line =~ s/_/\\_/g;
	  $line =~ s/\@env\{([^}]*)\}/{\\tt \1}/og;
	  print TRFILE "$line\n";
	  $lines = $lines + 1;
	}
      }
      print TRFILE "\\end{defalist}\n";
      print TRFILE "\\end{minipage}\n";
      print TRFILE "\\addtolength{\\miniwidth}{8mm}\n";
    }

#   Note

    undef @parlines;
    $lblock = 0;
    foreach $tag (@doclines) {
      ($kword,$kopt) = split(" ", $tag);
      $kword = uc($kword);
      if ( $lblock == 0 ) {
	if ( "$kword" eq "\@BEGINNOTE" ) {
	  $lblock = 1;
	  next;
	}
      }
      if ( $lblock == 1 ) {
	if ( "$kword" eq "\@ENDNOTE" ) { last; }
	push(@parlines, $tag);
      }
    }

    if ( $lblock == 1 ) {
      print HELPFILE "    \"\",\n";
      print HELPFILE "    \"NOTE\",\n";

      print TRFILE "\n\\subsection*{Note}\n\n";
      print TRFILE "\\setlength{\\miniwidth}{\\textwidth}\n";
      print TRFILE "\\addtolength{\\miniwidth}{-8mm}\n";
      print TRFILE "\\hspace*{8mm}\\begin{minipage}{\\miniwidth}\n";

      $help_spaces = 0;
      $help_print = 1;
      print_description(@parlines);
      $help_print = 1;

      print TRFILE "\\end{minipage}\n";
      print TRFILE "\\addtolength{\\miniwidth}{8mm}\n";
    }

#   Example

    undef @parlines;
    $lblock = 0;
    foreach $tag (@doclines) {
      ($kword,$kopt) = split(" ", $tag);
      $kword = uc($kword);
      if ( $lblock == 0 ) {
	if ( "$kword" eq "\@BEGINEXAMPLE" ) {
	  $lblock = 1;
	  next;
	}
      }
      if ( $lblock == 1 ) {
	if ( "$kword" eq "\@ENDEXAMPLE" ) { last; }
	push(@parlines, $tag);
      }
    }

    if ( $lblock == 1 ) {
      print TRFILE "\n\\subsection*{Example}\n\n";
      print TRFILE "\\setlength{\\miniwidth}{\\textwidth}\n";
      print TRFILE "\\addtolength{\\miniwidth}{-8mm}\n";
      print TRFILE "\\hspace*{8mm}\\begin{minipage}{\\miniwidth}\n";

      $help_spaces = 0;
      $help_print = 0;
      print_description(@parlines);
      $help_print = 1;

      print TRFILE "\\end{minipage}\n";
      print TRFILE "\\addtolength{\\miniwidth}{8mm}\n";
    }

#   See also

#    $nop = 0;
#    $linelen = 0;
#    $lineend = 0;
#    foreach $oper (@hkeys) {
#      if ( $oper ne $operator ) {
#	$nop = $nop + 1;
#	if ( $nop == 1 ) {
#	  print HELPFILE "    \"\",\n";
#	  print HELPFILE "    \"SEE ALSO\",\n";
#	}
#	if ( $linelen > 70 ) {
#	  $linelen = 0;
#	  print HELPFILE ",\",\n";
#	}
#	if ( $linelen == 0 ) {
#	  print HELPFILE "    \"    $oper";
#	}
#	else {
#	  print HELPFILE ", $oper";
#	}
#	$linelen = $linelen + length($oper) + 2;
#      }
#    }
#    if ( $lineend == 0 && $nop > 0 ) {
#      print HELPFILE "\",\n";
#    }

#   End

#      print HELPFILE "    \"\",\n";
#      print HELPFILE "    \"\@End_${operator}\",\n";

    print HELPFILE "    NULL\n";
    print HELPFILE "};\n";

    print TCFILE "\\end{tabular*}\n";
    print TCFILE "\\vspace{1mm}\n";
    print TCFILE "\n";

    print CDOHTML "</table>\n";

    print TRLIST "\\end{tabular*}\n";
    print TRLIST "\\vspace{1mm}\n";
    print TRLIST "\n";

    if ( $refskip == 0 ) {
#     print TRCARD "\\rowcolor[gray]{.9}\n";
      print TRCARD "\\multicolumn{2}{|>{\\columncolor{pcolor3}}l|}";
    }
    if ( "$opername" eq "selpctl" )  {
      $marguments =~ s/ifile/in/og;
      $marguments =~ s/ofile/out/og;
    }
    $opernamex = $opername;
    $opernamex =~ s/_/\\_/g;
    if ( $refskip == 0 ) {
      if ( $xopercnt == 1 ) {
	print TRCARD "{{\\bf $opernamex}{\\sl $operpara} \ {\\tt $marguments}} ";
      } else {
	print TRCARD "{{\$<\\!operator\\!>\$}{\\sl $operpara} \ {\\tt $marguments}} ";
      }
      print TRCARD "\\\\ \\hline \n";

      print TRCARD "\\end{tabular*}\n";
      print TRCARD "\\vspace{1mm}\n";
      print TRCARD "\n";
    }
}
print TRCARD "\\end{document}\n";
#print TCFILE "\\end{tabular*}\n";
#print TCFILE "\n";
#

foreach my $line (sort(@oplist)){
  print ABCLIST $line;
}
print ABCLIST "\\end{longtable}\n";
print ABCLIST "\n";

close(HELPFILE);
close(TRFILE);
close(TCFILE);
close(ABCLIST);
close(TROVER);
close(TRCARD);
close(MOFILE);
#
print "\nNumber of operators: $noper\n";


sub print_description {
  my @lines;
  @lines = @_;
  $nspace = $help_spaces;
  $noff   = 0;
  $ntab   = 0;

  $math    = 0;
  $itemize = 0;
  $doc     = 0;
  $man     = 0;
  $list    = 0;
  $text    = 0;
  $verb    = 0;
  foreach $tag (@lines) {
    $line = $tag;
    ($kword,$kopt) = split(" ", $line);
    $kword = uc($kword);
    if ( "$kword" eq "\@BEGINITEMIZE" ) {
      print TRFILE "\\begin{itemize}\n";
#      $nspace += 0;
      $itemize = 1;
    } elsif ( "$kword" eq "\@ENDITEMIZE" ) {
      print TRFILE "\\end{itemize}\n";
#      $nspace -= 0;
      $itemize = 0;
    } elsif ( "$kword" eq "\@BEGINLIST" ) {
      print TRFILE "\\begin{defalist}{$kopt \\ \\ }\n";
      $noff = length($kopt);
      $list = 1;
    } elsif ( "$kword" eq "\@ENDLIST" ) {
      print TRFILE "\\end{defalist}\n";
      $list = 0;
    } elsif ( $itemize == 1 && "$kword" eq "\@ITEM" ) {
      ($kopt, $value) = split(/\s*=\s*/, $line, 2);
      if ( $help_print == 1 ) {
	printf HELPFILE ("    \"    %*s%s- ${value}\",\n", $nspace, "");
      }
      $value =~ s/_/\\_/g;
      print TRFILE "\\item  $value\n";
    } elsif ( $list == 1 && "$kword" eq "\@ITEM" ) {
      ($kopt, $value) = split(/\s*=\s*/, $line, 2);
      if ( $help_print == 1 ) {
	$ntab = $noff - length($value);
	if ( $ntab < 0 ) { $ntab = 0 };
#	printf HELPFILE ("    \"    %*s%s%s%*s%s\"", $nspace, "", ${value}, $ntab, "");
	printf HELPFILE ("    \"    %*s%s${value}", $nspace, "");
	printf HELPFILE ("%*s%s\"", $ntab, "");
      }
      print TRFILE "\\item[{$value}\\ \\ \\hfill]\n";
    } elsif ( "$kword" eq "\@BEGINMATH" ) {
#	  print TRFILE "\n";
#	  print TRFILE "\\vspace*{2mm}\n";
#	  print TRFILE "\\hspace*{5mm}\\begin{math}\n";
      print TRFILE "\\begin{math}\n";
      $math = 1;
    } elsif ( "$kword" eq "\@ENDMATH" ) {
      print TRFILE "\\end{math}\n";
#	  print TRFILE "\\vspace*{2mm}\n";
      print TRFILE "\n";
      $math = 0;
    } elsif ( "$kword" eq "\@BEGINEQNARY" ) {
      print TRFILE "\\begin{eqnarray*}\n";
      $math = 1;
    } elsif ( "$kword" eq "\@ENDEQNARY" ) {
      print TRFILE "\\end{eqnarray*}\n";
      print TRFILE "\n";
      $math = 0;
    }elsif ( "$kword" eq "\@BEGINDISPLAYMATH" ) {
      print TRFILE "\\begin{displaymath}\n";
      $math = 1;
    } elsif ( "$kword" eq "\@ENDDISPLAYMATH" ) {
      print TRFILE "\\end{displaymath}\n";
      print TRFILE "\n";
      $math = 0;
#    } elsif ( "$kword" eq "\@BEGINVERBATIM" ) {
#      print TRFILE "\\begin{lstlisting}[backgroundcolor=\\color{pcolor1}, basicstyle=\\small]\n";
#      $verb = 1;
    } elsif ( "$kword" eq "\@BEGINVERBATIM" ) {
      print TRFILE "\\begin{lstlisting}[frame=single, backgroundcolor=\\color{pcolor2}, basicstyle=\\ttfamily, columns=flexible]\n";
      $verb = 1;
    } elsif ( "$kword" eq "\@ENDVERBATIM" ) {
      print TRFILE "\\end{lstlisting}\n";
      $verb = 0;
    } elsif ( "$kword" eq "\@BEGINLISTING" ) {
      print TRFILE "\\begin{lstlisting}[frame=single, backgroundcolor=\\color{pcolor1}, basicstyle=\\small]\n";
      $text = 1;
    } elsif ( "$kword" eq "\@ENDLISTING" ) {
      print TRFILE "\\end{lstlisting}\n";
      $text = 0;
    } elsif ( "$kword" eq "\@IFMAN" ) {
      $man = 1;
    } elsif ( "$kword" eq "\@ENDIFMAN" ) {
      $man = 0;
    } elsif ( "$kword" eq "\@IFDOC" ) {
      $doc = 1;
    } elsif ( "$kword" eq "\@ENDIFDOC" ) {
      $doc = 0;
    } else {
      $docline = $line;
      if ( $man == 0 ) {
	if ( $math == 0 && $verb == 0 && $text == 0 ) {
	  $line =~ s/CDO_PCTL_NBINS/CDO\\_PCTL\\_NBINS/og;
	  $line =~ s/\@newline/ \\\\/og;
	  $line =~ s/ ifile / {\\tt ifile} /og;
	  $line =~ s/ ifile1 / {\\tt ifile1} /og;
	  $line =~ s/ ifile2 / {\\tt ifile2} /og;
	  $line =~ s/ ofile / {\\tt ofile} /og;
	  $line =~ s/ ifiles / {\\tt ifiles} /og;
	  $line =~ s/\@math\{([^}]*)\}/\\begin{math}\1\\end{math}/og;
	  $line =~ s/\@file\{([^}]*)\}/{\\tt \1}/og;
	  $line =~ s/\@var\{([^}]*)\}/{\\it \1}/og;
	  $line =~ s/\@oper\{([^}]*)\}/{\\htmlref{\1}{\1}}/og;
	  $line =~ s/\@mod\{([^}]*)\}/{\\htmlref{\1}{\1}}/og;
	  $line =~ s/\@ref\{([^}]*)\}/{\\htmlref{\1}{\1}}/og;
	  $line =~ s/\@env\{([^}]*)\}/{\\tt \1}/og;
	  $line =~ s/\@cite\{([^}]*)\}/\\cite{\1}/og;
	  $line =~ s/\@bold\{([^}]*)\}/{\\bf \1}/og;
	  $line =~ s/\@celsius/{\\textcelsius}/og;
	  $line =~ s/</\$<\$/og;
	  $line =~ s/>/\$>\$/og;
	  $line =~ s/%/\\%/og;
	}
	print TRFILE "$line\n";
      }
      if ( $doc == 0 ) {
	$docline =~ s/\@newline//og;
	$docline =~ s/\@math\{([^}]*)\}/\1/og;
	$docline =~ s/\@file\{([^}]*)\}/\1/og;
	$docline =~ s/\@var\{([^}]*)\}/\1/og;
	$docline =~ s/\@oper\{([^}]*)\}/\1/og;
	$docline =~ s/\@mod\{([^}]*)\}/\1/og;
	$docline =~ s/\@ref\{([^}]*)\}/\1/og;
	$docline =~ s/\@env\{([^}]*)\}/\1/og;
	$docline =~ s/\@cite\{([^}]*)\}/\1/og;
	$docline =~ s/\@bold\{([^}]*)\}/\1/og;
	$docline =~ s/\@celsius/°C/og;
	$docline =~ s/\\_/_/g;
	$docline =~ s/\\/\\\\/og;
	$docline =~ s/\\cite//og;
#	$docline =~ s/%/\\%/og;
	$docline =~ s/"/\\"/og;
	if ( $help_print == 1 ) {
	  printf HELPFILE ("    \"    %*s%s\",\n", $nspace, "", $docline);
	}
      }
    }
  }
}
