/* #module IdxGen "3-001" *********************************************************************** * * * 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 of 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 * 2-004 RLA 10-Apr-1987 Enhance the visual appearance of the * index and add support of a master * index. * 2-005 RLA 11-Apr-1987 Fix spacing around each new group by * defining the \indexhead macro. * 2-006 RLA 14-Apr-1987 Support new page-no highlight option. * 2-007 RLA 16-Apr-1987 Add support for cross references. * 2-008 RLA 20-Apr-1987 Final formatting enhancements * 3-001 F.H. 17-May-1991 converted to portable C */ /* * Module IdxGen - Module-Wide Data Description Section * * Include Files: */ #ifdef MSDOS #include #include #define F_OK 0 /* access(): File exists */ #else #include extern char *sprintf(); #endif #include #include #include #include "IdxDef.h" /* * Module Definitions: */ #define TRUE 1 #define FALSE 0 /* * Global Declarations: */ /* * Static Declarations: */ #ifdef MSDOS void idx_generate(FILE *file, int toc_flag, int mst_flag); void idx_preamble(FILE *file, int toc_flag, int mst_flag); void idx_new_group(char *test_char, TREE_PTR node, FILE *file); void idx_write(TREE_PTR node, char *intro_str, FILE *file, int mst_flag); void idx_postamble(FILE *file); #else void idx_generate(); void idx_preamble(); void idx_new_group(); void idx_write(); void idx_postamble(); #endif /* * External References: */ #ifdef MSDOS extern void idx_build_range(TREE_PTR node); #else extern void idx_build_range(); #endif 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, mst_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 * * mst_flag -> is a flag which specifies whether a master index is * being generated. Volume labels are printed for the * master index. * * 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, mst_flag) FILE *file; int toc_flag; int mst_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; /* * Module Body */ /* Write the pre-amble. */ idx_preamble(file, toc_flag, mst_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, mst_flag); item_count++; node_2 = node_1->subhead; while (node_2 != 0) { idx_write (node_2, "\\subitem", file, mst_flag); subitem_count++; node_3 = node_2->subhead; while (node_3 != 0) { idx_write (node_3, "\\subsubitem", file, mst_flag); subsubitem_count++; node_3 = node_3->link; } node_2 = node_2->link; } node_1 = node_1->link; } /* Report the total counts of entries. */ (void)printf("\nIndex processing statistics:\n"); (void)printf(" Items: %d\n", item_count); (void)printf(" Subitems: %d\n", subitem_count); (void)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: * non * * 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, mst_flag) FILE *file; int toc_flag; int mst_flag; { /* * Local Declarations */ /* * Module Body * * Define the \indexhead macro: * \indexhead{BEFORESKIP}{AFTERSKIP}{HEADING} == * BEGIN * \par * IF @nobreak = TRUE * THEN \everypar == null * ELSE \addpenalty{\@secpanalty} * \addvspace{BEFORESKIP} * FI * \begingroup * \sl HEADING\par * \endgroup * \@xsect{AFTERSKIP} * END */ if (mst_flag) { (void)fprintf(file,"\\def\\indexname{\\masterindexname}\n"); } (void)fprintf (file, "\\makeatletter\n"); (void)fprintf (file, "\\def\\indexhead#1#2#3{\\par\\if@nobreak \\everypar{}\\else\n"); (void)fprintf (file, " \\addpenalty{\\@secpenalty}\\addvspace{#1}\\fi\n"); (void)fprintf (file, " \\begingroup \\large\\bf \\hfil #3 \\hfil\\par \\endgroup\n"); (void)fprintf (file, " \\@xsect{#2}}\n"); (void)fprintf (file, "\\makeatother\n"); /* * Define the \indexindent macro: * \indexindent == * \par \hangindent 50pt \hspace*{40pt} */ (void)fprintf (file, "\\def\\indexindent{\\par\\hangindent 50pt\\hspace*{40pt}}\n"); /* Start the index */ (void)fprintf (file, "\\begin{theindex} \\raggedright\n"); if (toc_flag == IDX_K_NONE) { if (mst_flag) { (void)fprintf(file, "\\typeout{Master Index.}\n"); return; } return; } if (toc_flag == IDX_K_ARTICLE) { if (mst_flag) { (void)fprintf (file,"\\addcontentsline{toc}{section}{\\masterindexname}\\typeout{Master Index.}\n"); } else { (void)fprintf (file,"\\addcontentsline{toc}{section}{\\indexname}\\typeout{Index.}\n"); } } if (toc_flag == IDX_K_REPORT) { if (mst_flag) (void)fprintf (file,"\\addcontentsline{toc}{chapter}{\\masterindexname}\\typeout{Index.}\n"); else (void)fprintf (file,"\\addcontentsline{toc}{chapter}{\\indexname}\\typeout{Index.}\n"); } (void)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 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 */ if ((strlen(node->spell)) > 0) current_char = node->spell[0]; if (isalpha(current_char) == 0) current_char = ' '; if ((current_char > 'a') && (current_char < 'z')) current_char -= 32; if (*test_char != current_char) { if (current_char == ' ') (void)fprintf (file, "\\indexhead{2em}{1em}{--- \\symbolsname ---}\n"); else (void)fprintf (file, "\\indexhead{2em}{1em}{--- %c ---}\n", current_char); *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, mst_flag) * * 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. * * mst_flag -> flag indicates if a master index is being generated. * * 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. If there is at least one cross reference specified, * 1. Print the "see" or "see also" line. * 2. For all cross references, * a. Print them. * D. 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 * IDX_K_FOLLOW - ff follows the page number */ /* * Function Idx_Write - Code Section */ void idx_write (node, intro_str, file, mst_flag) TREE_PTR node; char *intro_str; FILE *file; int mst_flag; { /* * Local Declarations */ char string[256]; int length; PGNODE_PTR pgnode; int highlight; char *old_vol; /* * Module Body */ length = strlen(intro_str) + strlen(node->item) + 1; (void)sprintf(string,"%s{%s",intro_str,node->item); if (node->pghead != 0) { idx_build_range(node); pgnode = node->pghead; if (mst_flag) { (void)sprintf(&string[length], "}\\indexindent{$\\bullet$ {\\sl %s}, ", pgnode->vol); length += strlen(pgnode->vol) + strlen("}\\indexindent{$\\bullet$ {\\sl }, "); old_vol = pgnode->vol; } else { (void)sprintf (&string[length], ", "); length += 2; } highlight = pgnode->highlight; switch (highlight) { case IDX_K_UNDERLINE : (void)sprintf (&string[length], "\\mbox{\\rm\\underline{%s}}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\rm\\underline{}}"); break; case IDX_K_ITALIC : (void)sprintf (&string[length], "\\mbox{\\em %s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\em }"); break; case IDX_K_BOLD : (void)sprintf (&string[length], "\\mbox{\\bf %s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\bf }"); break; case IDX_K_FOLLOW : (void)sprintf (&string[length], "\\mbox{\\rm %s\\sf ff}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\rm \\sf ff}"); break; default : (void)sprintf (&string[length], "\\mbox{\\rm %s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\rm }"); break; } while ((pgnode = pgnode->link) != 0) { if (length > 62) { (void)fprintf (file, "%s%%\n", string); length = 0; } if (mst_flag) { if ((strcmp(old_vol,pgnode->vol)) != 0) { (void)sprintf (&string[length], "}\\indexindent{$\\bullet$ {\\sl %s} ", pgnode->vol); length += strlen(pgnode->vol) + strlen("}\\indexindent{$\\bullet$ {\\sl } "); old_vol = pgnode->vol; } else { (void)sprintf (&string[length], ", "); length += 2; } } else { (void)sprintf (&string[length], ", "); length += 2; } highlight = pgnode->highlight; switch (highlight) { case IDX_K_UNDERLINE : (void)sprintf (&string[length], "\\mbox{\\rm\\underline{%s}}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\rm\\underline{}}"); break; case IDX_K_ITALIC : (void)sprintf (&string[length], "\\mbox{\\em %s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\em "); break; case IDX_K_BOLD : (void)sprintf(&string[length], "\\mbox{\\bf %s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\bf "); break; case IDX_K_FOLLOW : (void)sprintf(&string[length], "\\mbox{\\rm %s\\sf ff}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\rm \\sf ff}"); break; default : (void)sprintf (&string[length], "\\mbox{\\rm %s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("\\mbox{\\rm }"); break; } } } if (node->seehead != 0) { pgnode = node->seehead; if (mst_flag) { if (node->pghead == 0) (void)fprintf (file, "%s}\n\\indexindent{\\em \\seename", string); else (void)fprintf (file, "%s}\n\\indexindent{\\em \\alsoname", string); } else { if (node->pghead == 0) (void)fprintf (file, "%s, {\\em \\seename}\n", string); else (void)fprintf (file, "%s; {\\em \\alsoname}\n", string); } length = 0; while (pgnode != 0) { if (length > 62) { (void)fprintf (file, "%s%%\n", string); length = 0; } highlight = pgnode->highlight; switch(highlight) { case IDX_K_UNDERLINE : (void)sprintf (&string[length], "}\\indexindent{\\ $\\bullet$ \\rm\\underline{%s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("}\\indexindent{\\ $\\bullet$ \\rm\\underline{}"); break; case IDX_K_ITALIC : (void)sprintf (&string[length], "}\\indexindent{\\ $\\bullet$ {\\em %s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("}\\indexindent{\\ $\\bullet$ {\\em }"); break; case IDX_K_BOLD : (void)sprintf (&string[length], "}\\indexindent{\\ $\\bullet$ {\\bf %s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("}\\indexindent{\\ $\\bullet$ {\\bf }"); break; default : (void)sprintf (&string[length], "}\\indexindent{\\ $\\bullet$ {\\rm %s}", pgnode->page_dsc); length += strlen(pgnode->page_dsc) + strlen("}\\indexindent{\\ $\\bullet$ {\\rm }"); break; } pgnode=pgnode->link; } } (void)fprintf (file, "%s}\n", string); } /* * Function Idx_PostAmble - Documentation Sectionm * * 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:r * 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 Declarationst */ /* * Module Body */ (void)fprintf (file, "\\end{theindex}\n"); }