#!/usr/bin/perl
######################################################################
#                                                                    #
# Code2HTML                                                          #
# ---------                                                          #
#                                                                    #
# written 1999 by Palfrader Peter palfrader@writeme.com              #
#                                                                    #
# Version 0.1                                                        #
#                                                                    #
# Do not distribute!                                                 #
#                                                                    #
# The final version will be distributed under the GPL                #
#                                                                    #
######################################################################

# global variables:
	$langmode = "html";   # language mode
	$hidechar = "\x00";  # a character that must not exist in the code and which is used as a placeholder
	$code = "";          # the program source code
	@regexps = ();       # the array which holds the regexps to search for
	@matches = ();          # all matches of the regexps
	

sub parse_config_file
{
	open FILEHANDLE, "<config";
	
	while (<FILEHANDLE>)
	{
		$_ =~ s/\n//g;
		$_ =~ s/^[ \t]*(.*)[ \t]*/$1/; #remove beginning and trailing spaces / tabs
		
		my $search = "([\[,])$langmode([\],])";
		if ($_ =~ /$search/) {last} ;
	};
	
	while (<FILEHANDLE>)
	{
		$_ =~ s/\n//g;
		$_ =~ s/^[ \t]*(.*)[ \t]*/$1/; #remove beginning and trailing spaces / tabs
		if (substr($_,0,1) eq "[") {last};
		
		if (($_ ne "")&&(substr($_, 0, 1) ne "#"))
		{
			local %t;

			$_ =~ s/[ \t]*"([^"]|\\")*"[ \t]*,//; $tmp = $&; $tmp =~ m/".*[^\\]"/; $tmp = $&; $tmp =~ s/([^\\]|^)"/$1/g; $tmp =~ s/\\"/"/g; $t{"html1"}   = $tmp;
			$_ =~ s/[ \t]*"([^"]|\\")*"[ \t]*,//; $tmp = $&; $tmp =~ m/".*[^\\]"/; $tmp = $&; $tmp =~ s/([^\\]|^)"/$1/g; $tmp =~ s/\\"/"/g; $t{"html2"}   = $tmp;
		                                    	  $tmp = $_; $tmp =~ m/".*[^\\]"/; $tmp = $&; $tmp =~ s/([^\\]|^)"/$1/g; $tmp =~ s/\\"/"/g; $t{"regex"}   = $tmp;

			push @regexps, \%t;
		};
	};
	close FILEHANDLE;
};

sub get_input_file
{
	#read file
	while (<STDIN>) { $_ =~ s/\n|\r//g; $code = $code.$_."\n"; };
};

sub find_all_matches
{
	my $index = 0;
	for (@regexps)
	{
		while ($code =~ /$$_{"regex"}/gms)
		{
			local %t;
			
			$t{"start"} = pos($code) - length($&);
			$t{"length"} = length($&);
			$t{"type"} = $index;
			$t{"sortby"} = $t{"start"}*100 + $t{"type"};
			
			push @matches, \%t;
		};
		$index++;
	}
	
	#sorting matches by start
	@matches = sort {$$a{"sortby"} <=> $$b{"sortby"}} @matches;
};

sub find_valid_matches
{
	my $alreadymatched = $code;

	for (@matches) # go for all matches
	{
		if (substr($alreadymatched, $$_{"start"}, 1) eq $hidechar) # if it is not valid any more, do not take it
		{
			$$_{"takeit"} = 0;

		}
		else
		{
			$$_{"takeit"} = 1;
			
			local $tmp; for (1..$$_{"length"}) { $tmp .= $hidechar; }; # create a string of 255 bytes with the correct length
			substr($alreadymatched, $$_{"start"}, $$_{"length"}) = $tmp;
		};
	};
};

sub insert_hide_characters
{
	for (reverse @matches) # go for all matches
	{
		if ($$_{"takeit"})
		{
			$code = substr($code, 0, $$_{"start"}) .
			        $hidechar .
			        substr($code, $$_{"start"}, $$_{"length"}) .
			        $hidechar .
			        substr($code, $$_{"start"}+$$_{"length"});
		};
	}
};

sub convert_code_2_html
{
	$code =~ s/&/&amp;/g;
	$code =~ s/>/&gt;/g;
	$code =~ s/</&lt;/g;
	$code =~ s/"/&quot;/g;
};

sub insert_tags
{
	my $newcode = "";
	my $tmp = $code;
	
	for (@matches) # go for all matches
	{
		if ($$_{"takeit"})
		{
			# This goes must faster than
			# $code =~ s/$hidechar/$a/;
			# $code =~ s/$hidechar/$b/;

			my $t = $regexps[$$_{"type"}];

			$tmp =~ m/$hidechar/;
			$newcode .= $`.$$t{"html1"};
			$tmp = $';
			
			$tmp =~ m/$hidechar/;
			$newcode .= $`.$$t{"html2"};
			$tmp = $';
		};
	};
	$code = $newcode.$';
};

sub put_output
{
	print "<html><body bgcolor=\"#ffffff\"><pre>\n";
	print $code;
	print "</pre></body></html>\n";
};



                         print STDERR "parsing config file...\n";
&parse_config_file;      print STDERR "loading input file...\n";
&get_input_file;         print STDERR "finding all matches...\n";
&find_all_matches;       print STDERR "verifying matches...\n";
&find_valid_matches;     print STDERR "inserting placeholders...\n";
&insert_hide_characters; print STDERR "converting source code to HTML...\n";
&convert_code_2_html;    print STDERR "replacing placeholders with appropriate HTML tags...\n";
&insert_tags;            print STDERR "outputting file...\n";
&put_output;
