#!perl

## Formats the command DB files into HTML.
## See INFO

## if the TOC exists, it is inserted right at the start of the
## HTML file

#na)me: of object described herein; should match the filename
#de)scription: one line description
#eq)ual to: name of object 100% equal to this one, no further entries
#	allowed
#se)e also: references
#re)quirements: which other objects this object depends on
#op)tional: optional requirements for certain features
#co)nflicts: which other objects this object conflicts with

require 'parse.pl';

$ref = {
	'appendix' => sub { '<A HREF="appendix.html#' . lc($_[0]) . "\">"; }
	, 'cmd' => sub { '<A HREF="#' . lc($_[0].$_[1]) . '">'; }
	, 'main' => sub { my $n = shift;
		$n =~ s/^[_-]+//g;
		return '<A HREF="FreeCOM.html##-' . lc($n) . "\">"; }
	, 'section' => sub { "\n<H3>" . ucfirst(lc($_[0])) . "</H3>\n"; }
	, 'subsection' => sub { "\n<H4>" . $_[0] . "</H4>\n"; }
};

$file_toc = "TOC";
$file_html = "../cmd.html";
## $file_cmd = "CMDLIST";	# List of commands to be automatically linked

%headers = (
	'na', 'name',
	'de', 'description',
	'eq', 'equal to',
	'se', 'see also',
	're', 'requirements',
	'op', 'optional requirements',
	'co', 'conflicts with'
);
my($na, $de, $eq, $se, $re, $op, $co);
my(               @se, @re, @op, @co);

%toc = ();


$htmlHowToFormatOptions = '
Unless stated otherwise all options of this command do follow the
<A HREF="!:options">standard rules for options</A>.
';

&openCmdList;

&htmlOpenHtml;
&htmlOpenTOC;

@ARGV = glob("*.db") unless $#ARGV >= 0;

for (@ARGV) {
	&handle($_);
}

# &dumpAppendix;
&htmlCloseTOC;
&htmlCloseHtml;

&closeCmdList;

exit 0;

sub handle {
	my($file) = @_;

	## Read header of file
	if(!open(IN, $file)) {
		&log("Cannot open file \"$file\": $!");
	} else {
		($na, $de, $eq, $se, $re, $op, $co) = ();

		while(<IN>) {
			chomp;
			last if /^\s*$/;
			if(/^(.+?):\s*/) {
				my($key) = $1;
				my($value) = $';
				next unless $value;

				$key =~ tr/A-Z/a-z/;
				$key =~ s/\s+/ /g;
				if(length($key) < 2) {
					&log("Invalid header key '$key' in $file\n");
				} else {
					my($keyname) = substr($key, 0, 2);
					if(substr($headers{$keyname}, 0, length($key)) eq $key) {
					 	eval "\$$keyname = \$value";
					 } else {
					 	&log("Unknown header key '$key' in $file");
					 }
				}
			} else {
				&log("Syntax error in header section of $file");
			}
		}

		if($na && $de) {
			$na = &mangleName($na);
			&dumpHeader($na, $de);
			if($eq) {
				&dumpEqual($eq);
			} else {
				@se = sort map { &mangleName($_) }  split(/[,\s;]+/, $se);
				@re = sort map { &mangleName($_) }  split(/[,\s;]+/, $re);
				@op = sort map { &mangleName($_) }  split(/[,\s;]+/, $op);
				@co = sort map { &mangleName($_) }  split(/[,\s;]+/, $co);
				&dumpHeaderEntry;
				&dumpBodyEntry;
			}
			&dumpFooter;
		} else {
			&log("Missing header keys 'name' or 'description' in $file");
		}

		close IN;
	}
}

## Dump "equal-to" command in HTML
sub dumpEqual {
	my($eq) = &mangleName(@_);

	print HTML "This command is 100% compatible to ",
	 htmlCommandRef($ref, $eq), ", please see there\n";
}

## Dump new command header
sub dumpHeader {
	my($na, $de) = @_;

	&dumpTOC($na, $de);
	print HTML '<H2><A NAME="', lc($na), "\">$na - $de</A></H2>\n";
	&writeCmdList(uc($na));
}
sub dumpAppendix {
	print HTML '<H2><A NAME="_appendix">Appendix</A></H2>',"\n";
	open(IN, "stuff")
		or die "Cannot open Appendix: $!\n";
	$na = "_Appendix";
	&dumpBodyEntry;
	close IN;
}

## Dump Headers for normal entry
sub dumpHeaderEntry {
	if($#se >= 0) {
		print HTML "See also: "
		 , join(', ', (map { &htmlRefWord($_) } @se))
		 , "<BR>\n";
	}
	if($#re >= 0) {
		print HTML "Requirements: "
		 , join(', ', (map { &htmlRefWord($_) } @re))
		 , "<BR>\n";
	}
	if($#op >= 0) {
		print HTML "Optional requirements: "
		 , join(', ', (map { &htmlRefWord($_) } @op))
		 , "<BR>\n";
	}
	if($#co >= 0) {
		print HTML "Conflicts with: "
		 , join(', ', (map { &htmlRefWord($_) } @co))
		 , "<BR>\n";
	}
}
sub dumpBodyEntry {
	&parseEBNF($ref, lc($na));
}

sub dumpFooter {
	&htmlFooter;
}


sub htmlRefWord {
	my($cmd) = @_;

	return $cmd unless defined($cmdlist{uc($cmd)});
	return htmlCommandRef($ref, $cmd);
}

## Dump the command footer
sub htmlFooter {
	print HTML "<P><HR>\n";
}

# command name
sub mangleName {
	return uc($_[0]);
}

sub dumpTOC {
	my($na, $de) = @_;

	$toc{$na} = $de;
}

#############################3
sub htmlOpenTOC {
	open(TOC, ">$file_toc")
		or die "Cannot create TOC: $file_toc: $!\n";
}
sub htmlCloseTOC {
	my($na, $de);

	foreach $na (sort keys %toc) {
		print TOC '<LI><A HREF="#', lc($na), "\">$na - $toc{$na}</A>\n";
	}
	close TOC;
}
sub htmlOpenHtml {
	open(HTML, ">$file_html")
		or die "Cannot create HTML: $file_html: $!\n";
print HTML '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META HTTP-EQUIV="Content-Language" CONTENT="en">
<META NAME="GENERATOR" CONTENT="VI">
<META NAME="DESCRIPTION" CONTENT="Description of features and implementation status of FreeCOM, the COMMAND.COM replacement">
<META NAME="AUTHOR" CONTENT="Steffen Kaiser">
<META NAME="KEYWORDS" CONTENT="DOS, FreeDOS, FreeCOM, COMMAND.COM, CLI">
<META NAME="DATE" CONTENT="2001-02-06">
<TITLE>Internal Commands of FreeCOM</TITLE>
</HEAD>

<BODY>
List of commands and features of FreeCOM:
<UL>
';
	if(open(TOC, $file_toc)) {		# Import the previously created TOC
		print HTML <TOC>;
		close TOC;
	}
	print HTML "</UL>\n<BR><BR><HR><BR>\n";
}
sub htmlCloseHtml {
	print HTML "</BODY>\n";
	close HTML;
}

##################3
sub openCmdList {
	&readCmdList($ref);
	open(CMDLIST, ">$file_cmd")
		or die "Cannot create command list file: $!\n";
}
sub closeCmdList {
	close CMDLIST;
}
sub writeCmdList {
	print CMDLIST $_[0] . "\n";
}


## Log an error to the console and the logfile
sub log {
	local($logging) = 0;

	if(!$logging) {
		my($file) = "$0.LOG";
		die "Cannot create logfile: $!\n" unless open(LOG, ">$file");
		$logging = 1;
	}

	print LOG join("\n", @_) . "\n";
	print STDERR join("\n", @_) . "\n";
}

