int ipf_trans_line( /*****************/ section_def *section, int alloc_size ) { char *ptr; char *end; int ch; char *ctx_name; char *ctx_text; char buf[500]; int font_idx; int line_len; bool term_fix; int ch_len; int len; char *file_name; /* check for special column 0 stuff first */ ptr = Line_buf; ch = *(unsigned char *)ptr; ch_len = 0; line_len = 0; switch( ch ) { case CH_TABXMP: if( *skip_blank( ptr + 1 ) == '\0' ) { Tab_xmp = FALSE; trans_add_str( ":exmp.\n", section, &alloc_size ); Blank_line_sfx = FALSE; // remove following blanks } else { read_tabs( ptr + 1 ); trans_add_str( ":xmp.\n", section, &alloc_size ); Tab_xmp = TRUE; Blank_line_pfx = FALSE; // remove preceding blanks } return( alloc_size ); case CH_BOX_ON: /* Table support is the closest thing to boxing in IPF, but it doesn't work well with changing fonts on items in the tables (the edges don't line up). So we draw long lines at the top and bottom instead */ draw_line( section, &alloc_size ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_BOX_OFF: draw_line( section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_OLIST_START: trans_add_list( ":ol", section, &alloc_size, ptr ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_LIST_START: trans_add_list( ":ul", section, &alloc_size, ptr ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_DLIST_START: trans_add_str( ":dl break=all tsize=5.\n", section, &alloc_size ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_SLIST_START: trans_add_list( ":sl", section, &alloc_size, ptr ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_SLIST_END: trans_add_str( ":esl.\n", section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_OLIST_END: trans_add_str( ":eol.\n", section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_LIST_END: trans_add_str( ":eul.\n", section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_DLIST_END: trans_add_str( ":edl.\n", section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_LIST_ITEM: case CH_DLIST_TERM: /* eat blank lines before list items and terms */ Blank_line_pfx = FALSE; break; case CH_CTX_KW: ptr = whole_keyword_line( ptr ); if( ptr == NULL ) { return( alloc_size ); } break; } if( *skip_blank( ptr ) == '\0' ) { /* ignore blanks lines before the topic starts */ if( !Curr_ctx->empty ) { /* the line is completely blank. This tells us to output a blank line. BUT, all lists and things automatically generate blank lines before they display, so we must pend the line */ Blank_line_pfx = TRUE; } return( alloc_size ); } /* An explanation of 'Blank_line_pfx': when we hit a blank line, we set Blank_line_pfx to TRUE. On the non-tag next line, the blank line is generated. Some tags automatically generate a blank line, so they turn this flag off. This causes the next non-tag line to NOT put out the blank line */ if( Blank_line_pfx ) { if( Blank_line_sfx ) { line_len += trans_add_str( ".br\n", section, &alloc_size ); } Blank_line_pfx = FALSE; } /* An explanation of 'Blank_line_sfx': some ending tags automatically generate a blank line, so no blank line after them should get generated. Normally, this flag is set to TRUE, but ending tags and Defn list term tags set this FALSE, so no extra '.br' is generated. But, this rule only applies if a blank line immediately follows the tag, so its reset here regardless */ Blank_line_sfx = TRUE; ch = *(unsigned char *)ptr; if( ch != CH_LIST_ITEM && ch != CH_DLIST_TERM && ch != CH_DLIST_DESC && !Tab_xmp ) { /* a .br in front of li and dt would generate extra spaces */ line_len += trans_add_str( ".br\n", section, &alloc_size ); } term_fix = FALSE; for( ;; ) { ch = *(unsigned char *)ptr; if( ch == '\0' ) { if( term_fix ) { trans_add_str( ":ehp2.", section, &alloc_size ); term_fix = FALSE; } trans_add_char( '\n', section, &alloc_size ); break; } else if( ch == CH_HLINK || ch == CH_DFN ) { Curr_ctx->empty = FALSE; /* there are no popups in IPF, so treat them as links */ ctx_name = ptr + 1; ptr = strchr( ptr + 1, ch ); if( ptr == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } *ptr = '\0'; ctx_text = ptr + 1; ptr = strchr( ctx_text + 1, ch ); if( ptr == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } *ptr = '\0'; add_link( ctx_name ); sprintf( buf, ":link reftype=hd refid=%s.", ctx_name ); line_len += trans_add_str( buf, section, &alloc_size ); line_len += trans_add_str_ipf( ctx_text, section, &alloc_size ); ch_len += strlen( ctx_text ); line_len += trans_add_str( ":elink.", section, &alloc_size ); ++ptr; } else if( ch == CH_FLINK ) { Curr_ctx->empty = FALSE; file_name = strchr( ptr + 1, ch ); if( file_name == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } ctx_name = strchr( file_name + 1, ch ); if( ctx_name == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } ctx_text = strchr( ctx_name + 1, ch ); if( ctx_text == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } *ctx_text = '\0'; ctx_text = ctx_name + 1; *ctx_name = '\0'; ctx_name = file_name + 1; *file_name = '\0'; file_name = ptr + 1; sprintf( buf, ":link reftype=launch object='view.exe' " "data='%s %s'.", file_name, ctx_name ); line_len += trans_add_str( buf, section, &alloc_size ); line_len += trans_add_str_ipf( ctx_text, section, &alloc_size ); ch_len += strlen( ctx_text ); line_len += trans_add_str( ":elink.", section, &alloc_size ); ptr = ctx_text + strlen( ctx_text ) + 1; } else if( ch == CH_LIST_ITEM ) { /* list item */ line_len += trans_add_str( ":li.", section, &alloc_size ); ptr = skip_blank( ptr + 1 ); } else if( ch == CH_DLIST_DESC ) { trans_add_str( ":dd.", section, &alloc_size ); ptr = skip_blank( ptr + 1 ); } else if( ch == CH_DLIST_TERM ) { /* definition list term */ ptr = skip_blank( ptr + 1 ); if( *(unsigned char *)ptr == CH_FONTSTYLE_START ) { /* avoid nesting */ line_len += trans_add_str( ":dt.", section, &alloc_size ); Blank_line_sfx = FALSE; } else { line_len += trans_add_str( ":dt.:hp2.", section, &alloc_size ); term_fix = TRUE; Blank_line_sfx = FALSE; } } else if( ch == CH_CTX_KW ) { end = strchr( ptr + 1, CH_CTX_KW ); memcpy( buf, ptr + 1, end - ptr - 1 ); buf[end - ptr - 1] = '\0'; add_ctx_keyword( Curr_ctx, buf ); ptr = end + 1; if( *ptr == ' ' ) { /* kludge fix cuz of GML: GML thinks that keywords are are real words, so it puts a space after them. This should fix that */ ++ptr; } } else if( ch == CH_PAR_RESET ) { /* this can be ignored for IPF */ ++ptr; } else if( ch == CH_BMP ) { Curr_ctx->empty = FALSE; ++ptr; ch = *(unsigned char *)ptr; ptr += 2; end = strchr( ptr, CH_BMP ); *end = '\0'; switch( ch ) { case 'i': sprintf( buf, ":artwork runin name='%s'.", ptr ); break; case 'l': sprintf( buf, ":artwork align=left name='%s'.", ptr ); break; case 'r': sprintf( buf, ":artwork align=right name='%s'.", ptr ); break; case 'c': sprintf( buf, ":artwork align=center name='%s'.", ptr ); break; } line_len += trans_add_str( buf, section, &alloc_size ); ptr = end + 1; } else if( ch == CH_FONTSTYLE_START ) { ++ptr; end = strchr( ptr, CH_FONTSTYLE_START ); font_idx = 0; for( ; ptr != end; ++ptr ) { switch( *ptr ) { case 'b': font_idx |= FONT_STYLE_BOLD; break; case 'i': font_idx |= FONT_STYLE_ITALIC; break; case 'u': case 's': font_idx |= FONT_STYLE_UNDERLINE; break; } } line_len += trans_add_str( Font_match[font_idx], section, &alloc_size ); Font_list[Font_list_curr] = font_idx; ++Font_list_curr; ++ptr; } else if( ch == CH_FONTSTYLE_END ) { --Font_list_curr; line_len += trans_add_str( Font_end[Font_list[Font_list_curr]], section, &alloc_size ); ++ptr; } else if( ch == CH_FONTTYPE ) { ++ptr; end = strchr( ptr, CH_FONTTYPE ); *end = '\0'; strcpy( buf, ":font facename=" ); if( Real_ipf_font ) { /* This code supports fonts in the expected manor, but not in the usual IPF way. In IPF, font switching (including sizing) is NEVER done, except to Courier for examples. So, this code is inappropriate */ if( stricmp( ptr, Fonttype_roman ) == 0 ) { strcat( buf, "'Tms Rmn'" ); } else if( stricmp( ptr, Fonttype_helv ) == 0 ) { strcat( buf, "Helv" ); } else { /* Symbol doesn't work,so use courier instead */ strcat( buf, "Courier" ); } line_len += trans_add_str( buf, section, &alloc_size ); ptr = end + 1; end = strchr( ptr, CH_FONTTYPE ); *end = '\0'; sprintf( buf, " size=%dx10.", atoi( ptr ) ); } else { /* this code turns all font changes to the default system font, except for Courier. This is the normal IPF way */ strcat( buf, "Courier" ); if( stricmp( ptr, Fonttype_courier ) == 0 ) { strcat( buf, " size=12x10." ); } else { /* default system font */ strcat( buf, " size=0x0." ); } ptr = end + 1; end = strchr( ptr, CH_FONTTYPE ); } line_len += trans_add_str( buf, section, &alloc_size ); ptr = end + 1; } else { ++ptr; Curr_ctx->empty = FALSE; if( Tab_xmp && ch == Tab_xmp_char ) { len = tab_align( ch_len, section, &alloc_size ); ch_len += len; line_len += len; ptr = skip_blank( ptr ); } else { line_len += trans_add_char_ipf( ch, section, &alloc_size ); ++ch_len; } if( line_len > 120 && ch == ' ' && !Tab_xmp ) { /* break onto the next line */ line_len = 0; trans_add_char( '\n', section, &alloc_size ); } } } return( alloc_size ); }
int ib_trans_line( /*****************/ section_def *section, int alloc_size ) { char *ptr; char *end; int ch; char *ctx_name; char *ctx_text; char buf[ 100 ]; int indent = 0; int ctr; char *file_name; // check for special pre-processing stuff first ptr = Line_buf; ch = *(unsigned char *)ptr; // We start at a new line... Wrap_Safe = section->section_size; Cursor_X = 0; R_Chars = 0; if( Blank_line && ( ch != CH_LIST_ITEM || Curr_list->compact != LIST_SPACE_COMPACT ) ) { Blank_line = FALSE; } switch( ch ) { // Tabbed-example case CH_TABXMP: if( *skip_blank( ptr + 1 ) == '\0' ) { Tab_xmp = FALSE; } else { read_tabs( ptr + 1 ); Tab_xmp = TRUE; } return( alloc_size ); // Box-mode start case CH_BOX_ON: ctr = 0; // indent properly while( ctr < Curr_indent ) { ctr++; trans_add_char( ' ', section, &alloc_size); } // draw the top line of the box trans_add_char( BOX_CORNER_TOP_LEFT, section, &alloc_size ); for( ctr = 1; ctr <= Right_Margin - Curr_indent - 2; ctr++ ) { trans_add_char( BOX_HBAR, section, &alloc_size ); } trans_add_char( BOX_CORNER_TOP_RIGHT, section, &alloc_size ); trans_add_char_wrap( '\n', section, &alloc_size); Box_Mode = TRUE; return( alloc_size ); case CH_BOX_OFF: ctr = 0; while( ctr < Curr_indent ) { ctr++; trans_add_char( ' ', section, &alloc_size); } trans_add_char( BOX_CORNER_BOTOM_LEFT, section, &alloc_size ); for( ctr = 1; ctr <= Right_Margin - Curr_indent - 2; ctr++ ) { trans_add_char( BOX_HBAR, section, &alloc_size ); } trans_add_char( BOX_CORNER_BOTOM_RIGHT, section, &alloc_size ); Box_Mode = FALSE; trans_add_char_wrap( '\n', section, &alloc_size ); return( alloc_size ); case CH_OLIST_START: new_list( LIST_TYPE_ORDERED ); set_compact( ptr ); Curr_indent += Text_Indent; return( alloc_size ); case CH_LIST_START: case CH_DLIST_START: new_list( ( ch == CH_LIST_START ) ? LIST_TYPE_UNORDERED : LIST_TYPE_DEFN ); set_compact( ptr ); Curr_indent += Text_Indent; if( ch == CH_DLIST_START ) { ptr = skip_blank( ptr + 1 ); if( *ptr != '\0' ) { /* due to a weakness in GML, the definition term must be allowed on the same line as the definition tag. So if its there, continue */ break; } } return( alloc_size ); case CH_DLIST_TERM: Curr_indent -= Text_Indent; break; case CH_SLIST_START: indent = 0; if( Curr_list->type == LIST_TYPE_SIMPLE ) { /* nested simple lists, with no pre-indent. Force an indent */ indent = Text_Indent; } new_list( LIST_TYPE_SIMPLE ); set_compact( ptr ); Curr_indent += indent; return( alloc_size ); case CH_SLIST_END: case CH_OLIST_END: case CH_LIST_END: case CH_DLIST_END: pop_list(); return( alloc_size ); case CH_DLIST_DESC: Curr_indent += Text_Indent; if( *skip_blank( ptr + 1 ) == '\0' ) { /* no description on this line. Ignore it so that no blank line gets generated */ return( alloc_size ); } break; case CH_CTX_KW: ptr = whole_keyword_line( ptr ); if( ptr == NULL ) { return( alloc_size ); } break; } // skip preceding blank lines if( *skip_blank( ptr ) == '\0' && Curr_ctx->empty ) { return( alloc_size ); } // remove '\n' on the end if( Blank_line ) { --section->section_size; } // indent properly if the first char is not white-space if( ch != '\0' && ch != ' ' && ch != '\t') { ctr = ( ch == CH_LIST_ITEM && !Box_Mode && Curr_list->type != LIST_TYPE_SIMPLE ) ? Text_Indent : 0; while( ctr < Curr_indent ) { ctr++; trans_add_char_wrap( ' ', section, &alloc_size); } if( Box_Mode ) { trans_add_char_wrap( BOX_VBAR, section, &alloc_size); trans_add_char_wrap( ' ', section, &alloc_size); } } Blank_line = TRUE; for( ;; ) { ch = *(unsigned char *)ptr; if( ch != '\0' && ( ch != ' ' || ch != '\t' ) ) { Blank_line = FALSE; } if( ch == '\0' ) { // this just shuts off bolding after a def. list term if( Line_postfix == LPOSTFIX_TERM ) { Line_postfix = LPOSTFIX_NONE; trans_add_str( STR_BOLD_OFF, section, &alloc_size ); } trans_add_char_wrap( '\n', section, &alloc_size ); break; } else if( ch == CH_HLINK || ch == CH_DFN || ch == CH_FLINK ) { Curr_ctx->empty = FALSE; if( ch == CH_FLINK ) { file_name = strchr( ptr + 1, ch ); if( file_name == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } *file_name = '\0'; } else { file_name = ptr; } ctx_name = strchr( file_name + 1, ch ); if( ctx_name == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } *ctx_name = '\0'; ctx_text = strchr( ctx_name + 1, ch ); if( ctx_text == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } *ctx_text = '\0'; ctx_text = ctx_name + 1; ctx_name = file_name + 1; file_name = ptr + 1; if( ch != CH_FLINK ) { add_link( ctx_name ); } ptr = ctx_text + strlen( ctx_text ) + 1; // Definition pop-up's are converted to hyper-links in InfoBench trans_add_char( CHR_TEMP_HLINK , section, &alloc_size ); // Add line number to hyperlink so we can give meaningful errors trans_add_str( itoa( Line_num, buf, 10 ), section, &alloc_size ); trans_add_char( CHR_TEMP_HLINK, section, &alloc_size ); // We don't want links to break as IB doesn't like this... to_nobreak( ctx_text ); indent = Curr_indent; if( indent < 0 ) indent = 0; // find out the maximum allowed length for hyper-link text: ctr = Right_Margin - indent - ( ( Hyper_Brace_L == '<' ) ? 2 : 0 ); // if the link name is too long then we warn & truncate it if( strlen( ctx_text ) > ctr ) { warning( "Hyperlink name too long", Line_num ); ctx_text[ ctr ] = '\0'; } /* If hyper-link bracing is on we have to do a kludge to fix * the spacing. The "XX" will make the wrap routine happy. * They're stripped off when it comes time to write the file. */ if( Hyper_Brace_L == '<' ) { trans_add_str_wrap( "XX", section, &alloc_size ); } trans_add_str_wrap( ctx_text, section, &alloc_size ); trans_add_char( CHR_HLINK_BREAK , section, &alloc_size ); trans_add_str( ctx_name, section, &alloc_size ); if( ch == CH_FLINK ) { trans_add_char( CHR_HLINK_BREAK, section, &alloc_size ); trans_add_str( file_name, section, &alloc_size ); } trans_add_char( CHR_TEMP_HLINK , section, &alloc_size ); } else if( ch == CH_LIST_ITEM ) { if( Curr_list->type != LIST_TYPE_SIMPLE ) { if( Curr_list->type == LIST_TYPE_UNORDERED ) { // generate a bullet, correctly spaced for tab size buf[0] = '\0'; for( ctr = 1; ctr <= Text_Indent; ctr++) { strcat( buf, " " ); } buf[ Text_Indent / 2 - 1 ] = CHR_BULLET; } else if( Curr_list->type == LIST_TYPE_ORDERED ) { /* ordered list type */ sprintf( buf, "%*d. ", Text_Indent - 2, Curr_list->number ); ++Curr_list->number; } trans_add_str_wrap( buf, section, &alloc_size ); } Eat_blanks = TRUE; ptr = skip_blank( ptr + 1 ); } else if( ch == CH_DLIST_DESC ) { ptr = skip_blank( ptr + 1 ); } else if( ch == CH_DLIST_TERM ) { /* definition list term */ trans_add_str( STR_BOLD_ON, section, &alloc_size ); Line_postfix = LPOSTFIX_TERM; ptr = skip_blank( ptr + 1 ); Eat_blanks = TRUE; } else if( ch == CH_CTX_KW ) { end = strchr( ptr + 1, CH_CTX_KW ); memcpy( buf, ptr + 1, end - ptr - 1 ); buf[end - ptr - 1] = '\0'; add_ctx_keyword( Curr_ctx, buf ); ptr = end + 1; if( *ptr == ' ' ) { /* kludge fix cuz of GML: GML thinks that keywords are are real words, so it puts a space after them. This should fix that */ ++ptr; } } else if( ch == CH_PAR_RESET ) { // we ignore paragraph resets ++ptr; } else if( ch == CH_BMP ) { // we ignore bitmaps ptr = strchr( ptr + 3, CH_BMP ) + 1; } else if( ch == CH_FONTSTYLE_START ) { ++ptr; end = strchr( ptr, CH_FONTSTYLE_START ); for( ; ptr != end; ++ptr ) { switch( *ptr ) { // bold and italic map to bold case 'b': case 'i': trans_add_str( STR_BOLD_ON, section, &alloc_size ); break; // underline and underscore map to underline case 'u': case 's': trans_add_str( STR_UNDERLINE_ON, section, &alloc_size ); break; } } ++ptr; } else if( ch == CH_FONTSTYLE_END ) { // reset style (bold off, underline off) trans_add_str( Reset_Style, section, &alloc_size ); ++ptr; } else if( ch == CH_FONTTYPE ) { // we basically ignore font type changes ptr = strchr( strchr( ptr + 1 , CH_FONTTYPE ) + 1, CH_FONTTYPE ) + 1; } else { ++ptr; if( !Eat_blanks || ch != ' ' ) { Curr_ctx->empty = FALSE; if( Tab_xmp && ch == Tab_xmp_char ) { tab_align( section, &alloc_size ); ptr = skip_blank( ptr ); } else { trans_add_char_wrap( ch, section, &alloc_size ); } Eat_blanks = FALSE; } } } return( alloc_size ); }
int html_trans_line( section_def *section, int alloc_size ) /*********************************************************/ { char *ptr; char *end; int ch; char *ctx_name; char *ctx_text; char buf[ 500 ]; int font_idx; int line_len; bool term_fix; int ch_len; int len; char *file_name; /* check for special column 0 stuff first */ ptr = Line_buf; ch = *(unsigned char *)ptr; ch_len = 0; line_len = 0; switch( ch ) { case CH_TABXMP: if( *skip_blank( ptr + 1 ) == '\0' ) { Tab_xmp = FALSE; trans_add_str( "</xmp>\n", section, &alloc_size ); Blank_line_sfx = FALSE; // remove following blanks } else { read_tabs( ptr + 1 ); trans_add_str( "<xmp>\n", section, &alloc_size ); Tab_xmp = TRUE; Blank_line_pfx = FALSE; // remove preceding blanks } return( alloc_size ); case CH_BOX_ON: /* Table support is the closest thing to boxing in IPF, but it doesn't work well with changing fonts on items in the tables (the edges don't line up). So we draw long lines at the top and bottom instead */ draw_line( section, &alloc_size ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_BOX_OFF: draw_line( section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_OLIST_START: trans_add_list( "<OL>\n", section, &alloc_size, ptr ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_LIST_START: trans_add_list( "<UL>\n", section, &alloc_size, ptr ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_DLIST_START: trans_add_str( "<DL>\n", section, &alloc_size ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_SLIST_START: trans_add_list( "<UL>\n", section, &alloc_size, ptr ); Blank_line_pfx = FALSE; return( alloc_size ); case CH_SLIST_END: trans_add_str( "</UL>\n", section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_OLIST_END: trans_add_str( "</OL>\n", section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_LIST_END: trans_add_str( "</UL>\n", section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_DLIST_END: trans_add_str( "</DL>\n", section, &alloc_size ); Blank_line_sfx = FALSE; return( alloc_size ); case CH_LIST_ITEM: case CH_DLIST_TERM: /* eat blank lines before list items and terms */ Blank_line_pfx = FALSE; break; case CH_CTX_KW: ptr = whole_keyword_line( ptr ); if( ptr == NULL ) { return( alloc_size ); } break; } if( *skip_blank( ptr ) == '\0' ) { /* ignore blanks lines before the topic starts */ if( !Curr_ctx->empty ) { /* the line is completely blank. This tells us to output a blank line. BUT, all lists and things automatically generate blank lines before they display, so we must pend the line */ Blank_line_pfx = TRUE; } return( alloc_size ); } /* An explanation of 'Blank_line_pfx': when we hit a blank line, we set Blank_line_pfx to TRUE. On the non-tag next line, the blank line is generated. Some tags automatically generate a blank line, so they turn this flag off. This causes the next non-tag line to NOT put out the blank line */ if( Blank_line_pfx ) { if( Blank_line_sfx ) { line_len += trans_add_str( "<BR>", section, &alloc_size ); } Blank_line_pfx = FALSE; } /* An explanation of 'Blank_line_sfx': some ending tags automatically generate a blank line, so no blank line after them should get generated. Normally, this flag is set to TRUE, but ending tags and Defn list term tags set this FALSE, so no extra '<BR>' is generated. But, this rule only applies if a blank line immediately follows the tag, so its reset here regardless */ Blank_line_sfx = TRUE; ch = *(unsigned char *)ptr; if( ch != CH_LIST_ITEM && ch != CH_DLIST_TERM && ch != CH_DLIST_DESC && !Tab_xmp ) { /* a .br in front of li and dt would generate extra spaces */ line_len += trans_add_str( "<BR>", section, &alloc_size ); } term_fix = FALSE; for( ;; ) { ch = *(unsigned char *)ptr; if( ch == '\0' ) { if( term_fix ) { // trans_add_str( "</hp2>", section, &alloc_size ); term_fix = FALSE; } trans_add_char( '\n', section, &alloc_size ); break; } else if( ch == CH_HLINK || ch == CH_DFN ) { Curr_ctx->empty = FALSE; /* there are no popups in IPF, so treat them as links */ ctx_name = ptr + 1; ptr = strchr( ptr + 1, ch ); if( ptr == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } *ptr = '\0'; ctx_text = ptr + 1; ptr = strchr( ctx_text + 1, ch ); if( ptr == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } *ptr = '\0'; add_link( ctx_name ); sprintf( buf, "<A HREF=\"#%s\">", ctx_name ); line_len += trans_add_str( buf, section, &alloc_size ); line_len += trans_add_str_html( ctx_text, section, &alloc_size ); ch_len += strlen( ctx_text ); line_len += trans_add_str( "</A>", section, &alloc_size ); ++ptr; } else if( ch == CH_FLINK ) { Curr_ctx->empty = FALSE; file_name = strchr( ptr + 1, ch ); if( file_name == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } ctx_name = strchr( file_name + 1, ch ); if( ctx_name == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } ctx_text = strchr( ctx_name + 1, ch ); if( ctx_text == NULL ) { error( ERR_BAD_LINK_DFN, TRUE ); } *ctx_text = '\0'; ctx_text = ctx_name + 1; *ctx_name = '\0'; ctx_name = file_name + 1; *file_name = '\0'; file_name = ptr + 1; sprintf( buf, "<A HREF=\"#%s\">", ctx_name ); line_len += trans_add_str( buf, section, &alloc_size ); line_len += trans_add_str_html( ctx_text, section, &alloc_size ); ch_len += strlen( ctx_text ); line_len += trans_add_str( "</A>", section, &alloc_size ); ptr = ctx_text + strlen( ctx_text ) + 1; } else if( ch == CH_LIST_ITEM ) { /* list item */ line_len += trans_add_str( "<LI>", section, &alloc_size ); ptr = skip_blank( ptr + 1 ); } else if( ch == CH_DLIST_DESC ) { trans_add_str( "<DD>", section, &alloc_size ); ptr = skip_blank( ptr + 1 ); } else if( ch == CH_DLIST_TERM ) { /* definition list term */ line_len += trans_add_str( "<DT>", section, &alloc_size ); term_fix = TRUE; ptr = skip_blank( ptr + 1 ); Blank_line_sfx = FALSE; } else if( ch == CH_CTX_KW ) { end = strchr( ptr + 1, CH_CTX_KW ); memcpy( buf, ptr + 1, end - ptr - 1 ); buf[ end - ptr - 1 ] = '\0'; add_ctx_keyword( Curr_ctx, buf ); ptr = end + 1; if( *ptr == ' ' ) { /* kludge fix cuz of GML: GML thinks that keywords are are real words, so it puts a space after them. This should fix that */ ++ptr; } } else if( ch == CH_PAR_RESET ) { /* this can be ignored for IPF */ ++ptr; } else if( ch == CH_BMP ) { Curr_ctx->empty = FALSE; ++ptr; ch = *(unsigned char *)ptr; ptr += 2; end = strchr( ptr, CH_BMP ); *end = '\0'; // convert filenames to lower case strlwr( ptr ); switch( ch ) { case 'i': sprintf( buf, "<IMG SRC=\"%s\">", ptr ); break; case 'l': sprintf( buf, "<IMG SRC=\"%s\" ALIGN=TOP>", ptr ); break; case 'r': sprintf( buf, "<IMG SRC=\"%s\" ALIGN=BOTTOM>", ptr ); break; case 'c': sprintf( buf, "<IMG SRC=\"%s\" ALIGN=MIDDLE>", ptr ); break; } line_len += trans_add_str( buf, section, &alloc_size ); ptr = end + 1; } else if( ch == CH_FONTSTYLE_START ) { ++ptr; end = strchr( ptr, CH_FONTSTYLE_START ); font_idx = 0; for( ; ptr != end; ++ptr ) { switch( *ptr ) { case 'b': font_idx |= FONT_STYLE_BOLD; break; case 'i': font_idx |= FONT_STYLE_ITALIC; break; case 'u': case 's': font_idx |= FONT_STYLE_UNDERLINE; break; } } line_len += trans_add_str( Font_match[ font_idx ], section, &alloc_size ); Font_list[ Font_list_curr ] = font_idx; ++Font_list_curr; ++ptr; } else if( ch == CH_FONTSTYLE_END ) { --Font_list_curr; line_len += trans_add_str( Font_end[ Font_list[ Font_list_curr ] ], section, &alloc_size ); ++ptr; } else if( ch == CH_FONTTYPE ) { ++ptr; end = strchr( ptr, CH_FONTTYPE ); *end = '\0'; if( stricmp( ptr, Fonttype_courier ) == 0 ) { strcpy( buf, "<TT>" ); } else { /* default system font */ strcpy( buf, "</TT>" ); } ptr = end + 1; end = strchr( ptr, CH_FONTTYPE ); line_len += trans_add_str( buf, section, &alloc_size ); ptr = end + 1; } else { ++ptr; Curr_ctx->empty = FALSE; if( Tab_xmp && ch == Tab_xmp_char ) { len = tab_align( ch_len, section, &alloc_size ); ch_len += len; line_len += len * sizeof( HTML_SPACE ); ptr = skip_blank( ptr ); } if( line_len > 120 && ch == ' ' && !Tab_xmp ) { /* break onto the next line */ line_len = 0; trans_add_char( '\n', section, &alloc_size ); if( *ptr == ' ' ) { line_len += trans_add_str( HTML_SPACE, section, &alloc_size ); ++ch_len; ptr++; } } else { line_len += trans_add_char_html( ch, *(unsigned char *)ptr, section, &alloc_size ); ++ch_len; } } } return( alloc_size ); }