#! /usr/bin/env perl -w

# Copyright (c) 2017, 2018, 2021 Matthew R. Green
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

$rcsid = '$eterna: help2html.pl,v 1.9 2021/03/20 21:34:52 mrg Exp $';

# convert help files into help files.
#
# we give header and footer, and convert ^_<foo>^_ into a hyperlink to <foo>.

my $usage = "help2html.pl <helpdir> <htmloutputdir>\n";

my $debug = 0;
my $total_files = 1;

my %no_usage_list = (
	':' => 1,
	'alias/functions' => 1,
	'alias/quote' => 1,
	'alias/special' => 1,
	'alias/width' => 1,
	'basics' => 1,
	'bind/examples' => 1,
	'bind/keys' => 1,
	'bye' => 1,
	'channel' => 1,
	'commands' => 1,
	'etiquette' => 1,
	'exit' => 1,
	'expressions' => 1,
	'intro' => 1,
	'ircii/copyright' => 1,
	'ircii/environment_vars' => 1,
	'ircii/programming' => 1,
	'ircii/server_lists' => 1,
	'load/edit' => 1,
	'load/lynx_ircrc' => 1,
	'load/suggestions' => 1,
	'menus' => 1,
	'news' => 1,
	'newuser' => 1,
	'on/serial_numbers' => 1,
	'part' => 1,
	'signoff' => 1,
	'time' => 1
);

sub dirname($) {
	my ($path) = @_;

	$path =~ s,/[^/]*,,;
	return $path;
}

# eval this with $title set
sub header_from_title($) {
	my ($file) = @_;
	my $title = "ircII help";

	$file =~ s,^\./,,;
	if ($file ne ".") {
		$title .= " - $file";
	}

	my $header = "
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">
<!-- This is an automatically generated file.  Do Not Edit! -->
<html>
  <head>
    <title>$title</title>
  </head>
  <h1>$title</h1>
";
	$header;
}

sub footer($$) {
	my ($prefix, $file) = @_;

	my $footer .= "\n<p>";

	if ($prefix eq "../../") {
		$footer .= "<a href=\"../../$file.html\">Up index</a>\n</html>\n";
	} if ($prefix eq "../") {
		$footer .= "<a href=\"../$file.html\">Up index</a>\n</html>\n";
	}

	$footer .= "<a href=\"${prefix}index.html\">Top level index</a>\n</html>\n";

	return $footer;
}

sub convert_one_file($$$);
sub convert_one_file($$$) {
	my ($subdir, $file, $outdir) = @_;

	my $inpath;
	if ($subdir eq ".") {
		$inpath = $file;
	} else {
		$inpath = $subdir . "/" . $file;
	}
	$inpath =~ s,^\./,,g;

	if ( ! -d $outdir ) {
		mkdir $outdir, 0755 or die "couldn't mkdir $outdir";
	}

	my $slashes = $file;
	$slashes =~ s,\./\./,/.,g;
	$slashes =~ s,^\./,,g;
	$slashes =~ s/[^\/]//g;
	my $prefix = "";
	my $length = length($slashes);
	for (my $i = 0; $i < $length; $i++) {
		$prefix .= "../";
	}

	print "outdir $outdir file $file subdir $subdir -> inpath $inpath\n"
		if $debug;
	if (-d $inpath) {
		my @index_list;
		my $file_dirname = "$outdir/" . dirname($file);
		my $outdir_path = "$outdir/" . $file;

		if ( ! -d $outdir_path ) {
			mkdir $outdir_path, 0755 or die "couldn't mkdir $outdir_path";
		}
		print "file_dirname $file_dirname file $file outdir_path $outdir_path\n"
			if $debug;

		opendir(my $dh, $inpath) or die "opendir: $!\n";
		while (readdir $dh) {
			next if $_ =~ /^\./;
			my $this_file = $file . "/" . $_;
			push @index_list, $_;
			convert_one_file(".", $this_file, $outdir);
		}

		# create index.html in the subdir, and file.html in the topdir
		my $header = header_from_title($file);
		my $index_path = $outdir_path . "/index.html";
		open OUTI, ">$index_path" or die "couldn't open for write $index_path: $!\n"
			or die "couldn't open $index_path";
		print "creating $index_path\n"
			if $debug;
		print OUTI $header;
		for $f (@index_list) {
			print OUTI "<br><a href=\"$f.html\">$f<\/a>\n";
		}
		print OUTI footer($prefix, $file);
		close OUTI;

		if ($file ne ".") {
			my $name_path = $outdir_path . ".html";
			open OUTN, ">$name_path" or die "couldn't open for write $name_path: $!\n"
				or die "couldn't open $name_path";
			print "creating $name_path\n"
				if $debug;
			print OUTN $header;
			for $f (@index_list) {
				print OUTN "<br><a href=\"$file/$f.html\">$f<\/a>\n"
			}
			print OUTN footer($prefix, $file);
			close OUTN;
		}
		return;
	}
	my $outpath = $outdir . "/" . $file . ".html";
	print "inpath $inpath outpath $outpath\n"
		if $debug;

	$total_files++;
	open IN, $inpath or die "couldn't open $inpath: $!\n";
	open OUT, ">$outpath" or die "couldn't open for write $outpath: $!\n";
	print "creating $outpath\n"
		if $debug;

	my $title = $file;
	my $header = header_from_title($title);

	print OUT $header;

	# phases:
	# 1 - beginning, looking for Usage
	# 2 - got Usage, doing main doc
	# 3 - doing SEE ALSO, etc.
	# 4 - special case no "Usage:" files 
	my $phase = 1;
	# these help files don't have a Usage:
	if ($no_usage_list{$inpath}) {
		$phase = 2;
	}

	my $in_pre = 0;

	my $in;
	while ($in = <IN>) {
		if ($in =~ /^!/) {
			chomp $in;
			print OUT "<!-- $in -->\n";
			next;
		}
		$in =~ s/&/\&amp;/;	# first!
		$in =~ s/"/\&quot;/;
		$in =~ s/'/\&apos;/;
		$in =~ s/</\&lt;/;
		$in =~ s/>/\&gt;/;
		$in =~ s/^$/<p>\n/;
		$in =~ s/^$/<p>\n/;
		$in =~ s/\002//g;
		if ($phase == 1) {
			$in =~ s/$/\n<p>\n/;
		} elsif ($phase == 2) {
			if ($inpath eq "alias/functions" && $in =~ m/^  [A-Z]+\([^)]+\)/) {
				$phase = 4;
			}

			# display regions with 4-leading spaces as "pre".
			if ($in =~ m/^    (.*)/) {
				if (!$in_pre) {
					print OUT "<pre>\n";
				}
				$in_pre = 1;
			} else {
				if ($in_pre) {
					print OUT "</pre>\n";
				}
				$in_pre = 0;
			}
		}
		if ($phase == 4) {
			if ($in =~ m/^  ([A-Z]+\([^)]*\))\s+(.*)/) {
				$func = $1;
				print OUT "<p><br>$func<br>\n";
				$in = $2;
			} else {
				$in =~ s/^\s+/ /;
			}
		}

		# convert "^_one^_ ^_two^_" into "one/two", recursively
		# ugly do it converting "^_ ^_" into "/"
		$in =~ s/ /\//g;
		$in =~ s/([^]+?)/'<a href="' . $prefix . lc($1) . '.html">' . lc($1) . '<\/a>'/ge;

		print OUT $in;

		$phase = 3 if $in =~ /^See Also:/;
		$phase = 2 if $in =~ /^Usage:/;
	}
	print OUT footer($prefix, dirname($inpath));
}

sub main() {
	if ($#ARGV != 1) {
		print STDERR $usage;
		exit 1;
	}
	my $helpdir = $ARGV[0];
	my $htmldir = $ARGV[1];

	print "$0 ($rcsid)\n";

	chdir($helpdir) or die "couldn't chdir $helpdir";
	convert_one_file(".", ".", $htmldir);
	
	print "$0: created $total_files files\n";
}

main();
