#module    IdxGen    "1-003"
/*
 ***********************************************************************
 *                                                                     *
 * The software was developed at the Monsanto Company and is provided  *
 * "as-is".  Monsanto Company and the auther disclaim all warranties   *
 * on the software, including without limitation, all implied warran-  *
 * ties or merchantabilitiy and fitness.                               *
 *                                                                     *
 * This software does not contain any technical data or information    *
 * that is proprietary in nature.  It may be copied, modified, and     *
 * distributed on a non-profit basis and with the inclusion of this    *
 * notice.                                                             *
 *                                                                     *
 ***********************************************************************
 */

/*+
 * Module Name:	IdxGen
 *
 * Author:	R L Aurbach	CR&DS MIS Group    28-Apr-1986
 *
 * Function:
 *	Generate the text file used to actually generate the index text.
 *
 * Modification History:
 *
 * Version     Initials	   Date		Description
 * ------------------------------------------------------------------------
 * 1-001	RLA	28-Apr-1986	Original Code
 * 1-002	RLA	03-May-1986	Add support for page-no highlighting
 * 1-003	RLA	14-Jun-1986	Add support for the /TOC qualifier
-*/

/*
 * Module IdxGen - Module-Wide Data Description Section
 *
 * Include Files:
 */
#include	    descrip
#include	    stdio
#include	    ctype
#include	    "IdxDef.H"

/*
 * Module Definitions:
 */
#define		    TRUE	1
#define		    FALSE	0

/*
 * Global Declarations:
 */

/*
 * Static Declarations:
 */

/*
 * External References:
 */
    extern TREE_PTR	root;

/*
 * Functions Called:
 */

/*+
 * Function Idx_Generate - Documentation Section
 *
 * Discussion:
 *	Generate the output file containing the appropriate LaTeX command lines
 *	to generate the index.
 *
 * Calling Synopsis:
 *	Call Idx_Generate (file, toc_flag)
 *
 * Inputs:
 *	file	    ->	is the file descriptor for the current output file.
 *			It is a pointer to FILE.
 *
 *	toc_flag    ->	is a flag indicating what kind of treatment should be
 *			applied to for table-of-contents processing.  It is an
 *			integer, passed by value.  Values are:
 *			    IDX_K_NONE	  - Do nothing.
 *			    IDX_K_ARTICLE - Add a section-oriented toc entry
 *			    IDX_K_REPORT  - Add a chapter-oriented toc entry
 *
 * Outputs:
 *	none
 *
 * Return Value:
 *	none
 *
 * Global Data:
 *	The Index Tree is used read-only.
 *
 * Files Used:
 *	The current output file is written.
 *
 * Assumed Entry State:
 *	The output file pointed to by the file variable is open.
 *
 * Normal Exit State:
 *	Output is written to the file.
 *
 * Error Conditions:
 *	Errors are ignored, in the sense that they don't generate output.
 *
 * Algorithm:
 *	A. Write pre-amble information.
 *	B. For each item in the primary list,
 *	    1. If the first letter of the entry changed,
 *		a. Output special formatting information.
 *	    2. Process the information for this item.
 *	    3. For each subitem,
 *		a. Process information for this subitem.
 *		b. For each subsubitem,
 *		    1. Process information for this subsubitem.
 *	C. Write post-amble information.
 *
 * Special Notes:
 *	none
-*/

/*
 * Function Idx_Generate - Code Section
 */

void	idx_generate (file, toc_flag)

    FILE	    *file;
    int		    toc_flag;
{
/*
 * Local Declarations
 */
    TREE_PTR	    node_1;
    TREE_PTR	    node_2;
    TREE_PTR	    node_3;
    char	    first_letter;    
    int		    item_count = 0;
    int		    subitem_count = 0;
    int		    subsubitem_count = 0;
    void	    idx_preamble();
    void	    idx_new_group();
    void	    idx_write();
    void	    idx_postamble();
/*
 * Module Body
 */

/* Write the pre-amble.							*/

idx_preamble(file, toc_flag);

node_1 = root;
first_letter = ' ';

/* For each node of the primary tree,					*/

while (node_1 != 0)
    {
    idx_new_group(&first_letter, node_1, file);
    idx_write (node_1, "\\item", file);
    item_count++;
    node_2 = node_1->subhead;
    while (node_2 != 0)
	{
	idx_write (node_2, "\\subitem", file);
	subitem_count++;
	node_3 = node_2->subhead;
	while (node_3 != 0)
	    {
	    idx_write (node_3, "\\subsubitem", file);
	    subsubitem_count++;
	    node_3 = node_3->link;
	    }
	node_2 = node_2->link;
	}
    node_1 = node_1->link;
    }

/* Report the total counts of entries.					*/

printf("\nIndex processing statistics:\n");
printf("    Items:        %d\n",   item_count);
printf("    Subitems:     %d\n",   subitem_count);
printf("    Subsubitems:  %d\n\n", subsubitem_count);

/* Write the post-amble							*/

idx_postamble(file);
}

/*+
 * Function Idx_PreAmble - Documentation Section
 *
 * Discussion:
 *	Write the pre-amble information to the output file.
 *
 * Calling Synopsis:
 *	Call Idx_PreAmble (file, toc_flag)
 *
 * Inputs:
 *	file	    ->	is the file descriptor for the output file.
 *
 *	toc_flag    ->	is a flag used to indicate what treatment should be
 *			performed for table-of-contents processing.  It is
 *			an integer passed by value.  Values are:
 *			    IDX_K_NONE     - Do nothing.
 *			    IDX_K_ARTICLE  - Add a section-oriented toc entry.
 *			    IDX_K_REPORT   - Add a chapter-oriented toc entry.
 *
 * Outputs:
 *	none
 *
 * Return Value:
 *	none
 *
 * Global Data:
 *	none
 *
 * Files Used:
 *	The file described by "file" is written.
 *
 * Assumed Entry State:
 *	none
 *
 * Normal Exit State:
 *	none
 *
 * Error Conditions:
 *	none
 *
 * Algorithm:
 *	A. Write pre-amble information.
 *
 * Special Notes:
 *	none
-*/

/*
 * Function Idx_PreAmble - Code Section
 */

void	idx_preamble (file, toc_flag)

    FILE	    *file;
    int		    toc_flag;
{
/*
 * Local Declarations
 */

/*
 * Module Body
 */

fprintf (file, "\\begin{theindex}\n");
fprintf (file, "\\raggedright\n");
fprintf (file, "\\indexspace\n");

/* toc_flag processing							*/

if (toc_flag == IDX_K_NONE)
    return;

if (toc_flag == IDX_K_ARTICLE)
    fprintf (file,"\\addcontentsline{toc}{section}{Index}\\typeout{Index.}\n");

if (toc_flag == IDX_K_REPORT)
    fprintf (file,"\\addcontentsline{toc}{chapter}{Index}\\typeout{Index.}\n");

printf("\nA table of contents entry will be made for the Index.\n");
}

/*+
 * Function Idx_New_Group - Documentation Section
 *
 * Discussion:
 *	Handle special processing at the boundaries between index entries 
 *	which begin with different letters.
 *
 * Calling Synopsis:
 *	Call Idx_New_Group (test_char, node, file)
 *
 * Inputs:
 *	test_char	    ->	is the character which is the first character
 *				of the current group. Passed by reference.
 *
 *	node		    ->	is the TREE_PTR for the current node.
 *
 *	file		    ->	is a file pointer for the output file.
 *
 * Outputs:
 *	test_char	    ->	if a new group is declared, the test character
 *				is updated.
 *
 * Return Value:
 *	none
 *
 * Global Data:
 *	The Index Tree is read.
 *
 * Files Used:
 *	If a new group is declared, records are written to the output file.
 *
 * Assumed Entry State:
 *	none
 *
 * Normal Exit State:
 *	none
 *
 * Error Conditions:
 *	none
 *
 * Algorithm:
 *	A. Current_Char is the first character of the Spell String of the
 *	   current node, or a space if the first character is not a letter.
 *	B. If Current_Char != Test_Char,
 *	    1. Generate \indexspace commands.
 *	    2. Test_Char = Current_Char.
 *
 * Special Notes:
 *	none
-*/

/*
 * Function Idx_New_Group - Code Section
 */

void	idx_new_group (test_char, node, file)

    char	    *test_char;
    TREE_PTR	    node;
    FILE	    *file;
{
/*
 * Local Declarations
 */
    char	    current_char;
/*
 * Module Body
 */

current_char = node->spell.dsc$a_pointer[0];
if (isalpha(current_char) == 0)	    current_char = ' ';
current_char = _toupper(current_char);

if (*test_char != current_char)
    {
    fprintf (file, "\\indexspace\n");
    fprintf (file, "\\hfil {\\bf -- %c --} \\hfil \\par\n", current_char);
    fprintf (file, "\\smallskip\n");
    *test_char = current_char;
    }
}

/*+
 * Function Idx_Write - Documentation Section
 *
 * Discussion:
 *	Write the basic text line for the current entry.
 *
 * Calling Synopsis:
 *	Call Idx_Write (node, intro_str, file)
 *
 * Inputs:
 *	node	    ->	TREE_PTR of the node whose data is to be reported.
 *
 *	intro_str   ->	introductory character string, ASCIZ passed by ref.
 *
 *	file	    ->	file pointer for output file.
 *
 * Outputs:
 *	none
 *
 * Return Value:
 *	none
 *
 * Global Data:
 *	none
 *
 * Files Used:
 *	The output file is written.
 *
 * Assumed Entry State:
 *	none
 *
 * Normal Exit State:
 *	none
 *
 * Error Conditions:
 *	none
 *
 * Algorithm:
 *	A. Print the first part of the string, containing the item.
 *	B. If there is at least one page number specified,
 *	    1. Print the first page number (which is formatted specially).
 *	    2. For all remaining page numbers,
 *		a. Print them.
 *	C. Print the record trailer.
 *
 * Special Notes:
 *	When printing page numbers, allow for page-no highlighting.  The
 *	highlight code is specified in the pgnode list element.  Recognized
 *	values are:
 *	    IDX_K_NONE	    - No highlighting
 *	    IDX_K_UNDERLINE - Underline the page number
 *	    IDX_K_ITALIC    - Italicize the page number
 *	    IDX_K_BOLD	    - Boldface the page number
-*/

/*
 * Function Idx_Write - Code Section
 */

void	idx_write (node, intro_str, file)

    TREE_PTR	    node;
    char	    *intro_str;
    FILE	    *file;
{
/*
 * Local Declarations
 */
    char	    string[256];
    int		    length;
    PGNODE_PTR	    pgnode;
    int		    highlight;
/*
 * Module Body
 */

length = sprintf (string, "%s{%.*s", intro_str, node->item.dsc$w_length,
						    node->item.dsc$a_pointer);

if (node->pghead != 0)
    {
    pgnode = node->pghead;

    highlight = pgnode->highlight;
    switch (highlight)
	{
	case IDX_K_UNDERLINE :
	    length += sprintf (&string[length], ", \\mbox{\\underline{%.*s}}", 
		pgnode->page_dsc.dsc$w_length, pgnode->page_dsc.dsc$a_pointer);
	    break;
	case IDX_K_ITALIC :
	    length += sprintf (&string[length], ", \\mbox{\\em %.*s}", 
		pgnode->page_dsc.dsc$w_length, pgnode->page_dsc.dsc$a_pointer);
	    break;
	case IDX_K_BOLD :
	    length += sprintf (&string[length], ", \\mbox{\\bf %.*s}", 
		pgnode->page_dsc.dsc$w_length, pgnode->page_dsc.dsc$a_pointer);
	    break;
	default :
	    length += sprintf (&string[length], ", \\mbox{%.*s}", 
		pgnode->page_dsc.dsc$w_length, pgnode->page_dsc.dsc$a_pointer);
	    break;
	}

    while ((pgnode = pgnode->link) != 0)
	{
	if (length > 200)
	    {
	    fprintf (file, "%s%%\n", string);
	    length = 0;
	    }
	switch (pgnode->highlight)
	    {
	    case IDX_K_UNDERLINE :
		length += sprintf (&string[length], 
		    ", \\mbox{\\underline{%.*s}}", 
		    pgnode->page_dsc.dsc$w_length, 
			pgnode->page_dsc.dsc$a_pointer);    break;
	    case IDX_K_ITALIC :
		length += sprintf (&string[length], ", \\mbox{\\em %.*s}", 
		    pgnode->page_dsc.dsc$w_length, 
			pgnode->page_dsc.dsc$a_pointer);    break;
	    case IDX_K_BOLD :
		length += sprintf (&string[length], ", \\mbox{\\bf %.*s}", 
		    pgnode->page_dsc.dsc$w_length, 
			pgnode->page_dsc.dsc$a_pointer);    break;
	    default :
		length += sprintf (&string[length], ", \\mbox{%.*s}", 
		    pgnode->page_dsc.dsc$w_length, 
			pgnode->page_dsc.dsc$a_pointer);    break;
	    }
	}
    }
fprintf (file, "%s}\n", string);
}

/*+
 * Function Idx_PostAmble - Documentation Section
 *
 * Discussion:
 *	Write the lines which occur at the end of the file.
 *
 * Calling Synopsis:
 *	Call Idx_PostAmble (file);
 *
 * Inputs:
 *	file	    ->	is the file pointer for the output file.
 *
 * Outputs:
 *	none
 *
 * Return Value:
 *	none
 *
 * Global Data:
 *	none
 *
 * Files Used:
 *	Output file is written.
 *
 * Assumed Entry State:
 *	none
 *
 * Normal Exit State:
 *	none
 *
 * Error Conditions:
 *	none
 *
 * Algorithm:
 *	A. Write the end-matter.
 *
 * Special Notes:
 *	none
-*/

/*
 * Function Idx_PostAmble - Code Section
 */

void	idx_postamble (file)

    FILE	*file;
{
/*
 * Local Declarations
 */

/*
 * Module Body
 */

fprintf (file, "\\end{theindex}\n");
}
