#! /bin/sh

# $Id: mktroff,v 1.7 95/10/09 23:02:28 lee Exp Locker: lee $

# expect a list of categories 

for cat
do
    if test -f "Overviews/Categories/$cat/Overview"
    then
	echo ".so Overviews/Categories/$cat/Overview"
	echo ".so $cat"  1>&2
	# cat "Overviews/Categories/$cat/Overview"
	# echo "#included $cat"  1>&2
    else
	echo "MISSING OVERVIEW $cat" 1>&2
    fi

    ls Categories/$cat/* |
    while read i
    do
	# We want the output in this order:
	# Entry
	# Function
	# Name, Class
	# Decl
	# Returns
	# Purpose...
	# everything else...
	# /Entry

	# input is
	# Entry
	# Function
	# Name, Class
	# Purpose
	# Returns (optional)
	# everything else
	# Decl
	# /Entry

	mawk '
	BEGIN {
	    Saving = 0
	    SavedLinesCount = 0
	}

	/<Purpose>/ {
	    Saving = 1
	}

	/<Decl>/ {
	    Saving = 0
	    inDecl = 1;
	    print
	    next
	}

	/<\/Decl>/ {
	    print
	    PrintSavedLines()
	    inDecl = 0;
	    next
	}

	(Saving == 1) {
	    SaveLine($0)
	    next
	}

	{
	    print
	}

	function PrintSavedLines(				i) {
	    for (i = 1; i <= SavedLinesCount; i++) {
		print SavedLines[i]
	    }
	    SavedLinesCount = 0
	}

	function SaveLine(theLine) {
	    ++SavedLinesCount
	    SavedLines[SavedLinesCount] = theLine

	}

	' "$i" |
	perl -w -e '
	$inSeeAlso = 0;

	while (<>) {
	    # put cross-references in
	    if ($inSeeAlso) {
		if (/^[^a-zA-Z]/) {
		    $inSeeAlso = 0;
		} else {
		    s@\b([a-zA-Z][^,;]*)\b@<Xref>$1</Xref>@g;
		    s@</Xref>[^<]+<Xref>@</Xref><Xref>@g;
		}
	    }

	    # escape angle brackets in included files:
	    #	#include <strings.h>
	    # this should be done by mkdocfromc
	    # Note: uses control-B for backslash so that it does not
	    # get escaped later!
	    s@<\([a-z][a-z0-9_]*\.h\)>@*[+h]$1*[-h]@g;
	    s/<h>/*[+h]/g;
	    s@</h>@*[-h]@g;

	    # put tage on individual lines:
	    s/></>\n</g;

	    # delete unwanted </Name>:
	    s/<\/Name>//;

	    # change syntax of attributes:
	    if (/<Function/) {
		s/(<Function) File="([^"]*)"/$1 $2/i;
		s@\.\.\/src\/@@;
	    }
	    s/(<Entry) dir="([^"]*)"/$1 $2/i;

	    # change case of LIST:
	    s/LIST>/List>/;

	    # escape backslash
	    s/\\/\\e/g;

	    # escape lines starting with special troff characters:
	    s/^([.'"'"'])/\\\\\&$1/;

	    if (/<Decl>/ .. /\/Decl>/) {
		# within a Decl, use special fonts for function name:
		s/([A-Za-z][^ ]*)\(/\\*[+fn]$1\\*[-fn](/;
	    } elsif (/Purpose/ .. /<\/Function/) {
		# in the main body, use functions and small caps appropriately:
		s/\b(LQ[A-Z]*_[a-zA-Z\\%0-9]*)\b/\\*[+fn]$1\\*[-fn]/g;
		s/\b([A-Z][A-Z\\%][A-Z_0-9\\%]*[A-Z])\b/\\*[+c]$1\\*[-c]/g;
		s/_/_\\%/g;
	    }

	    # delete unwanted </P>
	    s@</P>[ 	]*$@@;

	    # escape a minus sign:
	    s/(-[0-9])/\\$1/g;

	    # newline before end list item:
	    s/(<\/LI>)/\n$1/g;

	    # restore control-b to backslash (see <h> processing above)
	    s//\\/g;

	    # check for cross references last, so we miss the <SeeAlso> line:
	    if (/<SeeAlso>/) {
		$inSeeAlso = 1;
	    }

	    # retain white space only in examples:
	    if (!(/<Example>/i .. /<\/Example/i) &&
		!(/<Decl>/i .. /<\/Decl/i)
	    ) {
		s/^[ 	]+//gm;
	    }

	    print;
	}
	' | 
    mawk '

    BEGIN {
	File = "'"$i"'"
	printf ".File \"%s\"\n", File
	saw_proto = 0;
	xrefs[1] = ""
    }

    /<SeeAlso>/ {
	inSeeAlso = 1;
	xrefs[1] = ".\\\" no xrefs this time??";
	handleTag($0);
	next
    }

    (inSeeAlso) {
	if ($0 ~ /<Xref/) {
	    # delete discretionary hyphens and smallcaps from the xref...
	    gsub(/\\\*\[[^\]]*\]/, "") # delete refs to troff strings
	    sub(/<\/Xref>/, "");
	    sub(/<\/LastXref>/, "");
	    xrefs[inSeeAlso] = $0
	    inSeeAlso++
	    next
	} else {
	    for (i = 1; i + 1 < inSeeAlso; i++) {
		if (xrefs[i] ~ /</) {
		    handleTag(xrefs[i])
		} else {
		    s = handleText(xrefs[i]);
		    if (s != "") {
			print xrefs[i]
		    }
		}
	    }
	    sub(/Xref/, "LastXref", xrefs[inSeeAlso - 1]);
	    i = inSeeAlso - 1;
	    if (xrefs[i] ~ /</) {
		handleTag(xrefs[i])
	    } else {
		s = handleText(xrefs[i]);
		if (s != "") {
		    print xrefs[i]
		}
	    }
	    inSeeAlso = 0;
	}
	# carry on to handle $0, which is not an xref
    }

    /^VARARGS.*\*\// {
	next
    }

    /<Name/ {
	# delete discretionary hyphens and smallcaps from the Name
	gsub(/\\%/, "");
	gsub(/\\\\*\*\[[^\]]*\]/, "");
    }

    /<File>/ {
	next
    }

    /<\/Decl>/ {
	printf "./Decl\n"
	next
    }

    /^<!/ {
	next
    }

    {
	gsub(/<I>/, "\\<\\f[I]", $0)
	gsub(/<\/I>/, "\\>", $0)
	gsub(/<var>/, "\\*[+var]", $0)
	gsub(/<\/var>/, "\\*[-var]", $0)
    }

    /^</ {
	handleTag($0)
	next
    }

    /./ {
	s = handleText($0);
	if (s != "") {
	    print s
	}
	next
    }

    function handleTag(theLine)
    {
	tag = theLine
	sub(/^</, "", tag)
	sub(/>.*$/, "", tag)
	sub(/^<[^>]*>[ 	]*/, "", theLine)
	if (length(theLine) > 0) {
	    s = handleText(theLine);
	    if (s != "") {
		printf ".%s \"%s\"\n", tag, s
	    }
	} else {
	    printf ".%s\n", tag
	}
    }

    function handleText(theLine) {
	if (theLine ~ /^#/) {
	    if (theLine ~ /HAVE_PROTO/) {
		saw_proto = 1
		return ""
	    } else if (saw_proto > 0 && theLine ~ /endif/) {
		saw_proto = 0
		return ""
	    }
	    gsub(/"/, "\"\"", theLine)
	    sub(/^/, ".CPP \"", theLine)
	    sub(/$/, "\"", theLine)
	}
	# gsub(/"/, "\"\"", theLine)
	gsub(/<--*>/, "\\[io]", theLine)
	gsub(/--*>/, "\\[->]", theLine)
	gsub(/<--*/, "\\[<-]", theLine)
	gsub(/&lt;/, "<", theLine)
	gsub(/&gt;/, ">", theLine)
	gsub(/&hy;/, "\\%", theLine)
	gsub(/\.\.\./, "\\*[ellipsis]", theLine)
	# expand tabs:
	sub(/^			/, "		        ", theLine)
	sub(/^		/, "	        ", theLine)
	sub(/^	/, "        ", theLine)
	return theLine
    }
    '
    done
done | bin/addhyphens.pl

