#!perl
# $Id: makeman.pl,v 1.5 2004/09/30 07:34:13 jlinoff Exp $
# Create the ccdoc man page from the help text.
use strict;
&Main;

# ================================================
# MAIN
# ================================================
sub Main
{
    my $hfile = "";
    my $lfile = "";
    my $ofile = "";
    while( $#ARGV >= 0 ) {
	my $arg = shift @ARGV;
	if( $arg eq "-h" ) {
	    $hfile = shift @ARGV;
	}
	elsif( $arg eq "-l" ) {
	    $lfile = shift @ARGV;
	}
	elsif( $arg eq "-o" ) {
	    $ofile = shift @ARGV;
	}
	elsif( $arg eq "-help" ) {
	    &Usage;
	}
	else {
	    print STDERR "ERROR: Unrecognized switch '$arg'.\n";
	    &Usage;
	}
    }
    if( $hfile eq "" ) {
	print STDERR "ERROR: The -h <file> switch was not specified.\n";
	&Usage;
    }
    if( $lfile eq "" ) {
	print STDERR "ERROR: The -l <file> switch was not specified.\n";
	&Usage;
    }
    if( $ofile eq "" ) {
	print STDERR "ERROR: The -o <file> switch was not specified.\n";
	&Usage;
    }

    open OFILE,">$ofile" || die "ERROR: Can't write '$ofile'.\n";
    my $tmp = "\$";
    print OFILE "\.\\\\\" Automatically created by \$Id: makeman.pl,v 1.5 2004/09/30 07:34:13 jlinoff Exp $tmp\"\n";

    # First line is ccdoc help <date>
    open HFILE,"$hfile" || die "ERROR: Can't read '$hfile'.\n";
    my $line = <HFILE>;
    my @tokens = split(/\s+/,$line);
    print OFILE ".TH $tokens[0] 1 $tokens[2] \"http://ccdoc.sourceforge.net\"\n";
    print OFILE ".SH NAME\n";
    print OFILE "ccdoc \\- C++ interface documentation tool\n";
    print OFILE ".SH SYNOPSIS\n";
    print OFILE ".B ccdoc [db\n";
    print OFILE ".I file\n";
    print OFILE ".B ] [\n";
    print OFILE ".I -switches\n";
    print OFILE ".B ]\n";
    print OFILE ".B ...\n";
    print OFILE ".br\n";
    print OFILE "  \n";
    print OFILE ".br\n";
    print OFILE ".I OR\n";
    print OFILE ".br\n";
    print OFILE "  \n";
    print OFILE ".br\n";
    print OFILE ".in +3\n";
    print OFILE ".I phase1: \n";
    print OFILE ".B ccdoc [-db\n";
    print OFILE ".I file\n";
    print OFILE ".B ] [\n";
    print OFILE ".I -phase1_switches\n";
    print OFILE ".B ]\n";
    print OFILE ".I header_file1\n";
    print OFILE ".B ...\n";
    print OFILE ".br\n";
    print OFILE ".I phase2: \n";
    print OFILE ".B ccdoc [-db\n";
    print OFILE ".I file\n";
    print OFILE ".B ] [-index]\n";
    print OFILE ".br\n";
    print OFILE ".I phase3: \n";
    print OFILE ".B ccdoc [-db\n";
    print OFILE ".I file\n";
    print OFILE ".B ] [-html \n";
    print OFILE ".I directory/\n";
    print OFILE ".B ] [\n";
    print OFILE ".I -phase3_switches\n";
    print OFILE ".B ]\n";
    print OFILE ".br\n";
    print OFILE ".in -3\n";
    &Description(\*OFILE);
    print OFILE ".SH OPTIONS\n";
    print OFILE "To understand how to use the options for the different phases, see\n";
    print OFILE "the on-line help or the users manual at http://ccdoc.sourceforge.net.\n";

    # Scan through the help text looking for options.
    # Collect them in a map so that they can be output
    # in alphabetical order.
    my %sws;
    my $lineno = 0;
    my $text;
    my $key = "";
    my $alt = "";
    my $phase = "";
    my $br_flag = 0;
    while(<HFILE>) {
	chop;
	$lineno++;
	my $line = $_;
	last if( $line =~ /^6 Running / );
	$phase = "all" if( $line =~ /Phase Independent Switches/ );
	$phase = "parse" if( $line =~ /Parse Phase/ );
	$phase = "index" if( $line =~ /Index Phase/ );
	$phase = "output" if( $line =~ /Output Phase/ );
	if( $line =~ /^\s{2}\-(\w+\S*)\s+(<\w+\>)\s*,\s*$/ ) {
	    $br_flag = 0;
	    $sws{$key}{"TEXT"} = $text if( $key ne "" );
	    $alt = "$1 $2";
	}
	elsif( $line =~ /^\s{2}\-(\w+\S*)\s*,\s*$/ ) {
	    $br_flag = 0;
	    $sws{$key}{"TEXT"} = $text if( $key ne "" );
	    $alt = "$1";
	}
	elsif( $line =~ /^\s{2}\-(\w+\S*)\s+(<\w+\>)\s+(.+)$/ ) {
	    $br_flag = 0;
	    $sws{$key}{"TEXT"} = $text if( $key ne "" );
	    $key = $1;
	    $sws{$key}{"NAME"}= "$1 $2";
	    $sws{$key}{"LINENO"} = $lineno;
	    $sws{$key}{"ALT"} = $alt;
	    $sws{$key}{"PHASE"} = $phase;
	    $alt = "";
	    $text = $3;
	}
	elsif( $line =~ /^\s{2}\-(\w+\S*)\s+(.+)$/ ) {
	    $br_flag = 0;
	    $sws{$key}{"TEXT"} = $text if( $key ne "" );
	    $key = $1;
	    $sws{$key}{"NAME"}= "$1";
	    $sws{$key}{"LINENO"} = $lineno;
	    $sws{$key}{"ALT"} = $alt;
	    $sws{$key}{"PHASE"} = $phase;
	    $alt = "";
	    $text = $2;
	}
	elsif( $line =~ /^\s{2}\-\[no\](\w+\S*)\s+(<\w+>)\s+(.+)$/ ) {
	    $br_flag = 0;
	    $sws{$key}{"TEXT"} = $text if( $key ne "" );
	    $key = $1;
	    my $n = "[no]$1";
	    $sws{$key}{"NAME"} = "$n $2";
	    $sws{$key}{"LINENO"} = $lineno;
	    $sws{$key}{"ALT"} = $alt;
	    $sws{$key}{"PHASE"} = $phase;
	    $alt = "";
	    $text = $3;
	}
	elsif( $line =~ /^\s{2}\-\[no\](\w+\S*)\s+(.+)$/ ) {
	    $br_flag = 0;
	    $sws{$key}{"TEXT"} = $text if( $key ne "" );
	    $key = $1;
	    my $n = "[no]$1";
	    $sws{$key}{"NAME"} = $n;
	    $sws{$key}{"LINENO"} = $lineno;
	    $sws{$key}{"ALT"} = $alt;
	    $sws{$key}{"PHASE"} = $phase;
	    $alt = "";
	    $text = $2;
	}
	elsif( $key ne "" ) {
	    if( $line =~ /^\s+========/ ) {
		$sws{$key}{"TEXT"} = $text if( $key ne "" );
		$key = "";
	    }
	    elsif( $line =~ /^   \s+(\S.*)$/ ) {
		$text .= " " if( ! $br_flag );
		$text .= "$1";
		$br_flag = 0;
		#print "DEBUG:2: -$key $text\n";
	    }
	    elsif( $line =~ /^\s*$/ ) {
		#print "DEBUG:3: -$key $text\n";
		$text .= "\n.br\n   \n.br\n";
		$br_flag = 1;
	    }
	}
    }
    my $key;
    foreach $key ( sort keys %sws ) {
	my $name = $sws{$key}{"NAME"};
	my $alt = $sws{$key}{"ALT"};
	my $line = $sws{$key}{"LINENO"};
	my $text = $sws{$key}{"TEXT"};
	my $phase = $sws{$key}{"PHASE"};
	if( $alt ne "" ) {
	    print OFILE ".IP \"-$alt\"\n";
	    print OFILE "Same as -$name.\n";
	}
	print OFILE ".IP \"-$name\"\n";
	#print OFILE "ALT: '$alt'\n";
	print OFILE "$text\n";
	print OFILE ".br\n";
	print OFILE "Phase: $phase\n";
    }
    close HFILE;

    print OFILE ".SH DIRECTIVES\n";
    print OFILE "These are the directives that drive the output format.\n";
    print OFILE "They are found in the comments associated with the entities.\n";
    print OFILE "The basic format is:\n";
    print OFILE ".br\n";
    print OFILE "  \n";
    print OFILE ".br\n";
    print OFILE ".in +3\n";
    print OFILE "/**\n";
    print OFILE ".br\n";
    print OFILE " *<brief_description>\n";
    print OFILE ".br\n";
    print OFILE " *<long_description>\n";
    print OFILE ".br\n";
    print OFILE " *<directives>\n";
    print OFILE ".br\n";
    print OFILE " */\n";
    print OFILE ".br\n";
    print OFILE ".in -3\n";
    print OFILE ".br\n";
    print OFILE "  \n";
    print OFILE ".br\n";
    print OFILE "Where the brief description is a single sentence terminated by a period,\n";
    print OFILE "the long description is anything else, including HTML tags and the\n";
    print OFILE "directives are special ccdoc tags.\n";
    print OFILE ".br\n";
    print OFILE "  \n";
    print OFILE ".br\n";
    print OFILE "These comments are associated with C++ entity declarations for classes,\n";
    print OFILE "variables, functions, enumerated types and typedefs as shown in the\n";
    print OFILE "simple example below for a class.\n";
    print OFILE ".br\n";
    print OFILE "  \n";
    print OFILE ".br\n";
    print OFILE ".in +3\n";
    print OFILE "/**\n.br\n";
    print OFILE " * Briefly, do important foo stuff.\n.br\n";
    print OFILE " * Long winded, do really important foo stuff.\n.br\n";
    print OFILE " * \@author Ima Programmer\n.br\n";
    print OFILE " * \@version 1.2\n.br\n";
    print OFILE " * \@see Bar\n.br\n";
    print OFILE " * \@see Spam\n.br\n";
    print OFILE " */\n.br\n";
    print OFILE ".in -3\n";
    print OFILE ".br\n";
    print OFILE "  \n";
    print OFILE ".br\n";
    print OFILE "For more information about the directives see the on-line help\n";
    print OFILE "or the users manual at http://ccdoc.sourceforge.net.\n";
    open HFILE,"$hfile" || die "ERROR: Can't read '$hfile'.\n";
    while( <HFILE> ) {
	chop;
	my $line = $_;
	if( $line =~ /^\s+Id\s+Directive\s+Quick Summary/ ) {
	    $line = <HFILE>; # skip the =====
	    #print "DEBUG: $line\n";
	    while( <HFILE> ) {
		chop;
		$line = $_;
		last if( $line =~ /^\s*$/ );
		last if( $line =~ /========/ );
		#print "DEBUG: $line\n";
		if( $line =~ /^\s+\d+\s+(\S+)\s\s+(.+)$/ ) {
		    print OFILE ".IP \"$1\"\n";
		    print OFILE "$2\n";
		}
		elsif( $line =~ /^\s+\d+\s+(\S+\s+\S+)\s\s+(.+)$/ ) {
		    print OFILE ".IP \"$1\"\n";
		    print OFILE "$2\n";
		}
		elsif( $line =~ /^\s+\d+\s+(\S+\s+\S+\s+\S+)\s\s+(.+)$/ ) {
		    print OFILE ".IP \"$1\"\n";
		    print OFILE "$2\n";
		}
		else {
		    # Catch any left over text.
		    $line =~ s/^\s+//;
		    print OFILE "$line\n";
		}
	    }
	}
    }
    close HFILE;

    print OFILE ".SH AUTHOR\n";
    print OFILE "Joe Linoff\n";

    print OFILE ".SH LICENSE\n";
    open LFILE,"$lfile" || die "ERROR: Can't read '$lfile'.\n";
    while(<LFILE>) {
	chop;
	my $line = $_;
	next if( $line =~ /^========================/ );
	if( $line =~ /^\s*$/ ) {
	    print OFILE ".br\n";
	    print OFILE "  \n";
	    print OFILE ".br\n";
	}
	else {
	    print OFILE "$line\n";
	}
    }
    close LFILE;
    close OFILE;
}
# ================================================
# Description
# ================================================
sub Description
{
    my $ofile = shift;
    print $ofile <<END;
.SH DESCRIPTION
.B ccdoc
automatically generates HTML web documentation from C++ programs by
parsing the source file headers. It was designed to aid collaboration
between package users and package developers by documenting the
interface.
.br
  
.br
The source code for this program is provided free charge from
http://ccdoc.sourceforge.net.
.br
  
.br
The program operates in three phases. The first phase translates the
C++ files to an intermediate format that is stored in the db file.  It
is usually run multiple times over header files in different
directories and is called the input phase.
This phase automatically recognizes the C++ structure to create the
documentation but you can add additional comments by using directives
that have a javadoc like syntax.
.br
  
.br
The second phase cross indexes all the parsed entities and is called
the index phase.
.br
  
.br
The third phase generates the HTML and is called the output phase.
.br
  
.br
Detailed information about the switches, program phases and comment syntax
can be found in the on-line help or in the users manual at
http://ccdoc.sourceforge.net.
END
}
# ================================================
# Usage
# ================================================
sub Usage
{
    print <<END;

usage\: make_man.pl [-i \<file\>] [-o \<file\>] [-h]

    -help        This help message.

    -h \<file\>  The input help text file. This must be the ccdoc help.txt file
                 because the program expects some syntactic conventions.

    -l \<file\>  The input license text file. This must be the ccdoc copyright.txt file
                 because the program expects some syntactic conventions.

    -o \<file\>  The output man page file.

END
    exit 0;
}
