#!/usr/bin/perl -w

#C to HTML converter
#Writen by Chebotarev Roman at 19.08.2008

use strict;

my $script_name = 'C to HTML converter';
my $version = '0.1';
my $source_file;
my @keywords = qw (auto break case char const continue default do double else enum extern float for goto if
                    int long register return short signed sizeof static struct switch typedef union unsigned 
                    void volatile while int8_t uint8_t int16_t uint16_t int32_t uint32_t);
my ($string, $word, @words, %keywords);
foreach (@keywords) { $keywords{$_} = 1; }

my $cf = '</font>';     #Close font
my $rem_font = "#DCDCDC";
my $keyword_font = "#0000FF";
my $preproc_font = "#228B22";
my $bgcolor = "#FFFFFF";
my $default_font_color = "#000000";
my $encoding = 'utf-8';
my $fontsize = '2';
my $print_num = 0;
my $title = undef;
my $rem_open = 0;           #If single-line comment open
my $rem_mstring_open = 0;   #If multiline coment open
my $string_num = 0;
my $lines_count = 0;
my $text_out;

foreach (@ARGV)
{
    if(/--comment=(#[0-9a-f]{6}|\w+)/i){$rem_font = "$1";}
    elsif(/--keyword=(#[0-9a-f]{6}|\w+)/i){$keyword_font = "$1";}
    elsif(/--preproc=(#[0-9a-f]{6}|\w+)/i){$preproc_font = "$1";}
    elsif(/--bgcolor=(#[0-9a-f]{6}|\w+)/i){$bgcolor = "$1";}
    elsif(/--default-font-color=(#[0-9a-f]{6}|\w+)/i){$default_font_color = "$1";}
    elsif(/--bgcolor=([a-f]{6}|\w+)/i){$bgcolor = "$1";}
    elsif(/--fontsize=(\-?[1-7])/){$fontsize = "$1";}
    elsif(/--encoding=([0-9\w-]+)/i){$encoding = "$1";}
    elsif(/--print-num/){$print_num = 1;}
    else {$source_file = $_;}
}

my $frem_font = "<font color=\"$rem_font\">";
my $fkeyword_font = "<font color=\"$keyword_font\">";
my $fpreproc_font = "<font color=\"$preproc_font\">";

if(!defined($source_file)) 
{
    print "Usage: $0 <souce_filename> [--comment=COLOR] [--keyword=COLOR] [--preproc=COLOR] [--bgcolor=COLOR] [--default-font-color=COLOR] [--encoding=encoding] [--fontsize=(1-7)] [--print-num]\n";
	print "$0 ($script_name v$version) writen by Chebotarev Roman at 19.08.2008\n";
    exit;
}

if(! -T $source_file)
{
    print "Source file '$source_file' not exist or not text file. Exit.\n";
    exit;
}

open(SOURCE, $source_file) || die "Can't open file: $!";

$source_file =~ s/.*\///;
print
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML xml:lang="ru" xmlns="http://www.w3.org/1999/xhtml">
    <HEAD>
        <TITLE>C source: "',$source_file,'"</TITLE>
        <META http-equiv="content-type" content="text/html; charset=',$encoding,'">
        <META http-equiv="content-style-type" content="text/css">
        <META http-equiv="content-language" content="ru">
    </head>
    <body bgcolor="',$bgcolor,'">';

$text_out = "<pre><code><font size='$fontsize' color='$default_font_color'>";
while (defined ($string = <SOURCE>))
{
    $string =~ s/\t/    /g;
    $string =~ s/&/&amp;/g;
    $string =~ s/</&lt;/g;
    $string =~ s/>/&gt;/g;
    $string =~ s/"/&quot;/g;

    #Processing preprocessor directives
    $string =~ s/^(\s*#.*)$/$fpreproc_font$1$cf/;
    #Processing comments
    $rem_open = 0;
    if($string =~ s/\/\*/$frem_font\/*/){$rem_mstring_open = 1;}
    if($string =~ s/\*\//*\/$cf/){ $rem_mstring_open = 0;}
    if($string =~ s/\/\/(.*)$/$frem_font\/\/$1$cf/){$rem_open = 1;};
    #Processing keywords
    @words = split(/[\s\W]+/, $string);
    
    if(!$rem_open && !$rem_mstring_open) {
        foreach $word (@words) {
            if($keywords{$word}) { $string =~ s/(\W|^)$word(\W)/$1$fkeyword_font$word$cf$2/g; }
        }
    }
    #Remove from comments tags '/* any text */' located on single-line
    while($string =~ s#(/\*.*?)<font.*?>(.*?)$cf(.*?\*/)#$1$2$3#gi){};
    
	$text_out .= $string;
	++$lines_count;
}
$text_out .= "$cf</code></pre>";
close(SOURCE);

if($print_num)
{	#If set --print-num (print line numbers) - create table
	#for separate output text and line numbers
	print "<table border='0'>";
	print "<tr>";
	print "<td>";	#Line numbers plase in this column
	print "<pre><code><font color='$rem_font' size='$fontsize'>";
	for(my $i = 1; $i <= $lines_count; ++$i) { print "$i\n"; }
	print "$cf</code></pre>";
	print "</td>";
	print "<td>";
	print "<pre><code><font color='$rem_font' size='$fontsize'>";
	for(my $i = 1; $i <= $lines_count; ++$i) { print "|\n"; }
	print "$cf</code></pre>";
	print "</td>";
	print "<td>";
	print "$text_out";
	print "</td>";
	print "$cf</td></tr></table>";
}
else { print $text_out; }

print "$cf</body></html>\n";
