# -*-perl-*-

#/*@@
#  @file      grdoc_converters
#  @date      Sun Apr 21 12:46:12 1996
#  @author    Paul Walker
#  @desc 
#  Source code converters/highlighters for the grdoc system.  Works
#  well for fortran and c and not so well for others...
#  <p>
#  Note the face colors are defined as globas at the top of this file!
#  @enddesc 
#  @comment
# <code>$Id: grdoc_converters,v 1.21 1996/04/22 01:19:43 pwalker Exp $</code>
#  @endcomment
#@@*/


######## makeSrcHTML #############################################
# Face definitions for comments, cpp things, and grdoc keywords.
# These are NS 2.0 enhanced.  Note each of these are for the src
# hence the src precursor.
$src_comment_start = "<font color=\"#105010\"><i>";
$src_comment_end   = "</i></font>";
$src_cpp_start     = "<font color=\"#802000\"><b>";
$src_cpp_end       = "</b></font>";
$src_type_start    = "<font color=\"#202090\"><i>";
$src_type_end      = "</i></font>";
$src_keywd_start   = "<font color=\"#901000\">";
$src_keywd_end     = "</font>";

# presumably all grdoc keywords will be in a comment, so note the comment_
# start and end
$src_grdoc_start   = "$src_comment_end<font color=\"#200020\"><b>";
$src_grdoc_end     = "</b></font>$src_comment_start";

sub
makeSrcHTML
{
    local($infile) = @_[0];
    local($dafile, $daroutine);
    $pfile = &strip_dirs($infile);
    print "      HTMLifying $pfile\n" if $opt_V;
    $dadots = &make_dotdot($infile);
    $outfile = $infile;
    $filebase = &strip_dirs($infile);
    $outfile =~ s/$opt_i/$opt_o\//;
    ($outdir, $outbase) = ($outfile =~ m:^(.*)/([^/]+)$:);
    print "$outdir -> $outbase\n";
    $outbase =~ s/\./_/g;
    $outbase = $outbase."_src.html";
    $totop = &make_dotdot($outfile);

    # Open files

    # Place in a PROTECTED directory
    $outdir =~ s:$opt_o:$opt_o/PROTECTED:;

    open(OUT, ">$outdir/$outbase") || die "$outdir/$outbase: $!\n";
    open(IN, "< $infile") || die "$infile: $!\n";

    # Establish a mode
    $cmode = 0; $fortranmode = 0;  $idlmode = 0;
    $fortranmode = 1 if $infile =~ m/\.[Ff]$/;
    $fortranmode = 1 if $infile =~ m/\.inc$/;
    $cmode = 1       if $infile =~ m/\.[Cch]$/;
    $idlmode = 1     if $infile =~ m/\.pro$/;

    # Header
    &html_head($filebase);
    print OUT "<h1 align=center>";
    &localnav($filebase,"brief");
    print OUT "</h1>\n";
    &navigation($dadots);
    print OUT "<hr>\n<pre>\n";

    while (<IN>) {
	if (m:/\*\@\@:) {
	    undef @grdlines, $daroutine, $dafile;
	    $dafile = "";
	    push (@grdlines, $_);
	    while ($grdline = <IN>)  {
		if ($grdline =~ m:\@routine\s+(\S+):) {
		    $daroutine = $1;
		}
		if ($grdline =~ m:\@(file|header)\s+(\S+):) {
		    $dafile = $2;
		}
		push (@grdlines, $grdline);
		last if ($grdline =~ m:\@\@\*/:);
	    }
	    if ($daroutine) {
		print OUT "<a name=\"$daroutine\"><!-- XREF --></a>";
	    }
	    print OUT "<!-- GRDOC $dafile$daroutine ";
	    print OUT "-->${src_comment_start}";
	    foreach $L (@grdlines) {
		$L = &html_safe($L);
		$L = &handle_xref($L);
		$L =~ s:(\@\S+):$src_grdoc_start\1$src_grdoc_end:g;
		$L =~ s:(\*/\s*)(.*)$:\2\1:;
		print OUT $L;
	    }
	    print OUT "${src_comment_end}<!-- END GRDOC -->";
	    next;
	}
	# C
	print OUT &c_src_line($_, $totop) if ($cmode);
	# Fortran
	print OUT &f_src_line($_, $totop) if ($fortranmode);
	# IDL
	print OUT &idl_src_line($_, $totop) if ($idlmode);
	# None of the above.
	print OUT &html_safe($_, "really") 
	    if (!$cmode && !$fortranmode && !$idlmode);
    }
    print OUT "</pre><hr>\n";
    &navigation($dadots);
    &html_foot($filebase);

    close IN;
    close OUT;
}

#
sub
c_src_line
{
    local($line, $totop) = @_;
    chop $line;

    # html breakers
    $line = &html_safe($line, "superdooper");

    # Comments
    # c++ style
    if ($line =~ m://:) {
	$line =~ s://:$src_comment_start//:;
	$line = $line.$src_comment_end;
    } 
    # c style
    $line =~ s:/\*:$src_comment_start/\*:g;
    $line =~ s:\*/:\*/$src_comment_end:g;

    # grdoc keywords
    $line =~ s/(\@[^\s<\*]+)/$src_grdoc_start\1$src_grdoc_end/g;

    # cpp directives
    $line =~ s/^(\#\S+)/$src_cpp_start\1$src_cpp_end/;
    $line = $line."\n";

    # types
    $line =~ s:\b(int|short|long|char|float|double|void|struct|union|enum|typedef)\b:$src_type_start\1$src_type_end:g;

    # keywords (eg, builtin tokens)
    $line =~ s:\b(for|while|do|return|goto|case|break|switch|if|then|else if|else|continue|default)\b:$src_keywd_start\1$src_keywd_end:g;


    return $line;
}

sub
f_src_line
{
    local($line, $totop) = @_;
    chop $line;

    # html breakers
    $line = &html_safe($line, "superdopper");

    # Comments
    if ($line =~ m/^[Cc\*]/) {
	$line = $src_comment_start.$line.$src_comment_end;
    } 
    # c style
    $line =~ s:/\*:$src_comment_start/\*:g;
    $line =~ s:\*/:\*/$src_comment_end:g;

    # grdoc keywords
    $line =~ s/([c ]*)(\@[^\s<\*]+)/\1$src_grdoc_start\2$src_grdoc_end/g;

    # cpp directives
    $line =~ s/^(\#\S+)/$src_cpp_start\1$src_cpp_end/;
    $line = $line."\n";

    # types
    $line =~ s:\b(integer|logical|real|complex|double[ \t]*precision|character|parameter|dimension):$src_type_start\1$src_type_end:g;

    # keywords
    $line =~ s:\b(subroutine|function|program|entry|common|save|external|intrinsic|data|if|then|else|endif|elseif|do|enddo|continue|call|goto|end|stop|return|implicit)\b:$src_keywd_start\1$src_keywd_end:g;
		 

    return $line;
}

sub
idl_src_line
{
    local ($line) = @_;
    $line = &html_safe($line, "superdopper");
    return $line;
}

sub
handle_xref
# Makes the source code X Refs.  note the call to &resolve_XRefs in
# grdoc_parse
{
    local($line, $totop) = @_;
    local($tag, $xrt, $xr);

    if ($line =~ m:\@(see\S+|calls|calledby)\s+(\S+):) {
	$tag = "\@$1"; $xrt = $2;
	($newxrt, $punct) = &de_punctualize($xrt);
	$xr = &resolve_XRefs("\@seefile $newxrt", "norichdoc");
	$xr =~ s:$opt_t:$opt_t/PROTECTED:;
	$line =~ s:$newxrt:$xr:;
    }

    return($line);
}
# end of routines for
######## makeSrcHTML #############################################


# ? I love perl. :
1;

