/* * File: so_split.c * Date: 2004-02-21 * * This program is used to split the Open/Star Office HTML file * into seperate files at the H1 level and H2 for a specific * section (Split_Section_Title). * * Copyright 2001,2002,2003,2004 David Eastcott <david@eastcott.net> * Released under terms of GPL * */ #include "stdio.h" #include "string.h" #include "stdlib.h" #include "ctype.h" #include "so_split.h" // Local Global Data static char Document_Title[TITLE_NAME_SIZE+2]; static char Target_Dir[FILE_NAME_SIZE+2]; static char next_line_buffer[BUFFER_SIZE+1]; // static void add_end_file( FILE *pout ) { fputs( "</BODY>\n", pout ); fputs( "</HTML>\n", pout ); } // static void add_end_leader( FILE *pout, SECTION_INFO *section_info ) { char **html; // raw HTML int length; html = end_leader; length = strlen ( Target_Dir ); while ( *html != (char *)NULL ) { if ( (strcmp( *html, "PREV" )) == 0 ) { // insert previous document reference if any if ( section_info->prvs != NULL ) { fputs( HREF_TAG, pout ); fputs( §ion_info->prvs->filename[length], pout ); fputs( HREF_TAG_END, pout ); fputs( "Prev", pout ); fputs( ANCHOR_TAG_END, pout ); fputs( TABLE_CELL_TAG_END, pout ); } else { fputs( "Prev", pout ); fputs( TABLE_CELL_TAG_END, pout ); } } else if ( (strcmp( *html, "NEXT" )) == 0 ) { // insert next document reference if any if ( section_info->pfwd != NULL ) { fputs( HREF_TAG, pout ); fputs( §ion_info->pfwd->filename[length], pout ); fputs( HREF_TAG_END, pout ); fputs( "Next", pout ); fputs( ANCHOR_TAG_END, pout ); fputs( TABLE_CELL_TAG_END, pout ); } // else // fputs( "Next</td>", pout ); } else if ( (strcmp( *html, "PREVIOUS_SECTION" )) == 0 ) { // insert previous document title if ( section_info->prvs != NULL ) { if( section_info->prvs->title[0] != 0 ) fputs( section_info->prvs->title, pout ); } } else if ( (strcmp( *html, "NEXT_SECTION" )) == 0 ) { // insert next document title if ( section_info->pfwd != NULL ) { if( section_info->pfwd->title[0] != 0 ) fputs( section_info->pfwd->title, pout ); } } else fputs( *html, pout ); // next string html++; }; } // static void add_head_file( FILE *pout ) { FILE *pin; char line_buffer[BUFFER_SIZE+1]; // working line buffer char filename[FILE_NAME_SIZE+1]; strcpy( filename, Target_Dir ); strcat( filename, HEAD_FILE ); pin = fopen( filename, "r" ); while( (fgets( line_buffer, BUFFER_SIZE, pin )) != NULL ) { fputs( line_buffer, pout ); }; // clean up fclose ( pin ); } // static void add_head_leader( FILE *pout, SECTION_INFO *section_info ) { char **html; // raw HTML int length; html = head_leader; length = strlen ( Target_Dir ); while ( *html != (char *)NULL ) { if ( (strcmp( *html, "TITLE" )) == 0 ) { // insert document title if( Document_Title[0] != 0 ) fputs( Document_Title, pout ); } else if ( (strcmp( *html, "PREV" )) == 0 ) { // insert previous document reference if any if ( section_info->prvs != NULL ) { fputs( HREF_TAG, pout ); fputs( §ion_info->prvs->filename[length], pout ); fputs( HREF_TAG_END, pout ); fputs( "Prev", pout ); fputs( ANCHOR_TAG_END, pout ); fputs( TABLE_CELL_TAG_END, pout ); } else { fputs( "Prev", pout ); fputs( TABLE_CELL_TAG_END, pout ); } } else if ( (strcmp( *html, "NEXT" )) == 0 ) { // insert next document reference if any if ( section_info->pfwd != NULL ) { fputs( HREF_TAG, pout ); fputs( §ion_info->pfwd->filename[length], pout ); fputs( HREF_TAG_END, pout ); fputs( "Next", pout ); fputs( ANCHOR_TAG_END, pout ); fputs( TABLE_CELL_TAG_END, pout ); } // else // fputs( "Next</td>", pout ); } else fputs( *html, pout ); // next string html++; }; } // static void add_to_queue ( SECTION_INFO **section_info_queue, SECTION_INFO *section_info ) { SECTION_INFO *pnext; // if queue is empty, put item at head if( *section_info_queue == NULL ) { *section_info_queue = section_info; section_info->pfwd = NULL; section_info->prvs = NULL; } else { // move down the chain till we get to last item for( pnext = *section_info_queue; pnext->pfwd != NULL; pnext = pnext->pfwd ) ; // make new item as the last in the chain pnext->pfwd = section_info; // make sure the new item does not point to junk section_info->pfwd = NULL; section_info->prvs = pnext; } } // static void add_to_symbols( SYMBOL_TABLE *symbol, SYMBOL_QUEUE *symbol_queue ) { if ( symbol_queue->head == NULL ) { // insert symbol at head of queue symbol_queue->head = symbol; symbol_queue->tail = symbol; symbol->pfwd = NULL; } else { // add new symbol to tail, updating fwd pntr of old tail symbol_queue->tail->pfwd = symbol; symbol_queue->tail = symbol; symbol->pfwd = NULL; } } // static void adjust_href( char *line_buffer, SECTION_INFO *section_info, SYMBOL_QUEUE *symbol_queue ) { char *position, *sposition; char *fposition; char buffer[TITLE_NAME_SIZE+2]; int length, fragment; SYMBOL_TABLE *symbol; // first locate the reference point position = strstr( line_buffer, HREF_TAG ); position += strlen ( HREF_TAG ); // check to see if this is TOC reference if ( *position == '\"' ) { // this means we have to find the tag based on the name text #ifdef DEBUG printf ( "\nSearching for TOC Reference in >>%s<<", line_buffer ); #endif // move to Text area sposition = position + 2; // get copy of the text string length = strcspn( sposition, "<" ); strncpy( buffer, sposition, length ); buffer[length] = 0; // locate the string in the available symbols for( symbol = symbol_queue->head; symbol != NULL; symbol = symbol->pfwd ) { if ( (strcmp ( symbol->name_text, buffer )) == 0 ) break; // we have a match } // on error, report and exit if( symbol == NULL ) { printf ( "Error: unable to locate symbol for %s\n", buffer ); return; } // make room for tag, and isert it with leading # length = strlen ( position ); my_memmove( position+(strlen(symbol->name) + 1), position, length ); *position = '#'; strncpy ( position+1, symbol->name, strlen( symbol->name ) ); } // exit now if href is not a relative type if ( *position != '#' ) return; // // SO 6.0Beta Bug Fix // if ( (strncmp ( position+1, "http:", 5)) == 0 || // (strncmp ( position+1, "ftp:", 4)) == 0 ) // return; #ifdef DEBUG printf ( "\nSearching for Relative Reference in >>%s<<", line_buffer ); #endif // get copy of the tag string length = strcspn( position, "\"" ); strncpy( buffer, position+1, length-1 ); buffer[length-1] = 0; // locate the string in the available symbols for( symbol = symbol_queue->head; symbol != NULL; symbol = symbol->pfwd ) { if ( (strcmp ( symbol->name, buffer )) == 0 ) break; // we have a match } // on error, report and exit if( symbol == NULL ) { printf ( "Error: unable to locate symbol for %s\n", buffer ); return; } // if the symbols section is the same as the one we are in now, just leave it relative if ( symbol->section_info == section_info ) return; // make room in buffer for filename and insert filename ahead of tag fposition = &symbol->section_info->filename[0] + strlen( Target_Dir ); fragment = strlen( position ); my_memmove( (position+(strlen ( fposition ))), position, fragment ); strncpy( position, fposition, (strlen(fposition)) ); } // static void build_symbol_table( char *line_buffer, SECTION_INFO **section_info_queue, SYMBOL_QUEUE *symbol_queue ) { SECTION_INFO *section_info; FILE *pin; char *position; int length; SYMBOL_TABLE *symbol; // go thru each section and extract Anchor symbols for( section_info = *section_info_queue; section_info != NULL; section_info = section_info->pfwd ) { // open file for reading pin = fopen ( section_info->section_id_name, "r" ); // read lines from file while( (fgets( line_buffer, BUFFER_SIZE, pin )) != NULL ) { // keep reading till we find the start of the Anchnor if ( (position = strstr( line_buffer, ANCHOR_TAG_NAME )) == NULL ) continue; // tag found, create structure to hold data symbol = calloc( 1, sizeof(SYMBOL_TABLE) ); // load structure symbol->section_info = section_info; // transfer anchor attribute position += strlen( ANCHOR_TAG_NAME ); get_html_field( pin, NULL, line_buffer, position, symbol->name, ANCHOR_TAG_NAME_END ); // now the text position = strstr( position, ANCHOR_TAG_END ); position += strlen ( ANCHOR_TAG_END ); get_html_field( pin, NULL, line_buffer, position, symbol->name_text, HEADER_TAG_END_OPEN ); // add it to the symbol table add_to_symbols ( symbol, symbol_queue ); #ifdef DEBUG printf( "Anch: %s, Text: %s, File: %s\n", symbol->name, symbol->name_text, symbol->section_info->filename ); #endif } // clean up fclose ( pin ); } } // static void get_head( FILE *pin, char *line_buffer ) { FILE *pout; char *position, **html; int title_size; char filename[FILE_NAME_SIZE+1]; strcpy( filename, Target_Dir ); strcat( filename, HEAD_FILE ); pout = fopen( filename, "w" ); // read lines from source until </HEAD> encountered, // transfering them to the HEAD_FILE as we go while( (fgets( line_buffer, BUFFER_SIZE, pin )) != NULL ) { // extract document title if( (position = strstr( line_buffer, TITLE_TAG )) ) { // end of where we want position += strlen( TITLE_TAG ); title_size = strcspn( position, "<" ); strncpy( Document_Title, position, (title_size < TITLE_NAME_SIZE) ? title_size : TITLE_NAME_SIZE ); } if( (position = strstr( line_buffer, HEAD_TAG_END )) ) { // end of where we want // write last line and exit fputs( line_buffer, pout ); break; } // write line fputs( line_buffer, pout ); }; // insert basic head stuff for( html = head_lines; *html != NULL; html++ ) fputs( *html, pout ); // clean up fclose( pout ); } // static void get_html_field( FILE *pin, FILE *pout, char *line_buffer, char *position, char *token_buffer, char *end_tag ) { char *tposition; char end[2]; int length; // preset for null token *token_buffer = 0; end[0] = *end_tag; end[1] = 0; // see if the end tag is on this line if ( (tposition = strstr (position, end_tag )) != NULL ) { // YES, transfer to buffer and mark end with null position = move_past_tokens( position ); length = strcspn( position, end ); // find length of text strncpy( token_buffer, position, length ); token_buffer[length] = 0; } else { // Nope, hard times now position = move_past_tokens( position ); strcpy( token_buffer, position ); // get first part strip_tail_white_space( token_buffer ); // add a SPACE because the text crossed line boundaries if ( (strlen ( token_buffer )) > 0 ) strcat ( token_buffer, " " ); // write out current line if ( pout != NULL ) fputs( line_buffer, pout ); // get next line fgets( line_buffer, BUFFER_SIZE, pin ); // append text up to end marker position = move_past_tokens( line_buffer ); length = strcspn( position, end ); strncat ( token_buffer, position, length ); strip_tail_white_space( token_buffer ); } } // static void get_section_title( char *line_buffer, SECTION_INFO *section_info, char *end_tag, FILE *pin, FILE *pout ) { char *position, *tposition; int length; // move to the begining of the name // <H1 STYLE="page-break-before: always"><A NAME="Introduction"></A>Introduction</H1> <-- if we're lucky position = strstr( line_buffer, ANCHOR_TAG_END ); position += strlen ( ANCHOR_TAG_END ); get_html_field ( pin, pout, line_buffer, position, section_info->title, end_tag ); } // static void get_title_section( FILE *pin, char *line_buffer, SECTION_INFO **section_info_queue ) { FILE *pout; char *position; SECTION_INFO *section_info; // create section for the title page section_info = calloc( 1, sizeof(SECTION_INFO) ); section_info->section_id = TITLE_SECTION_ID; sprintf( section_info->section_id_name, "%s%d.tmp.html", Target_Dir, section_info->section_id ); strcpy ( section_info->filename, Target_Dir ); strcat ( section_info->filename, TITLE_FILE ); strcpy ( section_info->title, "Title" ); // add the new section to chain add_to_queue( section_info_queue, section_info ); // open file for output pout = fopen( section_info->section_id_name, "w" ); // read lines from source starting at current position until <DIV> encountered, // transfering them to the temp Title file as we go // seek to next line after <BODY> while( (fgets( line_buffer, BUFFER_SIZE, pin )) != NULL ) { if( (position = strstr( line_buffer, BODY_TAG_OPEN )) ) break; }; // now transfer the stuff we want while( (fgets( line_buffer, BUFFER_SIZE, pin )) != NULL ) { // Stop when we get to the TOC stuff if( (position = strstr( line_buffer, TOC_DIV_TAG )) ) break; // write line fputs( line_buffer, pout ); }; // clean up fclose( pout ); } // static void get_toc_section( FILE *pin, char *line_buffer, SECTION_INFO **section_info_queue ) { FILE *pout; int iteration; char *position, *tposition; SECTION_INFO *section_info; int offset, toc_error; toc_error = FALSE; // create section for the Table of Contents page section_info = calloc( 1, sizeof(SECTION_INFO) ); section_info->section_id = TOC_SECTION_ID; sprintf( section_info->section_id_name, "%s%d.tmp.html", Target_Dir, section_info->section_id ); strcpy ( section_info->filename, Target_Dir ); strcat ( section_info->filename, TOC_FILE ); strcpy ( section_info->title, "Table of Contents" ); // add the new section to chain add_to_queue( section_info_queue, section_info ); // open file for output pout = fopen( section_info->section_id_name, "w" ); // then the opening <DIV line that was picked up by get_title_section for us fputs( line_buffer, pout ); // now read lines from source starting at current position until <DIV> encountered, // transfering them to the temp TOC file as we go iteration = 1; while( (fgets( line_buffer, BUFFER_SIZE, pin )) != NULL ) { // Watch out for the 2nd one because a title for TOC was entered if( (strstr( line_buffer, TOC_DIV_TAG )) ) iteration += 1; // stop reading when 2nd occurance of </DIV seen if( (strstr( line_buffer, DIV_TAG_END_OPEN )) ) { iteration -= 1; // second time we're done if ( iteration == 0 ) { fputs( line_buffer, pout ); break; } } // locate the lines which are the actual table of contents // and strip page number, and add empty HREF for later // // this is VERY SO 6 beta specific if ( iteration == 1 ) { // locate line with desired text on it if ( (strstr( line_buffer, PARA_TAG_OPEN )) != NULL ) { // now see if we have all we need if ( (position = strstr( line_buffer, PARA_TAG_END )) == NULL ) { // nope - magic time do { // get next line fgets( next_line_buffer, BUFFER_SIZE, pin ); if ( (strlen ( line_buffer ) + strlen ( next_line_buffer )) >= BUFFER_SIZE ) { printf ( "Error: Paragraph size too large in TOC\n" ); toc_error = TRUE; break; } // first strip whitespace and EOL from previous line position = &line_buffer[(strlen(line_buffer))-1]; *position-- = '\0'; while (position != line_buffer && isspace(*position) ) *position-- = '\0'; // now move past all whitespace at front of current line tposition = next_line_buffer; while ( isspace( *tposition ) ) tposition++; if ( !(*tposition == '<' || *position == '>') ) { *++position = ' '; *++position = '\0'; } strcat( position, tposition ); // merge the lines into one till we find the end of tag #ifdef DEBUG1 printf ( "\nTOC BEG:\n%s\n:END", line_buffer ); #endif } while ( (strstr ( next_line_buffer, PARA_TAG_END )) == NULL ); if ( toc_error ) { // stop processing on a line error toc_error = FALSE; continue; } // now reset as though it was all one line position = strstr( line_buffer, PARA_TAG_END ); } // remove page number from line tposition = position = move_past_token ( BACKWARD, position ); // get to page number position++; while ( isdigit( *tposition ) ) tposition--; // move past number while ( isspace( *tposition ) ) tposition--; // move to end of actual entry tposition++; strcpy ( tposition, position ); // now add tail stuff before paragraph close my_memmove ( tposition+(strlen(ANCHOR_TAG_END)), tposition, strlen( tposition )); strncpy( tposition, ANCHOR_TAG_END, strlen( ANCHOR_TAG_END ) ); // now insert dummy HREF for later tposition = move_past_token ( FORWARD, line_buffer ); // move to real text my_memmove( tposition+(strlen(HREF_TAG)+(strlen(HREF_TAG_END))), tposition, (strlen (tposition)) ); strncpy ( tposition, HREF_TAG, strlen (HREF_TAG) ); // add lead stuff strncpy ( tposition+strlen(HREF_TAG), HREF_TAG_END, strlen( HREF_TAG_END) ); } } // write line fputs( line_buffer, pout ); }; // clean up fclose( pout ); } // static void make_adjusted_html( char *line_buffer, SECTION_INFO **section_info_queue, SYMBOL_QUEUE *symbol_queue ) { FILE *pin, *pout; SECTION_INFO *section_info; int toc_found, toc_count, toc_error; char *position, *tposition, **html; toc_found = FALSE; toc_count = 0; toc_error = FALSE; // now convert all temp sections to final html files for( section_info = *section_info_queue; section_info != NULL; section_info = section_info->pfwd ) { pout = fopen( section_info->filename, "w" ); pin = fopen( section_info->section_id_name, "r" ); // transfer all body stuff now, adjust hrefs as we go while( (fgets( line_buffer, BUFFER_SIZE, pin )) != NULL ) { if( (strstr( line_buffer, TOC_DIV_TAG )) != NULL ) { toc_found = TRUE; toc_count += 1; } if ( toc_found == TRUE ) { if( (strstr( line_buffer, DIV_TAG_END )) != NULL ) toc_count -= 1; } #ifdef DEBUG1 printf ( "\nF=%d, C=%d, >>%s<<\n", toc_found, toc_count, line_buffer ); #endif if ( toc_found && toc_count == 1 ) { // adjust TOC text line with a dummy href // locate line with desired text on it if ( (strstr( line_buffer, PARA_TAG_OPEN )) != NULL ) { // now see if we have all we need if ( (position = strstr( line_buffer, PARA_TAG_END )) == NULL ) { // nope - magic time do { // get next line fgets( next_line_buffer, BUFFER_SIZE, pin ); if ( (strlen ( line_buffer ) + strlen ( next_line_buffer )) >= BUFFER_SIZE ) { printf ( "Error: Paragraph size too large in TOC\n" ); toc_error = TRUE; break; } // first strip whitespace and EOL from previous line position = &line_buffer[(strlen(line_buffer))-1]; *position-- = '\0'; while (position != line_buffer && isspace(*position) ) *position-- = '\0'; // now move past all whitespace at front of current line tposition = next_line_buffer; while ( isspace( *tposition ) ) tposition++; if ( !(*tposition == '<' || *position == '>') ) { *++position = ' '; *++position = '\0'; } strcat( position, tposition ); // merge the lines into one till we find the end of tag #ifdef DEBUG1 printf ( "\nHTML BEG:\n%s\n:END", line_buffer ); printf ( "\ntoc_found %d, toc_count %d\n", toc_found, toc_count ); #endif } while ( (strstr( next_line_buffer, PARA_TAG_END )) == NULL ); if ( toc_error ) { // stop processing line on error toc_error = FALSE; continue; } // now reset as though it was all one line position = strstr( line_buffer, PARA_TAG_END ); } // remove page number from line tposition = position = move_past_token ( BACKWARD, position ); // get to page number position++; while ( isdigit( *tposition ) ) tposition--; // move past number while ( isspace( *tposition ) ) tposition--; // move to end of actual entry tposition++; strcpy ( tposition, position ); // now add tail stuff before paragraph close my_memmove ( tposition+(strlen(ANCHOR_TAG_END)), tposition, strlen( tposition )); strncpy( tposition, ANCHOR_TAG_END, strlen( ANCHOR_TAG_END ) ); // now insert dummy HREF for later tposition = move_past_token ( FORWARD, line_buffer ); // move to real text my_memmove( tposition+(strlen(HREF_TAG)+(strlen(HREF_TAG_END))), tposition, (strlen (tposition)) ); strncpy ( tposition, HREF_TAG, strlen (HREF_TAG) ); // add lead stuff strncpy ( tposition+strlen(HREF_TAG), HREF_TAG_END, strlen( HREF_TAG_END) ); } } // replace the <BODY tag with our own, so that we get the attributes too if ( (strstr( line_buffer, BODY_TAG_OPEN )) != NULL ) { for( html = head_lines; *html != NULL; html++ ) fputs( *html, pout ); continue; } // adjust all href so that they point to the correct files if ( (strstr( line_buffer, HREF_TAG )) != NULL ) adjust_href( line_buffer, section_info, symbol_queue ); // write line fputs( line_buffer, pout ); }; // close this one and remove temp fclose( pin ); fclose( pout ); }; } // static void make_html( char *line_buffer, SECTION_INFO **section_info_queue, SYMBOL_QUEUE *symbol_queue ) { FILE *pin, *pout; SECTION_INFO *section_info; // now convert all temp sections to final html files for( section_info = *section_info_queue; section_info != NULL; section_info = section_info->pfwd ) { pout = fopen( section_info->filename, "w" ); pin = fopen( section_info->section_id_name, "r" ); if( section_info->section_id == TITLE_SECTION_ID ) { // process title page differnent than others add_head_file( pout ); } else { add_head_file( pout ); add_head_leader( pout, section_info ); } // transfer all boady stuff now, adjust hrefs as we go while( (fgets( line_buffer, BUFFER_SIZE, pin )) != NULL ) { // adjust all href so that they point to the correct files if ( (strstr( line_buffer, HREF_TAG )) != NULL ) adjust_href( line_buffer, section_info, symbol_queue ); // write line fputs( line_buffer, pout ); }; // closing remarks if ( section_info->section_id != TITLE_SECTION_ID ) add_end_leader( pout, section_info ); add_end_file( pout ); // close this one and remove temp fclose( pin ); fclose( pout ); unlink( section_info->section_id_name ); } } // static char *move_past_tokens( char *position ) { // if the first character is not a token start, we're done if ( *position != '<' ) return ( position ); else { // as long as there are characters to check, look for close of token while ( *position != 0 ) { // exit if end of token, but watch for second in a row if ( *position == '>' && *(position+1) != '<' ) return ( ++position ); position++; } return ( position ); } } // static char *move_past_token( int direction, char *buffer ) { if ( direction == FORWARD ) { while ( TRUE ) { while ( isspace( *buffer ) ) buffer++; // skip any white space if ( *buffer != '<' ) break; // no token start, so must be done while ( *buffer != '>' ) buffer++; buffer++; // move to next charc after token stop }; } else // must be BACKWARDS { while ( TRUE ) { if ( *buffer == '<' ) buffer--; // back up if token start while ( isspace( *buffer ) ) buffer--; // skip any white space if ( *buffer != '>' ) break; // done, if this is not the end on another token while ( *buffer != '<' ) buffer--; // move to start of token }; } } // static void my_memmove( char *dest, char *src, int count ) { // adjust src and dest to end of strings dest += count; src += count; count += 1; // to account for the null while( count-- ) *dest-- = *src--; } // static void split_source( FILE *pin, char *line_buffer, SECTION_INFO **section_info_queue ) { int section_id, sub_section_id, name_len; int enable_H2; char *position, *last_position; FILE *pout; SECTION_INFO *section_info; // make sure we are at the beginning of the source file rewind( pin ); pout = NULL; section_id = BODY_SECTION_ID; sub_section_id = 0; enable_H2 = FALSE; // run through the source file and create temp section files as we go // that contain the "body" of each <H1 tag // target file names based on the <H1 tag's title while( (fgets( line_buffer, BUFFER_SIZE, pin )) != NULL ) { // stop scanning lines if end of BODY seen if( (position = strstr( line_buffer, BODY_TAG_END )) != NULL ) { // if there is an open file, do end processing if ( pout != NULL ) { fclose ( pout ); pout = NULL; // set for next section id section_id += 1; } // go get next line continue; } // we have a line, lets see if its the start of a desired definition if( (position = strstr( line_buffer, HEADER_1_TAG )) == line_buffer || (enable_H2 && ((position = strstr( line_buffer, HEADER_2_TAG )) == line_buffer)) ) { // extract section title, and make it the section filename // if there is an open file, do end processing if ( pout != NULL ) { fclose ( pout ); pout = NULL; // set for next section id if ( (position = strstr( line_buffer, HEADER_1_TAG )) == line_buffer ) { // move to next section id and stop splitting at H2 section_id += 1; enable_H2 = FALSE; } else sub_section_id +=1; } // get and initialize a section block with the name section_info = calloc( 1, sizeof(SECTION_INFO) ); section_info->section_id = section_id; if ( enable_H2 ) { // for H2, extend names to include sub-section ID section_info->sub_section_id = sub_section_id; sprintf( section_info->section_id_name, "%s%d-%d.tmp.html", Target_Dir, section_info->section_id, section_info->sub_section_id ); sprintf( section_info->filename, "%ssection%d-%d.html", Target_Dir, section_info->section_id-BODY_SECTION_ID+1, section_info->sub_section_id ); } else { // H1, names only include section ID sprintf( section_info->section_id_name, "%s%d.tmp.html", Target_Dir, section_info->section_id ); sprintf( section_info->filename, "%ssection%d.html", Target_Dir, section_info->section_id-BODY_SECTION_ID+1 ); } // remove old file, if it exists unlink ( section_info->filename ); // create and initialize the new file pout = fopen( section_info->section_id_name, "w" ); // get section title, and put in structure get_section_title( line_buffer, section_info, (enable_H2 ? HEADER_2_TAG_END : HEADER_1_TAG_END), pin, pout ); // add the new section to chain add_to_queue( section_info_queue, section_info ); // then check to see if this section is the one that we are to split at the H2 level if( (strcmp( section_info->title, Split_Section_Title )) == 0 ) enable_H2 = TRUE; #ifdef DEBUG printf ( "Section %d = %s\n", section_info->section_id, section_info->filename ); printf( "Title: <%s> Look:<%s>\n\n", section_info->title, Split_Section_Title ); #endif } // output lines if we have skipped all the intro stuff if ( pout != NULL ) fputs( line_buffer, pout ); }; // if there is an open files, do end processing if ( pout != NULL ) fclose ( pout ); } // static void strip_tail_white_space( char *token_buffer ) { char *end; // get end of buffer end = &token_buffer[(strlen(token_buffer))-1]; // moving backward, strip white space from end of line while ( isspace( *end ) ) { *end = 0; if ( end == token_buffer ) break; else end--; } } // // Local Private Data static SECTION_INFO *section_info_queue = NULL; // section structure chain origin static SYMBOL_QUEUE symbol_queue = { NULL, NULL }; // symbol table chain static char line_buffer[BUFFER_SIZE+1]; // working line buffer static char filename[FILE_NAME_SIZE+1]; // temp filename buffer static int split_main( int argc, char *argv[] ) { FILE *pin; // set up directory leader if ( argc > 3 ) { strncpy ( Target_Dir, argv[3], FILE_NAME_SIZE ); // make sure path has terminating '/' if ( strlen ( Target_Dir ) > 1 ) { if ( Target_Dir[(strlen(Target_Dir)-1)] != '/' ) strcat( Target_Dir, "/" ); } } else // use current directory for files Target_Dir[0] = 0; // open source file for reading if ( !(pin = fopen ( argv[2], "r" )) ) { printf ( "Error: Unable to open source file: %s\n", argv[2] ); return ( 1 ); } // clear document title memset ( Document_Title, 0, sizeof(Document_Title) ); // First, extract up to </HEAD> into a temp file // picking up document title as we go get_head ( pin, line_buffer ); // Then get the TITLE data into a seperate file get_title_section ( pin, line_buffer, §ion_info_queue ); // Then extract the <DIV ... /DIV> since it contains the Table of contents get_toc_section ( pin, line_buffer, §ion_info_queue ); // Next run thru the source file and create independant files // which are delineated by the <H1 tag split_source ( pin, line_buffer, §ion_info_queue ); // Next, build Anchor/Href symbol table build_symbol_table( line_buffer, §ion_info_queue, &symbol_queue ); // Finally create file HTML files and add some beautifying code // that simplifies navigating about make_html ( line_buffer, §ion_info_queue, &symbol_queue ); // all done, close up shop fclose ( pin ); strcpy ( filename, Target_Dir ); strcat ( filename, HEAD_FILE ); unlink ( filename ); return ( 0 ); } static int toc_main( int argc, char *argv[] ) { FILE *pin; SECTION_INFO *section_info; // set up directory leader if ( argc > 3 ) { strncpy ( Target_Dir, argv[3], FILE_NAME_SIZE ); // make sure path has terminating '/' if ( strlen ( Target_Dir ) > 1 ) { if ( Target_Dir[(strlen(Target_Dir)-1)] != '/' ) strcat( Target_Dir, "/" ); } } else // use current directory for files Target_Dir[0] = 0; // open source file for reading if ( !(pin = fopen ( argv[2], "r" )) ) { printf ( "Error: Unable to open source file: %s\n", argv[2] ); return ( 1 ); } // close it for now fclose ( pin ); // First, build Anchor/Href symbol table // create section for the Table of Contents page section_info = calloc( 1, sizeof(SECTION_INFO) ); section_info->section_id = TOC_SECTION_ID; sprintf( section_info->section_id_name, "%s", argv[2] ); strcpy ( section_info->filename, Target_Dir ); strcat ( section_info->filename, "new." ); strcat ( section_info->filename, argv[2] ); strcpy ( section_info->title, "Table of Contents" ); // add the new section to chain add_to_queue( §ion_info_queue, section_info ); // now build up symbol table build_symbol_table( line_buffer, §ion_info_queue, &symbol_queue ); // Finally create file HTML files and add some beautifying code // that simplifies navigating about make_adjusted_html ( line_buffer, §ion_info_queue, &symbol_queue ); // all done, close up shop return ( 0 ); } int main( int argc, char *argv[] ) { // Check that we have some parameters if ( argc < 3 ) { printf ( usage ); return ( 1 ); } // see which mode wanted if ( (strncmp( argv[1], "-t", 2 )) == 0 ) { //wants to adjust TOC only return ( toc_main( argc, argv ) ); } else if ( (strncmp( argv[1], "-s", 2 )) == 0 ) { // wants to split the file up return ( split_main( argc, argv ) ); } else { // report error and exit printf ( usage ); return ( 1 ); } }